Changes the location of bison.simple after running bison on local
[findutils.git] / lib / quotearg.c
blob7fa5278bb18e7a7f79bfb679b41117b94242c528
1 /* quotearg.c - quote arguments for output
2 Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc.
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.
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.
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. */
18 /* Written by Paul Eggert <eggert@twinsun.com> */
20 #if HAVE_CONFIG_H
21 # include <config.h>
22 #endif
24 #include <sys/types.h>
25 #include <quotearg.h>
26 #include <xalloc.h>
28 #include <ctype.h>
30 #if ENABLE_NLS
31 # include <libintl.h>
32 # define _(text) gettext (text)
33 #else
34 # define _(text) text
35 #endif
37 #if HAVE_LIMITS_H
38 # include <limits.h>
39 #endif
40 #ifndef CHAR_BIT
41 # define CHAR_BIT 8
42 #endif
43 #ifndef UCHAR_MAX
44 # define UCHAR_MAX ((unsigned char) -1)
45 #endif
47 #if HAVE_C_BACKSLASH_A
48 # define ALERT_CHAR '\a'
49 #else
50 # define ALERT_CHAR '\7'
51 #endif
53 #if HAVE_STDLIB_H
54 # include <stdlib.h>
55 #endif
57 #if HAVE_STRING_H
58 # include <string.h>
59 #endif
61 #if HAVE_MBRTOWC && HAVE_WCHAR_H
62 # include <wchar.h>
63 # if !HAVE_MBSTATE_T_OBJECT
64 # define mbrtowc(pwc, s, n, ps) (mbrtowc) (pwc, s, n, 0)
65 # define mbstate_t int
66 # endif
67 #else
68 # define mbrtowc(pwc, s, n, ps) 1
69 # define mbsinit(ps) 1
70 # define mbstate_t int
71 #endif
73 #if HAVE_WCTYPE_H
74 # include <wctype.h>
75 #endif
76 #if !defined iswprint && !HAVE_ISWPRINT
77 # define iswprint(wc) 1
78 #endif
80 #define INT_BITS (sizeof (int) * CHAR_BIT)
82 #if defined (STDC_HEADERS) || (!defined (isascii) && !defined (HAVE_ISASCII))
83 /* Undefine to protect against the definition in wctype.h of solaris2.6. */
84 # undef ISASCII
85 # define ISASCII(c) 1
86 #else
87 # define ISASCII(c) isascii (c)
88 #endif
89 /* Undefine to protect against the definition in wctype.h of solaris2.6. */
90 #undef ISPRINT
91 #define ISPRINT(c) (ISASCII (c) && isprint (c))
93 struct quoting_options
95 /* Basic quoting style. */
96 enum quoting_style style;
98 /* Quote the characters indicated by this bit vector even if the
99 quoting style would not normally require them to be quoted. */
100 int quote_these_too[((UCHAR_MAX + 1) / INT_BITS
101 + ((UCHAR_MAX + 1) % INT_BITS != 0))];
104 /* Names of quoting styles. */
105 char const *const quoting_style_args[] =
107 "literal",
108 "shell",
109 "shell-always",
110 "c",
111 "escape",
112 "locale",
116 /* Correspondences to quoting style names. */
117 enum quoting_style const quoting_style_vals[] =
119 literal_quoting_style,
120 shell_quoting_style,
121 shell_always_quoting_style,
122 c_quoting_style,
123 escape_quoting_style,
124 locale_quoting_style
127 /* The default quoting options. */
128 static struct quoting_options default_quoting_options;
130 /* Allocate a new set of quoting options, with contents initially identical
131 to O if O is not null, or to the default if O is null.
132 It is the caller's responsibility to free the result. */
133 struct quoting_options *
134 clone_quoting_options (struct quoting_options *o)
136 struct quoting_options *p
137 = (struct quoting_options *) xmalloc (sizeof (struct quoting_options));
138 *p = *(o ? o : &default_quoting_options);
139 return p;
142 /* Get the value of O's quoting style. If O is null, use the default. */
143 enum quoting_style
144 get_quoting_style (struct quoting_options *o)
146 return (o ? o : &default_quoting_options)->style;
149 /* In O (or in the default if O is null),
150 set the value of the quoting style to S. */
151 void
152 set_quoting_style (struct quoting_options *o, enum quoting_style s)
154 (o ? o : &default_quoting_options)->style = s;
157 /* In O (or in the default if O is null),
158 set the value of the quoting options for character C to I.
159 Return the old value. Currently, the only values defined for I are
160 0 (the default) and 1 (which means to quote the character even if
161 it would not otherwise be quoted). */
163 set_char_quoting (struct quoting_options *o, char c, int i)
165 unsigned char uc = c;
166 int *p = (o ? o : &default_quoting_options)->quote_these_too + uc / INT_BITS;
167 int shift = uc % INT_BITS;
168 int r = (*p >> shift) & 1;
169 *p ^= ((i & 1) ^ r) << shift;
170 return r;
173 /* Place into buffer BUFFER (of size BUFFERSIZE) a quoted version of
174 argument ARG (of size ARGSIZE), using QUOTING_STYLE and the
175 non-quoting-style part of O to control quoting.
176 Terminate the output with a null character, and return the written
177 size of the output, not counting the terminating null.
178 If BUFFERSIZE is too small to store the output string, return the
179 value that would have been returned had BUFFERSIZE been large enough.
180 If ARGSIZE is -1, use the string length of the argument for ARGSIZE.
182 This function acts like quotearg_buffer (BUFFER, BUFFERSIZE, ARG,
183 ARGSIZE, O), except it uses QUOTING_STYLE instead of the quoting
184 style specified by O, and O may not be null. */
186 static size_t
187 quotearg_buffer_restyled (char *buffer, size_t buffersize,
188 char const *arg, size_t argsize,
189 enum quoting_style quoting_style,
190 struct quoting_options const *o)
192 size_t i;
193 size_t len = 0;
194 char const *quote_string = 0;
195 size_t quote_string_len = 0;
196 int backslash_escapes = 0;
198 #define STORE(c) \
199 do \
201 if (len < buffersize) \
202 buffer[len] = (c); \
203 len++; \
205 while (0)
207 switch (quoting_style)
209 case c_quoting_style:
210 STORE ('"');
211 backslash_escapes = 1;
212 quote_string = "\"";
213 quote_string_len = 1;
214 break;
216 case escape_quoting_style:
217 backslash_escapes = 1;
218 break;
220 case locale_quoting_style:
221 for (quote_string = _("`"); *quote_string; quote_string++)
222 STORE (*quote_string);
223 backslash_escapes = 1;
224 quote_string = _("'");
225 quote_string_len = strlen (quote_string);
226 break;
228 case shell_always_quoting_style:
229 STORE ('\'');
230 quote_string = "'";
231 quote_string_len = 1;
232 break;
234 default:
235 break;
238 for (i = 0; ! (argsize == (size_t) -1 ? arg[i] == '\0' : i == argsize); i++)
240 unsigned char c;
241 unsigned char esc;
243 if (backslash_escapes
244 && quote_string_len
245 && i + quote_string_len <= argsize
246 && memcmp (arg + i, quote_string, quote_string_len) == 0)
247 STORE ('\\');
249 c = arg[i];
250 switch (c)
252 case '?':
253 switch (quoting_style)
255 case shell_quoting_style:
256 goto use_shell_always_quoting_style;
258 case c_quoting_style:
259 if (i + 2 < argsize && arg[i + 1] == '?')
260 switch (arg[i + 2])
262 case '!': case '\'':
263 case '(': case ')': case '-': case '/':
264 case '<': case '=': case '>':
265 /* Escape the second '?' in what would otherwise be
266 a trigraph. */
267 i += 2;
268 c = arg[i + 2];
269 STORE ('?');
270 STORE ('\\');
271 STORE ('?');
272 break;
274 break;
276 default:
277 break;
279 break;
281 case ALERT_CHAR: esc = 'a'; goto c_escape;
282 case '\b': esc = 'b'; goto c_escape;
283 case '\f': esc = 'f'; goto c_escape;
284 case '\n': esc = 'n'; goto c_and_shell_escape;
285 case '\r': esc = 'r'; goto c_and_shell_escape;
286 case '\t': esc = 't'; goto c_and_shell_escape;
287 case '\v': esc = 'v'; goto c_escape;
288 case '\\': esc = c; goto c_and_shell_escape;
290 c_and_shell_escape:
291 if (quoting_style == shell_quoting_style)
292 goto use_shell_always_quoting_style;
293 c_escape:
294 if (backslash_escapes)
296 c = esc;
297 goto store_escape;
299 break;
301 case '#': case '~':
302 if (i != 0)
303 break;
304 /* Fall through. */
305 case ' ':
306 case '!': /* special in bash */
307 case '"': case '$': case '&':
308 case '(': case ')': case '*': case ';':
309 case '<': case '>': case '[':
310 case '^': /* special in old /bin/sh, e.g. SunOS 4.1.4 */
311 case '`': case '|':
312 /* A shell special character. In theory, '$' and '`' could
313 be the first bytes of multibyte characters, which means
314 we should check them with mbrtowc, but in practice this
315 doesn't happen so it's not worth worrying about. */
316 if (quoting_style == shell_quoting_style)
317 goto use_shell_always_quoting_style;
318 break;
320 case '\'':
321 switch (quoting_style)
323 case shell_quoting_style:
324 goto use_shell_always_quoting_style;
326 case shell_always_quoting_style:
327 STORE ('\'');
328 STORE ('\\');
329 STORE ('\'');
330 break;
332 default:
333 break;
335 break;
337 case '%': case '+': case ',': case '-': case '.': case '/':
338 case '0': case '1': case '2': case '3': case '4': case '5':
339 case '6': case '7': case '8': case '9': case ':': case '=':
340 case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
341 case 'G': case 'H': case 'I': case 'J': case 'K': case 'L':
342 case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R':
343 case 'S': case 'T': case 'U': case 'V': case 'W': case 'X':
344 case 'Y': case 'Z': case ']': case '_': case 'a': case 'b':
345 case 'c': case 'd': case 'e': case 'f': case 'g': case 'h':
346 case 'i': case 'j': case 'k': case 'l': case 'm': case 'n':
347 case 'o': case 'p': case 'q': case 'r': case 's': case 't':
348 case 'u': case 'v': case 'w': case 'x': case 'y': case 'z':
349 case '{': case '}':
350 /* These characters don't cause problems, no matter what the
351 quoting style is. They cannot start multibyte sequences. */
352 break;
354 default:
355 /* If we have a multibyte sequence, copy it until we reach
356 its end, find an error, or come back to the initial shift
357 state. For C-like styles, if the sequence has
358 unprintable characters, escape the whole sequence, since
359 we can't easily escape single characters within it. */
361 /* Length of multibyte sequence found so far. */
362 size_t m = 0;
364 int printable = 1;
365 mbstate_t mbstate;
366 memset (&mbstate, 0, sizeof mbstate);
368 if (argsize == (size_t) -1)
369 argsize = strlen (arg);
373 wchar_t w;
374 size_t bytes = mbrtowc (&w, &arg[i + m],
375 argsize - (i + m), &mbstate);
376 if (bytes == 0)
377 break;
378 else if (bytes == (size_t) -1)
380 printable = 0;
381 break;
383 else if (bytes == (size_t) -2)
385 printable = 0;
386 while (i + m < argsize && arg[i + m])
387 m++;
388 break;
390 else
392 if (! iswprint (w))
393 printable = 0;
394 m += bytes;
397 while (! mbsinit (&mbstate));
399 if (m <= 1)
401 /* Escape a unibyte character like a multibyte
402 sequence if using backslash escapes, and if the
403 character is not printable. */
404 m = backslash_escapes && ! ISPRINT (c);
405 printable = 0;
408 if (m)
410 /* Output a multibyte sequence, or an escaped
411 unprintable unibyte character. */
412 size_t imax = i + m - 1;
414 for (;;)
416 if (backslash_escapes && ! printable)
418 STORE ('\\');
419 STORE ('0' + (c >> 6));
420 STORE ('0' + ((c >> 3) & 7));
421 c = '0' + (c & 7);
423 if (i == imax)
424 break;
425 STORE (c);
426 c = arg[++i];
429 goto store_c;
434 if (! (backslash_escapes
435 && o->quote_these_too[c / INT_BITS] & (1 << (c % INT_BITS))))
436 goto store_c;
438 store_escape:
439 STORE ('\\');
441 store_c:
442 STORE (c);
445 if (quote_string)
446 for (; *quote_string; quote_string++)
447 STORE (*quote_string);
449 if (len < buffersize)
450 buffer[len] = '\0';
451 return len;
453 use_shell_always_quoting_style:
454 return quotearg_buffer_restyled (buffer, buffersize, arg, argsize,
455 shell_always_quoting_style, o);
458 /* Place into buffer BUFFER (of size BUFFERSIZE) a quoted version of
459 argument ARG (of size ARGSIZE), using O to control quoting.
460 If O is null, use the default.
461 Terminate the output with a null character, and return the written
462 size of the output, not counting the terminating null.
463 If BUFFERSIZE is too small to store the output string, return the
464 value that would have been returned had BUFFERSIZE been large enough.
465 If ARGSIZE is -1, use the string length of the argument for ARGSIZE. */
466 size_t
467 quotearg_buffer (char *buffer, size_t buffersize,
468 char const *arg, size_t argsize,
469 struct quoting_options const *o)
471 struct quoting_options const *p = o ? o : &default_quoting_options;
472 return quotearg_buffer_restyled (buffer, buffersize, arg, argsize,
473 p->style, p);
476 /* Use storage slot N to return a quoted version of the string ARG.
477 OPTIONS specifies the quoting options.
478 The returned value points to static storage that can be
479 reused by the next call to this function with the same value of N.
480 N must be nonnegative. N is deliberately declared with type `int'
481 to allow for future extensions (using negative values). */
482 static char *
483 quotearg_n_options (int n, char const *arg,
484 struct quoting_options const *options)
486 static unsigned int nslots;
487 static struct slotvec
489 size_t size;
490 char *val;
491 } *slotvec;
493 if (nslots <= n)
495 int n1 = n + 1;
496 size_t s = n1 * sizeof (struct slotvec);
497 if (! (0 < n1 && n1 == s / sizeof (struct slotvec)))
498 abort ();
499 slotvec = (struct slotvec *) xrealloc (slotvec, s);
500 memset (slotvec + nslots, 0, (n1 - nslots) * sizeof (struct slotvec));
501 nslots = n;
505 size_t size = slotvec[n].size;
506 char *val = slotvec[n].val;
507 size_t qsize = quotearg_buffer (val, size, arg, (size_t) -1, options);
509 if (size <= qsize)
511 slotvec[n].size = size = qsize + 1;
512 slotvec[n].val = val = xrealloc (val, size);
513 quotearg_buffer (val, size, arg, (size_t) -1, options);
516 return val;
520 char *
521 quotearg_n (unsigned int n, char const *arg)
523 return quotearg_n_options (n, arg, &default_quoting_options);
526 char *
527 quotearg (char const *arg)
529 return quotearg_n (0, arg);
532 char *
533 quotearg_n_style (unsigned int n, enum quoting_style s, char const *arg)
535 struct quoting_options o;
536 o.style = s;
537 memset (o.quote_these_too, 0, sizeof o.quote_these_too);
538 return quotearg_n_options (n, arg, &o);
541 char *
542 quotearg_style (enum quoting_style s, char const *arg)
544 return quotearg_n_style (0, s, arg);
547 char *
548 quotearg_char (char const *arg, char ch)
550 struct quoting_options options;
551 options = default_quoting_options;
552 set_char_quoting (&options, ch, 1);
553 return quotearg_n_options (0, arg, &options);
556 char *
557 quotearg_colon (char const *arg)
559 return quotearg_char (arg, ':');