1 /* quotearg.c - quote arguments for output
3 Copyright (C) 1998, 1999, 2000, 2001, 2002, 2004, 2005, 2006, 2007,
4 2008 Free Software Foundation, Inc.
6 This program is free software: you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program. If not, see <http://www.gnu.org/licenses/>. */
19 /* Written by Paul Eggert <eggert@twinsun.com> */
37 #define _(msgid) gettext (msgid)
38 #define N_(msgid) msgid
41 /* Disable multibyte processing entirely. Since MB_CUR_MAX is 1, the
42 other macros are defined only for documentation and to satisfy C
47 # define mbstate_t int
48 # define mbrtowc(pwc, s, n, ps) ((*(pwc) = *(s)) != 0)
49 # define iswprint(wc) isprint ((unsigned char) (wc))
53 #if !defined mbsinit && !HAVE_MBSINIT
54 # define mbsinit(ps) 1
58 # define SIZE_MAX ((size_t) -1)
61 #define INT_BITS (sizeof (int) * CHAR_BIT)
63 struct quoting_options
65 /* Basic quoting style. */
66 enum quoting_style style;
68 /* Additional flags. Bitwise combination of enum quoting_flags. */
71 /* Quote the characters indicated by this bit vector even if the
72 quoting style would not normally require them to be quoted. */
73 unsigned int quote_these_too[(UCHAR_MAX / INT_BITS) + 1];
76 /* Names of quoting styles. */
77 char const *const quoting_style_args[] =
90 /* Correspondences to quoting style names. */
91 enum quoting_style const quoting_style_vals[] =
93 literal_quoting_style,
95 shell_always_quoting_style,
97 c_maybe_quoting_style,
100 clocale_quoting_style
103 /* The default quoting options. */
104 static struct quoting_options default_quoting_options;
106 /* Allocate a new set of quoting options, with contents initially identical
107 to O if O is not null, or to the default if O is null.
108 It is the caller's responsibility to free the result. */
109 struct quoting_options *
110 clone_quoting_options (struct quoting_options *o)
113 struct quoting_options *p = xmemdup (o ? o : &default_quoting_options,
119 /* Get the value of O's quoting style. If O is null, use the default. */
121 get_quoting_style (struct quoting_options *o)
123 return (o ? o : &default_quoting_options)->style;
126 /* In O (or in the default if O is null),
127 set the value of the quoting style to S. */
129 set_quoting_style (struct quoting_options *o, enum quoting_style s)
131 (o ? o : &default_quoting_options)->style = s;
134 /* In O (or in the default if O is null),
135 set the value of the quoting options for character C to I.
136 Return the old value. Currently, the only values defined for I are
137 0 (the default) and 1 (which means to quote the character even if
138 it would not otherwise be quoted). */
140 set_char_quoting (struct quoting_options *o, char c, int i)
142 unsigned char uc = c;
144 (o ? o : &default_quoting_options)->quote_these_too + uc / INT_BITS;
145 int shift = uc % INT_BITS;
146 int r = (*p >> shift) & 1;
147 *p ^= ((i & 1) ^ r) << shift;
151 /* In O (or in the default if O is null),
152 set the value of the quoting options flag to I, which can be a
153 bitwise combination of enum quoting_flags, or 0 for default
154 behavior. Return the old value. */
156 set_quoting_flags (struct quoting_options *o, int i)
160 o = &default_quoting_options;
166 /* Return quoting options for STYLE, with no extra quoting. */
167 static struct quoting_options
168 quoting_options_from_style (enum quoting_style style)
170 struct quoting_options o;
173 memset (o.quote_these_too, 0, sizeof o.quote_these_too);
177 /* MSGID approximates a quotation mark. Return its translation if it
178 has one; otherwise, return either it or "\"", depending on S. */
180 gettext_quote (char const *msgid, enum quoting_style s)
182 char const *translation = _(msgid);
183 if (translation == msgid && s == clocale_quoting_style)
188 /* Place into buffer BUFFER (of size BUFFERSIZE) a quoted version of
189 argument ARG (of size ARGSIZE), using QUOTING_STYLE, FLAGS, and
190 QUOTE_THESE_TOO to control quoting.
191 Terminate the output with a null character, and return the written
192 size of the output, not counting the terminating null.
193 If BUFFERSIZE is too small to store the output string, return the
194 value that would have been returned had BUFFERSIZE been large enough.
195 If ARGSIZE is SIZE_MAX, use the string length of the argument for ARGSIZE.
197 This function acts like quotearg_buffer (BUFFER, BUFFERSIZE, ARG,
198 ARGSIZE, O), except it breaks O into its component pieces and is
199 not careful about errno. */
202 quotearg_buffer_restyled (char *buffer, size_t buffersize,
203 char const *arg, size_t argsize,
204 enum quoting_style quoting_style, int flags,
205 unsigned int *quote_these_too)
209 char const *quote_string = 0;
210 size_t quote_string_len = 0;
211 bool backslash_escapes = false;
212 bool unibyte_locale = MB_CUR_MAX == 1;
213 bool elide_outer_quotes = (flags & QA_ELIDE_OUTER_QUOTES) != 0;
218 if (len < buffersize) \
224 switch (quoting_style)
226 case c_maybe_quoting_style:
227 quoting_style = c_quoting_style;
228 elide_outer_quotes = true;
230 case c_quoting_style:
231 if (!elide_outer_quotes)
233 backslash_escapes = true;
235 quote_string_len = 1;
238 case escape_quoting_style:
239 backslash_escapes = true;
240 elide_outer_quotes = false;
243 case locale_quoting_style:
244 case clocale_quoting_style:
247 Get translations for open and closing quotation marks.
249 The message catalog should translate "`" to a left
250 quotation mark suitable for the locale, and similarly for
251 "'". If the catalog has no translation,
252 locale_quoting_style quotes `like this', and
253 clocale_quoting_style quotes "like this".
255 For example, an American English Unicode locale should
256 translate "`" to U+201C (LEFT DOUBLE QUOTATION MARK), and
257 should translate "'" to U+201D (RIGHT DOUBLE QUOTATION
258 MARK). A British English Unicode locale should instead
259 translate these to U+2018 (LEFT SINGLE QUOTATION MARK) and
260 U+2019 (RIGHT SINGLE QUOTATION MARK), respectively.
262 If you don't know what to put here, please see
263 <http://en.wikipedia.org/wiki/Quotation_mark#Glyphs>
264 and use glyphs suitable for your language. */
266 char const *left = gettext_quote (N_("`"), quoting_style);
267 char const *right = gettext_quote (N_("'"), quoting_style);
268 if (!elide_outer_quotes)
269 for (quote_string = left; *quote_string; quote_string++)
270 STORE (*quote_string);
271 backslash_escapes = true;
272 quote_string = right;
273 quote_string_len = strlen (quote_string);
277 case shell_quoting_style:
278 quoting_style = shell_always_quoting_style;
279 elide_outer_quotes = true;
281 case shell_always_quoting_style:
282 if (!elide_outer_quotes)
285 quote_string_len = 1;
288 case literal_quoting_style:
289 elide_outer_quotes = false;
296 for (i = 0; ! (argsize == SIZE_MAX ? arg[i] == '\0' : i == argsize); i++)
301 if (backslash_escapes
303 && i + quote_string_len <= argsize
304 && memcmp (arg + i, quote_string, quote_string_len) == 0)
306 if (elide_outer_quotes)
307 goto force_outer_quoting_style;
315 if (backslash_escapes)
317 if (elide_outer_quotes)
318 goto force_outer_quoting_style;
320 if (i + 1 < argsize && '0' <= arg[i + 1] && arg[i + 1] <= '9')
327 else if (flags & QA_ELIDE_NULL_BYTES)
332 switch (quoting_style)
334 case shell_always_quoting_style:
335 if (elide_outer_quotes)
336 goto force_outer_quoting_style;
339 case c_quoting_style:
340 if (i + 2 < argsize && arg[i + 1] == '?')
344 case '(': case ')': case '-': case '/':
345 case '<': case '=': case '>':
346 /* Escape the second '?' in what would otherwise be
348 if (elide_outer_quotes)
349 goto force_outer_quoting_style;
368 case '\a': esc = 'a'; goto c_escape;
369 case '\b': esc = 'b'; goto c_escape;
370 case '\f': esc = 'f'; goto c_escape;
371 case '\n': esc = 'n'; goto c_and_shell_escape;
372 case '\r': esc = 'r'; goto c_and_shell_escape;
373 case '\t': esc = 't'; goto c_and_shell_escape;
374 case '\v': esc = 'v'; goto c_escape;
375 case '\\': esc = c; goto c_and_shell_escape;
378 if (quoting_style == shell_always_quoting_style
379 && elide_outer_quotes)
380 goto force_outer_quoting_style;
383 if (backslash_escapes)
390 case '{': case '}': /* sometimes special if isolated */
391 if (! (argsize == SIZE_MAX ? arg[1] == '\0' : argsize == 1))
399 case '!': /* special in bash */
400 case '"': case '$': case '&':
401 case '(': case ')': case '*': case ';':
403 case '=': /* sometimes special in 0th or (with "set -k") later args */
405 case '^': /* special in old /bin/sh, e.g. SunOS 4.1.4 */
407 /* A shell special character. In theory, '$' and '`' could
408 be the first bytes of multibyte characters, which means
409 we should check them with mbrtowc, but in practice this
410 doesn't happen so it's not worth worrying about. */
411 if (quoting_style == shell_always_quoting_style
412 && elide_outer_quotes)
413 goto force_outer_quoting_style;
417 if (quoting_style == shell_always_quoting_style)
419 if (elide_outer_quotes)
420 goto force_outer_quoting_style;
427 case '%': case '+': case ',': case '-': case '.': case '/':
428 case '0': case '1': case '2': case '3': case '4': case '5':
429 case '6': case '7': case '8': case '9': case ':':
430 case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
431 case 'G': case 'H': case 'I': case 'J': case 'K': case 'L':
432 case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R':
433 case 'S': case 'T': case 'U': case 'V': case 'W': case 'X':
434 case 'Y': case 'Z': case ']': case '_': case 'a': case 'b':
435 case 'c': case 'd': case 'e': case 'f': case 'g': case 'h':
436 case 'i': case 'j': case 'k': case 'l': case 'm': case 'n':
437 case 'o': case 'p': case 'q': case 'r': case 's': case 't':
438 case 'u': case 'v': case 'w': case 'x': case 'y': case 'z':
439 /* These characters don't cause problems, no matter what the
440 quoting style is. They cannot start multibyte sequences. */
444 /* If we have a multibyte sequence, copy it until we reach
445 its end, find an error, or come back to the initial shift
446 state. For C-like styles, if the sequence has
447 unprintable characters, escape the whole sequence, since
448 we can't easily escape single characters within it. */
450 /* Length of multibyte sequence found so far. */
458 printable = isprint (c) != 0;
463 memset (&mbstate, 0, sizeof mbstate);
467 if (argsize == SIZE_MAX)
468 argsize = strlen (arg);
473 size_t bytes = mbrtowc (&w, &arg[i + m],
474 argsize - (i + m), &mbstate);
477 else if (bytes == (size_t) -1)
482 else if (bytes == (size_t) -2)
485 while (i + m < argsize && arg[i + m])
491 /* Work around a bug with older shells that "see" a '\'
492 that is really the 2nd byte of a multibyte character.
493 In practice the problem is limited to ASCII
494 chars >= '@' that are shell special chars. */
495 if ('[' == 0x5b && elide_outer_quotes
496 && quoting_style == shell_always_quoting_style)
499 for (j = 1; j < bytes; j++)
500 switch (arg[i + m + j])
502 case '[': case '\\': case '^':
504 goto force_outer_quoting_style;
516 while (! mbsinit (&mbstate));
519 if (1 < m || (backslash_escapes && ! printable))
521 /* Output a multibyte sequence, or an escaped
522 unprintable unibyte character. */
527 if (backslash_escapes && ! printable)
529 if (elide_outer_quotes)
530 goto force_outer_quoting_style;
532 STORE ('0' + (c >> 6));
533 STORE ('0' + ((c >> 3) & 7));
547 if (! ((backslash_escapes || elide_outer_quotes)
549 && quote_these_too[c / INT_BITS] & (1 << (c % INT_BITS))))
553 if (elide_outer_quotes)
554 goto force_outer_quoting_style;
561 if (len == 0 && quoting_style == shell_always_quoting_style
562 && elide_outer_quotes)
563 goto force_outer_quoting_style;
565 if (quote_string && !elide_outer_quotes)
566 for (; *quote_string; quote_string++)
567 STORE (*quote_string);
569 if (len < buffersize)
573 force_outer_quoting_style:
574 /* Don't reuse quote_these_too, since the addition of outer quotes
575 sufficiently quotes the specified characters. */
576 return quotearg_buffer_restyled (buffer, buffersize, arg, argsize,
578 flags & ~QA_ELIDE_OUTER_QUOTES, NULL);
581 /* Place into buffer BUFFER (of size BUFFERSIZE) a quoted version of
582 argument ARG (of size ARGSIZE), using O to control quoting.
583 If O is null, use the default.
584 Terminate the output with a null character, and return the written
585 size of the output, not counting the terminating null.
586 If BUFFERSIZE is too small to store the output string, return the
587 value that would have been returned had BUFFERSIZE been large enough.
588 If ARGSIZE is SIZE_MAX, use the string length of the argument for
591 quotearg_buffer (char *buffer, size_t buffersize,
592 char const *arg, size_t argsize,
593 struct quoting_options const *o)
595 struct quoting_options const *p = o ? o : &default_quoting_options;
597 size_t r = quotearg_buffer_restyled (buffer, buffersize, arg, argsize,
598 p->style, p->flags, p->quote_these_too);
603 /* Equivalent to quotearg_alloc (ARG, ARGSIZE, NULL, O). */
605 quotearg_alloc (char const *arg, size_t argsize,
606 struct quoting_options const *o)
608 return quotearg_alloc_mem (arg, argsize, NULL, o);
611 /* Like quotearg_buffer (..., ARG, ARGSIZE, O), except return newly
612 allocated storage containing the quoted string, and store the
613 resulting size into *SIZE, if non-NULL. The result can contain
614 embedded null bytes only if ARGSIZE is not SIZE_MAX, SIZE is not
615 NULL, and set_quoting_flags has not set the null byte elision
618 quotearg_alloc_mem (char const *arg, size_t argsize, size_t *size,
619 struct quoting_options const *o)
621 struct quoting_options const *p = o ? o : &default_quoting_options;
623 /* Elide embedded null bytes if we can't return a size. */
624 int flags = p->flags | (size ? 0 : QA_ELIDE_NULL_BYTES);
625 size_t bufsize = quotearg_buffer_restyled (0, 0, arg, argsize, p->style,
626 flags, p->quote_these_too) + 1;
627 char *buf = xcharalloc (bufsize);
628 quotearg_buffer_restyled (buf, bufsize, arg, argsize, p->style, flags,
636 /* A storage slot with size and pointer to a value. */
643 /* Preallocate a slot 0 buffer, so that the caller can always quote
644 one small component of a "memory exhausted" message in slot 0. */
645 static char slot0[256];
646 static unsigned int nslots = 1;
647 static struct slotvec slotvec0 = {sizeof slot0, slot0};
648 static struct slotvec *slotvec = &slotvec0;
653 struct slotvec *sv = slotvec;
655 for (i = 1; i < nslots; i++)
657 if (sv[0].val != slot0)
660 slotvec0.size = sizeof slot0;
661 slotvec0.val = slot0;
671 /* Use storage slot N to return a quoted version of argument ARG.
672 ARG is of size ARGSIZE, but if that is SIZE_MAX, ARG is a
673 null-terminated string.
674 OPTIONS specifies the quoting options.
675 The returned value points to static storage that can be
676 reused by the next call to this function with the same value of N.
677 N must be nonnegative. N is deliberately declared with type "int"
678 to allow for future extensions (using negative values). */
680 quotearg_n_options (int n, char const *arg, size_t argsize,
681 struct quoting_options const *options)
686 struct slotvec *sv = slotvec;
693 /* FIXME: technically, the type of n1 should be `unsigned int',
694 but that evokes an unsuppressible warning from gcc-4.0.1 and
695 older. If gcc ever provides an option to suppress that warning,
696 revert to the original type, so that the test in xalloc_oversized
697 is once again performed only at compile time. */
699 bool preallocated = (sv == &slotvec0);
701 if (xalloc_oversized (n1, sizeof *sv))
704 slotvec = sv = xrealloc (preallocated ? NULL : sv, n1 * sizeof *sv);
707 memset (sv + nslots, 0, (n1 - nslots) * sizeof *sv);
712 size_t size = sv[n].size;
713 char *val = sv[n].val;
714 /* Elide embedded null bytes since we don't return a size. */
715 int flags = options->flags | QA_ELIDE_NULL_BYTES;
716 size_t qsize = quotearg_buffer_restyled (val, size, arg, argsize,
717 options->style, flags,
718 options->quote_these_too);
722 sv[n].size = size = qsize + 1;
725 sv[n].val = val = xcharalloc (size);
726 quotearg_buffer_restyled (val, size, arg, argsize, options->style,
727 flags, options->quote_these_too);
736 quotearg_n (int n, char const *arg)
738 return quotearg_n_options (n, arg, SIZE_MAX, &default_quoting_options);
742 quotearg_n_mem (int n, char const *arg, size_t argsize)
744 return quotearg_n_options (n, arg, argsize, &default_quoting_options);
748 quotearg (char const *arg)
750 return quotearg_n (0, arg);
754 quotearg_mem (char const *arg, size_t argsize)
756 return quotearg_n_mem (0, arg, argsize);
760 quotearg_n_style (int n, enum quoting_style s, char const *arg)
762 struct quoting_options const o = quoting_options_from_style (s);
763 return quotearg_n_options (n, arg, SIZE_MAX, &o);
767 quotearg_n_style_mem (int n, enum quoting_style s,
768 char const *arg, size_t argsize)
770 struct quoting_options const o = quoting_options_from_style (s);
771 return quotearg_n_options (n, arg, argsize, &o);
775 quotearg_style (enum quoting_style s, char const *arg)
777 return quotearg_n_style (0, s, arg);
781 quotearg_style_mem (enum quoting_style s, char const *arg, size_t argsize)
783 return quotearg_n_style_mem (0, s, arg, argsize);
787 quotearg_char_mem (char const *arg, size_t argsize, char ch)
789 struct quoting_options options;
790 options = default_quoting_options;
791 set_char_quoting (&options, ch, 1);
792 return quotearg_n_options (0, arg, argsize, &options);
796 quotearg_char (char const *arg, char ch)
798 return quotearg_char_mem (arg, SIZE_MAX, ch);
802 quotearg_colon (char const *arg)
804 return quotearg_char (arg, ':');
808 quotearg_colon_mem (char const *arg, size_t argsize)
810 return quotearg_char_mem (arg, argsize, ':');