From: Dmitry V. Levin Date: Thu, 8 Jun 2017 22:15:58 +0000 (+0000) Subject: Introduce printflags_ex function X-Git-Tag: v4.18~100 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=127962f217a8205666431352bd611f7b2062476b;p=strace Introduce printflags_ex function Add printflags_ex extension over printflags64 that, similar to printxvals, takes a NULL-terminated sequence of xlat pointers. * defs.h (printflags_ex): New prototype. (printflags64): Turn into a thin wrapper around printflags_ex. * netlink.c (decode_nlmsg_flags): Use printflags_ex. * util.c (printflags_ex): New function. (printflags64): Remove. * xlat/netlink_get_flags.in: Remove entries listed in xlat/netlink_flags.in file. * xlat/netlink_new_flags.in: Likewise. --- diff --git a/defs.h b/defs.h index 51e5809e..6449bce9 100644 --- a/defs.h +++ b/defs.h @@ -564,7 +564,8 @@ extern int printargs_u(struct tcb *); extern int printargs_d(struct tcb *); extern void addflags(const struct xlat *, uint64_t); -extern int printflags64(const struct xlat *, uint64_t, const char *); +extern int printflags_ex(uint64_t, const char *, const struct xlat *, ...) + ATTRIBUTE_SENTINEL; extern const char *sprintflags(const char *, const struct xlat *, uint64_t); extern const char *sprinttime(long long sec); extern const char *sprinttime_nsec(long long sec, unsigned long long nsec); @@ -703,6 +704,12 @@ printstr(struct tcb *tcp, kernel_ulong_t addr) printstr_ex(tcp, addr, -1, QUOTE_0_TERMINATED); } +static inline int +printflags64(const struct xlat *x, uint64_t flags, const char *dflt) +{ + return printflags_ex(flags, dflt, x, NULL); +} + static inline int printflags(const struct xlat *x, unsigned int flags, const char *dflt) { diff --git a/netlink.c b/netlink.c index dc8a3493..049843de 100644 --- a/netlink.c +++ b/netlink.c @@ -157,7 +157,7 @@ decode_nlmsg_type(const uint16_t type, const unsigned int family) static void decode_nlmsg_flags(const uint16_t flags, const uint16_t type, const int family) { - const struct xlat *table = netlink_flags; + const struct xlat *table = NULL; switch (family) { case NETLINK_SOCK_DIAG: @@ -198,7 +198,7 @@ decode_nlmsg_flags(const uint16_t flags, const uint16_t type, const int family) break; } - printflags(table, flags, "NLM_F_???"); + printflags_ex(flags, "NLM_F_???", netlink_flags, table, NULL); } static int diff --git a/util.c b/util.c index c4128def..0316744e 100644 --- a/util.c +++ b/util.c @@ -409,29 +409,28 @@ sprintflags(const char *prefix, const struct xlat *xlat, uint64_t flags) } int -printflags64(const struct xlat *xlat, uint64_t flags, const char *dflt) +printflags_ex(uint64_t flags, const char *dflt, const struct xlat *xlat, ...) { - int n; - const char *sep; - - if (flags == 0 && xlat->val == 0 && xlat->str) { - tprints(xlat->str); - return 1; - } + unsigned int n = 0; + va_list args; - sep = ""; - for (n = 0; xlat->str; xlat++) { - if (xlat->val && (flags & xlat->val) == xlat->val) { - tprintf("%s%s", sep, xlat->str); - flags &= ~xlat->val; - sep = "|"; - n++; + va_start(args, xlat); + for (; xlat; xlat = va_arg(args, const struct xlat *)) { + for (; (flags || !n) && xlat->str; ++xlat) { + if ((flags == xlat->val) || + (xlat->val && (flags & xlat->val) == xlat->val)) { + tprintf("%s%s", (n++ ? "|" : ""), xlat->str); + flags &= ~xlat->val; + } + if (!flags) + break; } } + va_end(args); if (n) { if (flags) { - tprintf("%s%#" PRIx64, sep, flags); + tprintf("|%#" PRIx64, flags); n++; } } else { diff --git a/xlat/netlink_get_flags.in b/xlat/netlink_get_flags.in index 0b68ba91..96ab4a06 100644 --- a/xlat/netlink_get_flags.in +++ b/xlat/netlink_get_flags.in @@ -1,10 +1,3 @@ -NLM_F_REQUEST -NLM_F_MULTI -NLM_F_ACK -NLM_F_ECHO -NLM_F_DUMP_INTR -NLM_F_DUMP_FILTERED - NLM_F_DUMP NLM_F_ROOT NLM_F_MATCH diff --git a/xlat/netlink_new_flags.in b/xlat/netlink_new_flags.in index fa0c8594..4ef2fea6 100644 --- a/xlat/netlink_new_flags.in +++ b/xlat/netlink_new_flags.in @@ -1,10 +1,3 @@ -NLM_F_REQUEST -NLM_F_MULTI -NLM_F_ACK -NLM_F_ECHO -NLM_F_DUMP_INTR -NLM_F_DUMP_FILTERED - NLM_F_REPLACE NLM_F_EXCL NLM_F_CREATE