]> granicus.if.org Git - strace/commitdiff
evdev: support various types of xlats in decode_bitset
authorEugene Syromyatnikov <evgsyr@gmail.com>
Mon, 2 Apr 2018 18:32:19 +0000 (20:32 +0200)
committerDmitry V. Levin <ldv@altlinux.org>
Fri, 27 Apr 2018 00:56:25 +0000 (00:56 +0000)
* evdev.c (enum xlat_type): New enumeration.
(printxval_dispatch): New function.
(decode_bitset_): Rename from decode_bitset, add decode_nr_size
and xt arguments, call printxval_dispatch instead of printxval.
(decode_bitset): Add a decode_bitset_ wrapper that derives
decode_nr_size from the ARRAY_SIZE of decode_nr.
(bit_ioctl, evdev_read_ioctl): Update decode_bitset calls.

evdev.c

diff --git a/evdev.c b/evdev.c
index 6616eca13e991cad73c6d3d0727c372147229432..bafadbd0d27c6993a65f7b95cbdb0bdf91b91deb 100644 (file)
--- a/evdev.c
+++ b/evdev.c
@@ -163,10 +163,35 @@ getid_ioctl(struct tcb *const tcp, const kernel_ulong_t arg)
        return RVAL_IOCTL_DECODED;
 }
 
+enum xlat_type {
+       XT_NORMAL,
+       XT_SORTED,
+       XT_INDEXED,
+};
+
+static void
+printxval_dispatch(const struct xlat *xlat, size_t xlat_size, uint64_t val,
+                  const char *dflt, enum xlat_type xt)
+{
+       switch (xt) {
+       case XT_NORMAL:
+               printxval64(xlat, val, dflt);
+               break;
+
+       case XT_SORTED:
+               printxval_searchn(xlat, xlat_size, val, dflt);
+               break;
+
+       case XT_INDEXED:
+               printxval_indexn(xlat, xlat_size, val, dflt);
+               break;
+       }
+}
+
 static int
