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