Browse Source

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.
Eugene Syromyatnikov 9 months ago
parent
commit
d8b3dd3014
4 changed files with 53 additions and 17 deletions
  1. 1
    0
      Makefile.am
  2. 39
    0
      print_utils.h
  3. 9
    10
      util.c
  4. 4
    7
      v4l2.c

+ 1
- 0
Makefile.am View File

@@ -243,6 +243,7 @@ strace_SOURCES =	\
243 243
 	print_timespec.c \
244 244
 	print_timeval.c	\
245 245
 	print_timex.c	\
246
+	print_utils.h	\
246 247
 	printmode.c	\
247 248
 	printrusage.c	\
248 249
 	printsiginfo.c	\

+ 39
- 0
print_utils.h View File

@@ -0,0 +1,39 @@
1
+#ifndef STRACE_PRINT_UTILS_H
2
+# define STRACE_PRINT_UTILS_H
3
+
4
+# include <inttypes.h>
5
+
6
+/* Hexadecimal output utils */
7
+
8
+static const char hex_chars[16] = "0123456789abcdef";
9
+
10
+/**
11
+ * Character array representing hexadecimal encoding of a character value.
12
+ *
13
+ * @param b_ Byte to provide representation for.
14
+ */
15
+# define BYTE_HEX_CHARS(b_) \
16
+	hex_chars[((uint8_t) (b_)) >> 4], hex_chars[((uint8_t) (b_)) & 0xf]
17
+# define BYTE_HEX_CHARS_PRINTF(b_) \
18
+	'\\', 'x', BYTE_HEX_CHARS(b_)
19
+# define BYTE_HEX_CHARS_PRINTF_QUOTED(b_) \
20
+	'\'', BYTE_HEX_CHARS_PRINTF(b_), '\''
21
+
22
+static inline char *
23
+sprint_byte_hex(char *buf, uint8_t val)
24
+{
25
+	*buf++ = hex_chars[val >> 4];
26
+	*buf++ = hex_chars[val & 0xf];
27
+
28
+	return buf;
29
+}
30
+
31
+/* Character classification utils */
32
+
33
+static inline bool
34
+is_print(uint8_t c)
35
+{
36
+	return (c >= ' ') && (c < 0x7f);
37
+}
38
+
39
+#endif /* STRACE_PRINT_UTILS_H */

+ 9
- 10
util.c View File

@@ -24,6 +24,7 @@
24 24
 #include <sys/uio.h>
25 25
 
26 26
 #include "largefile_wrappers.h"
27
+#include "print_utils.h"
27 28
 #include "xlat.h"
28 29
 #include "xstring.h"
29 30
 
@@ -490,7 +491,7 @@ string_quote(const char *instr, char *outstr, const unsigned int size,
490 491
 	char *s = outstr;
491 492
 	unsigned int i;
492 493
 	int usehex, c, eol;
493
-	bool escape;
494
+	bool printable;
494 495
 
495 496
 	if (style & QUOTE_0_TERMINATED)
496 497
 		eol = '\0';
@@ -538,8 +539,7 @@ string_quote(const char *instr, char *outstr, const unsigned int size,
538 539
 				goto asciz_ended;
539 540
 			*s++ = '\\';
540 541
 			*s++ = 'x';
541
-			*s++ = "0123456789abcdef"[c >> 4];
542
-			*s++ = "0123456789abcdef"[c & 0xf];
542
+			s = sprint_byte_hex(s, c);
543 543
 		}
544 544
 
545 545
 		goto string_ended;
@@ -579,12 +579,12 @@ string_quote(const char *instr, char *outstr, const unsigned int size,
579 579
 			*s++ = 'v';
580 580
 			break;
581 581
 		default:
582
-			escape = (c < ' ') || (c > 0x7e);
582
+			printable = is_print(c);
583 583
 
584
-			if (!escape && escape_chars)
585
-				escape = !!strchr(escape_chars, c);
584
+			if (printable && escape_chars)
585
+				printable = !strchr(escape_chars, c);
586 586
 
587
-			if (!escape) {
587
+			if (printable) {
588 588
 				*s++ = c;
589 589
 			} else {
590 590
 				/* Print \octal */
@@ -942,8 +942,7 @@ dumpstr(struct tcb *const tcp, const kernel_ulong_t addr, const int len)
942 942
 		/* Hex dump */
943 943
 		do {
944 944
 			if (i < len) {
945
-				*dst++ = "0123456789abcdef"[*src >> 4];
946
-				*dst++ = "0123456789abcdef"[*src & 0xf];
945
+				dst = sprint_byte_hex(dst, *src);
947 946
 			} else {
948 947
 				*dst++ = ' ';
949 948
 				*dst++ = ' ';
@@ -958,7 +957,7 @@ dumpstr(struct tcb *const tcp, const kernel_ulong_t addr, const int len)
958 957
 		i -= 16;
959 958
 		src -= 16;
960 959
 		do {
961
-			if (*src >= ' ' && *src < 0x7f)
960
+			if (is_print(*src))
962 961
 				*dst++ = *src;
963 962
 			else
964 963
 				*dst++ = '.';

+ 4
- 7
v4l2.c View File

@@ -42,6 +42,7 @@ typedef struct v4l2_standard struct_v4l2_standard;
42 42
 #include MPERS_DEFS
43 43
 
44 44
 #include "print_fields.h"
45
+#include "print_utils.h"
45 46
 #include "xstring.h"
46 47
 
47 48
 /* 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)
70 71
 	unsigned int i;
71 72
 
72 73
 	tprints("v4l2_fourcc(");
74
+	/* Generic char array printing routine.  */
73 75
 	for (i = 0; i < ARRAY_SIZE(a); ++i) {
74 76
 		unsigned char c = a[i];
75 77
 
@@ -84,7 +86,7 @@ print_pixelformat(uint32_t fourcc, const struct xlat *xlat)
84 86
 				'\0'
85 87
 			};
86 88
 			tprints(sym);
87
-		} else if (c >= ' ' && c <= 0x7e) {
89
+		} else if (is_print(c)) {
88 90
 			char sym[] = {
89 91
 				'\'',
90 92
 				c,
@@ -94,12 +96,7 @@ print_pixelformat(uint32_t fourcc, const struct xlat *xlat)
94 96
 			tprints(sym);
95 97
 		} else {
96 98
 			char hex[] = {
97
-				'\'',
98
-				'\\',
99
-				'x',
100
-				"0123456789abcdef"[c >> 4],
101
-				"0123456789abcdef"[c & 0xf],
102
-				'\'',
99
+				BYTE_HEX_CHARS_PRINTF_QUOTED(c),
103 100
 				'\0'
104 101
 			};
105 102
 			tprints(hex);

Loading…
Cancel
Save