/* * 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