1 /***********************************************************************
2 * *
3 * This software is part of the ast package *
4 * Copyright (c) 1985-2010 AT&T Intellectual Property *
5 * and is licensed under the *
6 * Common Public License, Version 1.0 *
7 * by AT&T Intellectual Property *
8 * *
9 * A copy of the License is available at *
10 * http://www.opensource.org/licenses/cpl1.0.txt *
11 * (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) *
12 * *
13 * Information and Software Systems Research *
14 * AT&T Research *
15 * Florham Park NJ *
16 * *
17 * Glenn Fowler <gsf@research.att.com> *
18 * David Korn <dgk@research.att.com> *
19 * Phong Vo <kpv@research.att.com> *
20 * *
21 ***********************************************************************/
22 #pragma prototyped
23 /*
24 * Glenn Fowler
25 * AT&T Research
26 *
27 * return the next character in the string s
28 * \ character constants are converted
29 * p is updated to point to the next character in s
30 */
31
32 #include <ast.h>
33 #include <ctype.h>
34
35 #include <ccode.h>
36 #if !_PACKAGE_astsa
37 #include <regex.h>
38 #endif
39
40 int
chresc(register const char * s,char ** p)41 chresc(register const char* s, char** p)
42 {
43 register const char* q;
44 register int c;
45 const char* e;
46 #if !_PACKAGE_astsa
47 int n;
48 char buf[64];
49 #endif
50
51 switch (c = mbchar(s))
52 {
53 case 0:
54 s--;
55 break;
56 case '\\':
57 switch (c = *s++)
58 {
59 case '0': case '1': case '2': case '3':
60 case '4': case '5': case '6': case '7':
61 c -= '0';
62 q = s + 2;
63 while (s < q)
64 switch (*s)
65 {
66 case '0': case '1': case '2': case '3':
67 case '4': case '5': case '6': case '7':
68 c = (c << 3) + *s++ - '0';
69 break;
70 default:
71 q = s;
72 break;
73 }
74 break;
75 case 'a':
76 c = CC_bel;
77 break;
78 case 'b':
79 c = '\b';
80 break;
81 case 'c':
82 control:
83 if (c = *s)
84 {
85 s++;
86 if (islower(c))
87 c = toupper(c);
88 }
89 c = ccmapc(c, CC_NATIVE, CC_ASCII);
90 c ^= 0x40;
91 c = ccmapc(c, CC_ASCII, CC_NATIVE);
92 break;
93 case 'C':
94 if (*s == '-' && *(s + 1))
95 {
96 s++;
97 goto control;
98 }
99 #if !_PACKAGE_astsa
100 if (*s == '[' && (n = regcollate(s + 1, (char**)&e, buf, sizeof(buf))) >= 0)
101 {
102 if (n == 1)
103 c = buf[0];
104 s = e;
105 }
106 #endif
107 break;
108 case 'e':
109 case 'E':
110 c = CC_esc;
111 break;
112 case 'f':
113 c = '\f';
114 break;
115 case 'M':
116 if (*s == '-')
117 {
118 s++;
119 c = CC_esc;
120 }
121 break;
122 case 'n':
123 c = '\n';
124 break;
125 case 'r':
126 c = '\r';
127 break;
128 case 't':
129 c = '\t';
130 break;
131 case 'v':
132 c = CC_vt;
133 break;
134 case 'u':
135 case 'U':
136 case 'x':
137 c = 0;
138 q = c == 'u' ? (s + 4) : c == 'U' ? (s + 8) : (char*)0;
139 e = s;
140 while (!e || !q || s < q)
141 {
142 switch (*s)
143 {
144 case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
145 c = (c << 4) + *s++ - 'a' + 10;
146 continue;
147 case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
148 c = (c << 4) + *s++ - 'A' + 10;
149 continue;
150 case '0': case '1': case '2': case '3': case '4':
151 case '5': case '6': case '7': case '8': case '9':
152 c = (c << 4) + *s++ - '0';
153 continue;
154 case '{':
155 case '[':
156 if (s != e)
157 break;
158 e = 0;
159 s++;
160 continue;
161 case '}':
162 case ']':
163 if (!e)
164 s++;
165 break;
166 default:
167 break;
168 }
169 break;
170 }
171 break;
172 case 0:
173 s--;
174 break;
175 }
176 break;
177 }
178 if (p)
179 *p = (char*)s;
180 return c;
181 }
182