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)
59 #if HAVE_MBRTOWC && HAVE_WCHAR_H
62 # define iswprint(wc) 1
63 # define mbrtowc(pwc, s, n, ps) 1
64 # define mbsinit(ps) 1
65 # define mbstate_t int
68 #define INT_BITS (sizeof (int) * CHAR_BIT)
70 #if defined (STDC_HEADERS) || (!defined (isascii) && !defined (HAVE_ISASCII))
71 /* Undefine to protect against the definition in wctype.h of solaris2.6. */
75 # define ISASCII(c) isascii (c)
77 /* Undefine to protect against the definition in wctype.h of solaris2.6. */
79 #define ISPRINT(c) (ISASCII (c) && isprint (c))
81 struct quoting_options
83 /* Basic quoting style. */
84 enum quoting_style style;
86 /* Quote the characters indicated by this bit vector even if the
87 quoting style would not normally require them to be quoted. */
88 int quote_these_too[((UCHAR_MAX + 1) / INT_BITS
89 + ((UCHAR_MAX + 1) % INT_BITS != 0))];
92 /* Names of quoting styles. */
93 char const *const quoting_style_args[] =
104 /* Correspondences to quoting style names. */
105 enum quoting_style const quoting_style_vals[] =
107 literal_quoting_style,
109 shell_always_quoting_style,
111 escape_quoting_style,
115 /* The default quoting options. */
116 static struct quoting_options default_quoting_options;
118 /* Allocate a new set of quoting options, with contents initially identical
119 to O if O is not null, or to the default if O is null.
120 It is the caller's responsibility to free the result. */
121 struct quoting_options *
122 clone_quoting_options (struct quoting_options *o)
124 struct quoting_options *p
125 = (struct quoting_options *) xmalloc (sizeof (struct quoting_options));
126 *p = *(o ? o : &default_quoting_options);
130 /* Get the value of O's quoting style. If O is null, use the default. */
132 get_quoting_style (struct quoting_options *o)
134 return (o ? o : &default_quoting_options)->style;
137 /* In O (or in the default if O is null),
138 set the value of the quoting style to S. */
140 set_quoting_style (struct quoting_options *o, enum quoting_style s)
142 (o ? o : &default_quoting_options)->style = s;
145 /* In O (or in the default if O is null),
146 set the value of the quoting options for character C to I.
147 Return the old value. Currently, the only values defined for I are
148 0 (the default) and 1 (which means to quote the character even if
149 it would not otherwise be quoted). */
151 set_char_quoting (struct quoting_options *o, char c, int i)
153 unsigned char uc = c;
154 int *p = (o ? o : &default_quoting_options)->quote_these_too + uc / INT_BITS;
155 int shift = uc % INT_BITS;
156 int r = (*p >> shift) & 1;
157 *p ^= ((i & 1) ^ r) << shift;
161 /* Place into buffer BUFFER (of size BUFFERSIZE) a quoted version of
162 argument ARG (of size ARGSIZE), using QUOTING_STYLE and the
163 non-quoting-style part of O to control quoting.
164 Terminate the output with a null character, and return the written
165 size of the output, not counting the terminating null.
166 If BUFFERSIZE is too small to store the output string, return the
167 value that would have been returned had BUFFERSIZE been large enough.
168 If ARGSIZE is -1, use the string length of the argument for ARGSIZE.
170 This function acts like quotearg_buffer (BUFFER, BUFFERSIZE, ARG,
171 ARGSIZE, O), except it uses QUOTING_STYLE instead of the quoting
172 style specified by O, and O may not be null. */
175 quotearg_buffer_restyled (char *buffer, size_t buffersize,
176 char const *arg, size_t argsize,
177 enum quoting_style quoting_style,
178 struct quoting_options const *o)
182 char const *quote_string = 0;
183 size_t quote_string_len = 0;
184 int backslash_escapes = 0;
189 if (len < buffersize) \
195 switch (quoting_style)
197 case c_quoting_style:
199 backslash_escapes = 1;
201 quote_string_len = 1;
204 case escape_quoting_style:
205 backslash_escapes = 1;
208 case locale_quoting_style:
209 for (quote_string = _("`"); *quote_string; quote_string++)
210 STORE (*quote_string);
211 backslash_escapes = 1;
212 quote_string = _("'");
213 quote_string_len = strlen (quote_string);
216 case shell_always_quoting_style:
219 quote_string_len = 1;
226 for (i = 0; ! (argsize == (size_t) -1 ? arg[i] == '\0' : i == argsize); i++)
231 if (backslash_escapes
233 && i + quote_string_len <= argsize
234 && memcmp (arg + i, quote_string, quote_string_len) == 0)
241 switch (quoting_style)
243 case shell_quoting_style:
244 goto use_shell_always_quoting_style;
246 case c_quoting_style:
247 if (i + 2 < argsize && arg[i + 1] == '?')
251 case '(': case ')': case '-': case '/':
252 case '<': case '=': case '>':
253 /* Escape the second '?' in what would otherwise be
269 #if HAVE_C_BACKSLASH_A
270 case '\a': esc = 'a'; goto c_escape;
272 case '\b': esc = 'b'; goto c_escape;
273 case '\f': esc = 'f'; goto c_escape;
274 case '\n': esc = 'n'; goto c_and_shell_escape;
275 case '\r': esc = 'r'; goto c_and_shell_escape;
276 case '\t': esc = 't'; goto c_and_shell_escape;
277 case '\v': esc = 'v'; goto c_escape;
278 case '\\': esc = c; goto c_and_shell_escape;
281 if (quoting_style == shell_quoting_style)
282 goto use_shell_always_quoting_style;
284 if (backslash_escapes)
296 case '!': /* special in bash */
297 case '"': case '$': case '&':
298 case '(': case ')': case '*': case ';':
299 case '<': case '>': case '[':
300 case '^': /* special in old /bin/sh, e.g. SunOS 4.1.4 */
302 /* A shell special character. In theory, '$' and '`' could
303 be the first bytes of multibyte characters, which means
304 we should check them with mbrtowc, but in practice this
305 doesn't happen so it's not worth worrying about. */
306 if (quoting_style == shell_quoting_style)
307 goto use_shell_always_quoting_style;
311 switch (quoting_style)
313 case shell_quoting_style:
314 goto use_shell_always_quoting_style;
316 case shell_always_quoting_style:
327 case '%': case '+': case ',': case '-': case '.': case '/':
328 case '0': case '1': case '2': case '3': case '4': case '5':
329 case '6': case '7': case '8': case '9': case ':': case '=':
330 case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
331 case 'G': case 'H': case 'I': case 'J': case 'K': case 'L':
332 case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R':
333 case 'S': case 'T': case 'U': case 'V': case 'W': case 'X':
334 case 'Y': case 'Z': case ']': case '_': case 'a': case 'b':
335 case 'c': case 'd': case 'e': case 'f': case 'g': case 'h':
336 case 'i': case 'j': case 'k': case 'l': case 'm': case 'n':
337 case 'o': case 'p': case 'q': case 'r': case 's': case 't':
338 case 'u': case 'v': case 'w': case 'x': case 'y': case 'z':
340 /* These characters don't cause problems, no matter what the
341 quoting style is. They cannot start multibyte sequences. */
345 /* If we have a multibyte sequence, copy it until we reach
346 its end, find an error, or come back to the initial shift
347 state. For C-like styles, if the sequence has
348 unprintable characters, escape the whole sequence, since
349 we can't easily escape single characters within it. */
351 /* Length of multibyte sequence found so far. */
356 memset (&mbstate, 0, sizeof mbstate);
358 if (argsize == (size_t) -1)
359 argsize = strlen (arg);
364 size_t bytes = mbrtowc (&w, &arg[i + m],
365 argsize - (i + m), &mbstate);
368 else if (bytes == (size_t) -1)
373 else if (bytes == (size_t) -2)
376 while (i + m < argsize && arg[i + m])
387 while (! mbsinit (&mbstate));
391 /* Escape a unibyte character like a multibyte
392 sequence if using backslash escapes, and if the
393 character is not printable. */
394 m = backslash_escapes && ! ISPRINT (c);
400 /* Output a multibyte sequence, or an escaped
401 unprintable unibyte character. */
402 size_t imax = i + m - 1;
406 if (backslash_escapes && ! printable)
409 STORE ('0' + (c >> 6));
410 STORE ('0' + ((c >> 3) & 7));
424 if (! (backslash_escapes
425 && o->quote_these_too[c / INT_BITS] & (1 << (c % INT_BITS))))
436 for (; *quote_string; quote_string++)
437 STORE (*quote_string);
439 if (len < buffersize)
443 use_shell_always_quoting_style:
444 return quotearg_buffer_restyled (buffer, buffersize, arg, argsize,
445 shell_always_quoting_style, o);
448 /* Place into buffer BUFFER (of size BUFFERSIZE) a quoted version of
449 argument ARG (of size ARGSIZE), using O to control quoting.
450 If O is null, use the default.
451 Terminate the output with a null character, and return the written
452 size of the output, not counting the terminating null.
453 If BUFFERSIZE is too small to store the output string, return the
454 value that would have been returned had BUFFERSIZE been large enough.
455 If ARGSIZE is -1, use the string length of the argument for ARGSIZE. */
457 quotearg_buffer (char *buffer, size_t buffersize,
458 char const *arg, size_t argsize,
459 struct quoting_options const *o)
461 struct quoting_options const *p = o ? o : &default_quoting_options;
462 return quotearg_buffer_restyled (buffer, buffersize, arg, argsize,
466 /* Use storage slot N to return a quoted version of the string ARG.
467 OPTIONS specifies the quoting options.
468 The returned value points to static storage that can be
469 reused by the next call to this function with the same value of N.
470 N must be nonnegative. N is deliberately declared with type `int'
471 to allow for future extensions (using negative values). */
473 quotearg_n_options (int n, char const *arg,
474 struct quoting_options const *options)
476 static unsigned int nslots;
477 static struct slotvec
486 size_t s = n1 * sizeof (struct slotvec);
487 if (! (0 < n1 && n1 == s / sizeof (struct slotvec)))
489 slotvec = (struct slotvec *) xrealloc (slotvec, s);
490 memset (slotvec + nslots, 0, (n1 - nslots) * sizeof (struct slotvec));
495 size_t size = slotvec[n].size;
496 char *val = slotvec[n].val;
497 size_t qsize = quotearg_buffer (val, size, arg, (size_t) -1, options);
501 slotvec[n].size = size = qsize + 1;
502 slotvec[n].val = val = xrealloc (val, size);
503 quotearg_buffer (val, size, arg, (size_t) -1, options);
511 quotearg_n (unsigned int n, char const *arg)
513 return quotearg_n_options (n, arg, &default_quoting_options);
517 quotearg (char const *arg)
519 return quotearg_n (0, arg);
523 quotearg_n_style (unsigned int n, enum quoting_style s, char const *arg)
525 struct quoting_options o;
527 memset (o.quote_these_too, 0, sizeof o.quote_these_too);
528 return quotearg_n_options (n, arg, &o);
532 quotearg_style (enum quoting_style s, char const *arg)
534 return quotearg_n_style (0, s, arg);
538 quotearg_char (char const *arg, char ch)
540 struct quoting_options options;
541 options = default_quoting_options;
542 set_char_quoting (&options, ch, 1);
543 return quotearg_n_options (0, arg, &options);
547 quotearg_colon (char const *arg)
549 return quotearg_char (arg, ':');