From 464df1d5e5ab1322e2dd0a7796939fff1aeefa9a Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 7 Apr 2024 17:49:25 +0200 Subject: Adding upstream version 1.47.0. Signed-off-by: Daniel Baumann --- lib/support/cstring.c | 162 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 162 insertions(+) create mode 100644 lib/support/cstring.c (limited to 'lib/support/cstring.c') diff --git a/lib/support/cstring.c b/lib/support/cstring.c new file mode 100644 index 0000000..57f4522 --- /dev/null +++ b/lib/support/cstring.c @@ -0,0 +1,162 @@ +/* + * cstring.c -- parse and print strings using the C escape sequences + */ + +#include "config.h" +#include +#include +#include +#ifdef HAVE_GETOPT_H +#include +#endif +#include + +#include "cstring.h" + +int parse_c_string(char *str) +{ + char *to, *from, ch; + int v; + + to = from = str; + + for (to = from = (char *) str; + *from && *from != '"'; to++, from++) { + if (*from == '\\') { + ch = *(++from); + switch (ch) { + case 'a': + *to = '\a'; + break; + case 'b': + *to = '\b'; + break; + case 'f': + *to = '\f'; + break; + case 'n': + *to = '\n'; + break; + case 't': + *to = '\t'; + break; + case 'v': + *to = '\v'; + break; + case 'x': + ch = *(from + 1); + if (ch >= 'a' && ch <= 'f') + ch = ch - 'a' + 'A'; + if (ch >= '0' && ch <= '9') + v = ch - '0'; + else if (ch >= 'A' && ch <= 'F') + v = ch + 10 - 'A'; + else { + *to = 'x'; + break; + } + from++; + ch = *(from + 1); + if (ch >= 'a' && ch <= 'f') + ch = ch - 'a' + 'A'; + if (ch >= '0' && ch <= '9') + v = (v * 16) + (ch - '0'); + else if (ch >= 'A' && ch <= 'F') + v = (v * 16) + (ch + 10 - 'A'); + else { + *to = 'x'; + from--; + break; + } + from++; + *to = v; + break; + default: + if (ch >= '0' && ch <= '9') { + v = ch - '0'; + ch = *(from + 1); + if (ch >= '0' && ch <= '9') { + from++; + v = (8 * v) + (ch - '0'); + ch = *(from + 1); + if (ch >= '0' && ch <= '9') { + from++; + v = (8 * v) + (ch - '0'); + } + } + ch = v; + } + *to = ch; + } + continue; + } + *to = *from; + } + *to = '\0'; + return to - (char *) str; +} + +void print_c_string(FILE *f, const char *cp, int len) +{ + unsigned char ch; + + if (len < 0) + len = strlen(cp); + + while (len--) { + ch = *cp++; + if (ch == '\a') + fputs("\\a", f); + else if (ch == '\b') + fputs("\\b", f); + else if (ch == '\f') + fputs("\\f", f); + else if (ch == '\n') + fputs("\\n", f); + else if (ch == '\t') + fputs("\\t", f); + else if (ch == '\v') + fputs("\\v", f); + else if (ch == '\\') + fputs("\\\\", f); + else if (ch == '\'') + fputs("\\\'", f); + else if (ch == '\"') + fputs("\\\"", f); + else if ((ch < 32) || (ch > 126)) + fprintf(f, "\\%03o", ch); + else + fputc(ch, f); + } +} + +#ifdef DEBUG_PROGRAM +int main(int argc, char **argv) +{ + char buf[4096]; + int c, raw = 0; + + while ((c = getopt(argc, argv, "r")) != EOF) { + switch (c) { + case 'r': + raw++; + break; + default: + fprintf(stderr, "Usage: %s [-r]\n", argv[0]); + exit(1); + } + } + + while (!feof(stdin)) { + if (fgets(buf, sizeof(buf), stdin) == NULL) + break; + c = parse_c_string(buf); + if (raw) + fputs(buf, stdout); + else { + print_c_string(stdout, buf, c); + printf(" <%d>\n", c); + } + } +} +#endif -- cgit v1.2.3