summaryrefslogtreecommitdiff
path: root/src/libstrongswan/utils/enum.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/libstrongswan/utils/enum.c')
-rw-r--r--src/libstrongswan/utils/enum.c93
1 files changed, 88 insertions, 5 deletions
diff --git a/src/libstrongswan/utils/enum.c b/src/libstrongswan/utils/enum.c
index f96fe2989..089bebb79 100644
--- a/src/libstrongswan/utils/enum.c
+++ b/src/libstrongswan/utils/enum.c
@@ -60,20 +60,103 @@ bool enum_from_name_as_int(enum_name_t *e, const char *name, int *val)
}
/**
+ * Get the position of a flag name using offset calculation
+ */
+static int find_flag_pos(u_int val, u_int first)
+{
+ int offset = 0;
+
+ while (val != 0x01)
+ {
+ val = val >> 1;
+ offset++;
+ }
+ return first - offset;
+}
+
+/**
* Described in header.
*/
+char *enum_flags_to_string(enum_name_t *e, u_int val, char *buf, size_t len)
+{
+ char *pos = buf, *delim = "";
+ int i, wr;
+
+ if (e->next != ENUM_FLAG_MAGIC)
+ {
+ if (snprintf(buf, len, "(%d)", (int)val) >= len)
+ {
+ return NULL;
+ }
+ return buf;
+ }
+
+ if (snprintf(buf, len, "(unset)") >= len)
+ {
+ return NULL;
+ }
+
+ for (i = 0; val; i++)
+ {
+ u_int flag = 1 << i;
+
+ if (val & flag)
+ {
+ char *name = NULL, hex[32];
+
+ if (flag >= (u_int)e->first && flag <= (u_int)e->last)
+ {
+ name = e->names[find_flag_pos(e->first, i)];
+ }
+ else
+ {
+ snprintf(hex, sizeof(hex), "(0x%X)", flag);
+ name = hex;
+ }
+ if (name)
+ {
+ wr = snprintf(pos, len, "%s%s", delim, name);
+ if (wr >= len)
+ {
+ return NULL;
+ }
+ len -= wr;
+ pos += wr;
+ delim = " | ";
+ }
+ val &= ~flag;
+ }
+ }
+ return buf;
+}
+
+/**
+ * See header.
+ */
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]));
- char *name, buf[32];
+ char *name, buf[512];
- name = enum_to_name(ed, val);
- if (name == NULL)
+ if (ed->next == ENUM_FLAG_MAGIC)
+ {
+ name = enum_flags_to_string(ed, val, buf, sizeof(buf));
+ if (name == NULL)
+ {
+ snprintf(buf, sizeof(buf), "(0x%X)", val);
+ name = buf;
+ }
+ }
+ else
{
- snprintf(buf, sizeof(buf), "(%d)", val);
- name = buf;
+ name = enum_to_name(ed, val);
+ if (name == NULL)
+ {
+ snprintf(buf, sizeof(buf), "(%d)", val);
+ name = buf;
+ }
}
if (spec->minus)
{