]> granicus.if.org Git - strace/commitdiff
Add xlat description structure
authorEugene Syromyatnikov <evgsyr@gmail.com>
Sun, 19 Aug 2018 17:53:06 +0000 (19:53 +0200)
committerDmitry V. Levin <ldv@altlinux.org>
Wed, 24 Jul 2019 17:12:18 +0000 (17:12 +0000)
Rename struct xlat to struct xlat_data and make struct xlat an xlat
descriptor that contains various information about xlat.
So far it's the type and the number of items.

As a result, xlookup/printxval now have enough information for handling
xlat depending on its type, so *index/*_search API is not needed any
longer.

* xlat.h (struct xlat_data): Rename from struct xlat.
(struct xlat): New type definition.
* xlat.c (xlat_search, printxval_sized, printxval_searchn_ex, xlat_idx,
printxval_indexn_ex, printxval_dispatch_ex): Remove.
(xlookup): Handle xlat_data based on xlat type.
(xlat_search_eq_or_less, xlookup_le): New functions.
(sprintflags_ex, printflags_ex): Update.
* xlat/gen.sh (gen_header): Add handling for #sorted, generate new
struct xlat descriptor.
* defs.h (arp_hardware_types_size, ethernet_protocols_size,
inet_protocols_size, evdev_abs_size, xlat_search, xlat_idx,
printxval_searchn_ex, printxval_searchn, printxval_search,
printxval_search_ex, printxval_indexn_ex, printxval_indexn,
printxval_index, printxval_index_ex, printxval_dispatch_ex,
printxval_dispatch): Remove.
(enum xlat_style_private_flag_bits): Remove PAF_INDEX_XLAT_SORTED_BIT
and PAF_INDEX_XLAT_VALUE_INDEXED_BIT.
(enum xlat_style_private_flag): Remove PAF_INDEX_XLAT_SORTED and
PAF_INDEX_XLAT_VALUE_INDEXED.
(print_array_ex): Remove index_xlat_size argument.
(xlookup_le): New declaration.
(printxval_ex): New macro.
* dyxlat.c (struct dyxlat): Remove used field (use xlat.size instead),
embed struct xlat, add pointer to struct xlat_data.
(MARK_END): Remove.
(dyxlat_alloc, dyxlat_free, dyxlat_get, dyxlat_add_pair): Update in
accordance with the structure changes.
* evdev.c (evdev_abs_size): Remove.
(keycode_ioctl): Use printxval instead of printxval_index.
(decode_bitset): Remove.
(decode_bitset_): Rename to decode_bitset, remove decode_nr_size and xt
arguments, call printxval instead of printxval_dispatch.
(bit_ioctl, evdev_read_ioctl): Do not pass xlat type to decode_bitset.
* fsconfig.c (SYS_FUNC(fsconfig)): Use printxval instead of
printxval_index.
* print_fields.h (PRINT_FIELD_XVAL_SORTED_SIZED,
PRINT_FIELD_XVAL_INDEX): Remove.
* nlattr.h (struct decode_nla_xlat_opts): Remove xlat_size and xt
fields.
* nlattr.c (decode_nla_meminfo): Do not pass
PAF_INDEX_XLAT_VALUE_INDEXED flag and netlink_sk_meminfo_indices size
in a print_array_ex call.
(decode_nla_xval): Call printxval_ex instead of printxval_dispatch_ex.
(decode_nla_ether_proto, decode_nla_ip_proto): Do not pass xlat_size and
xt fields in opts.
(decode_nla_flags): Remove XT_INDEXED unsupported warning.
* process.c (struct_user_offsets_data): Rename from struct_user_offsets,
change type to struct xlat_data[].
(struct_user_offsets): New xlat description.
(print_user_offset_addr): Rewrite using xlookup_le.
* util.c (print_array_ex): Remove index_xlat_size argument, simply call
printxval_ex for index printing.
* aio.c (tprint_lio_opcode): Use printxval_ex instead of
printxval_indexn_ex.
* bpf.c: Use printxval instead of printxval_index; use PRINT_FIELD_XVAL
instead of PRINT_FIELD_XVAL_INDEX.
* bpf_filter.c (print_bpf_filter_code): Use printxval instead of
printxval_index.
* ioctl.c (evdev_decode_number): Use printxval instead of
printxval_indexn.
* kvm.c (kvm_ioctl_decode_check_extension): Use printxval64 instead of
printxval_index.
(kvm_ioctl_run_attach_auxstr): Use xlookup instead of xlat_idx.
* net.c: Use printxval instead of printxval_search/printxval_index, use
printxval_ex instead of printxval_searchn_ex.
* netlink.c (get_fd_nl_family): Rewrite using xlat descriptor structure.
* netlink_packet_diag.c (decode_packet_diag_msg): Use PRINT_FIELD_XVAL
instead of PRINT_FIELD_XVAL_SORTED_SIZED.
* netlink_smc_diag.c (decode_smc_diag_shutdown): Remove ARRSZ_PAIR
wrapper.
(decode_smc_diag_fallback): Use printxval_ex instead of
printxval_search_ex.
(decode_smc_diag_msg): Use PRINT_FIELD_XVAL instead of
PRINT_FIELD_XVAL_INDEX.
* print_statfs.c (print_statfs_type): Use printxval instead of
printxval_search.
* ptrace_syscall_info.c (print_ptrace_syscall_info): Use
PRINT_FIELD_XVAL instead of PRINT_FIELD_XVAL_INDEX.
* rtnl_link.c (decode_ifla_inet6_flags, decode_ifla_inet6_agm):
Likewise.
(decode_nla_tun_type, decode_ifla_xdp_attached): Remove xlat_size,
xt fields.
(decode_ifla_inet_conf, decode_ifla_inet6_conf, decode_ifla_inet6_stats,
decode_ifla_inet6_icmp6_stats): Remove PAF_INDEX_XLAT_VALUE_INDEXED flag
and ARRSZ_PAIR wrapper in print_array_ex calls.
(decode_ifinfomsg): Use PRINT_FIELD_XVAL instead of
PRINT_FIELD_XVAL_SORTED_SIZED.
* rtnl_route.c (decode_nla_rt_proto): Use printxval instead of
printxval_search.
* sock.c (print_ifreq): Use PRINT_FIELD_XVAL instead of
PRINT_FIELD_XVAL_SORTED_SIZED.
* sockaddr.c (print_sockaddr_data_ll, print_sockaddr_data_bt,
print_sockaddr): Use printxval instead of printxval_search and
printxval_index.
* time.c (getitimer, osf_getitimer, setitimer, osf_setitimer,
printclockname): Use printxval instead of printxval_index.
(do_adjtimex): Use xlookup instead of xlat_idx.
* tests/btrfs.c: Update xlat handling, use struct xlat_data instead of
struct xlat for XLAT() arrays.
* tests/ioctl_block.c: Likewise.
* tests/ioctl_rtc.c: Likewise.
* tests/printflags.c: Likewise.
* tests/printxval.c: Likewise.
* tests/prlimit64.c: Likewise.
* tests/setrlimit.c: Likewise.
* tests/socketcall.c: Likewise.
* tests/xgetrlimit.c: Likewise.
* tests/xstatfsx.c: Likewise.
* xlat/af_packet_versions.in: Add #value_indexed.
* xlat/arp_hardware_types.in: Add #sorted.
* xlat/ax25_protocols.in: Likewise.
* xlat/bluetooth_l2_cid.in: Likewise.
* xlat/bluetooth_l2_psm.in: Likewise.
* xlat/ethernet_protocols.in: Likewise.
* xlat/evdev_ff_types.in: Likewise.
* xlat/fsmagic.in: Likewise.
* xlat/hw_breakpoint_type.in: Likewise.
* xlat/iffflags.in: Likewise.
* xlat/inet6_if_flags.in: Likewise.
* xlat/inet_protocols.in: Likewise.
* xlat/msgctl_flags.in: Likewise.
* xlat/perf_hw_cache_id.in: Likewise.
* xlat/perf_hw_cache_op_id.in: Likewise.
* xlat/perf_hw_cache_op_result_id.in: Likewise.
* xlat/perf_hw_id.in: Likewise.
* xlat/perf_sw_ids.in: Likewise.
* xlat/perf_type_id.in: Likewise.
* xlat/routing_protocols.in: Likewise.
* xlat/semctl_flags.in: Likewise.
* xlat/shmctl_flags.in: Likewise.
* xlat/smc_decl_codes.in: Likewise.
* xlat/sock_ax25_options.in: Likewise.
* xlat/sock_bluetooth_options.in: Likewise.
* xlat/sock_dccp_options.in: Likewise.
* xlat/sock_tipc_options.in: Likewise.
* xlat/socketlayers.in: Likewise.
* xlat/v4l2_control_classes.in: Likewise.
* xlat/v4l2_pix_fmts.in: Likewise.
* xlat/v4l2_sdr_fmts.in: Likewise.

Co-Authored-by: Dmitry V. Levin <ldv@altlinux.org>
69 files changed:
aio.c
bpf.c
bpf_filter.c
defs.h
dyxlat.c
evdev.c
fsconfig.c
ioctl.c
kvm.c
net.c
netlink.c
netlink_packet_diag.c
netlink_smc_diag.c
nlattr.c
nlattr.h
print_fields.h
print_statfs.c
process.c
ptrace_syscall_info.c
rtnl_link.c
rtnl_route.c
sock.c
sockaddr.c
tests/btrfs.c
tests/ioctl_block.c
tests/ioctl_rtc.c
tests/printflags.c
tests/printxval.c
tests/prlimit64.c
tests/setrlimit.c
tests/socketcall.c
tests/xgetrlimit.c
tests/xstatfsx.c
time.c
util.c
xlat.c
xlat.h
xlat/af_packet_versions.in
xlat/arp_hardware_types.in
xlat/ax25_protocols.in
xlat/bluetooth_l2_cid.in
xlat/bluetooth_l2_psm.in
xlat/ethernet_protocols.in
xlat/evdev_ff_types.in
xlat/fsmagic.in
xlat/gen.sh
xlat/hw_breakpoint_type.in
xlat/iffflags.in
xlat/inet6_if_flags.in
xlat/inet_protocols.in
xlat/msgctl_flags.in
xlat/perf_hw_cache_id.in
xlat/perf_hw_cache_op_id.in
xlat/perf_hw_cache_op_result_id.in
xlat/perf_hw_id.in
xlat/perf_sw_ids.in
xlat/perf_type_id.in
xlat/routing_protocols.in
xlat/semctl_flags.in
xlat/shmctl_flags.in
xlat/smc_decl_codes.in
xlat/sock_ax25_options.in
xlat/sock_bluetooth_options.in
xlat/sock_dccp_options.in
xlat/sock_tipc_options.in
xlat/socketlayers.in
xlat/v4l2_control_classes.in
xlat/v4l2_pix_fmts.in
xlat/v4l2_sdr_fmts.in

diff --git a/aio.c b/aio.c
index 190ab35ec08b3844e714ae6786d3e5623e605720..45b1da88fe3dae322c5241fd906d6059a8389986 100644 (file)
--- a/aio.c
+++ b/aio.c
@@ -60,8 +60,7 @@ tprint_lio_opcode(unsigned int cmd)
                [IOCB_CMD_PWRITEV]      = SUB_VECTOR,
        };
 
-       printxval_indexn_ex(ARRSZ_PAIR(aio_cmds) - 1, cmd, "IOCB_CMD_???",
-                           XLAT_STYLE_FMT_U);
+       printxval_ex(aio_cmds, cmd, "IOCB_CMD_???", XLAT_STYLE_FMT_U);
 
        return cmd < ARRAY_SIZE(subs) ? subs[cmd] : SUB_NONE;
 }
diff --git a/bpf.c b/bpf.c
index 20ad938f526374d05d2e497212056d8584d9d034..e335bb74585141053bfe5a27fbea5785408d806c 100644 (file)
--- a/bpf.c
+++ b/bpf.c
@@ -131,9 +131,9 @@ print_ebpf_insn(struct tcb * const tcp, void * const elem_buf,
 
        /* We can't use PRINT_FIELD_XVAL on bit fields */
        tprints(", dst_reg=");
-       printxval_index(ebpf_regs, insn->dst_reg, "BPF_REG_???");
+       printxval(ebpf_regs, insn->dst_reg, "BPF_REG_???");
        tprints(", src_reg=");
-       printxval_index(ebpf_regs, insn->src_reg, "BPF_REG_???");
+       printxval(ebpf_regs, insn->src_reg, "BPF_REG_???");
 
        PRINT_FIELD_D(", ", *insn, off);
        PRINT_FIELD_X(", ", *insn, imm);
@@ -159,8 +159,8 @@ print_ebpf_prog(struct tcb *const tcp, const uint64_t addr, const uint32_t len)
 
 BEGIN_BPF_CMD_DECODER(BPF_MAP_CREATE)
 {
-       PRINT_FIELD_XVAL_INDEX("{", attr, map_type, bpf_map_types,
-                              "BPF_MAP_TYPE_???");
+       PRINT_FIELD_XVAL("{", attr, map_type, bpf_map_types,
+                        "BPF_MAP_TYPE_???");
        PRINT_FIELD_U(", ", attr, key_size);
        PRINT_FIELD_U(", ", attr, value_size);
        PRINT_FIELD_U(", ", attr, max_entries);
@@ -241,8 +241,8 @@ BEGIN_BPF_CMD_DECODER(BPF_MAP_UPDATE_ELEM)
        PRINT_FIELD_FD("{", attr, map_fd, tcp);
        PRINT_FIELD_ADDR64(", ", attr, key);
        PRINT_FIELD_ADDR64(", ", attr, value);
-       PRINT_FIELD_XVAL_INDEX(", ", attr, flags, bpf_map_update_elem_flags,
-                              "BPF_???");
+       PRINT_FIELD_XVAL(", ", attr, flags, bpf_map_update_elem_flags,
+                        "BPF_???");
 }
 END_BPF_CMD_DECODER(RVAL_DECODED)
 
