From: Martin Willi Date: Fri, 31 Aug 2012 13:50:09 +0000 (+0200) Subject: Support a %M specifier in the enum_name printf hook, selecting enum_name with a callback X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=6d13d4c9f0255240d6894713da1784095209d1be;p=thirdparty%2Fstrongswan.git Support a %M specifier in the enum_name printf hook, selecting enum_name with a callback --- diff --git a/src/libstrongswan/enum.c b/src/libstrongswan/enum.c index 2dc7c5dde1..bb552bf335 100644 --- a/src/libstrongswan/enum.c +++ b/src/libstrongswan/enum.c @@ -63,11 +63,43 @@ int enum_from_name(enum_name_t *e, char *name) int enum_printf_hook(printf_hook_data_t *data, printf_hook_spec_t *spec, const void *const *args) { - enum_name_t *ed = *((enum_name_t**)(args[0])); - int val = *((int*)(args[1])); + enum_name_t *e; + int val; + char *name; - char *name = enum_to_name(ed, val); + e = *((enum_name_t**)(args[0])); + val = *((int*)(args[1])); + name = enum_to_name(e, val); + if (name == NULL) + { + return print_in_hook(data, "(%d)", val); + } + else + { + return print_in_hook(data, "%s", name); + } +} +/** + * Described in header. + */ +int enum_dynamic_printf_hook(printf_hook_data_t *data, printf_hook_spec_t *spec, + const void *const *args) +{ + enum_name_t *e; + enum_name_get_t e_get; + int val, id = 0; + char *name = NULL; + + e_get = *((enum_name_get_t*)(args[0])); + id = *((int*)(args[1])); + val = *((int*)(args[2])); + + e = e_get(id); + if (e) + { + name = enum_to_name(e, val); + } if (name == NULL) { return print_in_hook(data, "(%d)", val); diff --git a/src/libstrongswan/enum.h b/src/libstrongswan/enum.h index 840371245c..63daa6c69e 100644 --- a/src/libstrongswan/enum.h +++ b/src/libstrongswan/enum.h @@ -26,6 +26,14 @@ typedef struct enum_name_t enum_name_t; +/** + * Callback function to get an enum name using an index variable. + * + * @param index variable to select enum_name_t + * @return enum name + */ +typedef enum_name_t* (*enum_name_get_t)(int id); + /** * Struct to store names for enums. * @@ -52,6 +60,11 @@ typedef struct enum_name_t enum_name_t; * character %N is replaced by the enum string. Printf needs two arguments to * resolve a %N, the enum_name_t* (the defined name in ENUM_BEGIN) followed * by the numerical enum value. + * + * To select an enum name dynamically, the %M printf format specifier can be + * used. Instead of an enum_name_t, the printf hook expects a enum_name_get_t + * followed by an index, followed by the enum value. The enum_name_t is looked + * up using the function and the index argument. */ struct enum_name_t { /** value of the first enum string */ @@ -133,4 +146,13 @@ int enum_from_name(enum_name_t *e, char *name); int enum_printf_hook(printf_hook_data_t *data, printf_hook_spec_t *spec, const void *const *args); +/** + * printf hook function for dynamically selected enum_names_t. + * + * Arguments are: + * enum_name_get_t getter, int index, int value + */ +int enum_dynamic_printf_hook(printf_hook_data_t *data, printf_hook_spec_t *spec, + const void *const *args); + #endif /** ENUM_H_ @}*/ diff --git a/src/libstrongswan/library.c b/src/libstrongswan/library.c index ed3f52027a..9a19f6b6d5 100644 --- a/src/libstrongswan/library.c +++ b/src/libstrongswan/library.c @@ -168,6 +168,9 @@ bool library_init(char *settings) pfh->add_handler(pfh, 'N', enum_printf_hook, PRINTF_HOOK_ARGTYPE_POINTER, PRINTF_HOOK_ARGTYPE_INT, PRINTF_HOOK_ARGTYPE_END); + pfh->add_handler(pfh, 'M', enum_dynamic_printf_hook, + PRINTF_HOOK_ARGTYPE_POINTER, PRINTF_HOOK_ARGTYPE_INT, + PRINTF_HOOK_ARGTYPE_INT, PRINTF_HOOK_ARGTYPE_END); pfh->add_handler(pfh, 'T', time_printf_hook, PRINTF_HOOK_ARGTYPE_POINTER, PRINTF_HOOK_ARGTYPE_INT, PRINTF_HOOK_ARGTYPE_END);