From: Eugene Syromyatnikov Date: Tue, 19 Feb 2019 01:46:58 +0000 (+0100) Subject: Generalise some printing primitives X-Git-Tag: v5.0~47 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=d8b3dd301477bfdfcca764ae4ff2afc3d04f8d2a;p=strace Generalise some printing primitives 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. --- diff --git a/Makefile.am b/Makefile.am index c2b7ee10..0e26296f 100644 --- a/Makefile.am +++ b/Makefile.am @@ -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 index 00000000..519cd401 --- /dev/null +++ b/print_utils.h @@ -0,0 +1,39 @@ +#ifndef STRACE_PRINT_UTILS_H +# define STRACE_PRINT_UTILS_H + +# include + +/* 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 f0c7c6ae..239e0f13 100644 --- a/util.c +++ b/util.c @@ -24,6 +24,7 @@ #include #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 edc06f2f..b87ea333 100644 --- 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);