strace/tests/print_quoted_string.c
Eugene Syromyatnikov 0b732f7e9d util.c: add support for additional escape characters in string_quote
Quotes are not always used to denote string limits; printfd uses angle
brackets for that, for example.  As result, mechanism for supplying
set of additional characters in order to avoid ambiguities regarding
the end of the quoted string is needed.

* defs.h (string_quote): Add escape_chars parameter.
(print_quoted_string_ex): New function prototype.
* util.c (string_quote): Add escape_chars parameter.
(print_quoted_string_ex): Rename from print_quoted_string, add
escape_chars parameter, pass it to string_quote call.
(print_quoted_string): Turn into a thin wrapper around
print_quoted_string_ex.
(printstr_ex): Pass NULL as escape_chars argument of string_quote call.
* socketutils.c (unix_parse_response): Pass NULL as escape_chars
argument of string_quote call.
* tests/print_quoted_string.c (print_octal): New function.
print_quoted_memory_ex): Use it.  Add escape_chars parameter.
(print_quoted_memory): Pass NULL as escape_chars argument
of print_quoted_memory_ex call.
* tests/tests.h (print_quoted_string_ex, print_quoted_memory_ex): Add
escape_chars parameter.
* tests/fsync-y.c: Pass NULL as escape_chars argument of
print_quoted_string_ex call.

Co-Authored-by: Dmitry V. Levin <ldv@altlinux.org>
2018-03-01 01:00:24 +00:00

127 lines
2.1 KiB
C

#include "tests.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/*
* Based on string_quote() from util.c.
* Assumes instr is NUL-terminated.
*/
void
print_quoted_string_ex(const char *instr, bool quote, const char *escape_chars)
{
print_quoted_memory_ex(instr, strlen(instr), quote, escape_chars);
}
void
print_quoted_string(const char *instr)
{
print_quoted_memory(instr, strlen(instr));
}
void
print_quoted_cstring(const char *instr, const size_t size)
{
const size_t len = strnlen(instr, size);
if (len < size) {
print_quoted_memory(instr, len);
} else {
print_quoted_memory(instr, size - 1);
printf("...");
}
}
static void
print_octal(unsigned char c, char next)
{
putchar('\\');
char c1 = '0' + (c & 0x7);
char c2 = '0' + ((c >> 3) & 0x7);
char c3 = '0' + (c >> 6);
if (next >= '0' && next <= '7') {
/* Print \octal */
putchar(c3);
putchar(c2);
} else {
/* Print \[[o]o]o */
if (c3 != '0')
putchar(c3);
if (c3 != '0' || c2 != '0')
putchar(c2);
}
putchar(c1);
}
void
print_quoted_memory_ex(const void *const instr, const size_t len,
bool quote, const char *escape_chars)
{
const unsigned char *str = (const unsigned char *) instr;
size_t i;
if (quote)
putchar('"');
for (i = 0; i < len; ++i) {
const int c = str[i];
switch (c) {
case '\"':
printf("\\\"");
break;
case '\\':
printf("\\\\");
break;
case '\f':
printf("\\f");
break;
case '\n':
printf("\\n");
break;
case '\r':
printf("\\r");
break;
case '\t':
printf("\\t");
break;
case '\v':
printf("\\v");
break;
default:
if (c >= ' ' && c <= 0x7e &&
!(escape_chars && strchr(escape_chars, c))) {
putchar(c);
} else {
print_octal(c,
i < (len - 1) ? str[i + 1] : 0);
}
break;
}
}
if (quote)
putchar('"');
}
void
print_quoted_memory(const void *const instr, const size_t len)
{
print_quoted_memory_ex(instr, len, true, NULL);
}
void
print_quoted_hex(const void *const instr, const size_t len)
{
const unsigned char *str = instr;
size_t i;
printf("\"");
for (i = 0; i < len; i++)
printf("\\x%02x", str[i]);
printf("\"");
}