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'
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 #if defined (STDC_HEADERS) || (!defined (isascii) && !defined (HAVE_ISASCII))
77 /* Undefine to protect against the definition in wctype.h of solaris2.6. */
81 # define ISASCII(c) isascii (c)
83 /* Undefine to protect against the definition in wctype.h of solaris2.6. */
85 #define ISPRINT(c) (ISASCII (c) && isprint (c))
87 struct quoting_options
89 /* Basic quoting style. */
90 enum quoting_style style;
92 /* Quote the characters indicated by this bit vector even if the
93 quoting style would not normally require them to be quoted. */
94 int quote_these_too[((UCHAR_MAX + 1) / INT_BITS
95 + ((UCHAR_MAX + 1) % INT_BITS != 0))];
98 /* Names of quoting styles. */
99 char const *const quoting_style_args[] =
110 /* Correspondences to quoting style names. */
111 enum quoting_style const quoting_style_vals[] =
113 literal_quoting_style,
115 shell_always_quoting_style,
117 escape_quoting_style,
121 /* The default quoting options. */
122 static struct quoting_options default_quoting_options;
124 /* Allocate a new set of quoting options, with contents initially identical
125 to O if O is not null, or to the default if O is null.
126 It is the caller's responsibility to free the result. */
127 struct quoting_options *
128 clone_quoting_options (struct quoting_options *o)
130 struct quoting_options *p
131 = (struct quoting_options *) xmalloc (sizeof (struct quoting_options));
132 *p = *(o ? o : &default_quoting_options);
136 /* Get the value of O's quoting style. If O is null, use the default. */
138 get_quoting_style (struct quoting_options *o)
140 return (o ? o : &default_quoting_options)->style;
143 /* In O (or in the default if O is null),
144 set the value of the quoting style to S. */
146 set_quoting_style (struct quoting_options *o, enum quoting_style s)
148 (o ? o : &default_quoting_options)->style = s;
151 /* In O (or in the default if O is null),
152 set the value of the quoting options for character C to I.
153 Return the old value. Currently, the only values defined for I are
154 0 (the default) and 1 (which means to quote the character even if
155 it would not otherwise be quoted). */
157 set_char_quoting (struct quoting_options *o, char c, int i)
159 unsigned char uc = c;
160 int *p = (o ? o : &default_quoting_options)->quote_these_too + uc / INT_BITS;
161 int shift = uc % INT_BITS;
162 int r = (*p >> shift) & 1;
163 *p ^= ((i & 1) ^ r) << shift;
167 /* Place into buffer BUFFER (of size BUFFERSIZE) a quoted version of
168 argument ARG (of size ARGSIZE), using QUOTING_STYLE and the
169 non-quoting-style part of O to control quoting.
170 Terminate the output with a null character, and return the written
171 size of the output, not counting the terminating null.
172 If BUFFERSIZE is too small to store the output string, return the
173 value that would have been returned had BUFFERSIZE been large enough.
174 If ARGSIZE is -1, use the string length of the argument for ARGSIZE.
176 This function acts like quotearg_buffer (BUFFER, BUFFERSIZE, ARG,
177 ARGSIZE, O), except it uses QUOTING_STYLE instead of the quoting
178 style specified by O, and O may not be null. */
181 quotearg_buffer_restyled (char *buffer, size_t buffersize,
182 char const *arg, size_t argsize,
183 enum quoting_style quoting_style,
184 struct quoting_options const *o)
188 char const *quote_string = 0;
189 size_t quote_string_len = 0;
190 int backslash_escapes = 0;
195 if (len < buffersize) \
201 switch (quoting_style)
203 case c_quoting_style:
205 backslash_escapes = 1;
207 quote_string_len = 1;
210 case escape_quoting_style:
211 backslash_escapes = 1;
214 case locale_quoting_style:
215 for (quote_string = _("`"); *quote_string; quote_string++)
216 STORE (*quote_string);
217 backslash_escapes = 1;
218 quote_string = _("'");
219 quote_string_len = strlen (quote_string);
222 case shell_always_quoting_style:
225 quote_string_len = 1;
232 for (i = 0; ! (argsize == (size_t) -1 ? arg[i] == '\0' : i == argsize); i++)
237 if (backslash_escapes
239 && i + quote_string_len <= argsize
240 && memcmp (arg + i, quote_string, quote_string_len) == 0)
247 switch (quoting_style)
249 case shell_quoting_style:
250 goto use_shell_always_quoting_style;
252 case c_quoting_style:
253 if (i + 2 < argsize && arg[i + 1] == '?')
257 case '(': case ')': case '-': case '/':
258 case '<': case '=': case '>':
259 /* Escape the second '?' in what would otherwise be
275 case ALERT_CHAR: esc = 'a'; goto c_escape;
276 case '\b': esc = 'b'; goto c_escape;
277 case '\f': esc = 'f'; goto c_escape;
278 case '\n': esc = 'n'; goto c_and_shell_escape;
279 case '\r': esc = 'r'; goto c_and_shell_escape;
280 case '\t': esc = 't'; goto c_and_shell_escape;
281 case '\v': esc = 'v'; goto c_escape;
282 case '\\': esc = c; goto c_and_shell_escape;
285 if (quoting_style == shell_quoting_style)
286 goto use_shell_always_quoting_style;
288 if (backslash_escapes)
300 case '!': /* special in bash */
301 case '"': case '$': case '&':
302 case '(': case ')': case '*': case ';':
303 case '<': case '>': case '[':
304 case '^': /* special in old /bin/sh, e.g. SunOS 4.1.4 */
306 /* A shell special character. In theory, '$' and '`' could
307 be the first bytes of multibyte characters, which means
308 we should check them with mbrtowc, but in practice this
309 doesn't happen so it's not worth worrying about. */
310 if (quoting_style == shell_quoting_style)
311 goto use_shell_always_quoting_style;
315 switch (quoting_style)
317 case shell_quoting_style:
318 goto use_shell_always_quoting_style;
320 case shell_always_quoting_style:
331 case '%': case '+': case ',': case '-': case '.': case '/':
332 case '0': case '1': case '2': case '3': case '4': case '5':
333 case '6': case '7': case '8': case '9': case ':': case '=':
334 case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
335 case 'G': case 'H': case 'I': case 'J': case 'K': case 'L':
336 case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R':
337 case 'S': case 'T': case 'U': case 'V': case 'W': case 'X':
338 case 'Y': case 'Z': case ']': case '_': case 'a': case 'b':
339 case 'c': case 'd': case 'e': case 'f': case 'g': case 'h':
340 case 'i': case 'j': case 'k': case 'l': case 'm': case 'n':
341 case 'o': case 'p': case 'q': case 'r': case 's': case 't':
342 case 'u': case 'v': case 'w': case 'x': case 'y': case 'z':
344 /* These characters don't cause problems, no matter what the
345 quoting style is. They cannot start multibyte sequences. */
349 /* If we have a multibyte sequence, copy it until we reach
350 its end, find an error, or come back to the initial shift
351 state. For C-like styles, if the sequence has
352 unprintable characters, escape the whole sequence, since
353 we can't easily escape single characters within it. */
355 /* Length of multibyte sequence found so far. */
360 memset (&mbstate, 0, sizeof mbstate);
362 if (argsize == (size_t) -1)
363 argsize = strlen (arg);
368 size_t bytes = mbrtowc (&w, &arg[i + m],
369 argsize - (i + m), &mbstate);
372 else if (bytes == (size_t) -1)
377 else if (bytes == (size_t) -2)
380 while (i + m < argsize && arg[i + m])
391 while (! mbsinit (&mbstate));
395 /* Escape a unibyte character like a multibyte
396 sequence if using backslash escapes, and if the
397 character is not printable. */
398 m = backslash_escapes && ! ISPRINT (c);
404 /* Output a multibyte sequence, or an escaped
405 unprintable unibyte character. */
406 size_t imax = i + m - 1;
410 if (backslash_escapes && ! printable)
413 STORE ('0' + (c >> 6));
414 STORE ('0' + ((c >> 3) & 7));
428 if (! (backslash_escapes
429 && o->quote_these_too[c / INT_BITS] & (1 << (c % INT_BITS))))
440 for (; *quote_string; quote_string++)
441 STORE (*quote_string);
443 if (len < buffersize)
447 use_shell_always_quoting_style:
448 return quotearg_buffer_restyled (buffer, buffersize, arg, argsize,
449 shell_always_quoting_style, o);
452 /* Place into buffer BUFFER (of size BUFFERSIZE) a quoted version of
453 argument ARG (of size ARGSIZE), using O to control quoting.
454 If O is null, use the default.
455 Terminate the output with a null character, and return the written
456 size of the output, not counting the terminating null.
457 If BUFFERSIZE is too small to store the output string, return the
458 value that would have been returned had BUFFERSIZE been large enough.
459 If ARGSIZE is -1, use the string length of the argument for ARGSIZE. */
461 quotearg_buffer (char *buffer, size_t buffersize,
462 char const *arg, size_t argsize,
463 struct quoting_options const *o)
465 struct quoting_options const *p = o ? o : &default_quoting_options;
466 return quotearg_buffer_restyled (buffer, buffersize, arg, argsize,
470 /* Use storage slot N to return a quoted version of the string ARG.
471 OPTIONS specifies the quoting options.
472 The returned value points to static storage that can be
473 reused by the next call to this function with the same value of N.
474 N must be nonnegative. N is deliberately declared with type `int'
475 to allow for future extensions (using negative values). */
477 quotearg_n_options (int n, char const *arg,
478 struct quoting_options const *options)
480 static unsigned int nslots;
481 static struct slotvec
490 size_t s = n1 * sizeof (struct slotvec);
491 if (! (0 < n1 && n1 == s / sizeof (struct slotvec)))
493 slotvec = (struct slotvec *) xrealloc (slotvec, s);
494 memset (slotvec + nslots, 0, (n1 - nslots) * sizeof (struct slotvec));
499 size_t size = slotvec[n].size;
500 char *val = slotvec[n].val;
501 size_t qsize = quotearg_buffer (val, size, arg, (size_t) -1, options);
505 slotvec[n].size = size = qsize + 1;
506 slotvec[n].val = val = xrealloc (val, size);
507 quotearg_buffer (val, size, arg, (size_t) -1, options);
515 quotearg_n (unsigned int n, char const *arg)
517 return quotearg_n_options (n, arg, &default_quoting_options);
521 quotearg (char const *arg)
523 return quotearg_n (0, arg);
527 quotearg_n_style (unsigned int n, enum quoting_style s, char const *arg)
529 struct quoting_options o;
531 memset (o.quote_these_too, 0, sizeof o.quote_these_too);
532 return quotearg_n_options (n, arg, &o);
536 quotearg_style (enum quoting_style s, char const *arg)
538 return quotearg_n_style (0, s, arg);
542 quotearg_char (char const *arg, char ch)
544 struct quoting_options options;
545 options = default_quoting_options;
546 set_char_quoting (&options, ch, 1);
547 return quotearg_n_options (0, arg, &options);
551 quotearg_colon (char const *arg)
553 return quotearg_char (arg, ':');