1 /* 2 * cstring.c -- parse and print strings using the C escape sequences 3 */ 4 5 #include "config.h" 6 #include <stdio.h> 7 #include <stdlib.h> 8 #include <ctype.h> 9 #ifdef HAVE_GETOPT_H 10 #include <getopt.h> 11 #endif 12 #include <string.h> 13 14 #include "cstring.h" 15 16 int parse_c_string(char *str) 17 { 18 char *to, *from, ch; 19 int v; 20 21 to = from = str; 22 23 for (to = from = (char *) str; 24 *from && *from != '"'; to++, from++) { 25 if (*from == '\\') { 26 ch = *(++from); 27 switch (ch) { 28 case 'a': 29 *to = '\a'; 30 break; 31 case 'b': 32 *to = '\b'; 33 break; 34 case 'f': 35 *to = '\f'; 36 break; 37 case 'n': 38 *to = '\n'; 39 break; 40 case 't': 41 *to = '\t'; 42 break; 43 case 'v': 44 *to = '\v'; 45 break; 46 case 'x': 47 ch = *(from + 1); 48 if (ch >= 'a' && ch <= 'f') 49 ch = ch - 'a' + 'A'; 50 if (ch >= '0' && ch <= '9') 51 v = ch - '0'; 52 else if (ch >= 'A' && ch <= 'F') 53 v = ch + 10 - 'A'; 54 else { 55 *to = 'x'; 56 break; 57 } 58 from++; 59 ch = *(from + 1); 60 if (ch >= 'a' && ch <= 'f') 61 ch = ch - 'a' + 'A'; 62 if (ch >= '0' && ch <= '9') 63 v = (v * 16) + (ch - '0'); 64 else if (ch >= 'A' && ch <= 'F') 65 v = (v * 16) + (ch + 10 - 'A'); 66 else { 67 *to = 'x'; 68 from--; 69 break; 70 } 71 from++; 72 *to = v; 73 break; 74 default: 75 if (ch >= '0' && ch <= '9') { 76 v = ch - '0'; 77 ch = *(from + 1); 78 if (ch >= '0' && ch <= '9') { 79 from++; 80 v = (8 * v) + (ch - '0'); 81 ch = *(from + 1); 82 if (ch >= '0' && ch <= '9') { 83 from++; 84 v = (8 * v) + (ch - '0'); 85 } 86 } 87 ch = v; 88 } 89 *to = ch; 90 } 91 continue; 92 } 93 *to = *from; 94 } 95 *to = '\0'; 96 return to - (char *) str; 97 } 98 99 void print_c_string(FILE *f, const char *cp, int len) 100 { 101 unsigned char ch; 102 103 if (len < 0) 104 len = strlen(cp); 105 106 while (len--) { 107 ch = *cp++; 108 if (ch == '\a') 109 fputs("\\a", f); 110 else if (ch == '\b') 111 fputs("\\b", f); 112 else if (ch == '\f') 113 fputs("\\f", f); 114 else if (ch == '\n') 115 fputs("\\n", f); 116 else if (ch == '\t') 117 fputs("\\t", f); 118 else if (ch == '\v') 119 fputs("\\v", f); 120 else if (ch == '\\') 121 fputs("\\\\", f); 122 else if (ch == '\'') 123 fputs("\\\'", f); 124 else if (ch == '\"') 125 fputs("\\\"", f); 126 else if ((ch < 32) || (ch > 126)) 127 fprintf(f, "\\%03o", ch); 128 else 129 fputc(ch, f); 130 } 131 } 132 133 #ifdef DEBUG_PROGRAM 134 int main(int argc, char **argv) 135 { 136 char buf[4096]; 137 int c, raw = 0; 138 139 while ((c = getopt(argc, argv, "r")) != EOF) { 140 switch (c) { 141 case 'r': 142 raw++; 143 break; 144 default: 145 fprintf(stderr, "Usage: %s [-r]\n", argv[0]); 146 exit(1); 147 } 148 } 149 150 while (!feof(stdin)) { 151 if (fgets(buf, sizeof(buf), stdin) == NULL) 152 break; 153 c = parse_c_string(buf); 154 if (raw) 155 fputs(buf, stdout); 156 else { 157 print_c_string(stdout, buf, c); 158 printf(" <%d>\n", c); 159 } 160 } 161 } 162 #endif