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