1 /* -*- buffer-read-only: t -*- vi: set ro: */
2 /* DO NOT EDIT! GENERATED AUTOMATICALLY! */
3 /* quotearg.c - quote arguments for output
5 Copyright (C) 1998, 1999, 2000, 2001, 2002, 2004, 2005, 2006, 2007, 2008,
6 2009, 2010 Free Software Foundation, Inc.
8 This program is free software: you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program. If not, see <http://www.gnu.org/licenses/>. */
21 /* Written by Paul Eggert <eggert@twinsun.com> */
39 #define _(msgid) gettext (msgid)
40 #define N_(msgid) msgid
43 # define SIZE_MAX ((size_t) -1)
46 #define INT_BITS (sizeof (int) * CHAR_BIT)
48 struct quoting_options
50 /* Basic quoting style. */
51 enum quoting_style style;
53 /* Additional flags. Bitwise combination of enum quoting_flags. */
56 /* Quote the characters indicated by this bit vector even if the
57 quoting style would not normally require them to be quoted. */
58 unsigned int quote_these_too[(UCHAR_MAX / INT_BITS) + 1];
60 /* The left quote for custom_quoting_style. */
61 char const *left_quote;
63 /* The right quote for custom_quoting_style. */
64 char const *right_quote;
67 /* Names of quoting styles. */
68 char const *const quoting_style_args[] =
81 /* Correspondences to quoting style names. */
82 enum quoting_style const quoting_style_vals[] =
84 literal_quoting_style,
86 shell_always_quoting_style,
88 c_maybe_quoting_style,
94 /* The default quoting options. */
95 static struct quoting_options default_quoting_options;
97 /* Allocate a new set of quoting options, with contents initially identical
98 to O if O is not null, or to the default if O is null.
99 It is the caller's responsibility to free the result. */
100 struct quoting_options *
101 clone_quoting_options (struct quoting_options *o)
104 struct quoting_options *p = xmemdup (o ? o : &default_quoting_options,
110 /* Get the value of O's quoting style. If O is null, use the default. */
112 get_quoting_style (struct quoting_options *o)
114 return (o ? o : &default_quoting_options)->style;
117 /* In O (or in the default if O is null),
118 set the value of the quoting style to S. */
120 set_quoting_style (struct quoting_options *o, enum quoting_style s)
122 (o ? o : &default_quoting_options)->style = s;
125 /* In O (or in the default if O is null),
126 set the value of the quoting options for character C to I.
127 Return the old value. Currently, the only values defined for I are
128 0 (the default) and 1 (which means to quote the character even if
129 it would not otherwise be quoted). */
131 set_char_quoting (struct quoting_options *o, char c, int i)
133 unsigned char uc = c;
135 (o ? o : &default_quoting_options)->quote_these_too + uc / INT_BITS;
136 int shift = uc % INT_BITS;
137 int r = (*p >> shift) & 1;
138 *p ^= ((i & 1) ^ r) << shift;
142 /* In O (or in the default if O is null),
143 set the value of the quoting options flag to I, which can be a
144 bitwise combination of enum quoting_flags, or 0 for default
145 behavior. Return the old value. */
147 set_quoting_flags (struct quoting_options *o, int i)
151 o = &default_quoting_options;
158 set_custom_quoting (struct quoting_options *o,
159 char const *left_quote, char const *right_quote)
162 o = &default_quoting_options;
163 o->style = custom_quoting_style;
164 if (!left_quote || !right_quote)
166 o->left_quote = left_quote;
167 o->right_quote = right_quote;
170 /* Return quoting options for STYLE, with no extra quoting. */
171 static struct quoting_options
172 quoting_options_from_style (enum quoting_style style)
174 struct quoting_options o;
177 memset (o.quote_these_too, 0, sizeof o.quote_these_too);
181 /* MSGID approximates a quotation mark. Return its translation if it
182 has one; otherwise, return either it or "\"", depending on S. */
184 gettext_quote (char const *msgid, enum quoting_style s)
186 char const *translation = _(msgid);
187 if (translation == msgid && s == clocale_quoting_style)
192 /* Place into buffer BUFFER (of size BUFFERSIZE) a quoted version of
193 argument ARG (of size ARGSIZE), using QUOTING_STYLE, FLAGS, and
194 QUOTE_THESE_TOO to control quoting.
195 Terminate the output with a null character, and return the written
196 size of the output, not counting the terminating null.
197 If BUFFERSIZE is too small to store the output string, return the
198 value that would have been returned had BUFFERSIZE been large enough.
199 If ARGSIZE is SIZE_MAX, use the string length of the argument for ARGSIZE.
201 This function acts like quotearg_buffer (BUFFER, BUFFERSIZE, ARG,
202 ARGSIZE, O), except it breaks O into its component pieces and is
203 not careful about errno. */
206 quotearg_buffer_restyled (char *buffer, size_t buffersize,
207 char const *arg, size_t argsize,
208 enum quoting_style quoting_style, int flags,
209 unsigned int const *quote_these_too,
210 char const *left_quote,
211 char const *right_quote)
215 char const *quote_string = 0;
216 size_t quote_string_len = 0;
217 bool backslash_escapes = false;
218 bool unibyte_locale = MB_CUR_MAX == 1;
219 bool elide_outer_quotes = (flags & QA_ELIDE_OUTER_QUOTES) != 0;
224 if (len < buffersize) \
230 switch (quoting_style)
232 case c_maybe_quoting_style:
233 quoting_style = c_quoting_style;
234 elide_outer_quotes = true;
236 case c_quoting_style:
237 if (!elide_outer_quotes)
239 backslash_escapes = true;
241 quote_string_len = 1;
244 case escape_quoting_style:
245 backslash_escapes = true;
246 elide_outer_quotes = false;
249 case locale_quoting_style:
250 case clocale_quoting_style:
251 case custom_quoting_style:
253 if (quoting_style != custom_quoting_style)
256 Get translations for open and closing quotation marks.
258 The message catalog should translate "`" to a left
259 quotation mark suitable for the locale, and similarly for
260 "'". If the catalog has no translation,
261 locale_quoting_style quotes `like this', and
262 clocale_quoting_style quotes "like this".
264 For example, an American English Unicode locale should
265 translate "`" to U+201C (LEFT DOUBLE QUOTATION MARK), and
266 should translate "'" to U+201D (RIGHT DOUBLE QUOTATION
267 MARK). A British English Unicode locale should instead
268 translate these to U+2018 (LEFT SINGLE QUOTATION MARK)
269 and U+2019 (RIGHT SINGLE QUOTATION MARK), respectively.
271 If you don't know what to put here, please see
272 <http://en.wikipedia.org/wiki/Quotation_mark#Glyphs>
273 and use glyphs suitable for your language. */
274 left_quote = gettext_quote (N_("`"), quoting_style);
275 right_quote = gettext_quote (N_("'"), quoting_style);
277 if (!elide_outer_quotes)
278 for (quote_string = left_quote; *quote_string; quote_string++)
279 STORE (*quote_string);
280 backslash_escapes = true;
281 quote_string = right_quote;
282 quote_string_len = strlen (quote_string);
286 case shell_quoting_style:
287 quoting_style = shell_always_quoting_style;
288 elide_outer_quotes = true;
290 case shell_always_quoting_style:
291 if (!elide_outer_quotes)
294 quote_string_len = 1;
297 case literal_quoting_style:
298 elide_outer_quotes = false;
305 for (i = 0; ! (argsize == SIZE_MAX ? arg[i] == '\0' : i == argsize); i++)
309 bool is_right_quote = false;
311 if (backslash_escapes
313 && i + quote_string_len <= argsize
314 && memcmp (arg + i, quote_string, quote_string_len) == 0)
316 if (elide_outer_quotes)
317 goto force_outer_quoting_style;
318 is_right_quote = true;
325 if (backslash_escapes)
327 if (elide_outer_quotes)
328 goto force_outer_quoting_style;
330 /* If quote_string were to begin with digits, we'd need to
331 test for the end of the arg as well. However, it's
332 hard to imagine any locale that would use digits in
333 quotes, and set_custom_quoting is documented not to
335 if (i + 1 < argsize && '0' <= arg[i + 1] && arg[i + 1] <= '9')
341 /* We don't have to worry that this last '0' will be
342 backslash-escaped because, again, quote_string should
343 not start with it and because quote_these_too is
344 documented as not accepting it. */
346 else if (flags & QA_ELIDE_NULL_BYTES)
351 switch (quoting_style)
353 case shell_always_quoting_style:
354 if (elide_outer_quotes)
355 goto force_outer_quoting_style;
358 case c_quoting_style:
359 if ((flags & QA_SPLIT_TRIGRAPHS)
360 && i + 2 < argsize && arg[i + 1] == '?')
364 case '(': case ')': case '-': case '/':
365 case '<': case '=': case '>':
366 /* Escape the second '?' in what would otherwise be
368 if (elide_outer_quotes)
369 goto force_outer_quoting_style;
388 case '\a': esc = 'a'; goto c_escape;
389 case '\b': esc = 'b'; goto c_escape;
390 case '\f': esc = 'f'; goto c_escape;
391 case '\n': esc = 'n'; goto c_and_shell_escape;
392 case '\r': esc = 'r'; goto c_and_shell_escape;
393 case '\t': esc = 't'; goto c_and_shell_escape;
394 case '\v': esc = 'v'; goto c_escape;
396 /* No need to escape the escape if we are trying to elide
397 outer quotes and nothing else is problematic. */
398 if (backslash_escapes && elide_outer_quotes && quote_string_len)
402 if (quoting_style == shell_always_quoting_style
403 && elide_outer_quotes)
404 goto force_outer_quoting_style;
407 if (backslash_escapes)
414 case '{': case '}': /* sometimes special if isolated */
415 if (! (argsize == SIZE_MAX ? arg[1] == '\0' : argsize == 1))
423 case '!': /* special in bash */
424 case '"': case '$': case '&':
425 case '(': case ')': case '*': case ';':
427 case '=': /* sometimes special in 0th or (with "set -k") later args */
429 case '^': /* special in old /bin/sh, e.g. SunOS 4.1.4 */
431 /* A shell special character. In theory, '$' and '`' could
432 be the first bytes of multibyte characters, which means
433 we should check them with mbrtowc, but in practice this
434 doesn't happen so it's not worth worrying about. */
435 if (quoting_style == shell_always_quoting_style
436 && elide_outer_quotes)
437 goto force_outer_quoting_style;
441 if (quoting_style == shell_always_quoting_style)
443 if (elide_outer_quotes)
444 goto force_outer_quoting_style;
451 case '%': case '+': case ',': case '-': case '.': case '/':
452 case '0': case '1': case '2': case '3': case '4': case '5':
453 case '6': case '7': case '8': case '9': case ':':
454 case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
455 case 'G': case 'H': case 'I': case 'J': case 'K': case 'L':
456 case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R':
457 case 'S': case 'T': case 'U': case 'V': case 'W': case 'X':
458 case 'Y': case 'Z': case ']': case '_': case 'a': case 'b':
459 case 'c': case 'd': case 'e': case 'f': case 'g': case 'h':
460 case 'i': case 'j': case 'k': case 'l': case 'm': case 'n':
461 case 'o': case 'p': case 'q': case 'r': case 's': case 't':
462 case 'u': case 'v': case 'w': case 'x': case 'y': case 'z':
463 /* These characters don't cause problems, no matter what the
464 quoting style is. They cannot start multibyte sequences.
465 A digit or a special letter would cause trouble if it
466 appeared at the beginning of quote_string because we'd then
467 escape by prepending a backslash. However, it's hard to
468 imagine any locale that would use digits or letters as
469 quotes, and set_custom_quoting is documented not to accept
470 them. Also, a digit or a special letter would cause
471 trouble if it appeared in quote_these_too, but that's also
472 documented as not accepting them. */
476 /* If we have a multibyte sequence, copy it until we reach
477 its end, find an error, or come back to the initial shift
478 state. For C-like styles, if the sequence has
479 unprintable characters, escape the whole sequence, since
480 we can't easily escape single characters within it. */
482 /* Length of multibyte sequence found so far. */
490 printable = isprint (c) != 0;
495 memset (&mbstate, 0, sizeof mbstate);
499 if (argsize == SIZE_MAX)
500 argsize = strlen (arg);
505 size_t bytes = mbrtowc (&w, &arg[i + m],
506 argsize - (i + m), &mbstate);
509 else if (bytes == (size_t) -1)
514 else if (bytes == (size_t) -2)
517 while (i + m < argsize && arg[i + m])
523 /* Work around a bug with older shells that "see" a '\'
524 that is really the 2nd byte of a multibyte character.
525 In practice the problem is limited to ASCII
526 chars >= '@' that are shell special chars. */
527 if ('[' == 0x5b && elide_outer_quotes
528 && quoting_style == shell_always_quoting_style)
531 for (j = 1; j < bytes; j++)
532 switch (arg[i + m + j])
534 case '[': case '\\': case '^':
536 goto force_outer_quoting_style;
548 while (! mbsinit (&mbstate));
551 if (1 < m || (backslash_escapes && ! printable))
553 /* Output a multibyte sequence, or an escaped
554 unprintable unibyte character. */
559 if (backslash_escapes && ! printable)
561 if (elide_outer_quotes)
562 goto force_outer_quoting_style;
564 STORE ('0' + (c >> 6));
565 STORE ('0' + ((c >> 3) & 7));
568 else if (is_right_quote)
571 is_right_quote = false;
584 if (! ((backslash_escapes || elide_outer_quotes)
586 && quote_these_too[c / INT_BITS] & (1 << (c % INT_BITS)))
591 if (elide_outer_quotes)
592 goto force_outer_quoting_style;
599 if (len == 0 && quoting_style == shell_always_quoting_style
600 && elide_outer_quotes)
601 goto force_outer_quoting_style;
603 if (quote_string && !elide_outer_quotes)
604 for (; *quote_string; quote_string++)
605 STORE (*quote_string);
607 if (len < buffersize)
611 force_outer_quoting_style:
612 /* Don't reuse quote_these_too, since the addition of outer quotes
613 sufficiently quotes the specified characters. */
614 return quotearg_buffer_restyled (buffer, buffersize, arg, argsize,
616 flags & ~QA_ELIDE_OUTER_QUOTES, NULL,
617 left_quote, right_quote);
620 /* Place into buffer BUFFER (of size BUFFERSIZE) a quoted version of
621 argument ARG (of size ARGSIZE), using O to control quoting.
622 If O is null, use the default.
623 Terminate the output with a null character, and return the written
624 size of the output, not counting the terminating null.
625 If BUFFERSIZE is too small to store the output string, return the
626 value that would have been returned had BUFFERSIZE been large enough.
627 If ARGSIZE is SIZE_MAX, use the string length of the argument for
630 quotearg_buffer (char *buffer, size_t buffersize,
631 char const *arg, size_t argsize,
632 struct quoting_options const *o)
634 struct quoting_options const *p = o ? o : &default_quoting_options;
636 size_t r = quotearg_buffer_restyled (buffer, buffersize, arg, argsize,
637 p->style, p->flags, p->quote_these_too,
638 p->left_quote, p->right_quote);
643 /* Equivalent to quotearg_alloc (ARG, ARGSIZE, NULL, O). */
645 quotearg_alloc (char const *arg, size_t argsize,
646 struct quoting_options const *o)
648 return quotearg_alloc_mem (arg, argsize, NULL, o);
651 /* Like quotearg_buffer (..., ARG, ARGSIZE, O), except return newly
652 allocated storage containing the quoted string, and store the
653 resulting size into *SIZE, if non-NULL. The result can contain
654 embedded null bytes only if ARGSIZE is not SIZE_MAX, SIZE is not
655 NULL, and set_quoting_flags has not set the null byte elision
658 quotearg_alloc_mem (char const *arg, size_t argsize, size_t *size,
659 struct quoting_options const *o)
661 struct quoting_options const *p = o ? o : &default_quoting_options;
663 /* Elide embedded null bytes if we can't return a size. */
664 int flags = p->flags | (size ? 0 : QA_ELIDE_NULL_BYTES);
665 size_t bufsize = quotearg_buffer_restyled (0, 0, arg, argsize, p->style,
666 flags, p->quote_these_too,
669 char *buf = xcharalloc (bufsize);
670 quotearg_buffer_restyled (buf, bufsize, arg, argsize, p->style, flags,
672 p->left_quote, p->right_quote);
679 /* A storage slot with size and pointer to a value. */
686 /* Preallocate a slot 0 buffer, so that the caller can always quote
687 one small component of a "memory exhausted" message in slot 0. */
688 static char slot0[256];
689 static unsigned int nslots = 1;
690 static struct slotvec slotvec0 = {sizeof slot0, slot0};
691 static struct slotvec *slotvec = &slotvec0;
696 struct slotvec *sv = slotvec;
698 for (i = 1; i < nslots; i++)
700 if (sv[0].val != slot0)
703 slotvec0.size = sizeof slot0;
704 slotvec0.val = slot0;
714 /* Use storage slot N to return a quoted version of argument ARG.
715 ARG is of size ARGSIZE, but if that is SIZE_MAX, ARG is a
716 null-terminated string.
717 OPTIONS specifies the quoting options.
718 The returned value points to static storage that can be
719 reused by the next call to this function with the same value of N.
720 N must be nonnegative. N is deliberately declared with type "int"
721 to allow for future extensions (using negative values). */
723 quotearg_n_options (int n, char const *arg, size_t argsize,
724 struct quoting_options const *options)
729 struct slotvec *sv = slotvec;
736 /* FIXME: technically, the type of n1 should be `unsigned int',
737 but that evokes an unsuppressible warning from gcc-4.0.1 and
738 older. If gcc ever provides an option to suppress that warning,
739 revert to the original type, so that the test in xalloc_oversized
740 is once again performed only at compile time. */
742 bool preallocated = (sv == &slotvec0);
744 if (xalloc_oversized (n1, sizeof *sv))
747 slotvec = sv = xrealloc (preallocated ? NULL : sv, n1 * sizeof *sv);
750 memset (sv + nslots, 0, (n1 - nslots) * sizeof *sv);
755 size_t size = sv[n].size;
756 char *val = sv[n].val;
757 /* Elide embedded null bytes since we don't return a size. */
758 int flags = options->flags | QA_ELIDE_NULL_BYTES;
759 size_t qsize = quotearg_buffer_restyled (val, size, arg, argsize,
760 options->style, flags,
761 options->quote_these_too,
763 options->right_quote);
767 sv[n].size = size = qsize + 1;
770 sv[n].val = val = xcharalloc (size);
771 quotearg_buffer_restyled (val, size, arg, argsize, options->style,
772 flags, options->quote_these_too,
774 options->right_quote);
783 quotearg_n (int n, char const *arg)
785 return quotearg_n_options (n, arg, SIZE_MAX, &default_quoting_options);
789 quotearg_n_mem (int n, char const *arg, size_t argsize)
791 return quotearg_n_options (n, arg, argsize, &default_quoting_options);
795 quotearg (char const *arg)
797 return quotearg_n (0, arg);
801 quotearg_mem (char const *arg, size_t argsize)
803 return quotearg_n_mem (0, arg, argsize);
807 quotearg_n_style (int n, enum quoting_style s, char const *arg)
809 struct quoting_options const o = quoting_options_from_style (s);
810 return quotearg_n_options (n, arg, SIZE_MAX, &o);
814 quotearg_n_style_mem (int n, enum quoting_style s,
815 char const *arg, size_t argsize)
817 struct quoting_options const o = quoting_options_from_style (s);
818 return quotearg_n_options (n, arg, argsize, &o);
822 quotearg_style (enum quoting_style s, char const *arg)
824 return quotearg_n_style (0, s, arg);
828 quotearg_style_mem (enum quoting_style s, char const *arg, size_t argsize)
830 return quotearg_n_style_mem (0, s, arg, argsize);
834 quotearg_char_mem (char const *arg, size_t argsize, char ch)
836 struct quoting_options options;
837 options = default_quoting_options;
838 set_char_quoting (&options, ch, 1);
839 return quotearg_n_options (0, arg, argsize, &options);
843 quotearg_char (char const *arg, char ch)
845 return quotearg_char_mem (arg, SIZE_MAX, ch);
849 quotearg_colon (char const *arg)
851 return quotearg_char (arg, ':');
855 quotearg_colon_mem (char const *arg, size_t argsize)
857 return quotearg_char_mem (arg, argsize, ':');
861 quotearg_n_custom (int n, char const *left_quote,
862 char const *right_quote, char const *arg)
864 return quotearg_n_custom_mem (n, left_quote, right_quote, arg,
869 quotearg_n_custom_mem (int n, char const *left_quote,
870 char const *right_quote,
871 char const *arg, size_t argsize)
873 struct quoting_options o = default_quoting_options;
874 set_custom_quoting (&o, left_quote, right_quote);
875 return quotearg_n_options (n, arg, argsize, &o);
879 quotearg_custom (char const *left_quote, char const *right_quote,
882 return quotearg_n_custom (0, left_quote, right_quote, arg);
886 quotearg_custom_mem (char const *left_quote, char const *right_quote,
887 char const *arg, size_t argsize)
889 return quotearg_n_custom_mem (0, left_quote, right_quote, arg,