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