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