| /* |
| * cstring.c -- parse and print strings using the C escape sequences |
| */ |
| |
| #include "config.h" |
| #include <stdio.h> |
| #include <stdlib.h> |
| #include <ctype.h> |
| #ifdef HAVE_GETOPT_H |
| #include <getopt.h> |
| #endif |
| #include <string.h> |
| |
| #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 |