diff options
author | Yves-Alexis Perez <corsac@debian.org> | 2015-04-11 22:03:59 +0200 |
---|---|---|
committer | Yves-Alexis Perez <corsac@debian.org> | 2015-04-11 22:03:59 +0200 |
commit | 83b8aebb19fe6e49e13a05d4e8f5ab9a06177642 (patch) | |
tree | 51255545ba43b84aa5d673bd0eb557cbd0155c9e /src/libstrongswan/utils/enum.c | |
parent | 2b8de74ff4c334c25e89988c4a401b24b5bcf03d (diff) | |
download | vyos-strongswan-83b8aebb19fe6e49e13a05d4e8f5ab9a06177642.tar.gz vyos-strongswan-83b8aebb19fe6e49e13a05d4e8f5ab9a06177642.zip |
Imported Upstream version 5.3.0
Diffstat (limited to 'src/libstrongswan/utils/enum.c')
-rw-r--r-- | src/libstrongswan/utils/enum.c | 93 |
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) { |