Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
att
GitHub Repository: att/ast
Path: blob/master/src/lib/libast/string/fmtesc.c
1810 views
1
/***********************************************************************
2
* *
3
* This software is part of the ast package *
4
* Copyright (c) 1985-2011 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 string with expanded escape chars
28
*/
29
30
#include <ast.h>
31
#include <ccode.h>
32
#include <ctype.h>
33
#if _hdr_wchar && _hdr_wctype
34
#include <wchar.h>
35
#include <wctype.h>
36
#endif
37
38
/*
39
* quote string as of length n with qb...qe
40
* (flags&FMT_ALWAYS) always quotes, otherwise quote output only if necessary
41
* qe and the usual suspects are \... escaped
42
* (flags&FMT_WIDE) doesn't escape 8 bit chars
43
* (flags&FMT_ESCAPED) doesn't \... escape the usual suspects
44
* (flags&FMT_SHELL) escape $`"#;~&|()<>[]*?
45
*/
46
47
char*
48
fmtquote(const char* as, const char* qb, const char* qe, size_t n, int flags)
49
{
50
register unsigned char* s = (unsigned char*)as;
51
register unsigned char* e = s + n;
52
register char* b;
53
register int c;
54
register int m;
55
register int escaped;
56
register int spaced;
57
register int doublequote;
58
register int singlequote;
59
int shell;
60
char* f;
61
char* buf;
62
63
c = 4 * (n + 1);
64
if (qb)
65
c += strlen((char*)qb);
66
if (qe)
67
c += strlen((char*)qe);
68
b = buf = fmtbuf(c);
69
shell = 0;
70
doublequote = 0;
71
singlequote = 0;
72
if (qb)
73
{
74
if (qb[0] == '$' && qb[1] == '\'' && qb[2] == 0)
75
shell = 1;
76
else if ((flags & FMT_SHELL) && qb[1] == 0)
77
{
78
if (qb[0] == '"')
79
doublequote = 1;
80
else if (qb[0] == '\'')
81
singlequote = 1;
82
}
83
while (*b = *qb++)
84
b++;
85
}
86
else if (flags & FMT_SHELL)
87
doublequote = 1;
88
f = b;
89
escaped = spaced = !!(flags & FMT_ALWAYS);
90
while (s < e)
91
{
92
if ((m = mbsize(s)) > 1 && (s + m) <= e)
93
{
94
#if _hdr_wchar && _hdr_wctype
95
c = mbchar(s);
96
if (!spaced && !escaped && (iswspace(c) || iswcntrl(c)))
97
spaced = 1;
98
s -= m;
99
#endif
100
while (m--)
101
*b++ = *s++;
102
}
103
else
104
{
105
c = *s++;
106
if (!(flags & FMT_ESCAPED) && (iscntrl(c) || !isprint(c) || c == '\\'))
107
{
108
escaped = 1;
109
*b++ = '\\';
110
switch (c)
111
{
112
case CC_bel:
113
c = 'a';
114
break;
115
case '\b':
116
c = 'b';
117
break;
118
case '\f':
119
c = 'f';
120
break;
121
case '\n':
122
c = 'n';
123
break;
124
case '\r':
125
c = 'r';
126
break;
127
case '\t':
128
c = 't';
129
break;
130
case CC_vt:
131
c = 'v';
132
break;
133
case CC_esc:
134
c = 'E';
135
break;
136
case '\\':
137
break;
138
default:
139
if (!(flags & FMT_WIDE) || !(c & 0200))
140
{
141
*b++ = '0' + ((c >> 6) & 07);
142
*b++ = '0' + ((c >> 3) & 07);
143
c = '0' + (c & 07);
144
}
145
else
146
b--;
147
break;
148
}
149
}
150
else if (c == '\\')
151
{
152
escaped = 1;
153
*b++ = c;
154
if (*s)
155
c = *s++;
156
}
157
else if (qe && strchr(qe, c))
158
{
159
if (singlequote && c == '\'')
160
{
161
spaced = 1;
162
*b++ = '\'';
163
*b++ = '\\';
164
*b++ = '\'';
165
c = '\'';
166
}
167
else
168
{
169
escaped = 1;
170
*b++ = '\\';
171
}
172
}
173
else if (c == '$' || c == '`')
174
{
175
if (c == '$' && (flags & FMT_PARAM) && (*s == '{' || *s == '('))
176
{
177
if (singlequote || shell)
178
{
179
escaped = 1;
180
*b++ = '\'';
181
*b++ = c;
182
*b++ = *s++;
183
if (shell)
184
{
185
spaced = 1;
186
*b++ = '$';
187
}
188
c = '\'';
189
}
190
else
191
{
192
escaped = 1;
193
*b++ = c;
194
c = *s++;
195
}
196
}
197
else if (doublequote)
198
*b++ = '\\';
199
else if (singlequote || (flags & FMT_SHELL))
200
spaced = 1;
201
}
202
else if (!spaced && !escaped && (isspace(c) || ((flags & FMT_SHELL) || shell) && (strchr("\";~&|()<>[]*?", c) || c == '#' && (b == f || isspace(*(b - 1))))))
203
spaced = 1;
204
*b++ = c;
205
}
206
}
207
if (qb)
208
{
209
if (!escaped)
210
buf += shell + !spaced;
211
if (qe && (escaped || spaced))
212
while (*b = *qe++)
213
b++;
214
}
215
*b = 0;
216
return buf;
217
}
218
219
/*
220
* escape the usual suspects and quote chars in qs
221
* in length n string as
222
*/
223
224
char*
225
fmtnesq(const char* as, const char* qs, size_t n)
226
{
227
return fmtquote(as, NiL, qs, n, 0);
228
}
229
230
/*
231
* escape the usual suspects and quote chars in qs
232
*/
233
234
char*
235
fmtesq(const char* as, const char* qs)
236
{
237
return fmtquote(as, NiL, qs, strlen((char*)as), 0);
238
}
239
240
/*
241
* escape the usual suspects
242
*/
243
244
char*
245
fmtesc(const char* as)
246
{
247
return fmtquote(as, NiL, NiL, strlen((char*)as), 0);
248
}
249
250