termios: fix pid_t always, not just for tcgetsid
[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   return (s == clocale_quoting_style ? "\"" : "'");
225 }
226
227 /* Place into buffer BUFFER (of size BUFFERSIZE) a quoted version of
228    argument ARG (of size ARGSIZE), using QUOTING_STYLE, FLAGS, and
229    QUOTE_THESE_TOO to control quoting.
230    Terminate the output with a null character, and return the written
231    size of the output, not counting the terminating null.
232    If BUFFERSIZE is too small to store the output string, return the
233    value that would have been returned had BUFFERSIZE been large enough.
234    If ARGSIZE is SIZE_MAX, use the string length of the argument for ARGSIZE.
235
236    This function acts like quotearg_buffer (BUFFER, BUFFERSIZE, ARG,
237    ARGSIZE, O), except it breaks O into its component pieces and is
238    not careful about errno.  */
239
240 static size_t
241 quotearg_buffer_restyled (char *buffer, size_t buffersize,
242                           char const *arg, size_t argsize,
243                           enum quoting_style quoting_style, int flags,
244                           unsigned int const *quote_these_too,
245                           char const *left_quote,
246                           char const *right_quote)
247 {
248   size_t i;
249   size_t len = 0;
250   char const *quote_string = 0;
251   size_t quote_string_len = 0;
252   bool backslash_escapes = false;
253   bool unibyte_locale = MB_CUR_MAX == 1;
254   bool elide_outer_quotes = (flags & QA_ELIDE_OUTER_QUOTES) != 0;
255
256 #define STORE(c) \
257     do \
258       { \
259         if (len < buffersize) \
260           buffer[len] = (c); \
261         len++; \
262       } \
263     while (0)
264
265   switch (quoting_style)
266     {
267     case c_maybe_quoting_style:
268       quoting_style = c_quoting_style;
269       elide_outer_quotes = true;
270       /* Fall through.  */
271     case c_quoting_style:
272       if (!elide_outer_quotes)
273         STORE ('"');
274       backslash_escapes = true;
275       quote_string = "\"";
276       quote_string_len = 1;
277       break;
278
279     case escape_quoting_style:
280       backslash_escapes = true;
281       elide_outer_quotes = false;
282       break;
283
284     case locale_quoting_style:
285     case clocale_quoting_style:
286     case custom_quoting_style:
287       {
288         if (quoting_style != custom_quoting_style)
289           {
290             /* TRANSLATORS:
291                Get translations for open and closing quotation marks.
292                The message catalog should translate "`" to a left
293                quotation mark suitable for the locale, and similarly for
294                "'".  For example, a French Unicode local should translate
295                these to U+00AB (LEFT-POINTING DOUBLE ANGLE
296                QUOTATION MARK), and U+00BB (RIGHT-POINTING DOUBLE ANGLE
297                QUOTATION MARK), respectively.
298
299                If the catalog has no translation, we will try to
300                use Unicode U+2018 (LEFT SINGLE QUOTATION MARK) and
301                Unicode U+2019 (RIGHT SINGLE QUOTATION MARK).  If the
302                current locale is not Unicode, locale_quoting_style
303                will quote 'like this', and clocale_quoting_style will
304                quote "like this".  You should always include translations
305                for "`" and "'" even if U+2018 and U+2019 are appropriate
306                for your locale.
307
308                If you don't know what to put here, please see
309                <http://en.wikipedia.org/wiki/Quotation_marks_in_other_languages>
310                and use glyphs suitable for your language.  */
311             left_quote = gettext_quote (N_("`"), quoting_style);
312             right_quote = gettext_quote (N_("'"), quoting_style);
313           }
314         if (!elide_outer_quotes)
315           for (quote_string = left_quote; *quote_string; quote_string++)
316             STORE (*quote_string);
317         backslash_escapes = true;
318         quote_string = right_quote;
319         quote_string_len = strlen (quote_string);
320       }
321       break;
322
323     case shell_quoting_style:
324       quoting_style = shell_always_quoting_style;
325       elide_outer_quotes = true;
326       /* Fall through.  */
327     case shell_always_quoting_style:
328       if (!elide_outer_quotes)
329         STORE ('\'');
330       quote_string = "'";
331       quote_string_len = 1;
332       break;
333
334     case literal_quoting_style:
335       elide_outer_quotes = false;
336       break;
337
338     default:
339       abort ();
340     }
341
342   for (i = 0;  ! (argsize == SIZE_MAX ? arg[i] == '\0' : i == argsize);  i++)
343     {
344       unsigned char c;
345       unsigned char esc;
346       bool is_right_quote = false;
347
348       if (backslash_escapes
349           && quote_string_len
350           && i + quote_string_len <= argsize
351           && memcmp (arg + i, quote_string, quote_string_len) == 0)
352         {
353           if (elide_outer_quotes)
354             goto force_outer_quoting_style;
355           is_right_quote = true;
356         }
357
358       c = arg[i];
359       switch (c)
360         {
361         case '\0':
362           if (backslash_escapes)
363             {
364               if (elide_outer_quotes)
365                 goto force_outer_quoting_style;
366               STORE ('\\');
367               /* If quote_string were to begin with digits, we'd need to
368                  test for the end of the arg as well.  However, it's
369                  hard to imagine any locale that would use digits in
370                  quotes, and set_custom_quoting is documented not to
371                  accept them.  */
372               if (i + 1 < argsize && '0' <= arg[i + 1] && arg[i + 1] <= '9')
373                 {
374                   STORE ('0');
375                   STORE ('0');
376                 }
377               c = '0';
378               /* We don't have to worry that this last '0' will be
379                  backslash-escaped because, again, quote_string should
380                  not start with it and because quote_these_too is
381                  documented as not accepting it.  */
382             }
383           else if (flags & QA_ELIDE_NULL_BYTES)
384             continue;
385           break;
386
387         case '?':
388           switch (quoting_style)
389             {
390             case shell_always_quoting_style:
391               if (elide_outer_quotes)
392                 goto force_outer_quoting_style;
393               break;
394
395             case c_quoting_style:
396               if ((flags & QA_SPLIT_TRIGRAPHS)
397                   && i + 2 < argsize && arg[i + 1] == '?')
398                 switch (arg[i + 2])
399                   {
400                   case '!': case '\'':
401                   case '(': case ')': case '-': case '/':
402                   case '<': case '=': case '>':
403                     /* Escape the second '?' in what would otherwise be
404                        a trigraph.  */
405                     if (elide_outer_quotes)
406                       goto force_outer_quoting_style;
407                     c = arg[i + 2];
408                     i += 2;
409                     STORE ('?');
410                     STORE ('"');
411                     STORE ('"');
412                     STORE ('?');
413                     break;
414
415                   default:
416                     break;
417                   }
418               break;
419
420             default:
421               break;
422             }
423           break;
424
425         case '\a': esc = 'a'; goto c_escape;
426         case '\b': esc = 'b'; goto c_escape;
427         case '\f': esc = 'f'; goto c_escape;
428         case '\n': esc = 'n'; goto c_and_shell_escape;
429         case '\r': esc = 'r'; goto c_and_shell_escape;
430         case '\t': esc = 't'; goto c_and_shell_escape;
431         case '\v': esc = 'v'; goto c_escape;
432         case '\\': esc = c;
433           /* No need to escape the escape if we are trying to elide
434              outer quotes and nothing else is problematic.  */
435           if (backslash_escapes && elide_outer_quotes && quote_string_len)
436             goto store_c;
437
438         c_and_shell_escape:
439           if (quoting_style == shell_always_quoting_style
440               && elide_outer_quotes)
441             goto force_outer_quoting_style;
442           /* Fall through.  */
443         c_escape:
444           if (backslash_escapes)
445             {
446               c = esc;
447               goto store_escape;
448             }
449           break;
450
451         case '{': case '}': /* sometimes special if isolated */
452           if (! (argsize == SIZE_MAX ? arg[1] == '\0' : argsize == 1))
453             break;
454           /* Fall through.  */
455         case '#': case '~':
456           if (i != 0)
457             break;
458           /* Fall through.  */
459         case ' ':
460         case '!': /* special in bash */
461         case '"': case '$': case '&':
462         case '(': case ')': case '*': case ';':
463         case '<':
464         case '=': /* sometimes special in 0th or (with "set -k") later args */
465         case '>': case '[':
466         case '^': /* special in old /bin/sh, e.g. SunOS 4.1.4 */
467         case '`': case '|':
468           /* A shell special character.  In theory, '$' and '`' could
469              be the first bytes of multibyte characters, which means
470              we should check them with mbrtowc, but in practice this
471              doesn't happen so it's not worth worrying about.  */
472           if (quoting_style == shell_always_quoting_style
473               && elide_outer_quotes)
474             goto force_outer_quoting_style;
475           break;
476
477         case '\'':
478           if (quoting_style == shell_always_quoting_style)
479             {
480               if (elide_outer_quotes)
481                 goto force_outer_quoting_style;
482               STORE ('\'');
483               STORE ('\\');
484               STORE ('\'');
485             }
486           break;
487
488         case '%': case '+': case ',': case '-': case '.': case '/':
489         case '0': case '1': case '2': case '3': case '4': case '5':
490         case '6': case '7': case '8': case '9': case ':':
491         case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
492         case 'G': case 'H': case 'I': case 'J': case 'K': case 'L':
493         case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R':
494         case 'S': case 'T': case 'U': case 'V': case 'W': case 'X':
495         case 'Y': case 'Z': case ']': case '_': case 'a': case 'b':
496         case 'c': case 'd': case 'e': case 'f': case 'g': case 'h':
497         case 'i': case 'j': case 'k': case 'l': case 'm': case 'n':
498         case 'o': case 'p': case 'q': case 'r': case 's': case 't':
499         case 'u': case 'v': case 'w': case 'x': case 'y': case 'z':
500           /* These characters don't cause problems, no matter what the
501              quoting style is.  They cannot start multibyte sequences.
502              A digit or a special letter would cause trouble if it
503              appeared at the beginning of quote_string because we'd then
504              escape by prepending a backslash.  However, it's hard to
505              imagine any locale that would use digits or letters as
506              quotes, and set_custom_quoting is documented not to accept
507              them.  Also, a digit or a special letter would cause
508              trouble if it appeared in quote_these_too, but that's also
509              documented as not accepting them.  */
510           break;
511
512         default:
513           /* If we have a multibyte sequence, copy it until we reach
514              its end, find an error, or come back to the initial shift
515              state.  For C-like styles, if the sequence has
516              unprintable characters, escape the whole sequence, since
517              we can't easily escape single characters within it.  */
518           {
519             /* Length of multibyte sequence found so far.  */
520             size_t m;
521
522             bool printable;
523
524             if (unibyte_locale)
525               {
526                 m = 1;
527                 printable = isprint (c) != 0;
528               }
529             else
530               {
531                 mbstate_t mbstate;
532                 memset (&mbstate, 0, sizeof mbstate);
533
534                 m = 0;
535                 printable = true;
536                 if (argsize == SIZE_MAX)
537                   argsize = strlen (arg);
538
539                 do
540                   {
541                     wchar_t w;
542                     size_t bytes = mbrtowc (&w, &arg[i + m],
543                                             argsize - (i + m), &mbstate);
544                     if (bytes == 0)
545                       break;
546                     else if (bytes == (size_t) -1)
547                       {
548                         printable = false;
549                         break;
550                       }
551                     else if (bytes == (size_t) -2)
552                       {
553                         printable = false;
554                         while (i + m < argsize && arg[i + m])
555                           m++;
556                         break;
557                       }
558                     else
559                       {
560                         /* Work around a bug with older shells that "see" a '\'
561                            that is really the 2nd byte of a multibyte character.
562                            In practice the problem is limited to ASCII
563                            chars >= '@' that are shell special chars.  */
564                         if ('[' == 0x5b && elide_outer_quotes
565                             && quoting_style == shell_always_quoting_style)
566                           {
567                             size_t j;
568                             for (j = 1; j < bytes; j++)
569                               switch (arg[i + m + j])
570                                 {
571                                 case '[': case '\\': case '^':
572                                 case '`': case '|':
573                                   goto force_outer_quoting_style;
574
575                                 default:
576                                   break;
577                                 }
578                           }
579
580                         if (! iswprint (w))
581                           printable = false;
582                         m += bytes;
583                       }
584                   }
585                 while (! mbsinit (&mbstate));
586               }
587
588             if (1 < m || (backslash_escapes && ! printable))
589               {
590                 /* Output a multibyte sequence, or an escaped
591                    unprintable unibyte character.  */
592                 size_t ilim = i + m;
593
594                 for (;;)
595                   {
596                     if (backslash_escapes && ! printable)
597                       {
598                         if (elide_outer_quotes)
599                           goto force_outer_quoting_style;
600                         STORE ('\\');
601                         STORE ('0' + (c >> 6));
602                         STORE ('0' + ((c >> 3) & 7));
603                         c = '0' + (c & 7);
604                       }
605                     else if (is_right_quote)
606                       {
607                         STORE ('\\');
608                         is_right_quote = false;
609                       }
610                     if (ilim <= i + 1)
611                       break;
612                     STORE (c);
613                     c = arg[++i];
614                   }
615
616                 goto store_c;
617               }
618           }
619         }
620
621       if (! ((backslash_escapes || elide_outer_quotes)
622              && quote_these_too
623              && quote_these_too[c / INT_BITS] & (1 << (c % INT_BITS)))
624           && !is_right_quote)
625         goto store_c;
626
627     store_escape:
628       if (elide_outer_quotes)
629         goto force_outer_quoting_style;
630       STORE ('\\');
631
632     store_c:
633       STORE (c);
634     }
635
636   if (len == 0 && quoting_style == shell_always_quoting_style
637       && elide_outer_quotes)
638     goto force_outer_quoting_style;
639
640   if (quote_string && !elide_outer_quotes)
641     for (; *quote_string; quote_string++)
642       STORE (*quote_string);
643
644   if (len < buffersize)
645     buffer[len] = '\0';
646   return len;
647
648  force_outer_quoting_style:
649   /* Don't reuse quote_these_too, since the addition of outer quotes
650      sufficiently quotes the specified characters.  */
651   return quotearg_buffer_restyled (buffer, buffersize, arg, argsize,
652                                    quoting_style,
653                                    flags & ~QA_ELIDE_OUTER_QUOTES, NULL,
654                                    left_quote, right_quote);
655 }
656
657 /* Place into buffer BUFFER (of size BUFFERSIZE) a quoted version of
658    argument ARG (of size ARGSIZE), using O to control quoting.
659    If O is null, use the default.
660    Terminate the output with a null character, and return the written
661    size of the output, not counting the terminating null.
662    If BUFFERSIZE is too small to store the output string, return the
663    value that would have been returned had BUFFERSIZE been large enough.
664    If ARGSIZE is SIZE_MAX, use the string length of the argument for
665    ARGSIZE.  */
666 size_t
667 quotearg_buffer (char *buffer, size_t buffersize,
668                  char const *arg, size_t argsize,
669                  struct quoting_options const *o)
670 {
671   struct quoting_options const *p = o ? o : &default_quoting_options;
672   int e = errno;
673   size_t r = quotearg_buffer_restyled (buffer, buffersize, arg, argsize,
674                                        p->style, p->flags, p->quote_these_too,
675                                        p->left_quote, p->right_quote);
676   errno = e;
677   return r;
678 }
679
680 /* Equivalent to quotearg_alloc (ARG, ARGSIZE, NULL, O).  */
681 char *
682 quotearg_alloc (char const *arg, size_t argsize,
683                 struct quoting_options const *o)
684 {
685   return quotearg_alloc_mem (arg, argsize, NULL, o);
686 }
687
688 /* Like quotearg_buffer (..., ARG, ARGSIZE, O), except return newly
689    allocated storage containing the quoted string, and store the
690    resulting size into *SIZE, if non-NULL.  The result can contain
691    embedded null bytes only if ARGSIZE is not SIZE_MAX, SIZE is not
692    NULL, and set_quoting_flags has not set the null byte elision
693    flag.  */
694 char *
695 quotearg_alloc_mem (char const *arg, size_t argsize, size_t *size,
696                     struct quoting_options const *o)
697 {
698   struct quoting_options const *p = o ? o : &default_quoting_options;
699   int e = errno;
700   /* Elide embedded null bytes if we can't return a size.  */
701   int flags = p->flags | (size ? 0 : QA_ELIDE_NULL_BYTES);
702   size_t bufsize = quotearg_buffer_restyled (0, 0, arg, argsize, p->style,
703                                              flags, p->quote_these_too,
704                                              p->left_quote,
705                                              p->right_quote) + 1;
706   char *buf = xcharalloc (bufsize);
707   quotearg_buffer_restyled (buf, bufsize, arg, argsize, p->style, flags,
708                             p->quote_these_too,
709                             p->left_quote, p->right_quote);
710   errno = e;
711   if (size)
712     *size = bufsize - 1;
713   return buf;
714 }
715
716 /* A storage slot with size and pointer to a value.  */
717 struct slotvec
718 {
719   size_t size;
720   char *val;
721 };
722
723 /* Preallocate a slot 0 buffer, so that the caller can always quote
724    one small component of a "memory exhausted" message in slot 0.  */
725 static char slot0[256];
726 static unsigned int nslots = 1;
727 static struct slotvec slotvec0 = {sizeof slot0, slot0};
728 static struct slotvec *slotvec = &slotvec0;
729
730 void
731 quotearg_free (void)
732 {
733   struct slotvec *sv = slotvec;
734   unsigned int i;
735   for (i = 1; i < nslots; i++)
736     free (sv[i].val);
737   if (sv[0].val != slot0)
738     {
739       free (sv[0].val);
740       slotvec0.size = sizeof slot0;
741       slotvec0.val = slot0;
742     }
743   if (sv != &slotvec0)
744     {
745       free (sv);
746       slotvec = &slotvec0;
747     }
748   nslots = 1;
749 }
750
751 /* Use storage slot N to return a quoted version of argument ARG.
752    ARG is of size ARGSIZE, but if that is SIZE_MAX, ARG is a
753    null-terminated string.
754    OPTIONS specifies the quoting options.
755    The returned value points to static storage that can be
756    reused by the next call to this function with the same value of N.
757    N must be nonnegative.  N is deliberately declared with type "int"
758    to allow for future extensions (using negative values).  */
759 static char *
760 quotearg_n_options (int n, char const *arg, size_t argsize,
761                     struct quoting_options const *options)
762 {
763   int e = errno;
764
765   unsigned int n0 = n;
766   struct slotvec *sv = slotvec;
767
768   if (n < 0)
769     abort ();
770
771   if (nslots <= n0)
772     {
773       /* FIXME: technically, the type of n1 should be 'unsigned int',
774          but that evokes an unsuppressible warning from gcc-4.0.1 and
775          older.  If gcc ever provides an option to suppress that warning,
776          revert to the original type, so that the test in xalloc_oversized
777          is once again performed only at compile time.  */
778       size_t n1 = n0 + 1;
779       bool preallocated = (sv == &slotvec0);
780
781       if (xalloc_oversized (n1, sizeof *sv))
782         xalloc_die ();
783
784       slotvec = sv = xrealloc (preallocated ? NULL : sv, n1 * sizeof *sv);
785       if (preallocated)
786         *sv = slotvec0;
787       memset (sv + nslots, 0, (n1 - nslots) * sizeof *sv);
788       nslots = n1;
789     }
790
791   {
792     size_t size = sv[n].size;
793     char *val = sv[n].val;
794     /* Elide embedded null bytes since we don't return a size.  */
795     int flags = options->flags | QA_ELIDE_NULL_BYTES;
796     size_t qsize = quotearg_buffer_restyled (val, size, arg, argsize,
797                                              options->style, flags,
798                                              options->quote_these_too,
799                                              options->left_quote,
800                                              options->right_quote);
801
802     if (size <= qsize)
803       {
804         sv[n].size = size = qsize + 1;
805         if (val != slot0)
806           free (val);
807         sv[n].val = val = xcharalloc (size);
808         quotearg_buffer_restyled (val, size, arg, argsize, options->style,
809                                   flags, options->quote_these_too,
810                                   options->left_quote,
811                                   options->right_quote);
812       }
813
814     errno = e;
815     return val;
816   }
817 }
818
819 char *
820 quotearg_n (int n, char const *arg)
821 {
822   return quotearg_n_options (n, arg, SIZE_MAX, &default_quoting_options);
823 }
824
825 char *
826 quotearg_n_mem (int n, char const *arg, size_t argsize)
827 {
828   return quotearg_n_options (n, arg, argsize, &default_quoting_options);
829 }
830
831 char *
832 quotearg (char const *arg)
833 {
834   return quotearg_n (0, arg);
835 }
836
837 char *
838 quotearg_mem (char const *arg, size_t argsize)
839 {
840   return quotearg_n_mem (0, arg, argsize);
841 }
842
843 char *
844 quotearg_n_style (int n, enum quoting_style s, char const *arg)
845 {
846   struct quoting_options const o = quoting_options_from_style (s);
847   return quotearg_n_options (n, arg, SIZE_MAX, &o);
848 }
849
850 char *
851 quotearg_n_style_mem (int n, enum quoting_style s,
852                       char const *arg, size_t argsize)
853 {
854   struct quoting_options const o = quoting_options_from_style (s);
855   return quotearg_n_options (n, arg, argsize, &o);
856 }
857
858 char *
859 quotearg_style (enum quoting_style s, char const *arg)
860 {
861   return quotearg_n_style (0, s, arg);
862 }
863
864 char *
865 quotearg_style_mem (enum quoting_style s, char const *arg, size_t argsize)
866 {
867   return quotearg_n_style_mem (0, s, arg, argsize);
868 }
869
870 char *
871 quotearg_char_mem (char const *arg, size_t argsize, char ch)
872 {
873   struct quoting_options options;
874   options = default_quoting_options;
875   set_char_quoting (&options, ch, 1);
876   return quotearg_n_options (0, arg, argsize, &options);
877 }
878
879 char *
880 quotearg_char (char const *arg, char ch)
881 {
882   return quotearg_char_mem (arg, SIZE_MAX, ch);
883 }
884
885 char *
886 quotearg_colon (char const *arg)
887 {
888   return quotearg_char (arg, ':');
889 }
890
891 char *
892 quotearg_colon_mem (char const *arg, size_t argsize)
893 {
894   return quotearg_char_mem (arg, argsize, ':');
895 }
896
897 char *
898 quotearg_n_custom (int n, char const *left_quote,
899                    char const *right_quote, char const *arg)
900 {
901   return quotearg_n_custom_mem (n, left_quote, right_quote, arg,
902                                 SIZE_MAX);
903 }
904
905 char *
906 quotearg_n_custom_mem (int n, char const *left_quote,
907                        char const *right_quote,
908                        char const *arg, size_t argsize)
909 {
910   struct quoting_options o = default_quoting_options;
911   set_custom_quoting (&o, left_quote, right_quote);
912   return quotearg_n_options (n, arg, argsize, &o);
913 }
914
915 char *
916 quotearg_custom (char const *left_quote, char const *right_quote,
917                  char const *arg)
918 {
919   return quotearg_n_custom (0, left_quote, right_quote, arg);
920 }
921
922 char *
923 quotearg_custom_mem (char const *left_quote, char const *right_quote,
924                      char const *arg, size_t argsize)
925 {
926   return quotearg_n_custom_mem (0, left_quote, right_quote, arg,
927                                 argsize);
928 }