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