quotearg: fall back to Unicode single quotes in UTF-8 and GB-18030 locales
[gnulib.git] / lib / quotearg.c
1 /* quotearg.c - quote arguments for output
2
3    Copyright (C) 1998-2002, 2004-2012 Free Software Foundation, Inc.
4
5    This program is free software: you can redistribute it and/or modify
6    it under the terms of the GNU General Public License as published by
7    the Free Software Foundation; either version 3 of the License, or
8    (at your option) any later version.
9
10    This program is distributed in the hope that it will be useful,
11    but WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13    GNU General Public License for more details.
14
15    You should have received a copy of the GNU General Public License
16    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
17
18 /* Written by Paul Eggert <eggert@twinsun.com> */
19
20 /* Without this pragma, gcc 4.7.0 20111124 mistakenly suggests that
21    the quoting_options_from_style function might be candidate for
22    attribute 'pure'  */
23 #if (__GNUC__ == 4 && 6 <= __GNUC_MINOR__) || 4 < __GNUC__
24 # pragma GCC diagnostic ignored "-Wsuggest-attribute=pure"
25 #endif
26
27 #include <config.h>
28
29 #include "quotearg.h"
30
31 #include "xalloc.h"
32 #include "c-strcaseeq.h"
33 #include "localcharset.h"
34
35 #include <ctype.h>
36 #include <errno.h>
37 #include <limits.h>
38 #include <stdbool.h>
39 #include <stdlib.h>
40 #include <string.h>
41 #include <wchar.h>
42 #include <wctype.h>
43
44 #include "gettext.h"
45 #define _(msgid) gettext (msgid)
46 #define N_(msgid) msgid
47
48 #ifndef SIZE_MAX
49 # define SIZE_MAX ((size_t) -1)
50 #endif
51
52 #define INT_BITS (sizeof (int) * CHAR_BIT)
53
54 struct quoting_options
55 {
56   /* Basic quoting style.  */
57   enum quoting_style style;
58
59   /* Additional flags.  Bitwise combination of enum quoting_flags.  */
60   int flags;
61
62   /* Quote the characters indicated by this bit vector even if the
63      quoting style would not normally require them to be quoted.  */
64   unsigned int quote_these_too[(UCHAR_MAX / INT_BITS) + 1];
65
66   /* The left quote for custom_quoting_style.  */
67   char const *left_quote;
68
69   /* The right quote for custom_quoting_style.  */
70   char const *right_quote;
71 };
72
73 /* Names of quoting styles.  */
74 char const *const quoting_style_args[] =
75 {
76   "literal",
77   "shell",
78   "shell-always",
79   "c",
80   "c-maybe",
81   "escape",
82   "locale",
83   "clocale",
84   0
85 };
86
87 /* Correspondences to quoting style names.  */
88 enum quoting_style const quoting_style_vals[] =
89 {
90   literal_quoting_style,
91   shell_quoting_style,
92   shell_always_quoting_style,
93   c_quoting_style,
94   c_maybe_quoting_style,
95   escape_quoting_style,
96   locale_quoting_style,
97   clocale_quoting_style
98 };
99
100 /* The default quoting options.  */
101 static struct quoting_options default_quoting_options;
102
103 /* Allocate a new set of quoting options, with contents initially identical
104    to O if O is not null, or to the default if O is null.
105    It is the caller's responsibility to free the result.  */
106 struct quoting_options *
107 clone_quoting_options (struct quoting_options *o)
108 {
109   int e = errno;
110   struct quoting_options *p = xmemdup (o ? o : &default_quoting_options,
111                                        sizeof *o);
112   errno = e;
113   return p;
114 }
115
116 /* Get the value of O's quoting style.  If O is null, use the default.  */
117 enum quoting_style
118 get_quoting_style (struct quoting_options *o)
119 {
120   return (o ? o : &default_quoting_options)->style;
121 }
122
123 /* In O (or in the default if O is null),
124    set the value of the quoting style to S.  */
125 void
126 set_quoting_style (struct quoting_options *o, enum quoting_style s)
127 {
128   (o ? o : &default_quoting_options)->style = s;
129 }
130
131 /* In O (or in the default if O is null),
132    set the value of the quoting options for character C to I.
133    Return the old value.  Currently, the only values defined for I are
134    0 (the default) and 1 (which means to quote the character even if
135    it would not otherwise be quoted).  */
136 int
137 set_char_quoting (struct quoting_options *o, char c, int i)
138 {
139   unsigned char uc = c;
140   unsigned int *p =
141     (o ? o : &default_quoting_options)->quote_these_too + uc / INT_BITS;
142   int shift = uc % INT_BITS;
143   int r = (*p >> shift) & 1;
144   *p ^= ((i & 1) ^ r) << shift;
145   return r;
146 }
147
148 /* In O (or in the default if O is null),
149    set the value of the quoting options flag to I, which can be a
150    bitwise combination of enum quoting_flags, or 0 for default
151    behavior.  Return the old value.  */
152 int
153 set_quoting_flags (struct quoting_options *o, int i)
154 {
155   int r;
156   if (!o)
157     o = &default_quoting_options;
158   r = o->flags;
159   o->flags = i;
160   return r;
161 }
162
163 void
164 set_custom_quoting (struct quoting_options *o,
165                     char const *left_quote, char const *right_quote)
166 {
167   if (!o)
168     o = &default_quoting_options;
169   o->style = custom_quoting_style;
170   if (!left_quote || !right_quote)
171     abort ();
172   o->left_quote = left_quote;
173   o->right_quote = right_quote;
174 }
175
176 /* Return quoting options for STYLE, with no extra quoting.  */
177 static struct quoting_options /* NOT PURE!! */
178 quoting_options_from_style (enum quoting_style style)
179 {
180   struct quoting_options o = { 0 };
181   if (style == custom_quoting_style)
182     abort ();
183   o.style = style;
184   return o;
185 }
186
187 /* MSGID approximates a quotation mark.  Return its translation if it
188    has one; otherwise, return either it or "\"", depending on S.
189
190    S is either clocale_quoting_style or locale_quoting_style.  */
191 static char const *
192 gettext_quote (char const *msgid, enum quoting_style s)
193 {
194   char const *translation = _(msgid);
195   char const *locale_code;
196
197   if (translation != msgid)
198     return translation;
199
200   /* For UTF-8 and GB-18030, use single quotes U+2018 and U+2019.
201      Here is a list of other locales that include U+2018 and U+2019:
202
203         ISO-8859-7   0xA1                 KOI8-T       0x91
204         CP869        0x8B                 CP874        0x91
205         CP932        0x81 0x65            CP936        0xA1 0xAE
206         CP949        0xA1 0xAE            CP950        0xA1 0xA5
207         CP1250       0x91                 CP1251       0x91
208         CP1252       0x91                 CP1253       0x91
209         CP1254       0x91                 CP1255       0x91
210         CP1256       0x91                 CP1257       0x91
211         EUC-JP       0xA1 0xC6            EUC-KR       0xA1 0xAE
212         EUC-TW       0xA1 0xE4            BIG5         0xA1 0xA5
213         BIG5-HKSCS   0xA1 0xA5            EUC-CN       0xA1 0xAE
214         GBK          0xA1 0xAE            Georgian-PS  0x91
215         PT154        0x91
216
217      None of these is still in wide use; using iconv is overkill.  */
218   locale_code = locale_charset ();
219   if (STRCASEEQ (locale_code, "UTF-8", 'U','T','F','-','8',0,0,0,0))
220     return msgid[0] == '`' ? "\xe2\x80\x98": "\xe2\x80\x99";
221   if (STRCASEEQ (locale_code, "GB18030", 'G','B','1','8','0','3','0',0,0))
222     return msgid[0] == '`' ? "\xa1\ae": "\xa1\xaf";
223
224   if (s == clocale_quoting_style)
225     return "\"";
226
227   return translation;
228 }
229
230 /* Place into buffer BUFFER (of size BUFFERSIZE) a quoted version of
231    argument ARG (of size ARGSIZE), using QUOTING_STYLE, FLAGS, and
232    QUOTE_THESE_TOO to control quoting.
233    Terminate the output with a null character, and return the written
234    size of the output, not counting the terminating null.
235    If BUFFERSIZE is too small to store the output string, return the
236    value that would have been returned had BUFFERSIZE been large enough.
237    If ARGSIZE is SIZE_MAX, use the string length of the argument for ARGSIZE.
238
239    This function acts like quotearg_buffer (BUFFER, BUFFERSIZE, ARG,
240    ARGSIZE, O), except it breaks O into its component pieces and is
241    not careful about errno.  */
242
243 static size_t
244 quotearg_buffer_restyled (char *buffer, size_t buffersize,
245                           char const *arg, size_t argsize,
246                           enum quoting_style quoting_style, int flags,
247                           unsigned int const *quote_these_too,
248                           char const *left_quote,
249                           char const *right_quote)
250 {
251   size_t i;
252   size_t len = 0;
253   char const *quote_string = 0;
254   size_t quote_string_len = 0;
255   bool backslash_escapes = false;
256   bool unibyte_locale = MB_CUR_MAX == 1;
257   bool elide_outer_quotes = (flags & QA_ELIDE_OUTER_QUOTES) != 0;
258
259 #define STORE(c) \
260     do \
261       { \
262         if (len < buffersize) \
263           buffer[len] = (c); \
264         len++; \
265       } \
266     while (0)
267
268   switch (quoting_style)
269     {
270     case c_maybe_quoting_style:
271       quoting_style = c_quoting_style;
272       elide_outer_quotes = true;
273       /* Fall through.  */
274     case c_quoting_style:
275       if (!elide_outer_quotes)
276         STORE ('"');
277       backslash_escapes = true;
278       quote_string = "\"";
279       quote_string_len = 1;
280       break;
281
282     case escape_quoting_style:
283       backslash_escapes = true;
284       elide_outer_quotes = false;
285       break;
286
287     case locale_quoting_style:
288     case clocale_quoting_style:
289     case custom_quoting_style:
290       {
291         if (quoting_style != custom_quoting_style)
292           {
293             /* TRANSLATORS:
294                Get translations for open and closing quotation marks.
295                The message catalog should translate "`" to a left
296                quotation mark suitable for the locale, and similarly for
297                "'".  For example, a French Unicode local should translate
298                these to U+00AB (LEFT-POINTING DOUBLE ANGLE
299                QUOTATION MARK), and U+00BB (RIGHT-POINTING DOUBLE ANGLE
300                QUOTATION MARK), respectively.
301
302                If the catalog has no translation, we will try to
303                use Unicode U+2018 (LEFT SINGLE QUOTATION MARK) and
304                Unicode U+2019 (RIGHT SINGLE QUOTATION MARK).  If the
305                current locale is not Unicode, locale_quoting_style
306                will quote `like this', and clocale_quoting_style will
307                quote "like this".  You should always include translations
308                for "`" and "'" even if U+2018 and U+2019 are appropriate
309                for your locale.
310
311                If you don't know what to put here, please see
312                <http://en.wikipedia.org/wiki/Quotation_marks_in_other_languages>
313                and use glyphs suitable for your language.  */
314             left_quote = gettext_quote (N_("`"), quoting_style);
315             right_quote = gettext_quote (N_("'"), quoting_style);
316           }
317         if (!elide_outer_quotes)
318           for (quote_string = left_quote; *quote_string; quote_string++)
319             STORE (*quote_string);
320         backslash_escapes = true;
321         quote_string = right_quote;
322         quote_string_len = strlen (quote_string);
323       }
324       break;
325
326     case shell_quoting_style:
327       quoting_style = shell_always_quoting_style;
328       elide_outer_quotes = true;
329       /* Fall through.  */
330     case shell_always_quoting_style:
331       if (!elide_outer_quotes)
332         STORE ('\'');
333       quote_string = "'";
334       quote_string_len = 1;
335       break;
336
337     case literal_quoting_style:
338       elide_outer_quotes = false;
339       break;
340
341     default:
342       abort ();
343     }
344
345   for (i = 0;  ! (argsize == SIZE_MAX ? arg[i] == '\0' : i == argsize);  i++)
346     {
347       unsigned char c;
348       unsigned char esc;
349       bool is_right_quote = false;
350
351       if (backslash_escapes
352           && quote_string_len
353           && i + quote_string_len <= argsize
354           && memcmp (arg + i, quote_string, quote_string_len) == 0)
355         {
356           if (elide_outer_quotes)
357             goto force_outer_quoting_style;
358           is_right_quote = true;
359         }
360
361       c = arg[i];
362       switch (c)
363         {
364         case '\0':
365           if (backslash_escapes)
366             {
367               if (elide_outer_quotes)
368                 goto force_outer_quoting_style;
369               STORE ('\\');
370               /* If quote_string were to begin with digits, we'd need to
371                  test for the end of the arg as well.  However, it's
372                  hard to imagine any locale that would use digits in
373                  quotes, and set_custom_quoting is documented not to
374                  accept them.  */
375               if (i + 1 < argsize && '0' <= arg[i + 1] && arg[i + 1] <= '9')
376                 {
377                   STORE ('0');
378                   STORE ('0');
379                 }
380               c = '0';
381               /* We don't have to worry that this last '0' will be
382                  backslash-escaped because, again, quote_string should
383                  not start with it and because quote_these_too is
384                  documented as not accepting it.  */
385             }
386           else if (flags & QA_ELIDE_NULL_BYTES)
387             continue;
388           break;
389
390         case '?':
391           switch (quoting_style)
392             {
393             case shell_always_quoting_style:
394               if (elide_outer_quotes)
395                 goto force_outer_quoting_style;
396               break;
397
398             case c_quoting_style:
399               if ((flags & QA_SPLIT_TRIGRAPHS)
400                   && i + 2 < argsize && arg[i + 1] == '?')
401                 switch (arg[i + 2])
402                   {
403                   case '!': case '\'':
404                   case '(': case ')': case '-': case '/':
405                   case '<': case '=': case '>':
406                     /* Escape the second '?' in what would otherwise be
407                        a trigraph.  */
408                     if (elide_outer_quotes)
409                       goto force_outer_quoting_style;
410                     c = arg[i + 2];
411                     i += 2;
412                     STORE ('?');
413                     STORE ('"');
414                     STORE ('"');
415                     STORE ('?');
416                     break;
417
418                   default:
419                     break;
420                   }
421               break;
422
423             default:
424               break;
425             }
426           break;
427
428         case '\a': esc = 'a'; goto c_escape;
429         case '\b': esc = 'b'; goto c_escape;
430         case '\f': esc = 'f'; goto c_escape;
431         case '\n': esc = 'n'; goto c_and_shell_escape;
432         case '\r': esc = 'r'; goto c_and_shell_escape;
433         case '\t': esc = 't'; goto c_and_shell_escape;
434         case '\v': esc = 'v'; goto c_escape;
435         case '\\': esc = c;
436           /* No need to escape the escape if we are trying to elide
437              outer quotes and nothing else is problematic.  */
438           if (backslash_escapes && elide_outer_quotes && quote_string_len)
439             goto store_c;
440
441         c_and_shell_escape:
442           if (quoting_style == shell_always_quoting_style
443               && elide_outer_quotes)
444             goto force_outer_quoting_style;
445           /* Fall through.  */
446         c_escape:
447           if (backslash_escapes)
448             {
449               c = esc;
450               goto store_escape;
451             }
452           break;
453
454         case '{': case '}': /* sometimes special if isolated */
455           if (! (argsize == SIZE_MAX ? arg[1] == '\0' : argsize == 1))
456             break;
457           /* Fall through.  */
458         case '#': case '~':
459           if (i != 0)
460             break;
461           /* Fall through.  */
462         case ' ':
463         case '!': /* special in bash */
464         case '"': case '$': case '&':
465         case '(': case ')': case '*': case ';':
466         case '<':
467         case '=': /* sometimes special in 0th or (with "set -k") later args */
468         case '>': case '[':
469         case '^': /* special in old /bin/sh, e.g. SunOS 4.1.4 */
470         case '`': case '|':
471           /* A shell special character.  In theory, '$' and '`' could
472              be the first bytes of multibyte characters, which means
473              we should check them with mbrtowc, but in practice this
474              doesn't happen so it's not worth worrying about.  */
475           if (quoting_style == shell_always_quoting_style
476               && elide_outer_quotes)
477             goto force_outer_quoting_style;
478           break;
479
480         case '\'':
481           if (quoting_style == shell_always_quoting_style)
482             {
483               if (elide_outer_quotes)
484                 goto force_outer_quoting_style;
485               STORE ('\'');
486               STORE ('\\');
487               STORE ('\'');
488             }
489           break;
490
491         case '%': case '+': case ',': case '-': case '.': case '/':
492         case '0': case '1': case '2': case '3': case '4': case '5':
493         case '6': case '7': case '8': case '9': case ':':
494         case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
495         case 'G': case 'H': case 'I': case 'J': case 'K': case 'L':
496         case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R':
497         case 'S': case 'T': case 'U': case 'V': case 'W': case 'X':
498         case 'Y': case 'Z': case ']': case '_': case 'a': case 'b':
499         case 'c': case 'd': case 'e': case 'f': case 'g': case 'h':
500         case 'i': case 'j': case 'k': case 'l': case 'm': case 'n':
501         case 'o': case 'p': case 'q': case 'r': case 's': case 't':
502         case 'u': case 'v': case 'w': case 'x': case 'y': case 'z':
503           /* These characters don't cause problems, no matter what the
504              quoting style is.  They cannot start multibyte sequences.
505              A digit or a special letter would cause trouble if it
506              appeared at the beginning of quote_string because we'd then
507              escape by prepending a backslash.  However, it's hard to
508              imagine any locale that would use digits or letters as
509              quotes, and set_custom_quoting is documented not to accept
510              them.  Also, a digit or a special letter would cause
511              trouble if it appeared in quote_these_too, but that's also
512              documented as not accepting them.  */
513           break;
514
515         default:
516           /* If we have a multibyte sequence, copy it until we reach
517              its end, find an error, or come back to the initial shift
518              state.  For C-like styles, if the sequence has
519              unprintable characters, escape the whole sequence, since
520              we can't easily escape single characters within it.  */
521           {
522             /* Length of multibyte sequence found so far.  */
523             size_t m;
524
525             bool printable;
526
527             if (unibyte_locale)
528               {
529                 m = 1;
530                 printable = isprint (c) != 0;
531               }
532             else
533               {
534                 mbstate_t mbstate;
535                 memset (&mbstate, 0, sizeof mbstate);
536
537                 m = 0;
538                 printable = true;
539                 if (argsize == SIZE_MAX)
540                   argsize = strlen (arg);
541
542                 do
543                   {
544                     wchar_t w;
545                     size_t bytes = mbrtowc (&w, &arg[i + m],
546                                             argsize - (i + m), &mbstate);
547                     if (bytes == 0)
548                       break;
549                     else if (bytes == (size_t) -1)
550                       {
551                         printable = false;
552                         break;
553                       }
554                     else if (bytes == (size_t) -2)
555                       {
556                         printable = false;
557                         while (i + m < argsize && arg[i + m])
558                           m++;
559                         break;
560                       }
561                     else
562                       {
563                         /* Work around a bug with older shells that "see" a '\'
564                            that is really the 2nd byte of a multibyte character.
565                            In practice the problem is limited to ASCII
566                            chars >= '@' that are shell special chars.  */
567                         if ('[' == 0x5b && elide_outer_quotes
568                             && quoting_style == shell_always_quoting_style)
569                           {
570                             size_t j;
571                             for (j = 1; j < bytes; j++)
572                               switch (arg[i + m + j])
573                                 {
574                                 case '[': case '\\': case '^':
575                                 case '`': case '|':
576                                   goto force_outer_quoting_style;
577
578                                 default:
579                                   break;
580                                 }
581                           }
582
583                         if (! iswprint (w))
584                           printable = false;
585                         m += bytes;
586                       }
587                   }
588                 while (! mbsinit (&mbstate));
589               }
590
591             if (1 < m || (backslash_escapes && ! printable))
592               {
593                 /* Output a multibyte sequence, or an escaped
594                    unprintable unibyte character.  */
595                 size_t ilim = i + m;
596
597                 for (;;)
598                   {
599                     if (backslash_escapes && ! printable)
600                       {
601                         if (elide_outer_quotes)
602                           goto force_outer_quoting_style;
603                         STORE ('\\');
604                         STORE ('0' + (c >> 6));
605                         STORE ('0' + ((c >> 3) & 7));
606                         c = '0' + (c & 7);
607                       }
608                     else if (is_right_quote)
609                       {
610                         STORE ('\\');
611                         is_right_quote = false;
612                       }
613                     if (ilim <= i + 1)
614                       break;
615                     STORE (c);
616                     c = arg[++i];
617                   }
618
619                 goto store_c;
620               }
621           }
622         }
623
624       if (! ((backslash_escapes || elide_outer_quotes)
625              && quote_these_too
626              && quote_these_too[c / INT_BITS] & (1 << (c % INT_BITS)))
627           && !is_right_quote)
628         goto store_c;
629
630     store_escape:
631       if (elide_outer_quotes)
632         goto force_outer_quoting_style;
633       STORE ('\\');
634
635     store_c:
636       STORE (c);
637     }
638
639   if (len == 0 && quoting_style == shell_always_quoting_style
640       && elide_outer_quotes)
641     goto force_outer_quoting_style;
642
643   if (quote_string && !elide_outer_quotes)
644     for (; *quote_string; quote_string++)
645       STORE (*quote_string);
646
647   if (len < buffersize)
648     buffer[len] = '\0';
649   return len;
650
651  force_outer_quoting_style:
652   /* Don't reuse quote_these_too, since the addition of outer quotes
653      sufficiently quotes the specified characters.  */
654   return quotearg_buffer_restyled (buffer, buffersize, arg, argsize,
655                                    quoting_style,
656                                    flags & ~QA_ELIDE_OUTER_QUOTES, NULL,
657                                    left_quote, right_quote);
658 }
659
660 /* Place into buffer BUFFER (of size BUFFERSIZE) a quoted version of
661    argument ARG (of size ARGSIZE), using O to control quoting.
662    If O is null, use the default.
663    Terminate the output with a null character, and return the written
664    size of the output, not counting the terminating null.
665    If BUFFERSIZE is too small to store the output string, return the
666    value that would have been returned had BUFFERSIZE been large enough.
667    If ARGSIZE is SIZE_MAX, use the string length of the argument for
668    ARGSIZE.  */
669 size_t
670 quotearg_buffer (char *buffer, size_t buffersize,
671                  char const *arg, size_t argsize,
672                  struct quoting_options const *o)
673 {
674   struct quoting_options const *p = o ? o : &default_quoting_options;
675   int e = errno;
676   size_t r = quotearg_buffer_restyled (buffer, buffersize, arg, argsize,
677                                        p->style, p->flags, p->quote_these_too,
678                                        p->left_quote, p->right_quote);
679   errno = e;
680   return r;
681 }
682
683 /* Equivalent to quotearg_alloc (ARG, ARGSIZE, NULL, O).  */
684 char *
685 quotearg_alloc (char const *arg, size_t argsize,
686                 struct quoting_options const *o)
687 {
688   return quotearg_alloc_mem (arg, argsize, NULL, o);
689 }
690
691 /* Like quotearg_buffer (..., ARG, ARGSIZE, O), except return newly
692    allocated storage containing the quoted string, and store the
693    resulting size into *SIZE, if non-NULL.  The result can contain
694    embedded null bytes only if ARGSIZE is not SIZE_MAX, SIZE is not
695    NULL, and set_quoting_flags has not set the null byte elision
696    flag.  */
697 char *
698 quotearg_alloc_mem (char const *arg, size_t argsize, size_t *size,
699                     struct quoting_options const *o)
700 {
701   struct quoting_options const *p = o ? o : &default_quoting_options;
702   int e = errno;
703   /* Elide embedded null bytes if we can't return a size.  */
704   int flags = p->flags | (size ? 0 : QA_ELIDE_NULL_BYTES);
705   size_t bufsize = quotearg_buffer_restyled (0, 0, arg, argsize, p->style,
706                                              flags, p->quote_these_too,
707                                              p->left_quote,
708                                              p->right_quote) + 1;
709   char *buf = xcharalloc (bufsize);
710   quotearg_buffer_restyled (buf, bufsize, arg, argsize, p->style, flags,
711                             p->quote_these_too,
712                             p->left_quote, p->right_quote);
713   errno = e;
714   if (size)
715     *size = bufsize - 1;
716   return buf;
717 }
718
719 /* A storage slot with size and pointer to a value.  */
720 struct slotvec
721 {
722   size_t size;
723   char *val;
724 };
725
726 /* Preallocate a slot 0 buffer, so that the caller can always quote
727    one small component of a "memory exhausted" message in slot 0.  */
728 static char slot0[256];
729 static unsigned int nslots = 1;
730 static struct slotvec slotvec0 = {sizeof slot0, slot0};
731 static struct slotvec *slotvec = &slotvec0;
732
733 void
734 quotearg_free (void)
735 {
736   struct slotvec *sv = slotvec;
737   unsigned int i;
738   for (i = 1; i < nslots; i++)
739     free (sv[i].val);
740   if (sv[0].val != slot0)
741     {
742       free (sv[0].val);
743       slotvec0.size = sizeof slot0;
744       slotvec0.val = slot0;
745     }
746   if (sv != &slotvec0)
747     {
748       free (sv);
749       slotvec = &slotvec0;
750     }
751   nslots = 1;
752 }
753
754 /* Use storage slot N to return a quoted version of argument ARG.
755    ARG is of size ARGSIZE, but if that is SIZE_MAX, ARG is a
756    null-terminated string.
757    OPTIONS specifies the quoting options.
758    The returned value points to static storage that can be
759    reused by the next call to this function with the same value of N.
760    N must be nonnegative.  N is deliberately declared with type "int"
761    to allow for future extensions (using negative values).  */
762 static char *
763 quotearg_n_options (int n, char const *arg, size_t argsize,
764                     struct quoting_options const *options)
765 {
766   int e = errno;
767
768   unsigned int n0 = n;
769   struct slotvec *sv = slotvec;
770
771   if (n < 0)
772     abort ();
773
774   if (nslots <= n0)
775     {
776       /* FIXME: technically, the type of n1 should be 'unsigned int',
777          but that evokes an unsuppressible warning from gcc-4.0.1 and
778          older.  If gcc ever provides an option to suppress that warning,
779          revert to the original type, so that the test in xalloc_oversized
780          is once again performed only at compile time.  */
781       size_t n1 = n0 + 1;
782       bool preallocated = (sv == &slotvec0);
783
784       if (xalloc_oversized (n1, sizeof *sv))
785         xalloc_die ();
786
787       slotvec = sv = xrealloc (preallocated ? NULL : sv, n1 * sizeof *sv);
788       if (preallocated)
789         *sv = slotvec0;
790       memset (sv + nslots, 0, (n1 - nslots) * sizeof *sv);
791       nslots = n1;
792     }
793
794   {
795     size_t size = sv[n].size;
796     char *val = sv[n].val;
797     /* Elide embedded null bytes since we don't return a size.  */
798     int flags = options->flags | QA_ELIDE_NULL_BYTES;
799     size_t qsize = quotearg_buffer_restyled (val, size, arg, argsize,
800                                              options->style, flags,
801                                              options->quote_these_too,
802                                              options->left_quote,
803                                              options->right_quote);
804
805     if (size <= qsize)
806       {
807         sv[n].size = size = qsize + 1;
808         if (val != slot0)
809           free (val);
810         sv[n].val = val = xcharalloc (size);
811         quotearg_buffer_restyled (val, size, arg, argsize, options->style,
812                                   flags, options->quote_these_too,
813                                   options->left_quote,
814                                   options->right_quote);
815       }
816
817     errno = e;
818     return val;
819   }
820 }
821
822 char *
823 quotearg_n (int n, char const *arg)
824 {
825   return quotearg_n_options (n, arg, SIZE_MAX, &default_quoting_options);
826 }
827
828 char *
829 quotearg_n_mem (int n, char const *arg, size_t argsize)
830 {
831   return quotearg_n_options (n, arg, argsize, &default_quoting_options);
832 }
833
834 char *
835 quotearg (char const *arg)
836 {
837   return quotearg_n (0, arg);
838 }
839
840 char *
841 quotearg_mem (char const *arg, size_t argsize)
842 {
843   return quotearg_n_mem (0, arg, argsize);
844 }
845
846 char *
847 quotearg_n_style (int n, enum quoting_style s, char const *arg)
848 {
849   struct quoting_options const o = quoting_options_from_style (s);
850   return quotearg_n_options (n, arg, SIZE_MAX, &o);
851 }
852
853 char *
854 quotearg_n_style_mem (int n, enum quoting_style s,
855                       char const *arg, size_t argsize)
856 {
857   struct quoting_options const o = quoting_options_from_style (s);
858   return quotearg_n_options (n, arg, argsize, &o);
859 }
860
861 char *
862 quotearg_style (enum quoting_style s, char const *arg)
863 {
864   return quotearg_n_style (0, s, arg);
865 }
866
867 char *
868 quotearg_style_mem (enum quoting_style s, char const *arg, size_t argsize)
869 {
870   return quotearg_n_style_mem (0, s, arg, argsize);
871 }
872
873 char *
874 quotearg_char_mem (char const *arg, size_t argsize, char ch)
875 {
876   struct quoting_options options;
877   options = default_quoting_options;
878   set_char_quoting (&options, ch, 1);
879   return quotearg_n_options (0, arg, argsize, &options);
880 }
881
882 char *
883 quotearg_char (char const *arg, char ch)
884 {
885   return quotearg_char_mem (arg, SIZE_MAX, ch);
886 }
887
888 char *
889 quotearg_colon (char const *arg)
890 {
891   return quotearg_char (arg, ':');
892 }
893
894 char *
895 quotearg_colon_mem (char const *arg, size_t argsize)
896 {
897   return quotearg_char_mem (arg, argsize, ':');
898 }
899
900 char *
901 quotearg_n_custom (int n, char const *left_quote,
902                    char const *right_quote, char const *arg)
903 {
904   return quotearg_n_custom_mem (n, left_quote, right_quote, arg,
905                                 SIZE_MAX);
906 }
907
908 char *
909 quotearg_n_custom_mem (int n, char const *left_quote,
910                        char const *right_quote,
911                        char const *arg, size_t argsize)
912 {
913   struct quoting_options o = default_quoting_options;
914   set_custom_quoting (&o, left_quote, right_quote);
915   return quotearg_n_options (n, arg, argsize, &o);
916 }
917
918 char *
919 quotearg_custom (char const *left_quote, char const *right_quote,
920                  char const *arg)
921 {
922   return quotearg_n_custom (0, left_quote, right_quote, arg);
923 }
924
925 char *
926 quotearg_custom_mem (char const *left_quote, char const *right_quote,
927                      char const *arg, size_t argsize)
928 {
929   return quotearg_n_custom_mem (0, left_quote, right_quote, arg,
930                                 argsize);
931 }