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