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>
29 #if defined (STDC_HEADERS) || (!defined (isascii) && !defined (HAVE_ISASCII))
32 # define ISASCII(c) isascii (c)
34 #define ISPRINT(c) (ISASCII (c) && isprint (c))
38 # define _(text) gettext (text)
50 # define UCHAR_MAX ((unsigned char) -1)
65 #if HAVE_MBRTOWC && HAVE_WCHAR_H
68 # define iswprint(wc) 1
69 # define mbrtowc(pwc, s, n, ps) 1
70 # define mbsinit(ps) 1
71 # define mbstate_t int
74 #define INT_BITS (sizeof (int) * CHAR_BIT)
76 struct quoting_options
78 /* Basic quoting style. */
79 enum quoting_style style;
81 /* Quote the characters indicated by this bit vector even if the
82 quoting style would not normally require them to be quoted. */
83 int quote_these_too[((UCHAR_MAX + 1) / INT_BITS
84 + ((UCHAR_MAX + 1) % INT_BITS != 0))];
87 /* Names of quoting styles. */
88 char const *const quoting_style_args[] =
99 /* Correspondences to quoting style names. */
100 enum quoting_style const quoting_style_vals[] =
102 literal_quoting_style,
104 shell_always_quoting_style,
106 escape_quoting_style,
110 /* The default quoting options. */
111 static struct quoting_options default_quoting_options;
113 /* Allocate a new set of quoting options, with contents initially identical
114 to O if O is not null, or to the default if O is null.
115 It is the caller's responsibility to free the result. */
116 struct quoting_options *
117 clone_quoting_options (struct quoting_options *o)
119 struct quoting_options *p
120 = (struct quoting_options *) xmalloc (sizeof (struct quoting_options));
121 *p = *(o ? o : &default_quoting_options);
125 /* Get the value of O's quoting style. If O is null, use the default. */
127 get_quoting_style (struct quoting_options *o)
129 return (o ? o : &default_quoting_options)->style;
132 /* In O (or in the default if O is null),
133 set the value of the quoting style to S. */
135 set_quoting_style (struct quoting_options *o, enum quoting_style s)
137 (o ? o : &default_quoting_options)->style = s;
140 /* In O (or in the default if O is null),
141 set the value of the quoting options for character C to I.
142 Return the old value. Currently, the only values defined for I are
143 0 (the default) and 1 (which means to quote the character even if
144 it would not otherwise be quoted). */
146 set_char_quoting (struct quoting_options *o, char c, int i)
148 unsigned char uc = c;
149 int *p = (o ? o : &default_quoting_options)->quote_these_too + uc / INT_BITS;
150 int shift = uc % INT_BITS;
151 int r = (*p >> shift) & 1;
152 *p ^= ((i & 1) ^ r) << shift;
156 /* Place into buffer BUFFER (of size BUFFERSIZE) a quoted version of
157 argument ARG (of size ARGSIZE), using QUOTING_STYLE and the
158 non-quoting-style part of O to control quoting.
159 Terminate the output with a null character, and return the written
160 size of the output, not counting the terminating null.
161 If BUFFERSIZE is too small to store the output string, return the
162 value that would have been returned had BUFFERSIZE been large enough.
163 If ARGSIZE is -1, use the string length of the argument for ARGSIZE.
165 This function acts like quotearg_buffer (BUFFER, BUFFERSIZE, ARG,
166 ARGSIZE, O), except it uses QUOTING_STYLE instead of the quoting
167 style specified by O, and O may not be null. */
170 quotearg_buffer_restyled (char *buffer, size_t buffersize,
171 char const *arg, size_t argsize,
172 enum quoting_style quoting_style,
173 struct quoting_options const *o)
177 char const *quote_string = 0;
178 size_t quote_string_len = 0;
179 int backslash_escapes = 0;
184 if (len < buffersize) \
190 switch (quoting_style)
192 case c_quoting_style:
194 backslash_escapes = 1;
196 quote_string_len = 1;
199 case escape_quoting_style:
200 backslash_escapes = 1;
203 case locale_quoting_style:
204 for (quote_string = _("`"); *quote_string; quote_string++)
205 STORE (*quote_string);
206 backslash_escapes = 1;
207 quote_string = _("'");
208 quote_string_len = strlen (quote_string);
211 case shell_always_quoting_style:
214 quote_string_len = 1;
221 for (i = 0; ! (argsize == (size_t) -1 ? arg[i] == '\0' : i == argsize); i++)
226 if (backslash_escapes
228 && i + quote_string_len <= argsize
229 && memcmp (arg + i, quote_string, quote_string_len) == 0)
236 switch (quoting_style)
238 case shell_quoting_style:
239 goto use_shell_always_quoting_style;
241 case c_quoting_style:
242 if (i + 2 < argsize && arg[i + 1] == '?')
246 case '(': case ')': case '-': case '/':
247 case '<': case '=': case '>':
248 /* Escape the second '?' in what would otherwise be
264 #if HAVE_C_BACKSLASH_A
265 case '\a': esc = 'a'; goto c_escape;
267 case '\b': esc = 'b'; goto c_escape;
268 case '\f': esc = 'f'; goto c_escape;
269 case '\n': esc = 'n'; goto c_and_shell_escape;
270 case '\r': esc = 'r'; goto c_and_shell_escape;
271 case '\t': esc = 't'; goto c_and_shell_escape;
272 case '\v': esc = 'v'; goto c_escape;
273 case '\\': esc = c; goto c_and_shell_escape;
276 if (quoting_style == shell_quoting_style)
277 goto use_shell_always_quoting_style;
279 if (backslash_escapes)
291 case '!': /* special in bash */
292 case '"': case '$': case '&':
293 case '(': case ')': case '*': case ';':
294 case '<': case '>': case '[':
295 case '^': /* special in old /bin/sh, e.g. SunOS 4.1.4 */
297 /* A shell special character. In theory, '$' and '`' could
298 be the first bytes of multibyte characters, which means
299 we should check them with mbrtowc, but in practice this
300 doesn't happen so it's not worth worrying about. */
301 if (quoting_style == shell_quoting_style)
302 goto use_shell_always_quoting_style;
306 switch (quoting_style)
308 case shell_quoting_style:
309 goto use_shell_always_quoting_style;
311 case shell_always_quoting_style:
322 case '%': case '+': case ',': case '-': case '.': case '/':
323 case '0': case '1': case '2': case '3': case '4': case '5':
324 case '6': case '7': case '8': case '9': case ':': case '=':
325 case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
326 case 'G': case 'H': case 'I': case 'J': case 'K': case 'L':
327 case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R':
328 case 'S': case 'T': case 'U': case 'V': case 'W': case 'X':
329 case 'Y': case 'Z': case ']': case '_': case 'a': case 'b':
330 case 'c': case 'd': case 'e': case 'f': case 'g': case 'h':
331 case 'i': case 'j': case 'k': case 'l': case 'm': case 'n':
332 case 'o': case 'p': case 'q': case 'r': case 's': case 't':
333 case 'u': case 'v': case 'w': case 'x': case 'y': case 'z':
335 /* These characters don't cause problems, no matter what the
336 quoting style is. They cannot start multibyte sequences. */
340 /* If we have a multibyte sequence, copy it until we reach
341 its end, find an error, or come back to the initial shift
342 state. For C-like styles, if the sequence has
343 unprintable characters, escape the whole sequence, since
344 we can't easily escape single characters within it. */
346 /* Length of multibyte sequence found so far. */
351 memset (&mbstate, 0, sizeof mbstate);
353 if (argsize == (size_t) -1)
354 argsize = strlen (arg);
359 size_t bytes = mbrtowc (&w, &arg[i + m],
360 argsize - (i + m), &mbstate);
363 else if (bytes == (size_t) -1)
368 else if (bytes == (size_t) -2)
371 while (i + m < argsize && arg[i + m])
382 while (! mbsinit (&mbstate));
386 /* Escape a unibyte character like a multibyte
387 sequence if using backslash escapes, and if the
388 character is not printable. */
389 m = backslash_escapes && ! ISPRINT (c);
395 /* Output a multibyte sequence, or an escaped
396 unprintable unibyte character. */
397 size_t imax = i + m - 1;
401 if (backslash_escapes && ! printable)
404 STORE ('0' + (c >> 6));
405 STORE ('0' + ((c >> 3) & 7));
419 if (! (backslash_escapes
420 && o->quote_these_too[c / INT_BITS] & (1 << (c % INT_BITS))))
431 for (; *quote_string; quote_string++)
432 STORE (*quote_string);
434 if (len < buffersize)
438 use_shell_always_quoting_style:
439 return quotearg_buffer_restyled (buffer, buffersize, arg, argsize,
440 shell_always_quoting_style, o);
443 /* Place into buffer BUFFER (of size BUFFERSIZE) a quoted version of
444 argument ARG (of size ARGSIZE), using O to control quoting.
445 If O is null, use the default.
446 Terminate the output with a null character, and return the written
447 size of the output, not counting the terminating null.
448 If BUFFERSIZE is too small to store the output string, return the
449 value that would have been returned had BUFFERSIZE been large enough.
450 If ARGSIZE is -1, use the string length of the argument for ARGSIZE. */
452 quotearg_buffer (char *buffer, size_t buffersize,
453 char const *arg, size_t argsize,
454 struct quoting_options const *o)
456 struct quoting_options const *p = o ? o : &default_quoting_options;
457 return quotearg_buffer_restyled (buffer, buffersize, arg, argsize,
461 /* Use storage slot N to return a quoted version of the string ARG.
462 OPTIONS specifies the quoting options.
463 The returned value points to static storage that can be
464 reused by the next call to this function with the same value of N.
465 N must be nonnegative. N is deliberately declared with type `int'
466 to allow for future extensions (using negative values). */
468 quotearg_n_options (int n, char const *arg,
469 struct quoting_options const *options)
471 static unsigned int nslots;
472 static struct slotvec
481 size_t s = n1 * sizeof (struct slotvec);
482 if (! (0 < n1 && n1 == s / sizeof (struct slotvec)))
484 slotvec = (struct slotvec *) xrealloc (slotvec, s);
485 memset (slotvec + nslots, 0, (n1 - nslots) * sizeof (struct slotvec));
490 size_t size = slotvec[n].size;
491 char *val = slotvec[n].val;
492 size_t qsize = quotearg_buffer (val, size, arg, (size_t) -1, options);
496 slotvec[n].size = size = qsize + 1;
497 slotvec[n].val = val = xrealloc (val, size);
498 quotearg_buffer (val, size, arg, (size_t) -1, options);
506 quotearg_n (unsigned int n, char const *arg)
508 return quotearg_n_options (n, arg, &default_quoting_options);
512 quotearg (char const *arg)
514 return quotearg_n (0, arg);
518 quotearg_n_style (unsigned int n, enum quoting_style s, char const *arg)
520 struct quoting_options o;
522 memset (o.quote_these_too, 0, sizeof o.quote_these_too);
523 return quotearg_n_options (n, arg, &o);
527 quotearg_style (enum quoting_style s, char const *arg)
529 return quotearg_n_style (0, s, arg);
533 quotearg_char (char const *arg, char ch)
535 struct quoting_options options;
536 options = default_quoting_options;
537 set_char_quoting (&options, ch, 1);
538 return quotearg_n_options (0, arg, &options);
542 quotearg_colon (char const *arg)
544 return quotearg_char (arg, ':');