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