import less(1)
[unleashed/tickless.git] / usr / src / lib / libast / common / string / fmtesc.c
blobde3acdba221857a16cd1529eed1c3cf748bd1351
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
24 * Glenn Fowler
25 * AT&T Research
27 * return string with expanded escape chars
30 #include <ast.h>
31 #include <ccode.h>
32 #include <ctype.h>
35 * quote string as of length n with qb...qe
36 * (flags&FMT_ALWAYS) always quotes, otherwise quote output only if necessary
37 * qe and the usual suspects are \... escaped
38 * (flags&FMT_WIDE) doesn't escape 8 bit chars
39 * (flags&FMT_ESCAPED) doesn't \... escape the usual suspects
40 * (flags&FMT_SHELL) escape $`"#;~&|()<>[]*?
43 char*
44 fmtquote(const char* as, const char* qb, const char* qe, size_t n, int flags)
46 register unsigned char* s = (unsigned char*)as;
47 register unsigned char* e = s + n;
48 register char* b;
49 register int c;
50 register int escaped;
51 register int spaced;
52 register int doublequote;
53 register int singlequote;
54 int shell;
55 char* f;
56 char* buf;
58 c = 4 * (n + 1);
59 if (qb)
60 c += strlen((char*)qb);
61 if (qe)
62 c += strlen((char*)qe);
63 b = buf = fmtbuf(c);
64 shell = 0;
65 doublequote = 0;
66 singlequote = 0;
67 if (qb)
69 if (qb[0] == '$' && qb[1] == '\'' && qb[2] == 0)
70 shell = 1;
71 else if ((flags & FMT_SHELL) && qb[1] == 0)
73 if (qb[0] == '"')
74 doublequote = 1;
75 else if (qb[0] == '\'')
76 singlequote = 1;
78 while (*b = *qb++)
79 b++;
81 else if (flags & FMT_SHELL)
82 doublequote = 1;
83 f = b;
84 escaped = spaced = !!(flags & FMT_ALWAYS);
85 while (s < e)
87 if ((c = mbsize(s)) > 1)
89 while (c-- && s < e)
90 *b++ = *s++;
92 else
94 c = *s++;
95 if (!(flags & FMT_ESCAPED) && (iscntrl(c) || !isprint(c) || c == '\\'))
97 escaped = 1;
98 *b++ = '\\';
99 switch (c)
101 case CC_bel:
102 c = 'a';
103 break;
104 case '\b':
105 c = 'b';
106 break;
107 case '\f':
108 c = 'f';
109 break;
110 case '\n':
111 c = 'n';
112 break;
113 case '\r':
114 c = 'r';
115 break;
116 case '\t':
117 c = 't';
118 break;
119 case CC_vt:
120 c = 'v';
121 break;
122 case CC_esc:
123 c = 'E';
124 break;
125 case '\\':
126 break;
127 default:
128 if (!(flags & FMT_WIDE) || !(c & 0200))
130 *b++ = '0' + ((c >> 6) & 07);
131 *b++ = '0' + ((c >> 3) & 07);
132 c = '0' + (c & 07);
134 else
135 b--;
136 break;
139 else if (c == '\\')
141 escaped = 1;
142 *b++ = c;
143 if (*s)
144 c = *s++;
146 else if (qe && strchr(qe, c))
148 if (singlequote && c == '\'')
150 spaced = 1;
151 *b++ = '\'';
152 *b++ = '\\';
153 *b++ = '\'';
154 c = '\'';
156 else
158 escaped = 1;
159 *b++ = '\\';
162 else if (c == '$' || c == '`')
164 if (c == '$' && (flags & FMT_PARAM) && (*s == '{' || *s == '('))
166 if (singlequote || shell)
168 escaped = 1;
169 *b++ = '\'';
170 *b++ = c;
171 *b++ = *s++;
172 if (shell)
174 spaced = 1;
175 *b++ = '$';
177 c = '\'';
179 else
181 escaped = 1;
182 *b++ = c;
183 c = *s++;
186 else if (doublequote)
187 *b++ = '\\';
188 else if (singlequote || (flags & FMT_SHELL))
189 spaced = 1;
191 else if (!spaced && !escaped && (isspace(c) || ((flags & FMT_SHELL) || shell) && (strchr("\";~&|()<>[]*?", c) || c == '#' && (b == f || isspace(*(b - 1))))))
192 spaced = 1;
193 *b++ = c;
196 if (qb)
198 if (!escaped)
199 buf += shell + !spaced;
200 if (qe && (escaped || spaced))
201 while (*b = *qe++)
202 b++;
204 *b = 0;
205 return buf;
209 * escape the usual suspects and quote chars in qs
210 * in length n string as
213 char*
214 fmtnesq(const char* as, const char* qs, size_t n)
216 return fmtquote(as, NiL, qs, n, 0);
220 * escape the usual suspects and quote chars in qs
223 char*
224 fmtesq(const char* as, const char* qs)
226 return fmtquote(as, NiL, qs, strlen((char*)as), 0);
230 * escape the usual suspects
233 char*
234 fmtesc(const char* as)
236 return fmtquote(as, NiL, NiL, strlen((char*)as), 0);