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