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
66 # if !HAVE_MBSTATE_T_OBJECT
67 # define mbrtowc(pwc, s, n, ps) (mbrtowc) (pwc, s, n, 0)
70 # define mbrtowc(pwc, s, n, ps) ((*(pwc) = *(s)) != 0)
71 # define mbsinit(ps) 1
72 # define iswprint(wc) ISPRINT ((unsigned char) (wc))
79 # if !defined iswprint && !HAVE_ISWPRINT
80 # define iswprint(wc) 1
84 #define INT_BITS (sizeof (int) * CHAR_BIT)
86 #if defined (STDC_HEADERS) || (!defined (isascii) && !defined (HAVE_ISASCII))
87 /* Undefine to protect against the definition in wctype.h of solaris2.6. */
91 # define ISASCII(c) isascii (c)
93 /* Undefine to protect against the definition in wctype.h of solaris2.6. */
95 #define ISPRINT(c) (ISASCII (c) && isprint (c))
97 struct quoting_options
99 /* Basic quoting style. */
100 enum quoting_style style;
102 /* Quote the characters indicated by this bit vector even if the
103 quoting style would not normally require them to be quoted. */
104 int quote_these_too[(UCHAR_MAX / INT_BITS) + 1];
107 /* Names of quoting styles. */
108 char const *const quoting_style_args[] =
119 /* Correspondences to quoting style names. */
120 enum quoting_style const quoting_style_vals[] =
122 literal_quoting_style,
124 shell_always_quoting_style,
126 escape_quoting_style,
130 /* The default quoting options. */
131 static struct quoting_options default_quoting_options;
133 /* Allocate a new set of quoting options, with contents initially identical
134 to O if O is not null, or to the default if O is null.
135 It is the caller's responsibility to free the result. */
136 struct quoting_options *
137 clone_quoting_options (struct quoting_options *o)
139 struct quoting_options *p
140 = (struct quoting_options *) xmalloc (sizeof (struct quoting_options));
141 *p = *(o ? o : &default_quoting_options);
145 /* Get the value of O's quoting style. If O is null, use the default. */
147 get_quoting_style (struct quoting_options *o)
149 return (o ? o : &default_quoting_options)->style;
152 /* In O (or in the default if O is null),
153 set the value of the quoting style to S. */
155 set_quoting_style (struct quoting_options *o, enum quoting_style s)
157 (o ? o : &default_quoting_options)->style = s;
160 /* In O (or in the default if O is null),
161 set the value of the quoting options for character C to I.
162 Return the old value. Currently, the only values defined for I are
163 0 (the default) and 1 (which means to quote the character even if
164 it would not otherwise be quoted). */
166 set_char_quoting (struct quoting_options *o, char c, int i)
168 unsigned char uc = c;
169 int *p = (o ? o : &default_quoting_options)->quote_these_too + uc / INT_BITS;
170 int shift = uc % INT_BITS;
171 int r = (*p >> shift) & 1;
172 *p ^= ((i & 1) ^ r) << shift;
176 /* Place into buffer BUFFER (of size BUFFERSIZE) a quoted version of
177 argument ARG (of size ARGSIZE), using QUOTING_STYLE and the
178 non-quoting-style part of O to control quoting.
179 Terminate the output with a null character, and return the written
180 size of the output, not counting the terminating null.
181 If BUFFERSIZE is too small to store the output string, return the
182 value that would have been returned had BUFFERSIZE been large enough.
183 If ARGSIZE is -1, use the string length of the argument for ARGSIZE.
185 This function acts like quotearg_buffer (BUFFER, BUFFERSIZE, ARG,
186 ARGSIZE, O), except it uses QUOTING_STYLE instead of the quoting
187 style specified by O, and O may not be null. */
190 quotearg_buffer_restyled (char *buffer, size_t buffersize,
191 char const *arg, size_t argsize,
192 enum quoting_style quoting_style,
193 struct quoting_options const *o)
197 char const *quote_string = 0;
198 size_t quote_string_len = 0;
199 int backslash_escapes = 0;
204 if (len < buffersize) \
210 switch (quoting_style)
212 case c_quoting_style:
214 backslash_escapes = 1;
216 quote_string_len = 1;
219 case escape_quoting_style:
220 backslash_escapes = 1;
223 case locale_quoting_style:
224 for (quote_string = _("`"); *quote_string; quote_string++)
225 STORE (*quote_string);
226 backslash_escapes = 1;
227 quote_string = _("'");
228 quote_string_len = strlen (quote_string);
231 case shell_always_quoting_style:
234 quote_string_len = 1;
241 for (i = 0; ! (argsize == (size_t) -1 ? arg[i] == '\0' : i == argsize); i++)
246 if (backslash_escapes
248 && i + quote_string_len <= argsize
249 && memcmp (arg + i, quote_string, quote_string_len) == 0)
256 switch (quoting_style)
258 case shell_quoting_style:
259 goto use_shell_always_quoting_style;
261 case c_quoting_style:
262 if (i + 2 < argsize && arg[i + 1] == '?')
266 case '(': case ')': case '-': case '/':
267 case '<': case '=': case '>':
268 /* Escape the second '?' in what would otherwise be
284 case ALERT_CHAR: esc = 'a'; goto c_escape;
285 case '\b': esc = 'b'; goto c_escape;
286 case '\f': esc = 'f'; goto c_escape;
287 case '\n': esc = 'n'; goto c_and_shell_escape;
288 case '\r': esc = 'r'; goto c_and_shell_escape;
289 case '\t': esc = 't'; goto c_and_shell_escape;
290 case '\v': esc = 'v'; goto c_escape;
291 case '\\': esc = c; goto c_and_shell_escape;
294 if (quoting_style == shell_quoting_style)
295 goto use_shell_always_quoting_style;
297 if (backslash_escapes)
309 case '!': /* special in bash */
310 case '"': case '$': case '&':
311 case '(': case ')': case '*': case ';':
312 case '<': case '>': case '[':
313 case '^': /* special in old /bin/sh, e.g. SunOS 4.1.4 */
315 /* A shell special character. In theory, '$' and '`' could
316 be the first bytes of multibyte characters, which means
317 we should check them with mbrtowc, but in practice this
318 doesn't happen so it's not worth worrying about. */
319 if (quoting_style == shell_quoting_style)
320 goto use_shell_always_quoting_style;
324 switch (quoting_style)
326 case shell_quoting_style:
327 goto use_shell_always_quoting_style;
329 case shell_always_quoting_style:
340 case '%': case '+': case ',': case '-': case '.': case '/':
341 case '0': case '1': case '2': case '3': case '4': case '5':
342 case '6': case '7': case '8': case '9': case ':': case '=':
343 case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
344 case 'G': case 'H': case 'I': case 'J': case 'K': case 'L':
345 case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R':
346 case 'S': case 'T': case 'U': case 'V': case 'W': case 'X':
347 case 'Y': case 'Z': case ']': case '_': case 'a': case 'b':
348 case 'c': case 'd': case 'e': case 'f': case 'g': case 'h':
349 case 'i': case 'j': case 'k': case 'l': case 'm': case 'n':
350 case 'o': case 'p': case 'q': case 'r': case 's': case 't':
351 case 'u': case 'v': case 'w': case 'x': case 'y': case 'z':
353 /* These characters don't cause problems, no matter what the
354 quoting style is. They cannot start multibyte sequences. */
358 /* If we have a multibyte sequence, copy it until we reach
359 its end, find an error, or come back to the initial shift
360 state. For C-like styles, if the sequence has
361 unprintable characters, escape the whole sequence, since
362 we can't easily escape single characters within it. */
364 /* Length of multibyte sequence found so far. */
369 memset (&mbstate, 0, sizeof mbstate);
371 if (argsize == (size_t) -1)
372 argsize = strlen (arg);
377 size_t bytes = mbrtowc (&w, &arg[i + m],
378 argsize - (i + m), &mbstate);
381 else if (bytes == (size_t) -1)
386 else if (bytes == (size_t) -2)
389 while (i + m < argsize && arg[i + m])
400 while (! mbsinit (&mbstate));
404 /* Escape a unibyte character like a multibyte
405 sequence if using backslash escapes, and if the
406 character is not printable. */
407 m = backslash_escapes && ! ISPRINT (c);
413 /* Output a multibyte sequence, or an escaped
414 unprintable unibyte character. */
415 size_t imax = i + m - 1;
419 if (backslash_escapes && ! printable)
422 STORE ('0' + (c >> 6));
423 STORE ('0' + ((c >> 3) & 7));
437 if (! (backslash_escapes
438 && o->quote_these_too[c / INT_BITS] & (1 << (c % INT_BITS))))
449 for (; *quote_string; quote_string++)
450 STORE (*quote_string);
452 if (len < buffersize)
456 use_shell_always_quoting_style:
457 return quotearg_buffer_restyled (buffer, buffersize, arg, argsize,
458 shell_always_quoting_style, o);
461 /* Place into buffer BUFFER (of size BUFFERSIZE) a quoted version of
462 argument ARG (of size ARGSIZE), using O to control quoting.
463 If O is null, use the default.
464 Terminate the output with a null character, and return the written
465 size of the output, not counting the terminating null.
466 If BUFFERSIZE is too small to store the output string, return the
467 value that would have been returned had BUFFERSIZE been large enough.
468 If ARGSIZE is -1, use the string length of the argument for ARGSIZE. */
470 quotearg_buffer (char *buffer, size_t buffersize,
471 char const *arg, size_t argsize,
472 struct quoting_options const *o)
474 struct quoting_options const *p = o ? o : &default_quoting_options;
475 return quotearg_buffer_restyled (buffer, buffersize, arg, argsize,
479 /* Use storage slot N to return a quoted version of the string ARG.
480 OPTIONS specifies the quoting options.
481 The returned value points to static storage that can be
482 reused by the next call to this function with the same value of N.
483 N must be nonnegative. N is deliberately declared with type `int'
484 to allow for future extensions (using negative values). */
486 quotearg_n_options (int n, char const *arg,
487 struct quoting_options const *options)
489 static unsigned int nslots;
490 static struct slotvec
499 size_t s = n1 * sizeof (struct slotvec);
500 if (! (0 < n1 && n1 == s / sizeof (struct slotvec)))
502 slotvec = (struct slotvec *) xrealloc (slotvec, s);
503 memset (slotvec + nslots, 0, (n1 - nslots) * sizeof (struct slotvec));
508 size_t size = slotvec[n].size;
509 char *val = slotvec[n].val;
510 size_t qsize = quotearg_buffer (val, size, arg, (size_t) -1, options);
514 slotvec[n].size = size = qsize + 1;
515 slotvec[n].val = val = xrealloc (val, size);
516 quotearg_buffer (val, size, arg, (size_t) -1, options);
524 quotearg_n (unsigned int n, char const *arg)
526 return quotearg_n_options (n, arg, &default_quoting_options);
530 quotearg (char const *arg)
532 return quotearg_n (0, arg);
536 quotearg_n_style (unsigned int n, enum quoting_style s, char const *arg)
538 struct quoting_options o;
540 memset (o.quote_these_too, 0, sizeof o.quote_these_too);
541 return quotearg_n_options (n, arg, &o);
545 quotearg_style (enum quoting_style s, char const *arg)
547 return quotearg_n_style (0, s, arg);
551 quotearg_char (char const *arg, char ch)
553 struct quoting_options options;
554 options = default_quoting_options;
555 set_char_quoting (&options, ch, 1);
556 return quotearg_n_options (0, arg, &options);
560 quotearg_colon (char const *arg)
562 return quotearg_char (arg, ':');