aboutsummaryrefslogtreecommitdiffstats
path: root/src/starter/parser/conf_parser.c
diff options
context:
space:
mode:
authorTobias Brunner <tobias@strongswan.org>2017-05-26 13:57:57 +0200
committerTobias Brunner <tobias@strongswan.org>2017-05-26 14:24:13 +0200
commitb668bf3f9ec1e6e44cb31c727ac928105e383b32 (patch)
treedb62e4fcd1a955b5179c6f172a9403500bb24e50 /src/starter/parser/conf_parser.c
parent0da10b73addd8c181bed0772c7eac32d28d8af77 (diff)
parent2e4d110d1e94a3be9da06894832492ff469eec37 (diff)
downloadstrongswan-b668bf3f9ec1.tar.bz2
strongswan-b668bf3f9ec1.tar.xz
Merge branch 'variadic-enumerators'
This adds several changes to enumerator_t and linked_list_t to improve portability. In particular to Apple's ARM64 iOS platform, whose calling convention for variadic and regular functions are different. This means that assigning a non-variadic function to a variadic function pointer, as we did with our enumerator_t::enumerate() implementations and several callbacks, will result in crashes as the called function will access the arguments differently than the caller provided them. To avoid this issue the enumerator_t interface is now fully variadic. A new mandatory method is added, venumerate(), that takes a va_list with the arguments provided while enumerating. enumerate() is replaced with a generic implementation that prepares a va_list and calls the enumerator's venumerate() implementation. As this allows passing the arguments of one enumerator to another it avoids the five pointer hack used by enumerator_create_nested() and enumerator_create_cleaner(). To simplify the implementation of venumerate() a helper macro is provided that assigns values from a given va_list to local variables. The signature of the callback passed to enumerator_create_filter() has also changed significantly. It's now required to enumerate over the original enumerator in the callback as this avoids the previous in/out pointer hack. The arguments to the outer enumerator are provided in a va_list. Similar changes to avoid such five pointer hacks affect the signatures of the callbacks for linked_list_t's invoke_function() and find_first() methods. For the latter the return type also changed from status_t to bool, which is important as SUCCESS is defined as 0, so checks for == SUCCESS will now fail.
Diffstat (limited to 'src/starter/parser/conf_parser.c')
-rw-r--r--src/starter/parser/conf_parser.c55
1 files changed, 39 insertions, 16 deletions
diff --git a/src/starter/parser/conf_parser.c b/src/starter/parser/conf_parser.c
index 6d1c54d20..66e0ae8e4 100644
--- a/src/starter/parser/conf_parser.c
+++ b/src/starter/parser/conf_parser.c
@@ -158,10 +158,13 @@ typedef struct {
} dictionary_enumerator_t;
METHOD(enumerator_t, dictionary_enumerate, bool,
- dictionary_enumerator_t *this, char **key, char **value)
+ dictionary_enumerator_t *this, va_list args)
{
setting_t *setting;
section_t *parent;
+ char **key, **value;
+
+ VA_ARGS_VGET(args, key, value);
while (TRUE)
{
@@ -221,7 +224,8 @@ METHOD(dictionary_t, dictionary_create_enumerator, enumerator_t*,
INIT(enumerator,
.public = {
- .enumerate = (void*)_dictionary_enumerate,
+ .enumerate = enumerator_enumerate_default,
+ .venumerate = _dictionary_enumerate,
.destroy = _dictionary_enumerator_destroy,
},
.seen = hashtable_create(hashtable_hash_str, hashtable_equals_str, 8),
@@ -290,24 +294,43 @@ static dictionary_t *section_dictionary_create(private_conf_parser_t *parser,
return &this->public;
}
-static bool conn_filter(void *unused, section_t **section, char **name)
+CALLBACK(conn_filter, bool,
+ void *unused, enumerator_t *orig, va_list args)
{
- if (streq((*section)->name, "%default"))
+ section_t *section;
+ char **name;
+
+ VA_ARGS_VGET(args, name);
+
+ while (orig->enumerate(orig, &section))
{
- return FALSE;
+ if (!streq(section->name, "%default"))
+ {
+ *name = section->name;
+ return TRUE;
+ }
}
- *name = (*section)->name;
- return TRUE;
+ return FALSE;
}
-static bool ca_filter(void *unused, void *key, char **name, section_t **section)
+CALLBACK(ca_filter, bool,
+ void *unused, enumerator_t *orig, va_list args)
{
- if (streq((*section)->name, "%default"))
+ void *key;
+ section_t *section;
+ char **name;
+
+ VA_ARGS_VGET(args, name);
+
+ while (orig->enumerate(orig, &key, &section))
{
- return FALSE;
+ if (!streq(section->name, "%default"))
+ {
+ *name = section->name;
+ return TRUE;
+ }
}
- *name = (*section)->name;
- return TRUE;
+ return FALSE;
}
METHOD(conf_parser_t, get_sections, enumerator_t*,
@@ -317,12 +340,12 @@ METHOD(conf_parser_t, get_sections, enumerator_t*,
{
case CONF_PARSER_CONN:
return enumerator_create_filter(
- array_create_enumerator(this->conns_order),
- (void*)conn_filter, NULL, NULL);
+ array_create_enumerator(this->conns_order),
+ conn_filter, NULL, NULL);
case CONF_PARSER_CA:
return enumerator_create_filter(
- this->cas->create_enumerator(this->cas),
- (void*)ca_filter, NULL, NULL);
+ this->cas->create_enumerator(this->cas),
+ ca_filter, NULL, NULL);
case CONF_PARSER_CONFIG_SETUP:
default:
return enumerator_create_empty();