@@ -269,8 +269,8 @@ END_BPF_CMD_DECODER(RVAL_DECODED)
 
 BEGIN_BPF_CMD_DECODER(BPF_PROG_LOAD)
 {
-       PRINT_FIELD_XVAL_INDEX("{", attr, prog_type, bpf_prog_types,
-                              "BPF_PROG_TYPE_???");
+       PRINT_FIELD_XVAL("{", attr, prog_type, bpf_prog_types,
+                        "BPF_PROG_TYPE_???");
        PRINT_FIELD_U(", ", attr, insn_cnt);
        tprints(", insns=");
        print_ebpf_prog(tcp, attr.insns, attr.insn_cnt);
@@ -362,8 +362,7 @@ BEGIN_BPF_CMD_DECODER(BPF_PROG_ATTACH)
 {
        PRINT_FIELD_FD("{", attr, target_fd, tcp);
        PRINT_FIELD_FD(", ", attr, attach_bpf_fd, tcp);
-       PRINT_FIELD_XVAL_INDEX(", ", attr, attach_type, bpf_attach_type,
-                              "BPF_???");
+       PRINT_FIELD_XVAL(", ", attr, attach_type, bpf_attach_type, "BPF_???");
        PRINT_FIELD_FLAGS(", ", attr, attach_flags, bpf_attach_flags,
                          "BPF_F_???");
 }
@@ -372,8 +371,7 @@ END_BPF_CMD_DECODER(RVAL_DECODED)
 BEGIN_BPF_CMD_DECODER(BPF_PROG_DETACH)
 {
        PRINT_FIELD_FD("{", attr, target_fd, tcp);
-       PRINT_FIELD_XVAL_INDEX(", ", attr, attach_type, bpf_attach_type,
-                              "BPF_???");
+       PRINT_FIELD_XVAL(", ", attr, attach_type, bpf_attach_type, "BPF_???");
 }
 END_BPF_CMD_DECODER(RVAL_DECODED)
 
@@ -826,8 +824,8 @@ BEGIN_BPF_CMD_DECODER(BPF_PROG_QUERY)
 
        if (entering(tcp)) {
                PRINT_FIELD_FD("{query={", attr, target_fd, tcp);
-               PRINT_FIELD_XVAL_INDEX(", ", attr, attach_type, bpf_attach_type,
-                                      "BPF_???");
+               PRINT_FIELD_XVAL(", ", attr, attach_type, bpf_attach_type,
+                                "BPF_???");
                PRINT_FIELD_FLAGS(", ", attr, query_flags, bpf_query_flags,
                                  "BPF_F_QUERY_???");
                PRINT_FIELD_FLAGS(", ", attr, attach_flags, bpf_attach_flags,
@@ -909,8 +907,8 @@ BEGIN_BPF_CMD_DECODER(BPF_TASK_FD_QUERY)
        print_big_u64_addr(attr.buf);
        printstr_ex(tcp, attr.buf, buf_len, QUOTE_0_TERMINATED);
        PRINT_FIELD_U(", ", attr, prog_id);
-       PRINT_FIELD_XVAL_INDEX(", ", attr, fd_type, bpf_task_fd_type,
-                              "BPF_FD_TYPE_???");
+       PRINT_FIELD_XVAL(", ", attr, fd_type, bpf_task_fd_type,
+                        "BPF_FD_TYPE_???");
        PRINT_FIELD_X(", ", attr, probe_offset);
        PRINT_FIELD_X(", ", attr, probe_addr);
 
@@ -952,7 +950,7 @@ SYS_FUNC(bpf)
        int rc = RVAL_DECODED;
 
        if (entering(tcp)) {
-               printxval_index(bpf_commands, cmd, "BPF_???");
+               printxval(bpf_commands, cmd, "BPF_???");
                tprints(", ");
        }
 
index fbd26a5c86fa166cdde7e4b22099dab06945893c..8acf08d78ea60885148fc7c5b46307ee2738a985 100644 (file)
@@ -36,10 +36,8 @@ print_bpf_filter_code(const uint16_t code, bool extended)
        const struct xlat *mode = extended ? ebpf_mode : bpf_mode;
        uint16_t i = code & ~BPF_CLASS(code);
 
-       if (extended)
-               printxval_index(ebpf_class, BPF_CLASS(code), "BPF_???");
-       else
-               printxval_index(bpf_class, BPF_CLASS(code), "BPF_???");
+       printxval(extended ? ebpf_class : bpf_class, BPF_CLASS(code),
+                 "BPF_???");
        switch (BPF_CLASS(code)) {
        case BPF_ST:
        case BPF_STX:
diff --git a/defs.h b/defs.h
index 1c2624b8632a49d50eb2db7627b7d5bd18246b68..51622c05d63eea23b32baaa0cf8fc68dbc879660 100644 (file)
--- a/defs.h
+++ b/defs.h
@@ -310,30 +310,13 @@ extern const struct_sysent stub_sysent;
 # include "xlat.h"
 
 extern const struct xlat addrfams[];
-
-/** Protocol hardware identifiers array, sorted, defined in sockaddr.c. */
 extern const struct xlat arp_hardware_types[];
-/** Protocol hardware identifiers array size without terminating record. */
-extern const size_t arp_hardware_types_size;
-
 extern const struct xlat at_flags[];
 extern const struct xlat clocknames[];
 extern const struct xlat dirent_types[];
-
-/** Ethernet protocols list, sorted, defined in sockaddr.c. */
 extern const struct xlat ethernet_protocols[];
-/** Ethernet protocols array size without terminating record. */
-extern const size_t ethernet_protocols_size;
-
-/** IP protocols list, sorted, defined in net.c. */
 extern const struct xlat inet_protocols[];
-/** IP protocols array size without terminating record. */
-extern const size_t inet_protocols_size;
-
 extern const struct xlat evdev_abs[];
-/** Number of elements in evdev_abs array without the terminating record. */
-extern const size_t evdev_abs_size;
-
 extern const struct xlat audit_arch[];
 extern const struct xlat evdev_ev[];
 extern const struct xlat iffflags[];
@@ -628,8 +611,7 @@ extern unsigned long getfdinode(struct tcb *, int);
 extern enum sock_proto getfdproto(struct tcb *, int);
 
 extern const char *xlookup(const struct xlat *, const uint64_t);
-extern const char *xlat_search(const struct xlat *, const size_t, const uint64_t);
-extern const char *xlat_idx(const struct xlat *xlat, size_t nmemb, uint64_t val);
+extern const char *xlookup_le(const struct xlat *, uint64_t *);
 
 struct dyxlat;
 struct dyxlat *dyxlat_alloc(size_t nmemb);
@@ -701,46 +683,8 @@ extern int printxvals_ex(uint64_t val, const char *dflt,
        ATTRIBUTE_SENTINEL;
 # define printxvals(val_, dflt_, ...) \
        printxvals_ex((val_), (dflt_), XLAT_STYLE_DEFAULT, __VA_ARGS__)
-
-extern int printxval_searchn_ex(const struct xlat *, size_t xlat_size,
-                               uint64_t val, const char *dflt,
-                               enum xlat_style);
-
-static inline int
-printxval_searchn(const struct xlat *xlat, size_t xlat_size, uint64_t val,
-                 const char *dflt)
-{
-       return printxval_searchn_ex(xlat, xlat_size, val, dflt,
-                                   XLAT_STYLE_DEFAULT);
-}
-
-/**
- * Wrapper around printxval_searchn that passes ARRAY_SIZE - 1
- * as the array size, as all arrays are XLAT_END-terminated and
- * printxval_searchn expects a size without the terminating record.
- */
-# define printxval_search(xlat__, val__, dflt__) \
-       printxval_searchn(xlat__, ARRAY_SIZE(xlat__) - 1, val__, dflt__)
-# define printxval_search_ex(xlat__, val__, dflt__, style__) \
-       printxval_searchn_ex((xlat__), ARRAY_SIZE(xlat__) - 1, (val__), \
-                            (dflt__), (style__))
-
-extern int printxval_indexn_ex(const struct xlat *, size_t xlat_size,
-                              uint64_t val, const char *dflt, enum xlat_style);
-
-static inline int
-printxval_indexn(const struct xlat *xlat, size_t xlat_size, uint64_t val,
-                const char *dflt)
-{
-       return printxval_indexn_ex(xlat, xlat_size, val, dflt,
-                                  XLAT_STYLE_DEFAULT);
-}
-
-# define printxval_index(xlat__, val__, dflt__) \
-       printxval_indexn(xlat__, ARRAY_SIZE(xlat__) - 1, val__, dflt__)
-# define printxval_index_ex(xlat__, val__, dflt__, style__) \
-       printxval_indexn_ex((xlat__), ARRAY_SIZE(xlat__) - 1, (val__), \
-                           (dflt__), (style__))
+# define printxval_ex(xlat_, val_, dflt_, style_) \
+       printxvals_ex((val_), (dflt_), (style_), (xlat_), NULL)
 
 extern int sprintxval_ex(char *buf, size_t size, const struct xlat *,
                         unsigned int val, const char *dflt, enum xlat_style);
@@ -752,22 +696,9 @@ sprintxval(char *buf, size_t size, const struct xlat *xlat, unsigned int val,
        return sprintxval_ex(buf, size, xlat, val, dflt, XLAT_STYLE_DEFAULT);
 }
 
-extern void printxval_dispatch_ex(const struct xlat *, size_t xlat_size,
-                                 uint64_t val, const char *dflt,
-                                 enum xlat_type, enum xlat_style);
-static inline void
-printxval_dispatch(const struct xlat *xlat, size_t xlat_size, uint64_t val,
-                  const char *dflt, enum xlat_type xt)
-{
-       return printxval_dispatch_ex(xlat, xlat_size, val, dflt, xt,
-                                    XLAT_STYLE_DEFAULT);
-}
-
 enum xlat_style_private_flag_bits {
        /* print_array */
        PAF_PRINT_INDICES_BIT = XLAT_STYLE_SPEC_BITS + 1,
-       PAF_INDEX_XLAT_SORTED_BIT,
-       PAF_INDEX_XLAT_VALUE_INDEXED_BIT,
 
        /* print_xlat */
        PXF_DEFAULT_STR_BIT,
@@ -778,8 +709,6 @@ enum xlat_style_private_flag_bits {
 enum xlat_style_private_flags {
        /* print_array */
        FLAG_(PAF_PRINT_INDICES),
-       FLAG_(PAF_INDEX_XLAT_SORTED),
-       FLAG_(PAF_INDEX_XLAT_VALUE_INDEXED),
 
        /* print_xlat */
        FLAG_(PXF_DEFAULT_STR),
@@ -871,7 +800,6 @@ print_array_ex(struct tcb *,
               void *opaque_data,
               unsigned int flags,
               const struct xlat *index_xlat,
-              size_t index_xlat_size,
               const char *index_dflt);
 
 static inline bool
@@ -886,7 +814,7 @@ print_array(struct tcb *const tcp,
 {
        return print_array_ex(tcp, start_addr, nmemb, elem_buf, elem_size,
                              tfetch_mem_func, print_func, opaque_data,
-                             0, NULL, 0, NULL);
+                             0, NULL, NULL);
 }
 
 extern kernel_ulong_t *
index d575d46018ba6fd9b283decc75663e2692ae3237..52d20a49775763c9296e255b12c81024df466f4a 100644 (file)
--- a/dyxlat.c
+++ b/dyxlat.c
@@ -7,26 +7,21 @@
 #include "defs.h"
 
 struct dyxlat {
-       size_t used;
        size_t allocated;
-       struct xlat *xlat;
+       struct xlat xlat;
+       struct xlat_data *data;
 };
 
-#define MARK_END(xlat)                         \
-       do {                                    \
-               (xlat).val = 0;                 \
-               (xlat).str = 0;                 \
-       } while (0)
-
 struct dyxlat *
 dyxlat_alloc(const size_t nmemb)
 {
        struct dyxlat *const dyxlat = xmalloc(sizeof(*dyxlat));
 
-       dyxlat->used = 1;
+       dyxlat->xlat.type = XT_NORMAL;
+       dyxlat->xlat.size = 0;
        dyxlat->allocated = nmemb;
-       dyxlat->xlat = xgrowarray(NULL, &dyxlat->allocated, sizeof(struct xlat));
-       MARK_END(dyxlat->xlat[0]);
+       dyxlat->xlat.data = dyxlat->data = xgrowarray(NULL, &dyxlat->allocated,
+                                                     sizeof(struct xlat_data));
 
        return dyxlat;
 }
@@ -36,20 +31,20 @@ dyxlat_free(struct dyxlat *const dyxlat)
 {
        size_t i;
 
-       for (i = 0; i < dyxlat->used - 1; ++i) {
-               free((void *) dyxlat->xlat[i].str);
-               dyxlat->xlat[i].str = NULL;
+       for (i = 0; i < dyxlat->xlat.size; ++i) {
+               free((void *) dyxlat->data[i].str);
+               dyxlat->data[i].str = NULL;
        }
 
-       free(dyxlat->xlat);
-       dyxlat->xlat = NULL;
+       free(dyxlat->data);
+       dyxlat->xlat.data = NULL;
        free(dyxlat);
 }
 
 const struct xlat *
 dyxlat_get(const struct dyxlat *const dyxlat)
 {
-       return dyxlat->xlat;
+       return &dyxlat->xlat;
 }
 
 void
@@ -58,24 +53,24 @@ dyxlat_add_pair(struct dyxlat *const dyxlat, const uint64_t val,
 {
        size_t i;
 
-       for (i = 0; i < dyxlat->used - 1; ++i) {
-               if (dyxlat->xlat[i].val == val) {
-                       if (strncmp(dyxlat->xlat[i].str, str, len) == 0
-                           && dyxlat->xlat[i].str[len] == '\0')
+       for (i = 0; i < dyxlat->xlat.size; ++i) {
+               if (dyxlat->data[i].val == val) {
+                       if (strncmp(dyxlat->data[i].str, str, len) == 0
+                           && dyxlat->data[i].str[len] == '\0')
                                return;
 
-                       free((void *) dyxlat->xlat[i].str);
-                       dyxlat->xlat[i].str = xstrndup(str, len);
+                       free((void *) dyxlat->data[i].str);
+                       dyxlat->data[i].str = xstrndup(str, len);
                        return;
                }
        }
 
-       if (dyxlat->used >= dyxlat->allocated)
-               dyxlat->xlat = xgrowarray(dyxlat->xlat, &dyxlat->allocated,
-                                         sizeof(struct xlat));
+       if (dyxlat->xlat.size >= dyxlat->allocated)
+               dyxlat->xlat.data = dyxlat->data =
+                       xgrowarray(dyxlat->data, &dyxlat->allocated,
+                                  sizeof(struct xlat_data));
 
-       dyxlat->xlat[dyxlat->used - 1].val = val;
-       dyxlat->xlat[dyxlat->used - 1].str = xstrndup(str, len);
-       MARK_END(dyxlat->xlat[dyxlat->used]);
-       dyxlat->used++;
+       dyxlat->data[dyxlat->xlat.size].val = val;
+       dyxlat->data[dyxlat->xlat.size].str = xstrndup(str, len);
+       dyxlat->xlat.size++;
 }
diff --git a/evdev.c b/evdev.c
index a3d9cb5536e6985fa3f4ab704e599bf4deadf642..1baf3f12f55d338b5126d75cca9a4f42f55c8312 100644 (file)
--- a/evdev.c
+++ b/evdev.c
@@ -33,8 +33,6 @@
 #  define SYN_MAX 0xf
 # endif
 
-const size_t evdev_abs_size = ARRAY_SIZE(evdev_abs) - 1;
-
 static int
 abs_ioctl(struct tcb *const tcp, const kernel_ulong_t arg)
 {
@@ -78,7 +76,7 @@ keycode_ioctl(struct tcb *const tcp, const kernel_ulong_t arg)
 
        if (!umove_or_printaddr(tcp, arg, &keycode)) {
                tprintf("[%u, ", keycode[0]);
-               printxval_index(evdev_keycode, keycode[1], "KEY_???");
+               printxval(evdev_keycode, keycode[1], "KEY_???");
                tprints("]");
        }
 
@@ -105,7 +103,7 @@ keycode_V2_ioctl(struct tcb *const tcp, const kernel_ulong_t arg)
                unsigned int i;
 
                tprintf("index=%" PRIu16 ", keycode=", ike.index);
-               printxval_index(evdev_keycode, ike.keycode, "KEY_???");
+               printxval(evdev_keycode, ike.keycode, "KEY_???");
                tprints(", scancode=[");
                for (i = 0; i < ARRAY_SIZE(ike.scancode); i++) {
                        if (i > 0)
@@ -144,9 +142,9 @@ getid_ioctl(struct tcb *const tcp, const kernel_ulong_t arg)
 }
 
 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, size_t decode_nr_size, enum xlat_type xt)
+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)
 {
        tprints(", ");
 
@@ -178,7 +176,7 @@ decode_bitset_(struct tcb *const tcp, const kernel_ulong_t arg,
        if (i < 0) {
                tprints(" 0 ");
        } else {
-               printxval_dispatch(decode_nr, decode_nr_size, i, dflt, xt);
+               printxval(decode_nr, i, dflt);
 
                while ((i = next_set_bit(decoded_arg, i + 1, size_bits)) > 0) {
                        if (abbrev(tcp) && bit_displayed >= 3) {
@@ -186,8 +184,7 @@ decode_bitset_(struct tcb *const tcp, const kernel_ulong_t arg,
                                break;
                        }
                        tprints(", ");
-                       printxval_dispatch(decode_nr, decode_nr_size, i, dflt,
-                                          xt);
+                       printxval(decode_nr, i, dflt);
                        bit_displayed++;
                }
        }
@@ -197,10 +194,6 @@ 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_) - 1, (xt_))
-
 # ifdef EVIOCGMTSLOTS
 static int
 mtslots_ioctl(struct tcb *const tcp, const unsigned int code,
@@ -251,42 +244,41 @@ bit_ioctl(struct tcb *const tcp, const unsigned int ev_nr,
        switch (ev_nr) {
                case 0:
                        return decode_bitset(tcp, arg, evdev_ev,
-                                            EV_MAX, "EV_???", XT_SORTED);
+                                            EV_MAX, "EV_???");
                case EV_KEY:
                        return decode_bitset(tcp, arg, evdev_keycode,
-                                            KEY_MAX, "KEY_???", XT_INDEXED);
+                                            KEY_MAX, "KEY_???");
                case EV_REL:
                        return decode_bitset(tcp, arg, evdev_relative_axes,
-                                            REL_MAX, "REL_???", XT_INDEXED);
+                                            REL_MAX, "REL_???");
                case EV_ABS:
                        return decode_bitset(tcp, arg, evdev_abs,
-                                            ABS_MAX, "ABS_???", XT_INDEXED);
+                                            ABS_MAX, "ABS_???");
                case EV_MSC:
                        return decode_bitset(tcp, arg, evdev_misc,
-                                            MSC_MAX, "MSC_???", XT_INDEXED);
+                                            MSC_MAX, "MSC_???");
                case EV_SW:
                        return decode_bitset(tcp, arg, evdev_switch,
-                                            SW_MAX, "SW_???", XT_INDEXED);
+                                            SW_MAX, "SW_???");
                case EV_LED:
                        return decode_bitset(tcp, arg, evdev_leds,
-                                            LED_MAX, "LED_???", XT_INDEXED);
+                                            LED_MAX, "LED_???");
                case EV_SND:
                        return decode_bitset(tcp, arg, evdev_snd,
-                                            SND_MAX, "SND_???", XT_INDEXED);
+                                            SND_MAX, "SND_???");
                case EV_REP:
                        return decode_bitset(tcp, arg, evdev_autorepeat,
-                                            REP_MAX, "REP_???", XT_INDEXED);
+                                            REP_MAX, "REP_???");
                case EV_FF:
                        return decode_bitset(tcp, arg, evdev_ff_types,
-                                            FF_MAX, "FF_???", XT_SORTED);
+                                            FF_MAX, "FF_???");
                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_???",
-                                            XT_INDEXED);
+                                            FF_STATUS_MAX, "FF_STATUS_???");
                default:
                        tprints(", ");
                        printaddr(arg);
@@ -340,23 +332,22 @@ 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_???",
-                                            XT_INDEXED);
+                                            INPUT_PROP_MAX, "PROP_???");
 # endif
                case _IOC_NR(EVIOCGSND(0)):
                        return decode_bitset(tcp, arg, evdev_snd,
-                                            SND_MAX, "SND_???", XT_INDEXED);
+                                            SND_MAX, "SND_???");
 # ifdef EVIOCGSW
                case _IOC_NR(EVIOCGSW(0)):
                        return decode_bitset(tcp, arg, evdev_switch,
-                                            SW_MAX, "SW_???", XT_INDEXED);
+                                            SW_MAX, "SW_???");
 # endif
                case _IOC_NR(EVIOCGKEY(0)):
                        return decode_bitset(tcp, arg, evdev_keycode,
-                                            KEY_MAX, "KEY_???", XT_INDEXED);
+                                            KEY_MAX, "KEY_???");
                case _IOC_NR(EVIOCGLED(0)):
                        return decode_bitset(tcp, arg, evdev_leds,
-                                            LED_MAX, "LED_???", XT_INDEXED);
+                                            LED_MAX, "LED_???");
        }
 
        /* multi-number fixed-length commands */
