]> Dogcows Code - chaz/tar/blob - lib/quotearg.c
(xalloc_msg_memory_exhausted): change to array from char *.
[chaz/tar] / lib / quotearg.c
1 /* quotearg.c - quote arguments for output
2 Copyright (C) 1998, 1999 Free Software Foundation, Inc.
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2, or (at your option)
7 any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software Foundation,
16 Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
17
18 /* Written by Paul Eggert <eggert@twinsun.com> */
19
20 #if HAVE_CONFIG_H
21 # include <config.h>
22 #endif
23
24 #include <sys/types.h>
25 #include <quotearg.h>
26 #include <xalloc.h>
27
28 #include <ctype.h>
29 #if defined (STDC_HEADERS) || (!defined (isascii) && !defined (HAVE_ISASCII))
30 # define ISASCII(c) 1
31 #else
32 # define ISASCII(c) isascii (c)
33 #endif
34 #ifdef isgraph
35 # define ISGRAPH(c) (ISASCII (c) && isgraph (c))
36 #else
37 # define ISGRAPH(c) (ISASCII (c) && isprint (c) && !isspace (c))
38 #endif
39
40 #if HAVE_LIMITS_H
41 # include <limits.h>
42 #endif
43 #ifndef CHAR_BIT
44 # define CHAR_BIT 8
45 #endif
46 #ifndef UCHAR_MAX
47 # define UCHAR_MAX ((unsigned char) -1)
48 #endif
49
50 #if HAVE_STDLIB_H
51 # include <stdlib.h>
52 #endif
53
54 #if HAVE_STRING_H
55 # include <string.h>
56 #endif
57
58 #define INT_BITS (sizeof (int) * CHAR_BIT)
59
60 struct quoting_options
61 {
62 /* Basic quoting style. */
63 enum quoting_style style;
64
65 /* Quote the chararacters indicated by this bit vector even if the
66 quoting style would not normally require them to be quoted. */
67 int quote_these_too[((UCHAR_MAX + 1) / INT_BITS
68 + ((UCHAR_MAX + 1) % INT_BITS != 0))];
69 };
70
71 /* Names of quoting styles. */
72 char const *const quoting_style_args[] =
73 {
74 "literal",
75 "shell",
76 "shell-always",
77 "c",
78 "escape",
79 0
80 };
81
82 /* Correspondances to quoting style names. */
83 enum quoting_style const quoting_style_vals[] =
84 {
85 literal_quoting_style,
86 shell_quoting_style,
87 shell_always_quoting_style,
88 c_quoting_style,
89 escape_quoting_style
90 };
91
92 /* The default quoting options. */
93 static struct quoting_options default_quoting_options;
94
95 /* Allocate a new set of quoting options, with contents initially identical
96 to O if O is not null, or to the default if O is null.
97 It is the caller's responsibility to free the result. */
98 struct quoting_options *
99 clone_quoting_options (struct quoting_options *o)
100 {
101 struct quoting_options *p
102 = (struct quoting_options *) xmalloc (sizeof (struct quoting_options));
103 *p = *(o ? o : &default_quoting_options);
104 return p;
105 }
106
107 /* Get the value of O's quoting style. If O is null, use the default. */
108 enum quoting_style
109 get_quoting_style (struct quoting_options *o)
110 {
111 return (o ? o : &default_quoting_options)->style;
112 }
113
114 /* In O (or in the default if O is null),
115 set the value of the quoting style to S. */
116 void
117 set_quoting_style (struct quoting_options *o, enum quoting_style s)
118 {
119 (o ? o : &default_quoting_options)->style = s;
120 }
121
122 /* In O (or in the default if O is null),
123 set the value of the quoting options for character C to I.
124 Return the old value. Currently, the only values defined for I are
125 0 (the default) and 1 (which means to quote the character even if
126 it would not otherwise be quoted). */
127 int
128 set_char_quoting (struct quoting_options *o, char c, int i)
129 {
130 unsigned char uc = c;
131 int *p = (o ? o : &default_quoting_options)->quote_these_too + uc / INT_BITS;
132 int shift = uc % INT_BITS;
133 int r = (*p >> shift) & 1;
134 *p ^= ((i & 1) ^ r) << shift;
135 return r;
136 }
137
138 /* Place into buffer BUFFER (of size BUFFERSIZE) a quoted version of
139 argument ARG (of size ARGSIZE), using O to control quoting.
140 If O is null, use the default.
141 Terminate the output with a null character, and return the written
142 size of the output, not counting the terminating null.
143 If BUFFERSIZE is too small to store the output string, return the
144 value that would have been returned had BUFFERSIZE been large enough.
145 If ARGSIZE is -1, use the string length of the argument for ARGSIZE. */
146 size_t
147 quotearg_buffer (char *buffer, size_t buffersize,
148 char const *arg, size_t argsize,
149 struct quoting_options const *o)
150 {
151 unsigned char c;
152 size_t i;
153 size_t len;
154 int quote_mark;
155 struct quoting_options const *p = o ? o : &default_quoting_options;
156 enum quoting_style quoting_style = p->style;
157 #define STORE(c) \
158 do \
159 { \
160 if (len < buffersize) \
161 buffer[len] = (c); \
162 len++; \
163 } \
164 while (0)
165
166 switch (quoting_style)
167 {
168 case shell_quoting_style:
169 if (! (argsize == (size_t) -1 ? arg[0] == '\0' : argsize == 0))
170 {
171 switch (arg[0])
172 {
173 case '#': case '~':
174 break;
175
176 default:
177 len = 0;
178 for (i = 0; ; i++)
179 {
180 if (argsize == (size_t) -1 ? arg[i] == '\0' : i == argsize)
181 goto done;
182
183 c = arg[i];
184
185 switch (c)
186 {
187 case '\t': case '\n': case ' ':
188 case '!': /* special in csh */
189 case '"': case '$': case '&': case '\'':
190 case '(': case ')': case '*': case ';':
191 case '<': case '>': case '?': case '[': case '\\':
192 case '^': /* special in old /bin/sh, e.g. SunOS 4.1.4 */
193 case '`': case '|':
194 goto needs_quoting;
195 }
196
197 if (p->quote_these_too[c / INT_BITS] & (1 << (c % INT_BITS)))
198 goto needs_quoting;
199
200 STORE (c);
201 }
202
203 needs_quoting:;
204 break;
205 }
206 }
207 /* Fall through. */
208
209 case shell_always_quoting_style:
210 quote_mark = '\'';
211 break;
212
213 case c_quoting_style:
214 quote_mark = '"';
215 break;
216
217 default:
218 quote_mark = 0;
219 break;
220 }
221
222 len = 0;
223
224 if (quote_mark)
225 STORE (quote_mark);
226
227 for (i = 0; ! (argsize == (size_t) -1 ? arg[i] == '\0' : i == argsize); i++)
228 {
229 c = arg[i];
230
231 switch (quoting_style)
232 {
233 case literal_quoting_style:
234 break;
235
236 case shell_quoting_style:
237 case shell_always_quoting_style:
238 if (c == '\'')
239 {
240 STORE ('\'');
241 STORE ('\\');
242 STORE ('\'');
243 }
244 break;
245
246 case c_quoting_style:
247 case escape_quoting_style:
248 switch (c)
249 {
250 case '?': /* Do not generate trigraphs. */
251 case '\\': goto store_escape;
252 /* Not all C compilers know what \a means. */
253 case 7 : c = 'a'; goto store_escape;
254 case '\b': c = 'b'; goto store_escape;
255 case '\f': c = 'f'; goto store_escape;
256 case '\n': c = 'n'; goto store_escape;
257 case '\r': c = 'r'; goto store_escape;
258 case '\t': c = 't'; goto store_escape;
259 case '\v': c = 'v'; goto store_escape;
260
261 case '"':
262 if (quoting_style == c_quoting_style)
263 goto store_escape;
264 break;
265
266 default:
267 if (!ISGRAPH (c))
268 {
269 STORE ('\\');
270 STORE ('0' + (c >> 6));
271 STORE ('0' + ((c >> 3) & 7));
272 c = '0' + (c & 7);
273 goto store_c;
274 }
275 break;
276 }
277
278 if (! (p->quote_these_too[c / INT_BITS] & (1 << (c % INT_BITS))))
279 goto store_c;
280
281 store_escape:
282 STORE ('\\');
283 }
284
285 store_c:
286 STORE (c);
287 }
288
289 if (quote_mark)
290 STORE (quote_mark);
291
292 done:
293 if (len < buffersize)
294 buffer[len] = '\0';
295 return len;
296 }
297
298 /* Use storage slot N to return a quoted version of the string ARG.
299 OPTIONS specifies the quoting options.
300 The returned value points to static storage that can be
301 reused by the next call to this function with the same value of N.
302 N must be nonnegative. N is deliberately declared with type `int'
303 to allow for future extensions (using negative values). */
304 static char *
305 quotearg_n_options (int n, char const *arg,
306 struct quoting_options const *options)
307 {
308 static unsigned int nslots;
309 static struct slotvec
310 {
311 size_t size;
312 char *val;
313 } *slotvec;
314
315 if (nslots <= n)
316 {
317 int n1 = n + 1;
318 size_t s = n1 * sizeof (struct slotvec);
319 if (! (0 < n1 && n1 == s / sizeof (struct slotvec)))
320 abort ();
321 slotvec = (struct slotvec *) xrealloc (slotvec, s);
322 memset (slotvec + nslots, 0, (n1 - nslots) * sizeof (struct slotvec));
323 nslots = n;
324 }
325
326 {
327 size_t size = slotvec[n].size;
328 char *val = slotvec[n].val;
329 size_t qsize = quotearg_buffer (val, size, arg, (size_t) -1, options);
330
331 if (size <= qsize)
332 {
333 slotvec[n].size = size = qsize + 1;
334 slotvec[n].val = val = xrealloc (val, size);
335 quotearg_buffer (val, size, arg, (size_t) -1, options);
336 }
337
338 return val;
339 }
340 }
341
342 char *
343 quotearg_n (unsigned int n, char const *arg)
344 {
345 return quotearg_n_options (n, arg, &default_quoting_options);
346 }
347
348 char *
349 quotearg (char const *arg)
350 {
351 return quotearg_n (0, arg);
352 }
353
354 char *
355 quotearg_char (char const *arg, char ch)
356 {
357 struct quoting_options options;
358 options = default_quoting_options;
359 set_char_quoting (&options, ch, 1);
360 return quotearg_n_options (0, arg, &options);
361 }
362
363 char *
364 quotearg_colon (char const *arg)
365 {
366 return quotearg_char (arg, ':');
367 }
This page took 0.050189 seconds and 4 git commands to generate.