From: Martin Willi Date: Fri, 31 Aug 2012 12:59:06 +0000 (+0200) Subject: Add a fallback callback to enum_name printf hook X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=c307a81e021c5662323008185d35571cc43986ea;p=thirdparty%2Fstrongswan.git Add a fallback callback to enum_name printf hook If mapping the enum value failed, the callback can directly write to the output stream to write the fallback value. --- diff --git a/src/libstrongswan/enum.c b/src/libstrongswan/enum.c index 6481f6f828..31f2d09c66 100644 --- a/src/libstrongswan/enum.c +++ b/src/libstrongswan/enum.c @@ -78,6 +78,10 @@ int enum_printf_hook(printf_hook_data_t *data, printf_hook_spec_t *spec, name = enum_to_name(e, val); if (name == NULL) { + if (e->cb) + { + return e->cb(data, 0, e, val); + } return print_in_hook(data, "(%d)", val); } else @@ -108,6 +112,10 @@ int enum_dynamic_printf_hook(printf_hook_data_t *data, printf_hook_spec_t *spec, } if (name == NULL) { + if (e && e->cb) + { + return e->cb(data, id, e, val); + } return print_in_hook(data, "(%d)", val); } else diff --git a/src/libstrongswan/enum.h b/src/libstrongswan/enum.h index f24e032897..69cf5a62b5 100644 --- a/src/libstrongswan/enum.h +++ b/src/libstrongswan/enum.h @@ -35,6 +35,21 @@ typedef struct enum_name_elem_t enum_name_elem_t; */ typedef enum_name_t* (*enum_name_get_t)(int id); +/** + * Fallback callback to call if enum could not be mapped to a string. + * + * This callback is invoked from within the printf hook. Use print_in_hook() + * with the supplied data to write to the output stream. + * + * @param data printf hook data to pass to print_in_hook() + * @param id index variable, as passed to enum_name_get function, or 0 + * @param e enum name for which callback is invoked + * @param val enum value to map + * @return number of characters written + */ +typedef int (*enum_name_cb_t)(printf_hook_data_t *data, int id, enum_name_t *e, + int val); + /** * Struct to store names for enums. * @@ -70,6 +85,8 @@ typedef enum_name_t* (*enum_name_get_t)(int id); struct enum_name_t { /** first enum_name_elem_t in chain */ enum_name_elem_t *elem; + /** callback function to invoke if enum string for value not found */ + enum_name_cb_t cb; }; struct enum_name_elem_t { @@ -116,6 +133,17 @@ struct enum_name_elem_t { static enum_name_t name##head = { .elem = &name##prev }; \ enum_name_t *name = &name##head +/** + * Complete enum name list started with ENUM_BEGIN, with a fallback callback. + * + * @param name name of the enum_name list + * @param cbf callback function if enum value could not be mapped + * @param prev enum value of the "last" defined in ENUM_BEGIN/previous ENUM_NEXT + */ +#define ENUM_END_CB(name, cbf, prev) \ + static enum_name_t name##head = { .elem = &name##prev, .cb = cbf }; \ + enum_name_t *name = &name##head + /** * Define a enum name with only one range. * @@ -130,6 +158,18 @@ struct enum_name_elem_t { #define ENUM(name, first, last, ...) \ ENUM_BEGIN(name, first, last, __VA_ARGS__); ENUM_END(name, last) +/** + * Define a enum name with only one range, but with a fallback callback. + * + * @param name name of the enum_name list + * @param cbf callback function if enum value could not be mapped + * @param first enum value of the first enum string + * @param last enum value of the last enum string + * @param ... a list of strings + */ +#define ENUM_CB(name, cbf, first, last, ...) \ + ENUM_BEGIN(name, first, last, __VA_ARGS__); ENUM_END_CB(name, cbf, last) + /** * Convert a enum value to its string representation. *