index 7be095b07fa235a6192c0e71ba52cd79219994ee..4ae6561c3e29c8a74f46edd8e990729c87908dbe 100644 (file)
@@ -22,7 +22,7 @@ SYS_FUNC(fsconfig)
        printfd(tcp, fs_fd);
        tprints(", ");
 
-       printxval_index(fsconfig_cmds, cmd, "FSCONFIG_???");
+       printxval(fsconfig_cmds, cmd, "FSCONFIG_???");
        tprints(", ");
 
        switch (cmd) {
diff --git a/ioctl.c b/ioctl.c
index 0ae1fbf1d32f522d7a7a1be9701a125bf22418c9..b80292cb859cc0f7c6ab1a7c0b11edb60463a469 100644 (file)
--- a/ioctl.c
+++ b/ioctl.c
@@ -65,8 +65,7 @@ evdev_decode_number(const unsigned int code)
        if (_IOC_DIR(code) == _IOC_WRITE) {
                if (nr >= 0xc0 && nr <= 0xc0 + 0x3f) {
                        tprints("EVIOCSABS(");
-                       printxval_indexn(evdev_abs, evdev_abs_size, nr - 0xc0,
-                                        "ABS_???");
+                       printxval(evdev_abs, nr - 0xc0, "ABS_???");
                        tprints(")");
                        return 1;
                }
@@ -85,8 +84,7 @@ evdev_decode_number(const unsigned int code)
                return 1;
        } else if (nr >= 0x40 && nr <= 0x40 + 0x3f) {
                tprints("EVIOCGABS(");
-               printxval_indexn(evdev_abs, evdev_abs_size, nr - 0x40,
-                                "ABS_???");
+               printxval(evdev_abs, nr - 0x40, "ABS_???");
                tprints(")");
                return 1;
        }
diff --git a/kvm.c b/kvm.c
index 8bdf1cc68556fb226c8ef044ac360b078ce030ae..5de41b2dbf8c549b6ddddaf00a537c41ed71ad24 100644 (file)
--- a/kvm.c
+++ b/kvm.c
@@ -308,7 +308,7 @@ kvm_ioctl_decode_check_extension(struct tcb *const tcp, const unsigned int code,
                                 const kernel_ulong_t arg)
 {
        tprints(", ");
-       printxval_index(kvm_cap, arg, "KVM_CAP_???");
+       printxval64(kvm_cap, arg, "KVM_CAP_???");
        return RVAL_IOCTL_DECODED;
 }
 
@@ -326,8 +326,7 @@ kvm_ioctl_run_attach_auxstr(struct tcb *const tcp,
        if (umove(tcp, info->mmap_addr, &vcpu_run_struct) < 0)
                return;
 
-       tcp->auxstr = xlat_idx(kvm_exit_reason, ARRAY_SIZE(kvm_exit_reason) - 1,
-                              vcpu_run_struct.exit_reason);
+       tcp->auxstr = xlookup(kvm_exit_reason, vcpu_run_struct.exit_reason);
        if (!tcp->auxstr)
                tcp->auxstr = "KVM_EXIT_???";
 }
diff --git a/net.c b/net.c
index f08691c7cd222690e65189c19e307e9424012e93..1cece9af05098d12e0a94f51e788b6bbcc384c21 100644 (file)
--- a/net.c
+++ b/net.c
@@ -123,14 +123,13 @@ SYS_FUNC(socket)
        switch (tcp->u_arg[0]) {
        case AF_INET:
        case AF_INET6:
-               printxval_search(inet_protocols, tcp->u_arg[2], "IPPROTO_???");
+               printxval(inet_protocols, tcp->u_arg[2], "IPPROTO_???");
                break;
 
        case AF_AX25:
                /* Those are not available in public headers.  */
-               printxval_searchn_ex(ARRSZ_PAIR(ax25_protocols) - 1,
-                                    tcp->u_arg[2], "AX25_P_???",
-                                    XLAT_STYLE_VERBOSE);
+               printxval_ex(ax25_protocols, tcp->u_arg[2], "AX25_P_???",
+                            XLAT_STYLE_VERBOSE);
                break;
 
        case AF_NETLINK:
@@ -139,21 +138,21 @@ SYS_FUNC(socket)
 
        case AF_PACKET:
                tprints("htons(");
-               printxval_searchn(ethernet_protocols, ethernet_protocols_size,
-                                 ntohs(tcp->u_arg[2]), "ETH_P_???");
+               printxval(ethernet_protocols, ntohs(tcp->u_arg[2]),
+                         "ETH_P_???");
                tprints(")");
                break;
 
        case AF_IRDA:
-               printxval_index(can_protocols, tcp->u_arg[2], "IRDAPROTO_???");
+               printxval(can_protocols, tcp->u_arg[2], "IRDAPROTO_???");
                break;
 
        case AF_CAN:
-               printxval_index(can_protocols, tcp->u_arg[2], "CAN_???");
+               printxval(can_protocols, tcp->u_arg[2], "CAN_???");
                break;
 
        case AF_BLUETOOTH:
-               printxval_index(bt_protocols, tcp->u_arg[2], "BTPROTO_???");
+               printxval(bt_protocols, tcp->u_arg[2], "BTPROTO_???");
                break;
 
        case AF_RXRPC:
@@ -165,24 +164,23 @@ SYS_FUNC(socket)
                break;
 
        case AF_PHONET:
-               printxval_index(phonet_protocols, tcp->u_arg[2], "PN_PROTO_???");
+               printxval(phonet_protocols, tcp->u_arg[2], "PN_PROTO_???");
                break;
 
        case AF_CAIF:
-               printxval_index(caif_protocols, tcp->u_arg[2], "CAIFPROTO_???");
+               printxval(caif_protocols, tcp->u_arg[2], "CAIFPROTO_???");
                break;
 
        case AF_NFC:
-               printxval_index(nfc_protocols, tcp->u_arg[2],
-                               "NFC_SOCKPROTO_???");
+               printxval(nfc_protocols, tcp->u_arg[2], "NFC_SOCKPROTO_???");
                break;
 
        case AF_KCM:
-               printxval_index(kcm_protocols, tcp->u_arg[2], "KCMPROTO_???");
+               printxval(kcm_protocols, tcp->u_arg[2], "KCMPROTO_???");
                break;
 
        case AF_SMC:
-               printxval_index(smc_protocols, tcp->u_arg[2], "SMCPROTO_???");
+               printxval(smc_protocols, tcp->u_arg[2], "SMCPROTO_???");
                break;
 
        default:
@@ -463,7 +461,7 @@ print_sockopt_fd_level_name(struct tcb *tcp, int fd, unsigned int level,
 {
        printfd(tcp, fd);
        tprints(", ");
-       printxval_search(socketlayers, level, "SOL_??");
+       printxval(socketlayers, level, "SOL_??");
        tprints(", ");
 
        switch (level) {
@@ -486,13 +484,13 @@ print_sockopt_fd_level_name(struct tcb *tcp, int fd, unsigned int level,
                printxval(sock_ipx_options, name, "IPX_???");
                break;
        case SOL_AX25:
-               printxval_search(sock_ax25_options, name, "AX25_???");
+               printxval(sock_ax25_options, name, "AX25_???");
                break;
        case SOL_PACKET:
                printxval(sock_packet_options, name, "PACKET_???");
                break;
        case SOL_TCP:
-               printxval_index(sock_tcp_options, name, "TCP_???");
+               printxval(sock_tcp_options, name, "TCP_???");
                break;
        case SOL_SCTP:
                printxval(sock_sctp_options, name, "SCTP_???");
@@ -507,31 +505,31 @@ print_sockopt_fd_level_name(struct tcb *tcp, int fd, unsigned int level,
                printxval(sock_udp_options, name, "UDP_???");
                break;
        case SOL_IRDA:
-               printxval_index(sock_irda_options, name, "IRLMP_???");
+               printxval(sock_irda_options, name, "IRLMP_???");
                break;
        case SOL_LLC:
-               printxval_index(sock_llc_options, name, "LLC_OPT_???");
+               printxval(sock_llc_options, name, "LLC_OPT_???");
                break;
        case SOL_DCCP:
-               printxval_search(sock_dccp_options, name, "DCCP_SOCKOPT_???");
+               printxval(sock_dccp_options, name, "DCCP_SOCKOPT_???");
                break;
        case SOL_TIPC:
-               printxval_search(sock_tipc_options, name, "TIPC_???");
+               printxval(sock_tipc_options, name, "TIPC_???");
                break;
        case SOL_RXRPC:
-               printxval_index(sock_rxrpc_options, name, "RXRPC_???");
+               printxval(sock_rxrpc_options, name, "RXRPC_???");
                break;
        case SOL_PPPOL2TP:
-               printxval_index(sock_pppol2tp_options, name, "PPPOL2TP_SO_???");
+               printxval(sock_pppol2tp_options, name, "PPPOL2TP_SO_???");
                break;
        case SOL_BLUETOOTH:
-               printxval_search(sock_bluetooth_options, name, "BT_???");
+               printxval(sock_bluetooth_options, name, "BT_???");
                break;
        case SOL_PNPIPE:
                printxval(sock_pnp_options, name, "PNPIPE_???");
                break;
        case SOL_RDS:
-               printxval_search(sock_rds_options, name, "RDS_???");
+               printxval(sock_rds_options, name, "RDS_???");
                break;
        case SOL_IUCV:
                printxval(sock_iucv_options, name, "SO_???");
@@ -540,10 +538,10 @@ print_sockopt_fd_level_name(struct tcb *tcp, int fd, unsigned int level,
                printxval(sock_caif_options, name, "CAIFSO_???");
                break;
        case SOL_ALG:
-               printxval_index(sock_alg_options, name, "ALG_???");
+               printxval(sock_alg_options, name, "ALG_???");
                break;
        case SOL_NFC:
-               printxval_index(sock_nfcllcp_options, name, "NFC_LLCP_???");
+               printxval(sock_nfcllcp_options, name, "NFC_LLCP_???");
                break;
        case SOL_KCM:
                printxval(sock_kcm_options, name, "KCM_???");
@@ -552,7 +550,7 @@ print_sockopt_fd_level_name(struct tcb *tcp, int fd, unsigned int level,
                printxval(sock_tls_options, name, "TLS_???");
                break;
        case SOL_XDP:
-               printxval_index(sock_xdp_options, name, "XDP_???");
+               printxval(sock_xdp_options, name, "XDP_???");
                break;
 
                /* Other SOL_* protocol levels still need work. */
index a107a17505b8c8a1421253bac824c7bc02cb43d7..0a5016f6051debcc2cb2c6e1b19e3c20f9c0efa6 100644 (file)
--- a/netlink.c
+++ b/netlink.c
@@ -80,11 +80,14 @@ get_fd_nl_family(struct tcb *const tcp, const int fd)
        if (nl_details == details)
                return -1;
 
-       const struct xlat *xlats = netlink_protocols;
-       for (; xlats->str; ++xlats) {
-               const char *name = STR_STRIP_PREFIX(xlats->str, "NETLINK_");
+       const struct xlat_data *xlats = netlink_protocols->data;
+       for (uint32_t idx = 0; idx < netlink_protocols->size; idx++) {
+               if (!netlink_protocols->data[idx].str)
+                       continue;
+
+               const char *name = STR_STRIP_PREFIX(xlats[idx].str, "NETLINK_");
                if (!strncmp(nl_details, name, strlen(name)))
-                       return xlats->val;
+                       return xlats[idx].val;
        }
 
        if (*nl_details >= '0' && *nl_details <= '9')
index dd26f95aa30ef775e314ba0d92f993489c6dd3c9..6355429bf0cd5317a961ba01e8cb49948861d914 100644 (file)
@@ -174,10 +174,8 @@ DECL_NETLINK_DIAG_DECODER(decode_packet_diag_msg)
                                         (char *) &msg + offset)) {
                        PRINT_FIELD_XVAL("", msg, pdiag_type,
                                         socktypes, "SOCK_???");
-                       PRINT_FIELD_XVAL_SORTED_SIZED(", ", msg, pdiag_num,
-                                                     ethernet_protocols,
-                                                     ethernet_protocols_size,
-                                                     "ETH_P_???");
+                       PRINT_FIELD_XVAL(", ", msg, pdiag_num,
+                                        ethernet_protocols, "ETH_P_???");
                        PRINT_FIELD_U(", ", msg, pdiag_ino);
                        PRINT_FIELD_COOKIE(", ", msg, pdiag_cookie);
                        decode_nla = true;
index 9255c0de1a8cd20bca004499c9f902eaec7d2acf..16815fdea5af1bcc684e6f1ad994547d20a3f73e 100644 (file)
@@ -136,7 +136,7 @@ decode_smc_diag_shutdown(struct tcb *const tcp,
                         const void *const opaque_data)
 {
        const struct decode_nla_xlat_opts opts = {
-               ARRSZ_PAIR(sock_shutdown_flags) - 1, "???_SHUTDOWN",
+               sock_shutdown_flags, "???_SHUTDOWN",
                .size = 1,
        };
 
@@ -183,11 +183,11 @@ decode_smc_diag_fallback(struct tcb *const tcp,
         * net/smc/smc_clc.h
         */
        tprints("{reason=");
-       printxval_search_ex(smc_decl_codes, fb.reason,
-                           "SMC_CLC_DECL_???", XLAT_STYLE_VERBOSE);
+       printxval_ex(smc_decl_codes, fb.reason, "SMC_CLC_DECL_???",
+                    XLAT_STYLE_VERBOSE);
        tprints(", peer_diagnosis=");
-       printxval_search_ex(smc_decl_codes, fb.peer_diagnosis,
-                           "SMC_CLC_DECL_???", XLAT_STYLE_VERBOSE);
+       printxval_ex(smc_decl_codes, fb.peer_diagnosis, "SMC_CLC_DECL_???",
+                    XLAT_STYLE_VERBOSE);
        tprints("}");
 
        return true;
@@ -215,9 +215,8 @@ DECL_NETLINK_DIAG_DECODER(decode_smc_diag_msg)
                                         (void *) &msg + offset)) {
                        PRINT_FIELD_XVAL("", msg, diag_state,
                                         smc_states, "SMC_???");
-                       PRINT_FIELD_XVAL_INDEX(", ", msg, diag_fallback,
-                                              smc_diag_mode,
-                                              "SMC_DIAG_MODE_???");
+                       PRINT_FIELD_XVAL(", ", msg, diag_fallback,
+                                        smc_diag_mode, "SMC_DIAG_MODE_???");
                        PRINT_FIELD_U(", ", msg, diag_shutdown);
                        /*
                         * AF_SMC protocol family socket handler
index f3df7d9984c2ccdd16a667eb0e58fa7f31b0d834..10d612fd3cbb8271baa21c280a7b5063321c5d7b 100644 (file)
--- a/nlattr.c
+++ b/nlattr.c
@@ -196,10 +196,8 @@ decode_nla_meminfo(struct tcb *const tcp,
        unsigned int count = 0;
        print_array_ex(tcp, addr, nmemb, &mem, sizeof(mem),
                       tfetch_mem, print_uint32_array_member, &count,
-                      PAF_PRINT_INDICES | PAF_INDEX_XLAT_VALUE_INDEXED
-                       | XLAT_STYLE_FMT_U,
-                      ARRSZ_PAIR(netlink_sk_meminfo_indices) - 1,
-                      "SK_MEMINFO_???");
+                      PAF_PRINT_INDICES | XLAT_STYLE_FMT_U,
+                      netlink_sk_meminfo_indices, "SK_MEMINFO_???");
 
        return true;
 }
@@ -286,8 +284,7 @@ decode_nla_xval(struct tcb *const tcp,
                        data.val = opts->process_fn(data.val);
                if (opts->prefix)
                        tprints(opts->prefix);
-               printxval_dispatch_ex(opts->xlat, opts->xlat_size, data.val,
-                                     opts->dflt, opts->xt, opts->style);
+               printxval_ex(opts->xlat, data.val, opts->dflt, opts->style);
                if (opts->suffix)
                        tprints(opts->suffix);
        }
@@ -307,11 +304,9 @@ decode_nla_ether_proto(struct tcb *const tcp,
                       const unsigned int len,
                       const void *const opaque_data)
 {
-       const struct decode_nla_xlat_opts opts = {
+       static const struct decode_nla_xlat_opts opts = {
                .xlat = ethernet_protocols,
-               .xlat_size = ethernet_protocols_size,
                .dflt = "ETHER_P_???",
-               .xt = XT_SORTED,
                .prefix = "htons(",
                .suffix = ")",
                .size = 2,
@@ -327,10 +322,8 @@ decode_nla_ip_proto(struct tcb *const tcp,
                    const unsigned int len,
                    const void *const opaque_data)
 {
-       const struct decode_nla_xlat_opts opts = {
+       static const struct decode_nla_xlat_opts opts = {
                .xlat = inet_protocols,
-               .xlat_size = inet_protocols_size,
-               .xt = XT_SORTED,
                .dflt = "IPPROTO_???",
                .size = 1,
        };
@@ -390,10 +383,6 @@ decode_nla_flags(struct tcb *const tcp,
 
        const size_t bytes_offs = is_bigendian ? sizeof(data) - len : 0;
 
-       if (opts->xt == XT_INDEXED)
-               error_func_msg("indexed xlats are currently incompatible with "
-                              "printflags");
-
        if (!umoven_or_printaddr(tcp, addr, len, data.bytes + bytes_offs)) {
                if (opts->process_fn)
                        data.flags = opts->process_fn(data.flags);
index a11f2f1d2d332ca9cc6b550e00b68fcf3600003d..60992e1713f33b71da230651448fb9344aaec0c7 100644 (file)
--- a/nlattr.h
+++ b/nlattr.h
@@ -14,9 +14,7 @@
 
 struct decode_nla_xlat_opts {
        const struct xlat *xlat;
-       size_t xlat_size; /* is not needed for XT_NORMAL */
        const char *dflt;
-       enum xlat_type xt;
        enum xlat_style style;
        const char *prefix;
        const char *suffix;
index 3dfd9317cf8496256db989d07d684f5e4a7de28e..677b5f6c220859621226dc21bc1835cd7e85f6dd 100644 (file)
                              (xlat_), NULL);                           \
        } while (0)
 
-# define PRINT_FIELD_XVAL_SORTED_SIZED(prefix_, where_, field_, xlat_, \
-                                     xlat_size_, dflt_)                \
-       do {                                                            \
-               STRACE_PRINTF("%s%s=", (prefix_), #field_);             \
-               printxval_searchn((xlat_), (xlat_size_),                \
-                                 zero_extend_signed_to_ull((where_).field_), \
-                                 (dflt_));                             \
-       } while (0)
-
-# define PRINT_FIELD_XVAL_INDEX(prefix_, where_, field_, xlat_, dflt_) \
-       do {                                                            \
-               STRACE_PRINTF("%s%s=", (prefix_), #field_);             \
-               printxval_index((xlat_),                                \
-                               zero_extend_signed_to_ull((where_).field_), \
-                               (dflt_));                               \
-       } while (0)
-
 /*
  * Generic "ID" printing. ID is considered unsigned except for the special value
  * of -1.
index b4e8f1e01f1e53eb238b3a68ba4cda808bfb7766..80ecf2f40c38917cb24b2b501f3e7c72788d425c 100644 (file)
@@ -14,7 +14,7 @@ static void
 print_statfs_type(const char *const prefix, const unsigned long long magic)
 {
        tprints(prefix);
-       printxval_search(fsmagic, magic, NULL);
+       printxval(fsmagic, magic, NULL);
 }
 
 #if defined HAVE_STRUCT_STATFS_F_FLAGS || defined HAVE_STRUCT_STATFS64_F_FLAGS
index d224c396d4b400f831b973891d2601a52e9ce1b7..d3e0449e4ae744419bb4340be01432c67d5bbfb7 100644 (file)
--- a/process.c
+++ b/process.c
 #define uoff(member)   offsetof(struct user, member)
 #define XLAT_UOFF(member)      { uoff(member), "offsetof(struct user, " #member ")" }
 
-static const struct xlat struct_user_offsets[] = {
+static const struct xlat_data struct_user_offsets_data[] = {
 #include "userent.h"
        XLAT_END
 };
 
+static const struct xlat struct_user_offsets = {
+       .type = XT_SORTED,
+       .size = ARRAY_SIZE(struct_user_offsets_data) - 1,
+       .data = struct_user_offsets_data,
+};
+
 static void
 print_user_offset_addr(const kernel_ulong_t addr)
 {
-       bool no_str = false;
-       const struct xlat *x;
+       const uint64_t last_user_offset = struct_user_offsets.size ?
+               struct_user_offsets.data[struct_user_offsets.size - 1].val : 0;
 
-       for (x = struct_user_offsets; x->str; ++x) {
-               if (x->val >= addr)
-                       break;
-       }
+       uint64_t base_addr = addr;
+       const char *str = xlookup_le(&struct_user_offsets, &base_addr);
 
-       if (!x->str || (x == struct_user_offsets && x->val > addr))
-               no_str = true;
-       if (no_str || xlat_verbose(xlat_verbosity) != XLAT_STYLE_ABBREV)
+       /* We don't want to pretty print addresses beyond struct user */
+       if (addr > base_addr && base_addr == last_user_offset)
+               str = NULL;
+
+       if (!str || xlat_verbose(xlat_verbosity) != XLAT_STYLE_ABBREV)
                printaddr(addr);
-       if (no_str || xlat_verbose(xlat_verbosity) == XLAT_STYLE_RAW)
+       if (!str || xlat_verbose(xlat_verbosity) == XLAT_STYLE_RAW)
                return;
 
        if (xlat_verbose(xlat_verbosity) == XLAT_STYLE_VERBOSE)
                tprints(" /* ");
 
-       if (x->val > addr) {
-               --x;
+       if (base_addr == addr)
+               tprints(str);
+       else
                tprintf("%s + %" PRI_klu,
-                       x->str, addr - (kernel_ulong_t) x->val);
-       } else {
-               tprints(x->str);
-       }
+                       str, addr - (kernel_ulong_t) base_addr);
 
        if (xlat_verbose(xlat_verbosity) == XLAT_STYLE_VERBOSE)
                tprints(" */");
index 8ded55ad15756a439a30b7b7351c362b3785a436..bfd10814ed0b3b97d282638663c70fc1115e1c62 100644 (file)
@@ -277,8 +277,8 @@ print_ptrace_syscall_info(struct tcb *tcp, kernel_ulong_t addr,
                return;
        }
 
-       PRINT_FIELD_XVAL_INDEX("{", info, op, ptrace_syscall_info_op,
-                              "PTRACE_SYSCALL_INFO_???");
+       PRINT_FIELD_XVAL("{", info, op, ptrace_syscall_info_op,
+                        "PTRACE_SYSCALL_INFO_???");
        if (fetch_size < offsetofend(struct ptrace_syscall_info, arch))
                goto printed;
        PRINT_FIELD_XVAL(", ", info, arch, audit_arch, "AUDIT_ARCH_???");
index 92bc1e03c07cdb34ef0fcc165101bdd19b835c1b..02df768f45236fcc00f18c8b30c55d086a78d85e 100644 (file)
@@ -337,10 +337,8 @@ decode_nla_tun_type(struct tcb *const tcp,
                    const unsigned int len,
                    const void *const opaque_data)
 {
-       const struct decode_nla_xlat_opts opts = {
+       static const struct decode_nla_xlat_opts opts = {
                .xlat = tun_device_types,
-               .xlat_size = ARRAY_SIZE(tun_device_types) - 1,
-               .xt = XT_INDEXED,
                .dflt = "IFF_???",
                .size = 1,
        };
@@ -563,10 +561,8 @@ decode_ifla_xdp_attached(struct tcb *const tcp,
                         const unsigned int len,
                         const void *const opaque_data)
 {
-       const struct decode_nla_xlat_opts opts = {
+       static const struct decode_nla_xlat_opts opts = {
                .xlat = rtnl_ifla_xdp_attached_mode,
-               .xlat_size = ARRAY_SIZE(rtnl_ifla_xdp_attached_mode) - 1,
-               .xt = XT_INDEXED,
                .dflt = "XDP_ATTACHED_???",
                .size = 1,
        };
@@ -628,10 +624,8 @@ decode_ifla_inet_conf(struct tcb *const tcp,
 
        print_array_ex(tcp, addr, cnt, &elem, sizeof(elem),
                       tfetch_mem, print_int32_array_member, NULL,
-                      PAF_PRINT_INDICES | PAF_INDEX_XLAT_VALUE_INDEXED
-                       | XLAT_STYLE_FMT_D,
-                      ARRSZ_PAIR(inet_devconf_indices) - 1,
-                      "IPV4_DEVCONF_???");
+                      PAF_PRINT_INDICES | XLAT_STYLE_FMT_D,
+                      inet_devconf_indices, "IPV4_DEVCONF_???");
 
        return true;
 }
@@ -646,8 +640,8 @@ decode_ifla_inet6_flags(struct tcb *const tcp,
                        const unsigned int len,
                        const void *const opaque_data)
 {
-       const struct decode_nla_xlat_opts opts = {
-               ARRSZ_PAIR(inet6_if_flags) - 1, "IF_???",
+       static const struct decode_nla_xlat_opts opts = {
+               inet6_if_flags, "IF_???",
                .size = 4,
        };
 
@@ -668,10 +662,8 @@ decode_ifla_inet6_conf(struct tcb *const tcp,
 
        print_array_ex(tcp, addr, cnt, &elem, sizeof(elem),
                       tfetch_mem, print_int32_array_member, NULL,
-                      PAF_PRINT_INDICES | PAF_INDEX_XLAT_VALUE_INDEXED
-                       | XLAT_STYLE_FMT_D,
-                      ARRSZ_PAIR(inet6_devconf_indices) - 1,
-                      "DEVCONF_???");
+                      PAF_PRINT_INDICES | XLAT_STYLE_FMT_D,
+                      inet6_devconf_indices, "DEVCONF_???");
 
        return true;
 }
@@ -690,9 +682,8 @@ decode_ifla_inet6_stats(struct tcb *const tcp,
 
        print_array_ex(tcp, addr, cnt, &elem, sizeof(elem),
                       tfetch_mem, print_uint64_array_member, NULL,
-                      PAF_PRINT_INDICES | PAF_INDEX_XLAT_VALUE_INDEXED
-                       | XLAT_STYLE_FMT_U, ARRSZ_PAIR(snmp_ip_stats) - 1,
-                      "IPSTATS_MIB_???");
+                      PAF_PRINT_INDICES | XLAT_STYLE_FMT_U,
+                      snmp_ip_stats, "IPSTATS_MIB_???");
 
        return true;
 }
@@ -737,9 +728,8 @@ decode_ifla_inet6_icmp6_stats(struct tcb *const tcp,
 
        print_array_ex(tcp, addr, cnt, &elem, sizeof(elem),
                       tfetch_mem, print_uint64_array_member, NULL,
-                      PAF_PRINT_INDICES | PAF_INDEX_XLAT_VALUE_INDEXED
-                       | XLAT_STYLE_FMT_U, ARRSZ_PAIR(snmp_icmp6_stats) - 1,
-                      "ICMP6_MIB_???");
+                      PAF_PRINT_INDICES | XLAT_STYLE_FMT_U,
+                      snmp_icmp6_stats, "ICMP6_MIB_???");
 
        return true;
 }
@@ -750,9 +740,8 @@ decode_ifla_inet6_agm(struct tcb *const tcp,
                      const unsigned int len,
                      const void *const opaque_data)
 {
-       const struct decode_nla_xlat_opts opts = {
-               ARRSZ_PAIR(in6_addr_gen_mode) - 1, "IN6_ADDR_GEN_MODE_???",
-               .xt = XT_INDEXED,
+       static const struct decode_nla_xlat_opts opts = {
+               in6_addr_gen_mode, "IN6_ADDR_GEN_MODE_???",
                .size = 1,
        };
 
@@ -887,10 +876,8 @@ DECL_NETLINK_ROUTE_DECODER(decode_ifinfomsg)
                if (!umoven_or_printaddr(tcp, addr + offset,
                                         sizeof(ifinfo) - offset,
                                         (char *) &ifinfo + offset)) {
-                       PRINT_FIELD_XVAL_SORTED_SIZED("", ifinfo, ifi_type,
-                                                     arp_hardware_types,
-                                                     arp_hardware_types_size,
-                                                     "ARPHRD_???");
+                       PRINT_FIELD_XVAL("", ifinfo, ifi_type,
+                                        arp_hardware_types, "ARPHRD_???");
                        PRINT_FIELD_IFINDEX(", ", ifinfo, ifi_index);
                        PRINT_FIELD_FLAGS(", ", ifinfo, ifi_flags,
                                          iffflags, "IFF_???");
index f1bca94d6c9d51b945b22a89c1a93a187c331559..8e6337b713e2db9ff7c549a44fa38bbe288a13a4 100644 (file)
@@ -52,7 +52,7 @@ decode_nla_rt_proto(struct tcb *const tcp,
        if (len < sizeof(num))
                return false;
        if (!umove_or_printaddr(tcp, addr, &num))
-               printxval_search(routing_protocols, num, "RTPROT_???");
+               printxval(routing_protocols, num, "RTPROT_???");
        return true;
 }
 
diff --git a/sock.c b/sock.c
index e24898557896bd353ebcc0259a864c7cc4335e16..5b140070706d05e826bbacea8d4ec5293e02bbc4 100644 (file)
--- a/sock.c
+++ b/sock.c
@@ -60,10 +60,8 @@ print_ifreq(struct tcb *const tcp, const unsigned int code,
                break;
        case SIOCSIFHWADDR:
        case SIOCGIFHWADDR: {
-               PRINT_FIELD_XVAL_SORTED_SIZED("ifr_hwaddr={", ifr->ifr_hwaddr,
-                                             sa_family, arp_hardware_types,
-                                             arp_hardware_types_size,
-                                             "ARPHRD_???");
+               PRINT_FIELD_XVAL("ifr_hwaddr={", ifr->ifr_hwaddr, sa_family,
+                                arp_hardware_types, "ARPHRD_???");
                PRINT_FIELD_HWADDR_SZ(", ", ifr->ifr_hwaddr, sa_data,
                                      sizeof(ifr->ifr_hwaddr.sa_data),
                                      ifr->ifr_hwaddr.sa_family);
index acba7f02b65682b909a06031921e3b7063ee0934..dbf3856c64b7a21e25fc1e246f2fbb485d49f900 100644 (file)
@@ -433,8 +433,8 @@ print_sll_protocol(const struct sockaddr_ll *const sa_ll)
                tprints(" /* ");
 
        tprints("htons(");
-       printxval_search_ex(ethernet_protocols, ntohs(sa_ll->sll_protocol),
-                           "ETH_P_???", XLAT_STYLE_ABBREV);
+       printxval_ex(ethernet_protocols, ntohs(sa_ll->sll_protocol),
+                    "ETH_P_???", XLAT_STYLE_ABBREV);
        tprints(")");
 
        if (x_style == XLAT_STYLE_VERBOSE)
@@ -449,9 +449,9 @@ print_sockaddr_data_ll(const void *const buf, const int addrlen)
        print_sll_protocol(sa_ll);
        PRINT_FIELD_IFINDEX(", ", *sa_ll, sll_ifindex);
        tprints(", sll_hatype=");
-       printxval_search(arp_hardware_types, sa_ll->sll_hatype, "ARPHRD_???");
+       printxval(arp_hardware_types, sa_ll->sll_hatype, "ARPHRD_???");
        tprints(", sll_pkttype=");
-       printxval_index(af_packet_types, sa_ll->sll_pkttype, "PACKET_???");
+       printxval(af_packet_types, sa_ll->sll_pkttype, "PACKET_???");
        tprintf(", sll_halen=%u", sa_ll->sll_halen);
        if (sa_ll->sll_halen) {
                const unsigned int oob_halen =
@@ -603,8 +603,7 @@ print_sockaddr_data_bt(const void *const buf, const int addrlen)
                const struct sockaddr_hci *const hci = buf;
                tprintf("hci_dev=htobs(%hu), hci_channel=",
                        btohs(hci->hci_dev));
-               printxval_index(hci_channels, hci->hci_channel,
-                               "HCI_CHANNEL_???");
+               printxval(hci_channels, hci->hci_channel, "HCI_CHANNEL_???");
                break;
        }
        case sizeof(struct sockaddr_sco): {
@@ -630,8 +629,8 @@ print_sockaddr_data_bt(const void *const buf, const int addrlen)
 
                if (addrlen == sizeof(struct sockaddr_l2)) {
                        tprints(", l2_bdaddr_type=");
-                       printxval_index(bdaddr_types, l2->l2_bdaddr_type,
-                                       "BDADDR_???");
+                       printxval(bdaddr_types, l2->l2_bdaddr_type,
+                                 "BDADDR_???");
                }
 
                break;
@@ -665,7 +664,7 @@ print_sockaddr(const void *const buf, const int addrlen)
        const struct sockaddr *const sa = buf;
 
        tprints("{sa_family=");
-       printxval_index(addrfams, sa->sa_family, "AF_???");
+       printxval(addrfams, sa->sa_family, "AF_???");
 
        if (addrlen > (int) SIZEOF_SA_FAMILY) {
                tprints(", ");
index f1a26bf32643e6042ec151d4f841053363bbea62..f631310d9cc178d6e3f20482325d0cdf4471799c 100644 (file)
@@ -886,9 +886,9 @@ btrfs_test_defrag_ioctls(void)
 static const char *
 xlookup(const struct xlat *xlat, const uint64_t val)
 {
-       for (; xlat->str != NULL; xlat++)
-               if (xlat->val == val)
-                       return xlat->str;
+       for (size_t i = 0; i < xlat->size; i++)
+               if (xlat->data[i].val == val)
+                       return xlat->data[i].str;
        return NULL;
 }
 
@@ -2068,7 +2068,7 @@ btrfs_test_features_ioctls(void)
 static void
 btrfs_test_read_ioctls(void)
 {
-       static const struct xlat btrfs_read_cmd[] = {
+       static const struct xlat_data btrfs_read_cmd[] = {
                XLAT(BTRFS_IOC_BALANCE_PROGRESS),
                XLAT(BTRFS_IOC_FS_INFO),
                XLAT(BTRFS_IOC_GET_FEATURES),
index 65f434c8f344bdb8b15826c9391d0cf52fd7ba6b..643daf8712256152e99ecc4d05657e8122b4c9ad 100644 (file)
@@ -24,7 +24,7 @@
 static const unsigned int magic = 0xdeadbeef;
 static const unsigned long lmagic = (unsigned long) 0xdeadbeefbadc0dedULL;
 
-static struct xlat block_argless[] = {
+static struct xlat_data block_argless[] = {
        XLAT(BLKRRPART),
        XLAT(BLKFLSBUF),
 #ifdef BLKTRACESTART
index d192e37827c5f5729599960e54107eddd64de8f2..19d54f6b8155204d063c5d7f30776ea33b00fde2 100644 (file)
@@ -34,7 +34,7 @@ print_rtc_time(const struct rtc_time *rt)
 #endif
 }
 
-static struct xlat rtc_argless[] = {
+static struct xlat_data rtc_argless[] = {
        XLAT(RTC_AIE_OFF),
        XLAT(RTC_PIE_ON),
        XLAT(RTC_PIE_OFF),
index e9d66471351ec10a72865ed3fcf4b8db828408f5..8793dfe0e635688afb5096a516c1c5a17a407cf3 100644 (file)
@@ -17,21 +17,26 @@ int
 printflags(const struct xlat *xlat, unsigned long long flags,
           const char *const dflt)
 {
-       if (flags == 0 && xlat->val == 0 && xlat->str) {
-               fputs(xlat->str, stdout);
+       if (flags == 0 && xlat->data->val == 0 && xlat->data->str) {
+               fputs(xlat->data->str, stdout);
                return 1;
        }
 
        int n;
+       size_t i = 0;
        char sep = 0;
-       for (n = 0; xlat->str; xlat++) {
-               if (xlat->val && (flags & xlat->val) == xlat->val) {
+       const struct xlat_data *xd = xlat->data;
+       for (n = 0; i < xlat->size; xd++, i++) {
+               if (!xd->str)
+                       continue;
+
+               if (xd->val && (flags & xd->val) == xd->val) {
                        if (sep)
                                putc(sep, stdout);
                        else
                                sep = '|';
-                       fputs(xlat->str, stdout);
-                       flags &= ~xlat->val;
+                       fputs(xd->str, stdout);
+                       flags &= ~xd->val;
                        n++;
                }
        }
index 0cd629e4bdd76524b48df73ca5f1188a0413c0ec..90d848c31949bd964f3495132adb2d2d15a55f42 100644 (file)
@@ -17,9 +17,14 @@ int
 printxval(const struct xlat *xlat, unsigned long long val,
          const char *const dflt)
 {
-       for (; xlat->str; xlat++) {
-               if (xlat->val == val) {
-                       fputs(xlat->str, stdout);
+       const struct xlat_data *xd = xlat->data;
+
+       for (size_t i = 0; i < xlat->size; i++, xd++) {
+               if (!xd->str)
+                       continue;
+
+               if (xd->val == val) {
+                       fputs(xd->str, stdout);
                        return 1;
                }
        }
index fc0646af3ab9448d3b89c1d5d9ecc199c89f3cb1..b88057802aa16ecc5bdfbab888a72bc5e990cb5b 100644 (file)
@@ -44,9 +44,13 @@ main(void)
        unsigned long pid =
                (unsigned long) 0xdefaced00000000ULL | (unsigned) getpid();
        uint64_t *const rlimit = tail_alloc(sizeof(*rlimit) * 2);
-       const struct xlat *xlat;
+       const struct xlat_data *xlat;
+       size_t i = 0;
+
+       for (xlat = resources->data; i < resources->size; ++xlat, ++i) {
+               if (!xlat->str)
+                       continue;
 
-       for (xlat = resources; xlat->str; ++xlat) {
                unsigned long res = 0xfacefeed00000000ULL | xlat->val;
                long rc = syscall(__NR_prlimit64, pid, res, 0, rlimit);
                if (rc)
index 4e2c1ca9dc40f02dcdb219a9ef1ddd49031e578e..886cf65acdbdee9b43dce944e9e14a54374aec0c 100644 (file)
@@ -19,9 +19,13 @@ int
 main(void)
 {
        kernel_ulong_t *const rlimit = tail_alloc(sizeof(*rlimit) * 2);
-       const struct xlat *xlat;
+       const struct xlat_data *xlat;
+       size_t i = 0;
+
+       for (xlat = resources->data, i = 0; i < resources->size; ++xlat, ++i) {
+               if (!xlat->str)
+                       continue;
 
-       for (xlat = resources; xlat->str; ++xlat) {
                unsigned long res = 0xfacefeed00000000ULL | xlat->val;
                long rc = syscall(__NR_setrlimit, res, 0);
 # if XLAT_RAW
index 31cae64199ddb6a4a89bdf3045f3577afb42ef60..95c0ebe057dc9c08ae9eb2225cbfbd7fe05a55b7 100644 (file)
@@ -22,9 +22,9 @@
 static const char *
 xlookup_uint(const struct xlat *xlat, const unsigned int val)
 {
-       for (; xlat->str != NULL; xlat++)
-               if (xlat->val == val)
-                       return xlat->str;
+       for (size_t i = 0; i < xlat->size; i++)
+               if (xlat->data[i].val == val)
+                       return xlat->data[i].str;
        return NULL;
 }
 
@@ -52,8 +52,8 @@ test_socketcall(const int i, const void *const addr)
 int
 main(void)
 {
-       assert((unsigned) sc_min == socketcalls[0].val);
-       assert((unsigned) sc_max == socketcalls[ARRAY_SIZE(socketcalls) - 2].val);
+       assert((unsigned) sc_min == socketcalls->data[0].val);
+       assert((unsigned) sc_max == socketcalls->data[socketcalls->size - 1].val);
 
        const unsigned long *const args = tail_alloc(sizeof(*args) * 6);
        efault = tail_alloc(1) + 1;
index a1c89e9b7eb691208478cbf94eb9618bf71ee19d..6a9c053817c9e1fb66f212f8201bf524d77591db 100644 (file)
@@ -77,9 +77,13 @@ int
 main(void)
 {
        kernel_ulong_t *const rlimit = tail_alloc(sizeof(*rlimit) * 2);
-       const struct xlat *xlat;
+       const struct xlat_data *xlat;
+       size_t i;
+
+       for (xlat = resources->data, i = 0; i < resources->size; ++xlat, ++i) {
+               if (!xlat->str)
+                       continue;
 
-       for (xlat = resources; xlat->str; ++xlat) {
                unsigned long res = 0xfacefeed00000000ULL | xlat->val;
                long rc = syscall(NR_GETRLIMIT, res, 0);
                if (rc && ENOSYS == errno)
index 1b91e84467e300d4d520f7491dc890e8ed77c93b..8a86fdc39ad326686abf743534b5c8bae9effbaf 100644 (file)
@@ -34,10 +34,9 @@ static void
 print_statfs_type(const char *const prefix, const unsigned int magic)
 {
        fputs(prefix, stdout);
-       unsigned int i;
-       for (i = 0; i < ARRAY_SIZE(fsmagic); ++i)
-               if (magic == fsmagic[i].val) {
-                       fputs(fsmagic[i].str, stdout);
+       for (unsigned int i = 0; i < fsmagic->size; ++i)
+               if (magic == fsmagic->data[i].val) {
+                       fputs(fsmagic->data[i].str, stdout);
                        return;
                }
        printf("%#x", magic);
diff --git a/time.c b/time.c
index 5b163c84de2ad9f10a50cfb114d42974e6a45794..19b06c4026dc81c44786836e71accddeb4ba2cd2 100644 (file)
--- a/time.c
+++ b/time.c
@@ -113,8 +113,7 @@ SYS_FUNC(nanosleep_time64)
 SYS_FUNC(getitimer)
 {
        if (entering(tcp)) {
-               printxval_index(itimer_which, (unsigned int) tcp->u_arg[0],
-                               "ITIMER_???");
+               printxval(itimer_which, tcp->u_arg[0], "ITIMER_???");
                tprints(", ");
        } else {
                print_itimerval(tcp, tcp->u_arg[1]);
@@ -126,8 +125,7 @@ SYS_FUNC(getitimer)
 SYS_FUNC(osf_getitimer)
 {
        if (entering(tcp)) {
-               printxval_index(itimer_which, (unsigned int) tcp->u_arg[0],
-                               "ITIMER_???");
+               printxval(itimer_which, tcp->u_arg[0], "ITIMER_???");
                tprints(", ");
        } else {
                print_itimerval32(tcp, tcp->u_arg[1]);
@@ -139,8 +137,7 @@ SYS_FUNC(osf_getitimer)
 SYS_FUNC(setitimer)
 {
        if (entering(tcp)) {
-               printxval_index(itimer_which, (unsigned int) tcp->u_arg[0],
-                               "ITIMER_???");
+               printxval(itimer_which, tcp->u_arg[0], "ITIMER_???");
                tprints(", ");
                print_itimerval(tcp, tcp->u_arg[1]);
                tprints(", ");
@@ -154,8 +151,7 @@ SYS_FUNC(setitimer)
 SYS_FUNC(osf_setitimer)
 {
        if (entering(tcp)) {
-               printxval_index(itimer_which, (unsigned int) tcp->u_arg[0],
-                               "ITIMER_???");
+               printxval(itimer_which, tcp->u_arg[0], "ITIMER_???");
                tprints(", ");
                print_itimerval32(tcp, tcp->u_arg[1]);
                tprints(", ");
@@ -174,8 +170,7 @@ do_adjtimex(struct tcb *const tcp, const print_obj_by_addr_fn print_tx,
 {
        if (print_tx(tcp, addr))
                return 0;
-       tcp->auxstr = xlat_idx(adjtimex_state, ARRAY_SIZE(adjtimex_state) - 1,
-                              (kernel_ulong_t) tcp->u_rval);
+       tcp->auxstr = xlookup(adjtimex_state, (kernel_ulong_t) tcp->u_rval);
        return RVAL_STR;
 }
 
@@ -228,9 +223,8 @@ printclockname(int clockid)
                                        "MAKE_THREAD_CPUCLOCK" :
                                        "MAKE_PROCESS_CPUCLOCK",
                                CPUCLOCK_PID(clockid));
-                       printxval_index(cpuclocknames,
-                                       (unsigned int) clockid & CLOCKFD_MASK,
-                                       "CPUCLOCK_???");
+                       printxval(cpuclocknames, clockid & CLOCKFD_MASK,
+                                 "CPUCLOCK_???");
                        tprints(")");
                }
 
@@ -238,7 +232,7 @@ printclockname(int clockid)
                        tprints(" */");
        } else
 #endif
-               printxval_index(clocknames, clockid, "CLOCK_???");
+               printxval(clocknames, clockid, "CLOCK_???");
 }
 
 static int
diff --git a/util.c b/util.c
index 42253ebb05dcedc3a625f051d9745d8b4488a2f0..2349ec1589f2b31201b1d0daba2e92403de049e1 100644 (file)
--- a/util.c
+++ b/util.c
@@ -1239,7 +1239,6 @@ print_array_ex(struct tcb *const tcp,
               void *const opaque_data,
               unsigned int flags,
               const struct xlat *index_xlat,
-              size_t index_xlat_size,
               const char *index_dflt)
 {
        if (!start_addr) {
@@ -1295,15 +1294,9 @@ print_array_ex(struct tcb *const tcp,
 
                        if (!index_xlat) {
                                print_xlat_ex(idx, NULL, xlat_style);
-                       } else if (flags & PAF_INDEX_XLAT_VALUE_INDEXED) {
-                               printxval_indexn_ex(index_xlat,
-                                                   index_xlat_size, idx,
-                                                   index_dflt, xlat_style);
                        } else {
-                               printxvals_ex(idx, index_dflt, xlat_style,
-                                             (flags & PAF_INDEX_XLAT_SORTED)
-                                               && idx ? NULL : index_xlat,
-                                             NULL);
+                               printxval_ex(idx ? NULL : index_xlat, idx,
+                                            index_dflt, xlat_style);
                        }
 
                        tprints("] = ");
diff --git a/xlat.c b/xlat.c
index d00a0e2198567ae0ae42a2c14992d020e0e4a6c5..59a1186ce3a4af4a6d0cf2d15f6bdad7d0728579 100644 (file)
--- a/xlat.c
+++ b/xlat.c
@@ -50,49 +50,159 @@ print_xlat_val(uint64_t val, enum xlat_style style)
        tprints(sprint_xlat_val(val, style));
 }
 
+static int
+xlat_bsearch_compare(const void *a, const void *b)
+{
+       const uint64_t val1 = *(const uint64_t *) a;
+       const uint64_t val2 = ((const struct xlat_data *) b)->val;
+       return (val1 > val2) ? 1 : (val1 < val2) ? -1 : 0;
+}
+
 const char *
 xlookup(const struct xlat *xlat, const uint64_t val)
 {
-       static const struct xlat *pos;
+       static const struct xlat *x;
+       static size_t idx;
+       const struct xlat_data *e;
 
-       if (xlat)
-               pos = xlat;
+       if (xlat) {
+               x = xlat;
+               idx = 0;
+       }
+
+       if (!x || !x->data)
+               return NULL;
+
+       switch (x->type) {
+       case XT_NORMAL:
+               for (; idx < x->size; idx++)
+                       if (x->data[idx].val == val)
+                               return x->data[idx].str;
+               break;
+
+       case XT_SORTED:
+               e = bsearch((const void *) &val,
+                           x->data + idx,
+                           x->size - idx,
+                           sizeof(x->data[0]),
+                           xlat_bsearch_compare);
+               if (e) {
+                       idx = e - x->data;
+                       return e->str;
+               }
+               break;
+
+       case XT_INDEXED:
+               if (val < x->size) {
+                       if (val == x->data[val].val)
+                               return x->data[val].str;
+                       if (x->data[val].val == 0)
+                               break; /* a hole in the index */
+                       error_func_msg("Unexpected xlat value %" PRIu64
+                                      " at index %" PRIu64 " (str %s)",
+                                      x->data[val].val, val,
+                                      x->data[val].str);
+               }
+               break;
+
+       default:
+               error_func_msg("Invalid xlat type: %#x", x->type);
+       }
 
-       for (; pos->str != NULL; pos++)
-               if (pos->val == val)
-                       return pos->str;
        return NULL;
 }
 
-static int
-xlat_bsearch_compare(const void *a, const void *b)
+static const char *
+xlat_search_eq_or_less(const struct xlat *xlat, uint64_t *val)
 {
-       const uint64_t val1 = *(const uint64_t *) a;
-       const uint64_t val2 = ((const struct xlat *) b)->val;
-       return (val1 > val2) ? 1 : (val1 < val2) ? -1 : 0;
+       const struct xlat_data *base = xlat->data;
+       const struct xlat_data *cur = xlat->data;
+       size_t nmemb = xlat->size;
+
+       for (; nmemb > 0; nmemb >>= 1) {
+               cur = base + (nmemb >> 1);
+
+               if (*val == cur->val)
+                       return cur->str;
+
+               if (*val > cur->val) {
+                       base = cur + 1;
+                       nmemb--;
+               }
+       }
+
+       if (*val < cur->val) {
+               if (cur > xlat->data)
+                       cur--;
+               else
+                       return NULL;
+       }
+
+       *val = cur->val;
+       return cur->str;
 }
 
 const char *
-xlat_search(const struct xlat *xlat, const size_t nmemb, const uint64_t val)
+xlookup_le(const struct xlat *xlat, uint64_t *val)
 {
-       static const struct xlat *pos;
-       static size_t memb_left;
+       if (!xlat || !xlat->data)
+               return NULL;
 
-       if (xlat) {
-               pos = xlat;
-               memb_left = nmemb;
+       switch (xlat->type) {
+       case XT_SORTED:
+               return xlat_search_eq_or_less(xlat, val);
+
+#if 0 /* enable when used */
+       case XT_NORMAL: {
+               uint64_t best_hit = 0;
+               const char *str = NULL;
+
+               for (size_t idx = 0; idx < xlat->size; idx++) {
+                       if (xlat->data[idx].val == *val)
+                               return xlat->data[idx].str;
+
+                       if (xlat->data[idx].val < *val
+                           && xlat->data[idx].val > best_hit) {
+                               best_hit = xlat->data[idx].val;
+                               str = xlat->data[idx].str;
+                       }
+               }
+
+               *val = best_hit;
+               return str;
        }
 
-       const struct xlat *e =
-               bsearch((const void *) &val,
-                       pos, memb_left, sizeof(*pos), xlat_bsearch_compare);
+       case XT_INDEXED: {
+               size_t idx = *val;
 
-       if (e) {
-               memb_left -= e - pos;
-               return e->str;
-       } else {
+               if (idx >= xlat->size) {
+                       if (!xlat->size)
+                               return NULL;
+
+                       idx = xlat->size - 1;
+               }
+
+               do {
+                       if (idx == xlat->data[idx].val && xlat->data[idx].str) {
+                               *val = idx;
+                               return xlat->data[idx].str;
+                       }
+                       if (xlat->data[idx].val == 0)
+                               continue; /* a hole in the index */
+                       error_func_msg("Unexpected xlat value %" PRIu64
+                                      " at index %zu (str %s)",
+                                      xlat->data[idx].val, idx,
+                                      xlat->data[idx].str);
+               } while (idx--);
                return NULL;
        }
+#endif
+
+       default:
+               error_func_msg("Invalid xlat type: %#x", xlat->type);
+       }
+
+       return NULL;
 }
 
 /**
@@ -180,94 +290,6 @@ sprintxval_ex(char *const buf, const size_t size, const struct xlat *const x,
        return xsnprintf(buf, size, "%s", sprint_xlat_val(val, style));
 }
 
-/**
- * Print entry in sorted struct xlat table, if it is there.
- *
- * @param xlat      Pointer to an array of xlat values (not terminated with
- *                  XLAT_END).
- * @param xlat_size Number of xlat elements present in array (usually ARRAY_SIZE
- *                  if array is declared in the unit's scope and not
- *                  terminated with XLAT_END).
- * @param val       Value to search literal representation for.
- * @param dflt      String (abbreviated in comment syntax) which should be
- *                  emitted if no appropriate xlat value has been found.
- * @param style     Style in which xlat value should be printed.
- * @param fn        Search function.
- * @return          1 if appropriate xlat value has been found, 0
- *                  otherwise.
- */
-static int
-printxval_sized(const struct xlat *xlat, size_t xlat_size, uint64_t val,
-               const char *dflt, enum xlat_style style,
-               const char *(* fn)(const struct xlat *, size_t, uint64_t))
-{
-       style = get_xlat_style(style);
-
-       if (xlat_verbose(style) == XLAT_STYLE_RAW) {
-               print_xlat_val(val, style);
-               return 0;
-       }
-
-       const char *s = fn(xlat, xlat_size, val);
-
-       if (s) {
-               if (xlat_verbose(style) == XLAT_STYLE_VERBOSE) {
-                       print_xlat_val(val, style);
-                       tprints_comment(s);
-               } else {
-                       tprints(s);
-               }
-               return 1;
-       }
-
-       print_xlat_val(val, style);
-       tprints_comment(dflt);
-
-       return 0;
-}
-
-int
-printxval_searchn_ex(const struct xlat *xlat, size_t xlat_size, uint64_t val,
-                    const char *dflt, enum xlat_style style)
-{
-       return printxval_sized(xlat, xlat_size, val, dflt, style,
-                                 xlat_search);
-}
-
-const char *
-xlat_idx(const struct xlat *xlat, size_t nmemb, uint64_t val)
-{
-       static const struct xlat *pos;
-       static size_t memb_left;
-
-       if (xlat) {
-               pos = xlat;
-               memb_left = nmemb;
-       }
-
-       if (val >= memb_left)
-               return NULL;
-
-       if (val != pos[val].val) {
-               if (pos[val].val == 0)
-                       return NULL;    /* a hole in the index */
-
-               error_func_msg("Unexpected xlat value %" PRIu64
-                              " at index %" PRIu64,
-                              pos[val].val, val);
-               return NULL;
-       }
-
-       return pos[val].str;
-}
-
-int
-printxval_indexn_ex(const struct xlat *xlat, size_t xlat_size, uint64_t val,
-                   const char *dflt, enum xlat_style style)
-{
-       return printxval_sized(xlat, xlat_size, val, dflt, style, xlat_idx);
-}
-
 /*
  * Interpret `xlat' as an array of flags.
  * Print to static string the entries whose bits are on in `flags'
@@ -313,14 +335,14 @@ sprintflags_ex(const char *prefix, const struct xlat *xlat, uint64_t flags,
                return outstr;
        }
 
-       if (flags == 0 && xlat->val == 0 && xlat->str) {
+       if (flags == 0 && xlat->data->val == 0 && xlat->data->str) {
                if (sep)
                        *outptr++ = sep;
                if (xlat_verbose(style) == XLAT_STYLE_VERBOSE) {
                        outptr = xappendstr(outstr, outptr, "0 /* %s */",
-                                           xlat->str);
+                                           xlat->data->str);
                } else {
-                       strcpy(outptr, xlat->str);
+                       strcpy(outptr, xlat->data->str);
                }
 
                return outstr;
@@ -335,18 +357,19 @@ sprintflags_ex(const char *prefix, const struct xlat *xlat, uint64_t flags,
                                    sprint_xlat_val(flags, style));
        }
 
-       for (; flags && xlat->str; xlat++) {
-               if (xlat->val && (flags & xlat->val) == xlat->val) {
+       for (size_t idx = 0; flags && idx < xlat->size; idx++) {
+               if (xlat->data[idx].val && xlat->data[idx].str
+                   && (flags & xlat->data[idx].val) == xlat->data[idx].val) {
                        if (sep) {
                                *outptr++ = sep;
                        } else if (xlat_verbose(style) == XLAT_STYLE_VERBOSE) {
                                outptr = stpcpy(outptr, " /* ");
                        }
 
-                       outptr = stpcpy(outptr, xlat->str);
+                       outptr = stpcpy(outptr, xlat->data[idx].str);
                        found = 1;
                        sep = '|';
-                       flags &= ~xlat->val;
+                       flags &= ~xlat->data[idx].val;
                }
        }
 
@@ -418,15 +441,17 @@ printflags_ex(uint64_t flags, const char *dflt, enum xlat_style style,
 
        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)) {
+               for (size_t idx = 0; (flags || !n) && idx < xlat->size; ++idx) {
+                       uint64_t v = xlat->data[idx].val;
+                       if (xlat->data[idx].str
+                           && ((flags == v) || (v && (flags & v) == v))) {
                                if (xlat_verbose(style) == XLAT_STYLE_VERBOSE
                                    && !flags)
                                        tprints("0");
                                tprintf("%s%s",
-                                       (n++ ? "|" : init_sep), xlat->str);
-                               flags &= ~xlat->val;
+                                       (n++ ? "|" : init_sep),
+                                       xlat->data[idx].str);
+                               flags &= ~v;
                        }
                        if (!flags)
                                break;
@@ -489,23 +514,3 @@ print_xlat_ex(const uint64_t val, const char *str, enum xlat_style style)
                tprints_comment(str);
        }
 }
-
-void
-printxval_dispatch_ex(const struct xlat *xlat, size_t xlat_size, uint64_t val,
-                     const char *dflt, enum xlat_type xt,
-                     enum xlat_style style)
-{
-       switch (xt) {
-       case XT_NORMAL:
-               printxvals_ex(val, dflt, style, xlat, NULL);
-               break;
-
-       case XT_SORTED:
-               printxval_searchn_ex(xlat, xlat_size, val, dflt, style);
-               break;
-
-       case XT_INDEXED:
-               printxval_indexn_ex(xlat, xlat_size, val, dflt, style);
-               break;
-       }
-}
diff --git a/xlat.h b/xlat.h
index 366678acd6535287171d999195b4c59fadbf5921..b83ca4fb11ed1a65d9cd12000b4b163e3c4c744d 100644 (file)
--- a/xlat.h
+++ b/xlat.h
@@ -48,11 +48,17 @@ enum xlat_style {
 # define XLAT_STYLE_MASK ((1 << XLAT_STYLE_SPEC_BITS) - 1)
 };
 
-struct xlat {
+struct xlat_data {
        uint64_t val;
        const char *str;
 };
 
+struct xlat {
+       const struct xlat_data *data;
+       uint32_t size;
+       enum xlat_type type;
+};
+
 # define XLAT(val)                     { (unsigned)(val), #val }
 # define XLAT_PAIR(val, str)           { (unsigned)(val), str  }
 # define XLAT_TYPE(type, val)          {     (type)(val), #val }
index 399cdf4d40bda80aac418cc7a6bd96b31e0a8320..17a9f31a50854a2889f91d544eeeae8ee0fc4e65 100644 (file)
@@ -1,3 +1,4 @@
+#value_indexed
 TPACKET_V1     0
 TPACKET_V2     1
 TPACKET_V3     2
index 3d81314a4600536ad7b860f3a3b96b45ba54af70..9b57da34419a86236ff126a6f6bba8815a9ec5b9 100644 (file)
@@ -1,4 +1,4 @@
-/* sort -k2,2g */
+#sorted sort -k2,2g
 ARPHRD_NETROM                  0
 ARPHRD_ETHER                   1
 ARPHRD_EETHER                  2
index 89ced436d78116467314af1c1953e14e2a37f36c..9cac1a63671a0427392c3025f5fdec8bab03a793 100644 (file)
@@ -1,4 +1,4 @@
-/* sorted */
+#sorted
 /* Those are pulled from include/net/ax25.h, they should be part of UAPI */
 AX25_P_ROSE            0x01
 AX25_P_VJCOMP          0x06    /* Compressed TCP/IP packet   */
index 5fd8fd172e60760b605c12220c3a63ffdb67a311..e2b47f73281808c356a25638ae3139c0d179379a 100644 (file)
@@ -1,4 +1,4 @@
-/* sort -k2,2 */
+#sorted sort -k2,2
 L2CAP_CID_SIGNALING    0x0001
 L2CAP_CID_CONN_LESS    0x0002
 L2CAP_CID_A2MP         0x0003
index afac026aaad1aabb19256b9fd4ce2d13cbe592e5..f83370432f3d70df837672bf9606aefc0736c522 100644 (file)
@@ -1,4 +1,4 @@
-/* sort -k2,2 */
+#sorted sort -k2,2
 L2CAP_PSM_SDP           0x0001
 L2CAP_PSM_RFCOMM        0x0003
 L2CAP_PSM_3DSP          0x0021
index 7a6348725e70e3126f3aecf0de6fc22edc9df9bb..3197fbe5c7229120d7e56705e7546037ea8d64f2 100644 (file)
@@ -1,4 +1,4 @@
-/* sort -k2,2 */
+#sorted sort -k2,2
 ETH_P_802_3    0x0001          /* Dummy type for 802.3 frames  */
 ETH_P_AX25     0x0002          /* Dummy protocol id for AX.25  */
 ETH_P_ALL      0x0003          /* Every packet (be careful!!!) */
index 72b87c5320abfba69322bbc22cf0b0a412051295..71dc538229fc71b9554b521d1687b5e788a3590a 100644 (file)
@@ -1,4 +1,4 @@
-/* sort -k2,2 */
+#sorted sort -k2,2
 FF_RUMBLE       0x50
 FF_PERIODIC     0x51
 FF_CONSTANT     0x52
index ffab9e04aaf5704ce84e1a488e382190d50585ff..7564f512c7eb5c5e954b6db6a5c00c9c306c329b 100644 (file)
@@ -1,4 +1,4 @@
-/* sort -k2,2 */
+#sorted sort -k2,2
 { 0x0000002f,  "QNX4_SUPER_MAGIC"      },
 { 0x00000187,  "AUTOFS_SUPER_MAGIC"    },
 { 0x00001373,  "DEVFS_SUPER_MAGIC"     },
index 30b2dd82c2e52bedee19e5363b2e2211ab38a585..4d34b15c7726e8ff0a9c790fa62116f19af2e597 100755 (executable)
@@ -112,6 +112,7 @@ gen_header()
        local mpers="${0%/*}/../mpers_xlat.h"
        local decl="extern const struct xlat ${name}[];"
        local in_defs= in_mpers=
+       local xlat_type="XT_NORMAL"
 
        value_indexed=0
 
@@ -152,8 +153,12 @@ gen_header()
                '#val_type '*)
                        # to be processed during 2nd pass
                        ;;
+               '#sorted'|'#sorted '*)
+                       xlat_type="XT_SORTED"
+                       ;;
                '#value_indexed')
                        value_indexed=1
+                       xlat_type="XT_INDEXED"
                        ;;
                '#'*)
                        echo "${line}"
@@ -184,9 +189,6 @@ gen_header()
 
                        # else
 
-                       #  if !(defined HAVE_M32_MPERS || defined HAVE_MX32_MPERS)
-                       static
-                       #  endif
                EOF
        else
                cat <<-EOF
@@ -196,11 +198,10 @@ gen_header()
 
                        # else
 
-                       static
                EOF
        fi
 
-       echo "const struct xlat ${name}[] = {"
+       echo "static const struct xlat_data ${name}_xdata[] = {"
 
        unconditional= val_type=
        # 2nd pass: output everything.
@@ -219,6 +220,8 @@ gen_header()
                '#unconditional')
                        unconditional=1
                        ;;
+               '#sorted'|'#sorted '*)
+                       ;;
                '#value_indexed')
                        ;;
                '#val_type '*)
@@ -246,10 +249,28 @@ gen_header()
                        ;;
                esac
        done < "${input}"
-       echo ' XLAT_END'
+       echo '};'
+
+       if [ -n "$in_defs" ]; then
+               :
+       elif [ -n "$in_mpers" ]; then
+               cat <<-EOF
+                       #  if !(defined HAVE_M32_MPERS || defined HAVE_MX32_MPERS)
+                       static
+                       #  endif
+               EOF
+       else
+               cat <<-EOF
+                       static
+               EOF
+       fi
 
        cat <<-EOF
-               };
+               const struct xlat ${name}[1] = { {
+                        .data = ${name}_xdata,
+                        .size = ARRAY_SIZE(${name}_xdata),
+                        .type = ${xlat_type},
+               } };
 
                # endif /* !IN_MPERS */
 
index 0fc625b7546ce8c9cf071b83f5e62d2e8d313e89..4ffcaae1354112a77789b1904e959d9c74e00372 100644 (file)
@@ -1,4 +1,4 @@
-/* sort -k2,2n */
+#sorted sort -k2,2n
 HW_BREAKPOINT_EMPTY 0
 HW_BREAKPOINT_R 1
 HW_BREAKPOINT_W 2
index 210495b701b1ecda90623e6f11fcb317bf90e822..53b552402e6c1d54d46625bb9c4f633ac57c5b02 100644 (file)
@@ -1,4 +1,4 @@
-/* sort -k4,4g */
+#sorted sort -k4,4g
 IFF_UP         (1 << 0)
 IFF_BROADCAST  (1 << 1)
 IFF_DEBUG      (1 << 2)
index befd22320ed285fecb0e717624a4067451ed9d94..634c9ab216cdeb6ae8ecd91a4f37bb0eef7ba063 100644 (file)
@@ -1,4 +1,4 @@
-/* sort -k2,2g */
+#sorted sort -k2,2g
 IF_RS_SENT     0x10
 IF_RA_RCVD     0x20
 IF_RA_MANAGED  0x40
index b35b428310944ec838c6bcc386778b260595de51..7e14dc058522aa2d4ec506678988720daa9e6934 100644 (file)
@@ -1,4 +1,4 @@
-/* sort -k2,2n */
+#sorted sort -k2,2n
 IPPROTO_IP             0
 IPPROTO_ICMP           1
 IPPROTO_IGMP           2
index a81a81920b35ce9bd98bb1cae5061fdca4707a3c..20da35d8783987838c6c02bf056a34d4a31fea15 100644 (file)
@@ -1,4 +1,4 @@
-/* sort -k2,2g */
+#sorted sort -k2,2g
 IPC_RMID 0
 IPC_SET 1
 IPC_STAT 2
index 1ba0b1fc347aa4d27e6226eb689ab39f88b7299a..40c2827d36c1c89637c67ab37e625eeb4798e707 100644 (file)
@@ -1,4 +1,4 @@
-/* sort -k2,2n */
+#sorted sort -k2,2n
 PERF_COUNT_HW_CACHE_L1D  0
 PERF_COUNT_HW_CACHE_L1I  1
 PERF_COUNT_HW_CACHE_LL   2
index 7e30c3ad6565d4cd0084934d212ac03ad6bbc3e3..0b27e866dbbd882d19a588300737221683afbcfa 100644 (file)
@@ -1,4 +1,4 @@
-/* sort -k2,2n */
+#sorted sort -k2,2n
 PERF_COUNT_HW_CACHE_OP_READ     0
 PERF_COUNT_HW_CACHE_OP_WRITE    1
 PERF_COUNT_HW_CACHE_OP_PREFETCH 2
index 075054659c527aeaa875c4d23d6e95e920b7ee8c..e403229023d621036515828a6e6311d996715854 100644 (file)
@@ -1,3 +1,3 @@
-/* sort -k2,2n */
+#sorted sort -k2,2n
 PERF_COUNT_HW_CACHE_RESULT_ACCESS 0
 PERF_COUNT_HW_CACHE_RESULT_MISS   1
index c46bcecd98803ef2ddaa228362cae27475260a7e..3b0ce4a7c03739d083f9936c96f1947f1c286a0e 100644 (file)
@@ -1,4 +1,4 @@
-/* sort -k2,2n */
+#sorted sort -k2,2n
 PERF_COUNT_HW_CPU_CYCLES               0
 PERF_COUNT_HW_INSTRUCTIONS             1
 PERF_COUNT_HW_CACHE_REFERENCES         2
index e2ad8a8c3b53fb23cb8f317301354167093dd460..0e097112c3a2f0e96851d67a44261e40128c833d 100644 (file)
@@ -1,4 +1,4 @@
-/* sort -k2,2n */
+#sorted sort -k2,2n
 PERF_COUNT_SW_CPU_CLOCK         0
 PERF_COUNT_SW_TASK_CLOCK        1
 PERF_COUNT_SW_PAGE_FAULTS       2
index 88f633814ba0561a038fd2daf09206ce95351b21..29f6f2b853c3314c9416cd6c323c9d338f976722 100644 (file)
@@ -1,4 +1,4 @@
-/* sort -k2,2n */
+#sorted sort -k2,2n
 PERF_TYPE_HARDWARE    0
 PERF_TYPE_SOFTWARE    1
 PERF_TYPE_TRACEPOINT  2
index 5433c25e22077f39f7b77327dadf17d10dbfe8f5..9c92dde0acb2c80666bc32c08e24fccd652fb9bf 100644 (file)
@@ -1,4 +1,4 @@
-/* sort -k2,2n */
+#sorted sort -k2,2n
 RTPROT_UNSPEC  0
 RTPROT_REDIRECT        1
 RTPROT_KERNEL  2
index 9e8b84b39910b3c93fd8ac658be134e7544c24b9..455ceebd4bf30025e56e3bda4013b489ccd8b053 100644 (file)
@@ -1,4 +1,4 @@
-/* sort -k2,2g */
+#sorted sort -k2,2g
 IPC_RMID 0
 IPC_SET 1
 IPC_STAT 2
index b7943064b8931f2f7aa1fce5ec2b031671ae1e3b..8394a53e899f82f9c7717b65bb7de6349fcddfb0 100644 (file)
@@ -1,4 +1,4 @@
-/* sort -k2,2g */
+#sorted sort -k2,2g
 IPC_RMID 0
 IPC_SET 1
 IPC_STAT 2
index d7810f8931b0dfd04a0305a4521a595edc18e282..2832da334e6f6f5eb6897d44fb0777e4906ab1fd 100644 (file)
@@ -1,4 +1,4 @@
-/* sorted */
+#sorted
 SMC_CLC_DECL_MEM       0x01010000
 SMC_CLC_DECL_TIMEOUT_CL        0x02010000
 SMC_CLC_DECL_TIMEOUT_AL        0x02020000
index 4b6bed5813bc18867930dd1ce92517be02316fce..2a526104f327ca3b4c8a46173a8e2a6fc6130bc1 100644 (file)
@@ -1,4 +1,4 @@
-/* sorted */
+#sorted
 AX25_WINDOW    1
 AX25_T1                2
 AX25_N2                3
index 919b21b0b27e8a6f784321a60d2642ed899f96d5..4c91dd296db3f7ca02bf0668ecbafd23aeeab578 100644 (file)
@@ -1,4 +1,4 @@
-/* sort -k2,2n */
+#sorted sort -k2,2n
 BT_SECURITY            4
 BT_DEFER_SETUP         7
 BT_FLUSHABLE           8
index 06a0efe804647c0ee51d99292627df74dbce38f0..e168b06b378270d8881cd246ea25d79a2323bfed 100644 (file)
@@ -1,4 +1,4 @@
-/* sort -k2,2n */
+#sorted sort -k2,2n
 DCCP_SOCKOPT_PACKET_SIZE       1
 DCCP_SOCKOPT_SERVICE           2
 DCCP_SOCKOPT_CHANGE_L          3
index 2ecc2019e7e05a3d207681401e9843c9fbb26c90..5538dad17866ac8f7a58ac3fc60295c99193e8de 100644 (file)
@@ -1,4 +1,4 @@
-/* sort -k2,2n */
+#sorted sort -k2,2n
 TIPC_IMPORTANCE                127
 TIPC_SRC_DROPPABLE     128
 TIPC_DEST_DROPPABLE    129
index fd44dd19ac5e5a698d0724a861bba988acd6d400..e633cf5cd9f86eafff13011fbd67800fbd17d5e5 100644 (file)
@@ -1,4 +1,4 @@
-/* sort -k2,2n */
+#sorted sort -k2,2n
 SOL_IP         0
 #if !(defined __alpha__ || defined __hppa__ || defined __mips__ || defined __sparc__)
 SOL_SOCKET     1
index adbf88e2cff230ab3d3609f9f9ee09f63108aca5..cc86e3b2fe29527bcf7de0a92d7fa61d798189af 100644 (file)
@@ -1,4 +1,4 @@
-/* sort -k2,2 */
+#sorted sort -k2,2
 V4L2_CTRL_CLASS_USER           0x00980000      /* Old-style 'user' controls */
 V4L2_CTRL_CLASS_MPEG           0x00990000      /* MPEG-compression controls */
 V4L2_CTRL_CLASS_CAMERA         0x009a0000      /* Camera class controls */
index e742d07ac51c067cd25fae56502925304cf6594f..877d4e5381f491a062f48537931d87d12df1453f 100644 (file)
@@ -1,4 +1,4 @@
-/* sed -rn 's/.*v4l2_fourcc(_be)?\('"'(.)', '(.)', '(.)', '(.)'"'\).*/\10\5\4\3\2\t\0/p' |LC_COLLATE=C sort -k1,1 -t' ' |cut -f2- */
+#sorted sed -rn 's/.*v4l2_fourcc(_be)?\('"'(.)', '(.)', '(.)', '(.)'"'\).*/\10\5\4\3\2\t\0/p' |LC_COLLATE=C sort -k1,1 -t' ' |cut -f2-
 V4L2_PIX_FMT_Y10     v4l2_fourcc('Y', '1', '0', ' ') /* 10  Greyscale     */
 V4L2_PIX_FMT_Y12     v4l2_fourcc('Y', '1', '2', ' ') /* 12  Greyscale     */
 V4L2_PIX_FMT_Y4      v4l2_fourcc('Y', '0', '4', ' ') /*  4  Greyscale     */
index e462561dc969a02d58bfeee1446cb44f67d7ea35..bd5a2482273c0e494d4f7c081f8ba3021f5df43c 100644 (file)
@@ -1,4 +1,4 @@
-/* sed -rn 's/.*v4l2_fourcc(_be)?\('"'(.)', '(.)', '(.)', '(.)'"'\).*/\10\5\4\3\2\t\0/p' |LC_COLLATE=C sort -k1,1 -t' ' |cut -f2- */
+#sorted sed -rn 's/.*v4l2_fourcc(_be)?\('"'(.)', '(.)', '(.)', '(.)'"'\).*/\10\5\4\3\2\t\0/p' |LC_COLLATE=C sort -k1,1 -t' ' |cut -f2-
 V4L2_SDR_FMT_PCU20BE      v4l2_fourcc('P', 'C', '2', '0') /* planar complex u20be */
 V4L2_SDR_FMT_RU12LE       v4l2_fourcc('R', 'U', '1', '2') /* real u12le */
 V4L2_SDR_FMT_CS14LE       v4l2_fourcc('C', 'S', '1', '4') /* complex s14le */