Quotearg part 4: add tests, fix c-maybe colon quoting.
[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 /* 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 *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 (i + 2 < argsize && arg[i + 1] == '?')
341                 switch (arg[i + 2])
342                   {
343                   case '!': case '\'':
344                   case '(': case ')': case '-': case '/':
345                   case '<': case '=': case '>':
346                     /* Escape the second '?' in what would otherwise be
347                        a trigraph.  */
348                     if (elide_outer_quotes)
349                       goto force_outer_quoting_style;
350                     c = arg[i + 2];
351                     i += 2;
352                     STORE ('?');
353                     STORE ('"');
354                     STORE ('"');
355                     STORE ('?');
356                     break;
357
358                   default:
359                     break;
360                   }
361               break;
362
363             default:
364               break;
365             }
366           break;
367
368         case '\a': esc = 'a'; goto c_escape;
369         case '\b': esc = 'b'; goto c_escape;
370         case '\f': esc = 'f'; goto c_escape;
371         case '\n': esc = 'n'; goto c_and_shell_escape;
372         case '\r': esc = 'r'; goto c_and_shell_escape;
373         case '\t': esc = 't'; goto c_and_shell_escape;
374         case '\v': esc = 'v'; goto c_escape;
375         case '\\': esc = c; goto c_and_shell_escape;
376
377         c_and_shell_escape:
378           if (quoting_style == shell_always_quoting_style
379               && elide_outer_quotes)
380             goto force_outer_quoting_style;
381           /* Fall through.  */
382         c_escape:
383           if (backslash_escapes)
384             {
385               c = esc;
386               goto store_escape;
387             }
388           break;
389
390         case '{': case '}': /* sometimes special if isolated */
391           if (! (argsize == SIZE_MAX ? arg[1] == '\0' : argsize == 1))
392             break;
393           /* Fall through.  */
394         case '#': case '~':
395           if (i != 0)
396             break;
397           /* Fall through.  */
398         case ' ':
399         case '!': /* special in bash */
400         case '"': case '$': case '&':
401         case '(': case ')': case '*': case ';':
402         case '<':
403         case '=': /* sometimes special in 0th or (with "set -k") later args */
404         case '>': case '[':
405         case '^': /* special in old /bin/sh, e.g. SunOS 4.1.4 */
406         case '`': case '|':
407           /* A shell special character.  In theory, '$' and '`' could
408              be the first bytes of multibyte characters, which means
409              we should check them with mbrtowc, but in practice this
410              doesn't happen so it's not worth worrying about.  */
411           if (quoting_style == shell_always_quoting_style
412               && elide_outer_quotes)
413             goto force_outer_quoting_style;
414           break;
415
416         case '\'':
417           if (quoting_style == shell_always_quoting_style)
418             {
419               if (elide_outer_quotes)
420                 goto force_outer_quoting_style;
421               STORE ('\'');
422               STORE ('\\');
423               STORE ('\'');
424             }
425           break;
426
427         case '%': case '+': case ',': case '-': case '.': case '/':
428         case '0': case '1': case '2': case '3': case '4': case '5':
429         case '6': case '7': case '8': case '9': case ':':
430         case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
431         case 'G': case 'H': case 'I': case 'J': case 'K': case 'L':
432         case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R':
433         case 'S': case 'T': case 'U': case 'V': case 'W': case 'X':
434         case 'Y': case 'Z': case ']': case '_': case 'a': case 'b':
435         case 'c': case 'd': case 'e': case 'f': case 'g': case 'h':
436         case 'i': case 'j': case 'k': case 'l': case 'm': case 'n':
437         case 'o': case 'p': case 'q': case 'r': case 's': case 't':
438         case 'u': case 'v': case 'w': case 'x': case 'y': case 'z':
439           /* These characters don't cause problems, no matter what the
440              quoting style is.  They cannot start multibyte sequences.  */
441           break;
442
443         default:
444           /* If we have a multibyte sequence, copy it until we reach
445              its end, find an error, or come back to the initial shift
446              state.  For C-like styles, if the sequence has
447              unprintable characters, escape the whole sequence, since
448              we can't easily escape single characters within it.  */
449           {
450             /* Length of multibyte sequence found so far.  */
451             size_t m;
452
453             bool printable;
454
455             if (unibyte_locale)
456               {
457                 m = 1;
458                 printable = isprint (c) != 0;
459               }
460             else
461               {
462                 mbstate_t mbstate;
463                 memset (&mbstate, 0, sizeof mbstate);
464
465                 m = 0;
466                 printable = true;
467                 if (argsize == SIZE_MAX)
468                   argsize = strlen (arg);
469
470                 do
471                   {
472                     wchar_t w;
473                     size_t bytes = mbrtowc (&w, &arg[i + m],
474                                             argsize - (i + m), &mbstate);
475                     if (bytes == 0)
476                       break;
477                     else if (bytes == (size_t) -1)
478                       {
479                         printable = false;
480                         break;
481                       }
482                     else if (bytes == (size_t) -2)
483                       {
484                         printable = false;
485                         while (i + m < argsize && arg[i + m])
486                           m++;
487                         break;
488                       }
489                     else
490                       {
491                         /* Work around a bug with older shells that "see" a '\'
492                            that is really the 2nd byte of a multibyte character.
493                            In practice the problem is limited to ASCII
494                            chars >= '@' that are shell special chars.  */
495                         if ('[' == 0x5b && elide_outer_quotes
496                             && quoting_style == shell_always_quoting_style)
497                           {
498                             size_t j;
499                             for (j = 1; j < bytes; j++)
500                               switch (arg[i + m + j])
501                                 {
502                                 case '[': case '\\': case '^':
503                                 case '`': case '|':
504                                   goto force_outer_quoting_style;
505
506                                 default:
507                                   break;
508                                 }
509                           }
510
511                         if (! iswprint (w))
512                           printable = false;
513                         m += bytes;
514                       }
515                   }
516                 while (! mbsinit (&mbstate));
517               }
518
519             if (1 < m || (backslash_escapes && ! printable))
520               {
521                 /* Output a multibyte sequence, or an escaped
522                    unprintable unibyte character.  */
523                 size_t ilim = i + m;
524
525                 for (;;)
526                   {
527                     if (backslash_escapes && ! printable)
528                       {
529                         if (elide_outer_quotes)
530                           goto force_outer_quoting_style;
531                         STORE ('\\');
532                         STORE ('0' + (c >> 6));
533                         STORE ('0' + ((c >> 3) & 7));
534                         c = '0' + (c & 7);
535                       }
536                     if (ilim <= i + 1)
537                       break;
538                     STORE (c);
539                     c = arg[++i];
540                   }
541
542                 goto store_c;
543               }
544           }
545         }
546
547       if (! ((backslash_escapes || elide_outer_quotes)
548              && quote_these_too
549              && quote_these_too[c / INT_BITS] & (1 << (c % INT_BITS))))
550         goto store_c;
551
552     store_escape:
553       if (elide_outer_quotes)
554         goto force_outer_quoting_style;
555       STORE ('\\');
556
557     store_c:
558       STORE (c);
559     }
560
561   if (len == 0 && quoting_style == shell_always_quoting_style
562       && elide_outer_quotes)
563     goto force_outer_quoting_style;
564
565   if (quote_string && !elide_outer_quotes)
566     for (; *quote_string; quote_string++)
567       STORE (*quote_string);
568
569   if (len < buffersize)
570     buffer[len] = '\0';
571   return len;
572
573  force_outer_quoting_style:
574   /* Don't reuse quote_these_too, since the addition of outer quotes
575      sufficiently quotes the specified characters.  */
576   return quotearg_buffer_restyled (buffer, buffersize, arg, argsize,
577                                    quoting_style,
578                                    flags & ~QA_ELIDE_OUTER_QUOTES, NULL);
579 }
580
581 /* Place into buffer BUFFER (of size BUFFERSIZE) a quoted version of
582    argument ARG (of size ARGSIZE), using O to control quoting.
583    If O is null, use the default.
584    Terminate the output with a null character, and return the written
585    size of the output, not counting the terminating null.
586    If BUFFERSIZE is too small to store the output string, return the
587    value that would have been returned had BUFFERSIZE been large enough.
588    If ARGSIZE is SIZE_MAX, use the string length of the argument for
589    ARGSIZE.  */
590 size_t
591 quotearg_buffer (char *buffer, size_t buffersize,
592                  char const *arg, size_t argsize,
593                  struct quoting_options const *o)
594 {
595   struct quoting_options const *p = o ? o : &default_quoting_options;
596   int e = errno;
597   size_t r = quotearg_buffer_restyled (buffer, buffersize, arg, argsize,
598                                        p->style, p->flags, p->quote_these_too);
599   errno = e;
600   return r;
601 }
602
603 /* Equivalent to quotearg_alloc (ARG, ARGSIZE, NULL, O).  */
604 char *
605 quotearg_alloc (char const *arg, size_t argsize,
606                 struct quoting_options const *o)
607 {
608   return quotearg_alloc_mem (arg, argsize, NULL, o);
609 }
610
611 /* Like quotearg_buffer (..., ARG, ARGSIZE, O), except return newly
612    allocated storage containing the quoted string, and store the
613    resulting size into *SIZE, if non-NULL.  The result can contain
614    embedded null bytes only if ARGSIZE is not SIZE_MAX, SIZE is not
615    NULL, and set_quoting_flags has not set the null byte elision
616    flag.  */
617 char *
618 quotearg_alloc_mem (char const *arg, size_t argsize, size_t *size,
619                     struct quoting_options const *o)
620 {
621   struct quoting_options const *p = o ? o : &default_quoting_options;
622   int e = errno;
623   /* Elide embedded null bytes if we can't return a size.  */
624   int flags = p->flags | (size ? 0 : QA_ELIDE_NULL_BYTES);
625   size_t bufsize = quotearg_buffer_restyled (0, 0, arg, argsize, p->style,
626                                              flags, p->quote_these_too) + 1;
627   char *buf = xcharalloc (bufsize);
628   quotearg_buffer_restyled (buf, bufsize, arg, argsize, p->style, flags,
629                             p->quote_these_too);
630   errno = e;
631   if (size)
632     *size = bufsize - 1;
633   return buf;
634 }
635
636 /* A storage slot with size and pointer to a value.  */
637 struct slotvec
638 {
639   size_t size;
640   char *val;
641 };
642
643 /* Preallocate a slot 0 buffer, so that the caller can always quote
644    one small component of a "memory exhausted" message in slot 0.  */
645 static char slot0[256];
646 static unsigned int nslots = 1;
647 static struct slotvec slotvec0 = {sizeof slot0, slot0};
648 static struct slotvec *slotvec = &slotvec0;
649
650 void
651 quotearg_free (void)
652 {
653   struct slotvec *sv = slotvec;
654   unsigned int i;
655   for (i = 1; i < nslots; i++)
656     free (sv[i].val);
657   if (sv[0].val != slot0)
658     {
659       free (sv[0].val);
660       slotvec0.size = sizeof slot0;
661       slotvec0.val = slot0;
662     }
663   if (sv != &slotvec0)
664     {
665       free (sv);
666       slotvec = &slotvec0;
667     }
668   nslots = 1;
669 }
670
671 /* Use storage slot N to return a quoted version of argument ARG.
672    ARG is of size ARGSIZE, but if that is SIZE_MAX, ARG is a
673    null-terminated string.
674    OPTIONS specifies the quoting options.
675    The returned value points to static storage that can be
676    reused by the next call to this function with the same value of N.
677    N must be nonnegative.  N is deliberately declared with type "int"
678    to allow for future extensions (using negative values).  */
679 static char *
680 quotearg_n_options (int n, char const *arg, size_t argsize,
681                     struct quoting_options const *options)
682 {
683   int e = errno;
684
685   unsigned int n0 = n;
686   struct slotvec *sv = slotvec;
687
688   if (n < 0)
689     abort ();
690
691   if (nslots <= n0)
692     {
693       /* FIXME: technically, the type of n1 should be `unsigned int',
694          but that evokes an unsuppressible warning from gcc-4.0.1 and
695          older.  If gcc ever provides an option to suppress that warning,
696          revert to the original type, so that the test in xalloc_oversized
697          is once again performed only at compile time.  */
698       size_t n1 = n0 + 1;
699       bool preallocated = (sv == &slotvec0);
700
701       if (xalloc_oversized (n1, sizeof *sv))
702         xalloc_die ();
703
704       slotvec = sv = xrealloc (preallocated ? NULL : sv, n1 * sizeof *sv);
705       if (preallocated)
706         *sv = slotvec0;
707       memset (sv + nslots, 0, (n1 - nslots) * sizeof *sv);
708       nslots = n1;
709     }
710
711   {
712     size_t size = sv[n].size;
713     char *val = sv[n].val;
714     /* Elide embedded null bytes since we don't return a size.  */
715     int flags = options->flags | QA_ELIDE_NULL_BYTES;
716     size_t qsize = quotearg_buffer_restyled (val, size, arg, argsize,
717                                              options->style, flags,
718                                              options->quote_these_too);
719
720     if (size <= qsize)
721       {
722         sv[n].size = size = qsize + 1;
723         if (val != slot0)
724           free (val);
725         sv[n].val = val = xcharalloc (size);
726         quotearg_buffer_restyled (val, size, arg, argsize, options->style,
727                                   flags, options->quote_these_too);
728       }
729
730     errno = e;
731     return val;
732   }
733 }
734
735 char *
736 quotearg_n (int n, char const *arg)
737 {
738   return quotearg_n_options (n, arg, SIZE_MAX, &default_quoting_options);
739 }
740
741 char *
742 quotearg_n_mem (int n, char const *arg, size_t argsize)
743 {
744   return quotearg_n_options (n, arg, argsize, &default_quoting_options);
745 }
746
747 char *
748 quotearg (char const *arg)
749 {
750   return quotearg_n (0, arg);
751 }
752
753 char *
754 quotearg_mem (char const *arg, size_t argsize)
755 {
756   return quotearg_n_mem (0, arg, argsize);
757 }
758
759 char *
760 quotearg_n_style (int n, enum quoting_style s, char const *arg)
761 {
762   struct quoting_options const o = quoting_options_from_style (s);
763   return quotearg_n_options (n, arg, SIZE_MAX, &o);
764 }
765
766 char *
767 quotearg_n_style_mem (int n, enum quoting_style s,
768                       char const *arg, size_t argsize)
769 {
770   struct quoting_options const o = quoting_options_from_style (s);
771   return quotearg_n_options (n, arg, argsize, &o);
772 }
773
774 char *
775 quotearg_style (enum quoting_style s, char const *arg)
776 {
777   return quotearg_n_style (0, s, arg);
778 }
779
780 char *
781 quotearg_style_mem (enum quoting_style s, char const *arg, size_t argsize)
782 {
783   return quotearg_n_style_mem (0, s, arg, argsize);
784 }
785
786 char *
787 quotearg_char_mem (char const *arg, size_t argsize, char ch)
788 {
789   struct quoting_options options;
790   options = default_quoting_options;
791   set_char_quoting (&options, ch, 1);
792   return quotearg_n_options (0, arg, argsize, &options);
793 }
794
795 char *
796 quotearg_char (char const *arg, char ch)
797 {
798   return quotearg_char_mem (arg, SIZE_MAX, ch);
799 }
800
801 char *
802 quotearg_colon (char const *arg)
803 {
804   return quotearg_char (arg, ':');
805 }
806
807 char *
808 quotearg_colon_mem (char const *arg, size_t argsize)
809 {
810   return quotearg_char_mem (arg, argsize, ':');
811 }