xref: /aosp_15_r20/external/e2fsprogs/lib/support/cstring.c (revision 6a54128f25917bfc36a8a6e9d722c04a0b4641b6)
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