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