]> granicus.if.org Git - strace/commitdiff
Generalise some printing primitives
authorEugene Syromyatnikov <evgsyr@gmail.com>
Tue, 19 Feb 2019 01:46:58 +0000 (02:46 +0100)
committerDmitry V. Levin <ldv@altlinux.org>
Wed, 20 Feb 2019 00:59:49 +0000 (00:59 +0000)
Character class checks and hexadecimal number formatting are open-coded
all over the place, let's try to de-duplicate them a bit.

* print_utils.h: New file.
* Makefile.am (strace_SOURCES): Add it.
* util.c: Include "print_utils.h".
(string_quote, dumpstr): Use sprint_byte_hex and is_print.
* v4l2.c: Include "print_utils.h".
(print_pixelformat): Use is_print and BYTE_HEX_CHARS_PRINTF_QUOTED,
add a note that the routine is rather generic.

Makefile.am
print_utils.h [new file with mode: 0644]
util.c
v4l2.c

index c2b7ee109b4a6c36a855db2a18f5ce7f124e3b51..0e26296f0ecd3687a18bda91306bb826342d5ff1 100644 (file)
@@ -243,6 +243,7 @@ strace_SOURCES =    \
        print_timespec.c \
        print_timeval.c \
        print_timex.c   \
+       print_utils.h   \
        printmode.c     \
        printrusage.c   \
        printsiginfo.c  \
diff --git a/print_utils.h b/print_utils.h
new file mode 100644 (file)
index 0000000..519cd40
--- /dev/null
@@ -0,0 +1,39 @@
+#ifndef STRACE_PRINT_UTILS_H
+# define STRACE_PRINT_UTILS_H
+
+# include <inttypes.h>
+
+/* Hexadecimal output utils */
+
+static const char hex_chars[16] = "0123456789abcdef";
+
+/**
+ * Character array representing hexadecimal encoding of a character value.
+ *
+ * @param b_ Byte to provide representation for.
+ */
+# define BYTE_HEX_CHARS(b_) \
+       hex_chars[((uint8_t) (b_)) >> 4], hex_chars[((uint8_t) (b_)) & 0xf]
+# define BYTE_HEX_CHARS_PRINTF(b_) \
+       '\\', 'x', BYTE_HEX_CHARS(b_)
+# define BYTE_HEX_CHARS_PRINTF_QUOTED(b_) \
+       '\'', BYTE_HEX_CHARS_PRINTF(b_), '\''
+
+static inline char *
+sprint_byte_hex(char *buf, uint8_t val)
+{
+       *buf++ = hex_chars[val >> 4];
+       *buf++ = hex_chars[val & 0xf];
+
+       return buf;
+}
+
+/* Character classification utils */
+
+static inline bool
+is_print(uint8_t c)
+{
+       return (c >= ' ') && (c < 0x7f);
+}
+
+#endif /* STRACE_PRINT_UTILS_H */
diff --git a/util.c b/util.c
index f0c7c6ae80b6c9048e3db32503546891db3742c7..239e0f132d8b47179e4d81887ded390fe6cf43b2 100644 (file)
--- a/util.c
+++ b/util.c
@@ -24,6 +24,7 @@
 #include <sys/uio.h>
 
 #include "largefile_wrappers.h"
+#include "print_utils.h"
 #include "xlat.h"
 #include "xstring.h"
 
@@ -490,7 +491,7 @@ string_quote(const char *instr, char *outstr, const unsigned int size,
        char *s = outstr;
        unsigned int i;
        int usehex, c, eol;
-       bool escape;
+       bool printable;
 
        if (style & QUOTE_0_TERMINATED)
                eol = '\0';
@@ -538,8 +539,7 @@ string_quote(const char *instr, char *outstr, const unsigned int size,
                                goto asciz_ended;
                        *s++ = '\\';
                        *s++ = 'x';
-                       *s++ = "0123456789abcdef"[c >> 4];
-                       *s++ = "0123456789abcdef"[c & 0xf];
+                       s = sprint_byte_hex(s, c);
                }
 
                goto string_ended;
@@ -579,12 +579,12 @@ string_quote(const char *instr, char *outstr, const unsigned int size,
                        *s++ = 'v';
                        break;
                default:
-                       escape = (c < ' ') || (c > 0x7e);
+                       printable = is_print(c);
 
-                       if (!escape && escape_chars)
-                               escape = !!strchr(escape_chars, c);
+                       if (printable && escape_chars)
+                               printable = !strchr(escape_chars, c);
 
-                       if (!escape) {
+                       if (printable) {
                                *s++ = c;
                        } else {
                                /* Print \octal */
@@ -942,8 +942,7 @@ dumpstr(struct tcb *const tcp, const kernel_ulong_t addr, const int len)
                /* Hex dump */
                do {
                        if (i < len) {
-                               *dst++ = "0123456789abcdef"[*src >> 4];
-                               *dst++ = "0123456789abcdef"[*src & 0xf];
+                               dst = sprint_byte_hex(dst, *src);
                        } else {
                                *dst++ = ' ';
                                *dst++ = ' ';
@@ -958,7 +957,7 @@ dumpstr(struct tcb *const tcp, const kernel_ulong_t addr, const int len)
                i -= 16;
                src -= 16;
                do {
-                       if (*src >= ' ' && *src < 0x7f)
+                       if (is_print(*src))
                                *dst++ = *src;
                        else
                                *dst++ = '.';
diff --git a/v4l2.c b/v4l2.c
index edc06f2fcd2d1709eb275045752493a8ea7dc740..b87ea333bd7e73085088973585c916353145e665 100644 (file)
--- a/v4l2.c
+++ b/v4l2.c
@@ -42,6 +42,7 @@ typedef struct v4l2_standard struct_v4l2_standard;
 #include MPERS_DEFS
 
 #include "print_fields.h"
+#include "print_utils.h"
 #include "xstring.h"
 
 /* v4l2_fourcc_be was added by Linux commit v3.18-rc1~101^2^2~127 */
@@ -70,6 +71,7 @@ print_pixelformat(uint32_t fourcc, const struct xlat *xlat)
        unsigned int i;
 
        tprints("v4l2_fourcc(");
+       /* Generic char array printing routine.  */
        for (i = 0; i < ARRAY_SIZE(a); ++i) {
                unsigned char c = a[i];
 
@@ -84,7 +86,7 @@ print_pixelformat(uint32_t fourcc, const struct xlat *xlat)
                                '\0'
                        };
                        tprints(sym);
-               } else if (c >= ' ' && c <= 0x7e) {
+               } else if (is_print(c)) {
                        char sym[] = {
                                '\'',
                                c,
@@ -94,12 +96,7 @@ print_pixelformat(uint32_t fourcc, const struct xlat *xlat)
                        tprints(sym);
                } else {
                        char hex[] = {
-                               '\'',
-                               '\\',
-                               'x',
-                               "0123456789abcdef"[c >> 4],
-                               "0123456789abcdef"[c & 0xf],
-                               '\'',
+                               BYTE_HEX_CHARS_PRINTF_QUOTED(c),
                                '\0'
                        };
                        tprints(hex);