-decode_bitset(struct tcb *const tcp, const kernel_ulong_t arg,
-             const struct xlat decode_nr[], const unsigned int max_nr,
-             const char *const dflt)
+decode_bitset_(struct tcb *const tcp, const kernel_ulong_t arg,
+              const struct xlat decode_nr[], const unsigned int max_nr,
+              const char *const dflt, size_t decode_nr_size, enum xlat_type xt)
 {
        tprints(", ");
 
@@ -187,7 +212,7 @@ decode_bitset(struct tcb *const tcp, const kernel_ulong_t arg,
        if (i < 0) {
                tprints(" 0 ");
        } else {
-               printxval(decode_nr, i, dflt);
+               printxval_dispatch(decode_nr, decode_nr_size, i, dflt, xt);
 
                while ((i = next_set_bit(decoded_arg, i + 1, size)) > 0) {
                        if (abbrev(tcp) && bit_displayed >= 3) {
@@ -195,7 +220,8 @@ decode_bitset(struct tcb *const tcp, const kernel_ulong_t arg,
                                break;
                        }
                        tprints(", ");
-                       printxval(decode_nr, i, dflt);
+                       printxval_dispatch(decode_nr, decode_nr_size, i, dflt,
+                                          xt);
                        bit_displayed++;
                }
        }
@@ -205,6 +231,10 @@ decode_bitset(struct tcb *const tcp, const kernel_ulong_t arg,
        return RVAL_IOCTL_DECODED;
 }
 
+#define decode_bitset(tcp_, arg_, decode_nr_, max_nr_, dflt_, xt_) \
+       decode_bitset_((tcp_), (arg_), (decode_nr_), (max_nr_), \
+                      (dflt_), ARRAY_SIZE(decode_nr_), (xt_))
+
 # ifdef EVIOCGMTSLOTS
 static int
 mtslots_ioctl(struct tcb *const tcp, const unsigned int code,
@@ -255,41 +285,42 @@ bit_ioctl(struct tcb *const tcp, const unsigned int ev_nr,
        switch (ev_nr) {
                case EV_SYN:
                        return decode_bitset(tcp, arg, evdev_sync,
-                                            SYN_MAX, "SYN_???");
+                                            SYN_MAX, "SYN_???", XT_NORMAL);
                case EV_KEY:
                        return decode_bitset(tcp, arg, evdev_keycode,
-                                            KEY_MAX, "KEY_???");
+                                            KEY_MAX, "KEY_???", XT_NORMAL);
                case EV_REL:
                        return decode_bitset(tcp, arg, evdev_relative_axes,
-                                            REL_MAX, "REL_???");
+                                            REL_MAX, "REL_???", XT_NORMAL);
                case EV_ABS:
                        return decode_bitset(tcp, arg, evdev_abs,
-                                            ABS_MAX, "ABS_???");
+                                            ABS_MAX, "ABS_???", XT_NORMAL);
                case EV_MSC:
                        return decode_bitset(tcp, arg, evdev_misc,
-                                            MSC_MAX, "MSC_???");
+                                            MSC_MAX, "MSC_???", XT_NORMAL);
                case EV_SW:
                        return decode_bitset(tcp, arg, evdev_switch,
-                                            SW_MAX, "SW_???");
+                                            SW_MAX, "SW_???", XT_NORMAL);
                case EV_LED:
                        return decode_bitset(tcp, arg, evdev_leds,
-                                            LED_MAX, "LED_???");
+                                            LED_MAX, "LED_???", XT_NORMAL);
                case EV_SND:
                        return decode_bitset(tcp, arg, evdev_snd,
-                                            SND_MAX, "SND_???");
+                                            SND_MAX, "SND_???", XT_NORMAL);
                case EV_REP:
                        return decode_bitset(tcp, arg, evdev_autorepeat,
-                                            REP_MAX, "REP_???");
+                                            REP_MAX, "REP_???", XT_NORMAL);
                case EV_FF:
                        return decode_bitset(tcp, arg, evdev_ff_types,
-                                            FF_MAX, "FF_???");
+                                            FF_MAX, "FF_???", XT_NORMAL);
                case EV_PWR:
                        tprints(", ");
                        printnum_int(tcp, arg, "%d");
                        return RVAL_IOCTL_DECODED;
                case EV_FF_STATUS:
                        return decode_bitset(tcp, arg, evdev_ff_status,
-                                            FF_STATUS_MAX, "FF_STATUS_???");
+                                            FF_STATUS_MAX, "FF_STATUS_???",
+                                            XT_NORMAL);
                default:
                        tprints(", ");
                        printaddr(arg);
@@ -343,22 +374,23 @@ evdev_read_ioctl(struct tcb *const tcp, const unsigned int code,
 # ifdef EVIOCGPROP
                case _IOC_NR(EVIOCGPROP(0)):
                        return decode_bitset(tcp, arg, evdev_prop,
-                                            INPUT_PROP_MAX, "PROP_???");
+                                            INPUT_PROP_MAX, "PROP_???",
+                                            XT_NORMAL);
 # endif
                case _IOC_NR(EVIOCGSND(0)):
                        return decode_bitset(tcp, arg, evdev_snd,
-                                            SND_MAX, "SND_???");
+                                            SND_MAX, "SND_???", XT_NORMAL);
 # ifdef EVIOCGSW
                case _IOC_NR(EVIOCGSW(0)):
                        return decode_bitset(tcp, arg, evdev_switch,
-                                            SW_MAX, "SW_???");
+                                            SW_MAX, "SW_???", XT_NORMAL);
 # endif
                case _IOC_NR(EVIOCGKEY(0)):
                        return decode_bitset(tcp, arg, evdev_keycode,
-                                            KEY_MAX, "KEY_???");
+                                            KEY_MAX, "KEY_???", XT_NORMAL);
                case _IOC_NR(EVIOCGLED(0)):
                        return decode_bitset(tcp, arg, evdev_leds,
-                                            LED_MAX, "LED_???");
+                                            LED_MAX, "LED_???", XT_NORMAL);
        }
 
        /* multi-number fixed-length commands */