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