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