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)
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> */
24 #include <sys/types.h>
32 # define _(text) gettext (text)
44 # define UCHAR_MAX ((unsigned char) -1)
47 #if HAVE_C_BACKSLASH_A
48 # define ALERT_CHAR '\a'
50 # define ALERT_CHAR '\7'
61 #if HAVE_MBRTOWC && HAVE_WCHAR_H
63 # if !HAVE_MBSTATE_T_OBJECT
64 # define mbrtowc(pwc, s, n, ps) (mbrtowc) (pwc, s, n, 0)
67 # define mbrtowc(pwc, s, n, ps) ((*(pwc) = *(s)) != 0)
68 # define mbsinit(ps) 1
69 # define iswprint(wc) ISPRINT ((unsigned char) (wc))
76 # if !defined iswprint && !HAVE_ISWPRINT
77 # define iswprint(wc) 1
81 #define INT_BITS (sizeof (int) * CHAR_BIT)
83 #if defined (STDC_HEADERS) || (!defined (isascii) && !defined (HAVE_ISASCII))
84 /* Undefine to protect against the definition in wctype.h of solaris2.6. */
88 # define ISASCII(c) isascii (c)
90 /* Undefine to protect against the definition in wctype.h of solaris2.6. */
92 #define ISPRINT(c) (ISASCII (c) && isprint (c))
94 struct quoting_options
96 /* Basic quoting style. */
97 enum quoting_style style;
99 /* Quote the characters indicated by this bit vector even if the
100 quoting style would not normally require them to be quoted. */
101 int quote_these_too[((UCHAR_MAX + 1) / INT_BITS
102 + ((UCHAR_MAX + 1) % INT_BITS != 0))];
105 /* Names of quoting styles. */
106 char const *const quoting_style_args[] =
117 /* Correspondences to quoting style names. */
118 enum quoting_style const quoting_style_vals[] =
120 literal_quoting_style,
122 shell_always_quoting_style,
124 escape_quoting_style,
128 /* The default quoting options. */
129 static struct quoting_options default_quoting_options;
131 /* Allocate a new set of quoting options, with contents initially identical
132 to O if O is not null, or to the default if O is null.
133 It is the caller's responsibility to free the result. */
134 struct quoting_options *
135 clone_quoting_options (struct quoting_options *o)
137 struct quoting_options *p
138 = (struct quoting_options *) xmalloc (sizeof (struct quoting_options));
139 *p = *(o ? o : &default_quoting_options);
143 /* Get the value of O's quoting style. If O is null, use the default. */
145 get_quoting_style (struct quoting_options *o)
147 return (o ? o : &default_quoting_options)->style;
150 /* In O (or in the default if O is null),
151 set the value of the quoting style to S. */
153 set_quoting_style (struct quoting_options *o, enum quoting_style s)
155 (o ? o : &default_quoting_options)->style = s;
158 /* In O (or in the default if O is null),
159 set the value of the quoting options for character C to I.
160 Return the old value. Currently, the only values defined for I are
161 0 (the default) and 1 (which means to quote the character even if
162 it would not otherwise be quoted). */
164 set_char_quoting (struct quoting_options *o, char c, int i)
166 unsigned char uc = c;
167 int *p = (o ? o : &default_quoting_options)->quote_these_too + uc / INT_BITS;
168 int shift = uc % INT_BITS;
169 int r = (*p >> shift) & 1;
170 *p ^= ((i & 1) ^ r) << shift;
174 /* Place into buffer BUFFER (of size BUFFERSIZE) a quoted version of
175 argument ARG (of size ARGSIZE), using QUOTING_STYLE and the
176 non-quoting-style part of O to control quoting.
177 Terminate the output with a null character, and return the written
178 size of the output, not counting the terminating null.
179 If BUFFERSIZE is too small to store the output string, return the
180 value that would have been returned had BUFFERSIZE been large enough.
181 If ARGSIZE is -1, use the string length of the argument for ARGSIZE.
183 This function acts like quotearg_buffer (BUFFER, BUFFERSIZE, ARG,
184 ARGSIZE, O), except it uses QUOTING_STYLE instead of the quoting
185 style specified by O, and O may not be null. */
188 quotearg_buffer_restyled (char *buffer, size_t buffersize,
189 char const *arg, size_t argsize,
190 enum quoting_style quoting_style,
191 struct quoting_options const *o)
195 char const *quote_string = 0;
196 size_t quote_string_len = 0;
197 int backslash_escapes = 0;
202 if (len < buffersize) \
208 switch (quoting_style)
210 case c_quoting_style:
212 backslash_escapes = 1;
214 quote_string_len = 1;
217 case escape_quoting_style:
218 backslash_escapes = 1;
221 case locale_quoting_style:
222 for (quote_string = _("`"); *quote_string; quote_string++)
223 STORE (*quote_string);
224 backslash_escapes = 1;
225 quote_string = _("'");
226 quote_string_len = strlen (quote_string);
229 case shell_always_quoting_style:
232 quote_string_len = 1;
239 for (i = 0; ! (argsize == (size_t) -1 ? arg[i] == '\0' : i == argsize); i++)
244 if (backslash_escapes
246 && i + quote_string_len <= argsize
247 && memcmp (arg + i, quote_string, quote_string_len) == 0)
254 switch (quoting_style)
256 case shell_quoting_style:
257 goto use_shell_always_quoting_style;
259 case c_quoting_style:
260 if (i + 2 < argsize && arg[i + 1] == '?')
264 case '(': case ')': case '-': case '/':
265 case '<': case '=': case '>':
266 /* Escape the second '?' in what would otherwise be
282 case ALERT_CHAR: esc = 'a'; goto c_escape;
283 case '\b': esc = 'b'; goto c_escape;
284 case '\f': esc = 'f'; goto c_escape;
285 case '\n': esc = 'n'; goto c_and_shell_escape;
286 case '\r': esc = 'r'; goto c_and_shell_escape;
287 case '\t': esc = 't'; goto c_and_shell_escape;
288 case '\v': esc = 'v'; goto c_escape;
289 case '\\': esc = c; goto c_and_shell_escape;
292 if (quoting_style == shell_quoting_style)
293 goto use_shell_always_quoting_style;
295 if (backslash_escapes)
307 case '!': /* special in bash */
308 case '"': case '$': case '&':
309 case '(': case ')': case '*': case ';':
310 case '<': case '>': case '[':
311 case '^': /* special in old /bin/sh, e.g. SunOS 4.1.4 */
313 /* A shell special character. In theory, '$' and '`' could
314 be the first bytes of multibyte characters, which means
315 we should check them with mbrtowc, but in practice this
316 doesn't happen so it's not worth worrying about. */
317 if (quoting_style == shell_quoting_style)
318 goto use_shell_always_quoting_style;
322 switch (quoting_style)
324 case shell_quoting_style:
325 goto use_shell_always_quoting_style;
327 case shell_always_quoting_style:
338 case '%': case '+': case ',': case '-': case '.': case '/':
339 case '0': case '1': case '2': case '3': case '4': case '5':
340 case '6': case '7': case '8': case '9': case ':': case '=':
341 case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
342 case 'G': case 'H': case 'I': case 'J': case 'K': case 'L':
343 case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R':
344 case 'S': case 'T': case 'U': case 'V': case 'W': case 'X':
345 case 'Y': case 'Z': case ']': case '_': case 'a': case 'b':
346 case 'c': case 'd': case 'e': case 'f': case 'g': case 'h':
347 case 'i': case 'j': case 'k': case 'l': case 'm': case 'n':
348 case 'o': case 'p': case 'q': case 'r': case 's': case 't':
349 case 'u': case 'v': case 'w': case 'x': case 'y': case 'z':
351 /* These characters don't cause problems, no matter what the
352 quoting style is. They cannot start multibyte sequences. */
356 /* If we have a multibyte sequence, copy it until we reach
357 its end, find an error, or come back to the initial shift
358 state. For C-like styles, if the sequence has
359 unprintable characters, escape the whole sequence, since
360 we can't easily escape single characters within it. */
362 /* Length of multibyte sequence found so far. */
367 memset (&mbstate, 0, sizeof mbstate);
369 if (argsize == (size_t) -1)
370 argsize = strlen (arg);
375 size_t bytes = mbrtowc (&w, &arg[i + m],
376 argsize - (i + m), &mbstate);
379 else if (bytes == (size_t) -1)
384 else if (bytes == (size_t) -2)
387 while (i + m < argsize && arg[i + m])
398 while (! mbsinit (&mbstate));
402 /* Escape a unibyte character like a multibyte
403 sequence if using backslash escapes, and if the
404 character is not printable. */
405 m = backslash_escapes && ! ISPRINT (c);
411 /* Output a multibyte sequence, or an escaped
412 unprintable unibyte character. */
413 size_t imax = i + m - 1;
417 if (backslash_escapes && ! printable)
420 STORE ('0' + (c >> 6));
421 STORE ('0' + ((c >> 3) & 7));
435 if (! (backslash_escapes
436 && o->quote_these_too[c / INT_BITS] & (1 << (c % INT_BITS))))
447 for (; *quote_string; quote_string++)
448 STORE (*quote_string);
450 if (len < buffersize)
454 use_shell_always_quoting_style:
455 return quotearg_buffer_restyled (buffer, buffersize, arg, argsize,
456 shell_always_quoting_style, o);
459 /* Place into buffer BUFFER (of size BUFFERSIZE) a quoted version of
460 argument ARG (of size ARGSIZE), using O to control quoting.
461 If O is null, use the default.
462 Terminate the output with a null character, and return the written
463 size of the output, not counting the terminating null.
464 If BUFFERSIZE is too small to store the output string, return the
465 value that would have been returned had BUFFERSIZE been large enough.
466 If ARGSIZE is -1, use the string length of the argument for ARGSIZE. */
468 quotearg_buffer (char *buffer, size_t buffersize,
469 char const *arg, size_t argsize,
470 struct quoting_options const *o)
472 struct quoting_options const *p = o ? o : &default_quoting_options;
473 return quotearg_buffer_restyled (buffer, buffersize, arg, argsize,
477 /* Use storage slot N to return a quoted version of the string ARG.
478 OPTIONS specifies the quoting options.
479 The returned value points to static storage that can be
480 reused by the next call to this function with the same value of N.
481 N must be nonnegative. N is deliberately declared with type `int'
482 to allow for future extensions (using negative values). */
484 quotearg_n_options (int n, char const *arg,
485 struct quoting_options const *options)
487 static unsigned int nslots;
488 static struct slotvec
497 size_t s = n1 * sizeof (struct slotvec);
498 if (! (0 < n1 && n1 == s / sizeof (struct slotvec)))
500 slotvec = (struct slotvec *) xrealloc (slotvec, s);
501 memset (slotvec + nslots, 0, (n1 - nslots) * sizeof (struct slotvec));
506 size_t size = slotvec[n].size;
507 char *val = slotvec[n].val;
508 size_t qsize = quotearg_buffer (val, size, arg, (size_t) -1, options);
512 slotvec[n].size = size = qsize + 1;
513 slotvec[n].val = val = xrealloc (val, size);
514 quotearg_buffer (val, size, arg, (size_t) -1, options);
522 quotearg_n (unsigned int n, char const *arg)
524 return quotearg_n_options (n, arg, &default_quoting_options);
528 quotearg (char const *arg)
530 return quotearg_n (0, arg);
534 quotearg_n_style (unsigned int n, enum quoting_style s, char const *arg)
536 struct quoting_options o;
538 memset (o.quote_these_too, 0, sizeof o.quote_these_too);
539 return quotearg_n_options (n, arg, &o);
543 quotearg_style (enum quoting_style s, char const *arg)
545 return quotearg_n_style (0, s, arg);
549 quotearg_char (char const *arg, char ch)
551 struct quoting_options options;
552 options = default_quoting_options;
553 set_char_quoting (&options, ch, 1);
554 return quotearg_n_options (0, arg, &options);
558 quotearg_colon (char const *arg)
560 return quotearg_char (arg, ':');