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