Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
att
GitHub Repository: att/ast
Path: blob/master/src/lib/libast/string/chresc.c
1810 views
1
/***********************************************************************
2
* *
3
* This software is part of the ast package *
4
* Copyright (c) 1985-2012 AT&T Intellectual Property *
5
* and is licensed under the *
6
* Eclipse Public License, Version 1.0 *
7
* by AT&T Intellectual Property *
8
* *
9
* A copy of the License is available at *
10
* http://www.eclipse.org/org/documents/epl-v10.html *
11
* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
12
* *
13
* Information and Software Systems Research *
14
* AT&T Research *
15
* Florham Park NJ *
16
* *
17
* Glenn Fowler <[email protected]> *
18
* David Korn <[email protected]> *
19
* Phong Vo <[email protected]> *
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 expanded
29
* *p is updated to point to the next character in s
30
* *m is 1 if return value is wide
31
*/
32
33
#include <ast.h>
34
#include <ctype.h>
35
36
#include <ccode.h>
37
#if !_PACKAGE_astsa
38
#include <regex.h>
39
#endif
40
41
int
42
chrexp(register const char* s, char** p, int* m, register int flags)
43
{
44
register const char* q;
45
register int c;
46
const char* e;
47
const char* b;
48
char* r;
49
int n;
50
int w;
51
52
w = 0;
53
for (;;)
54
{
55
b = s;
56
switch (c = mbchar(s))
57
{
58
case 0:
59
s--;
60
break;
61
case '\\':
62
switch (c = *s++)
63
{
64
case '0': case '1': case '2': case '3':
65
case '4': case '5': case '6': case '7':
66
if (!(flags & FMT_EXP_CHAR))
67
goto noexpand;
68
c -= '0';
69
q = s + 2;
70
while (s < q)
71
switch (*s)
72
{
73
case '0': case '1': case '2': case '3':
74
case '4': case '5': case '6': case '7':
75
c = (c << 3) + *s++ - '0';
76
break;
77
default:
78
q = s;
79
break;
80
}
81
break;
82
case 'a':
83
if (!(flags & FMT_EXP_CHAR))
84
goto noexpand;
85
c = CC_bel;
86
break;
87
case 'b':
88
if (!(flags & FMT_EXP_CHAR))
89
goto noexpand;
90
c = '\b';
91
break;
92
case 'c': /*DEPRECATED*/
93
case 'C':
94
if (!(flags & FMT_EXP_CHAR))
95
goto noexpand;
96
if (c = *s)
97
{
98
s++;
99
if (c == '\\')
100
{
101
c = chrexp(s - 1, &r, 0, flags);
102
s = (const char*)r;
103
}
104
if (islower(c))
105
c = toupper(c);
106
c = ccmapc(c, CC_NATIVE, CC_ASCII);
107
c ^= 0x40;
108
c = ccmapc(c, CC_ASCII, CC_NATIVE);
109
}
110
break;
111
case 'e': /*DEPRECATED*/
112
case 'E':
113
if (!(flags & FMT_EXP_CHAR))
114
goto noexpand;
115
c = CC_esc;
116
break;
117
case 'f':
118
if (!(flags & FMT_EXP_CHAR))
119
goto noexpand;
120
c = '\f';
121
break;
122
case 'M':
123
if (!(flags & FMT_EXP_CHAR))
124
goto noexpand;
125
if (*s == '-')
126
{
127
s++;
128
c = CC_esc;
129
}
130
break;
131
case 'n':
132
if (flags & FMT_EXP_NONL)
133
continue;
134
if (!(flags & FMT_EXP_LINE))
135
goto noexpand;
136
c = '\n';
137
break;
138
case 'r':
139
if (flags & FMT_EXP_NOCR)
140
continue;
141
if (!(flags & FMT_EXP_LINE))
142
goto noexpand;
143
c = '\r';
144
break;
145
case 't':
146
if (!(flags & FMT_EXP_CHAR))
147
goto noexpand;
148
c = '\t';
149
break;
150
case 'v':
151
if (!(flags & FMT_EXP_CHAR))
152
goto noexpand;
153
c = CC_vt;
154
break;
155
case 'u':
156
case 'U':
157
case 'x':
158
if (q = c == 'u' ? (s + 4) : c == 'U' ? (s + 8) : (char*)0)
159
{
160
if (!(flags & FMT_EXP_WIDE))
161
goto noexpand;
162
w = 1;
163
}
164
b = e = s;
165
n = 0;
166
c = 0;
167
while (!e || !q || s < q)
168
{
169
switch (*s)
170
{
171
case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
172
c = (c << 4) + *s++ - 'a' + 10;
173
n++;
174
continue;
175
case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
176
c = (c << 4) + *s++ - 'A' + 10;
177
n++;
178
continue;
179
case '0': case '1': case '2': case '3': case '4':
180
case '5': case '6': case '7': case '8': case '9':
181
c = (c << 4) + *s++ - '0';
182
n++;
183
continue;
184
case '{':
185
case '[':
186
if (s != e)
187
break;
188
e = 0;
189
s++;
190
if (w && *s == 'U' && *(s + 1) == '+')
191
s += 2;
192
continue;
193
case '}':
194
case ']':
195
if (!e)
196
s++;
197
break;
198
default:
199
break;
200
}
201
break;
202
}
203
if (n <= 2 && !(flags & FMT_EXP_CHAR) || n > 2 && (w = 1) && !(flags & FMT_EXP_WIDE))
204
{
205
c = '\\';
206
s = b;
207
}
208
break;
209
case 0:
210
s--;
211
break;
212
}
213
break;
214
default:
215
if ((s - b) > 1)
216
w = 1;
217
break;
218
}
219
break;
220
}
221
normal:
222
if (p)
223
*p = (char*)s;
224
if (m)
225
*m = w;
226
return c;
227
noexpand:
228
c = '\\';
229
s--;
230
goto normal;
231
}
232
233
int
234
chresc(register const char* s, char** p)
235
{
236
return chrexp(s, p, NiL, FMT_EXP_CHAR|FMT_EXP_LINE|FMT_EXP_WIDE);
237
}
238
239