(quotearg_n_options): Don't make the initial
[gnulib.git] / lib / quotearg.c
1 /* quotearg.c - quote arguments for output
2    Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc.
3
4    This program is free software; you can redistribute it and/or modify
5    it under the terms of the GNU General Public License as published by
6    the Free Software Foundation; either version 2, or (at your option)
7    any later version.
8
9    This program is distributed in the hope that it will be useful,
10    but WITHOUT ANY WARRANTY; without even the implied warranty of
11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12    GNU General Public License for more details.
13
14    You should have received a copy of the GNU General Public License
15    along with this program; if not, write to the Free Software Foundation,
16    Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
17
18 /* Written by Paul Eggert <eggert@twinsun.com> */
19
20 #if HAVE_CONFIG_H
21 # include <config.h>
22 #endif
23
24 #include <sys/types.h>
25 #include <quotearg.h>
26 #include <xalloc.h>
27
28 #include <ctype.h>
29
30 #if ENABLE_NLS
31 # include <libintl.h>
32 # define _(text) gettext (text)
33 #else
34 # define _(text) text
35 #endif
36 #define N_(text) text
37
38 #if HAVE_LIMITS_H
39 # include <limits.h>
40 #endif
41 #ifndef CHAR_BIT
42 # define CHAR_BIT 8
43 #endif
44 #ifndef UCHAR_MAX
45 # define UCHAR_MAX ((unsigned char) -1)
46 #endif
47
48 #if HAVE_C_BACKSLASH_A
49 # define ALERT_CHAR '\a'
50 #else
51 # define ALERT_CHAR '\7'
52 #endif
53
54 #if HAVE_STDLIB_H
55 # include <stdlib.h>
56 #endif
57
58 #if HAVE_STRING_H
59 # include <string.h>
60 #endif
61
62 #if HAVE_WCHAR_H
63 # include <wchar.h>
64 #endif
65
66 #if HAVE_MBRTOWC
67 size_t mbrtowc ();
68 # ifdef mbstate_t
69 #  define mbrtowc(pwc, s, n, ps) (mbrtowc) (pwc, s, n, 0)
70 #  define mbsinit(ps) 1
71 # endif
72 #else
73 /* Disable multibyte processing entirely.  Since MB_CUR_MAX is 1, the
74    other macros are defined only for documentation and to satisfy C
75    syntax.  */
76 # undef MB_CUR_MAX
77 # define MB_CUR_MAX 1
78 # define mbrtowc(pwc, s, n, ps) ((*(pwc) = *(s)) != 0)
79 # define mbsinit(ps) 1
80 # define iswprint(wc) ISPRINT ((unsigned char) (wc))
81 #endif
82
83 #ifndef iswprint
84 # if HAVE_WCTYPE_H
85 #  include <wctype.h>
86 # endif
87 # if !defined iswprint && !HAVE_ISWPRINT
88 #  define iswprint(wc) 1
89 # endif
90 #endif
91
92 #define INT_BITS (sizeof (int) * CHAR_BIT)
93
94 #if defined (STDC_HEADERS) || (!defined (isascii) && !defined (HAVE_ISASCII))
95 /* Undefine to protect against the definition in wctype.h of solaris2.6.   */
96 # undef ISASCII
97 # define ISASCII(c) 1
98 #else
99 # define ISASCII(c) isascii (c)
100 #endif
101 /* Undefine to protect against the definition in wctype.h of solaris2.6.   */
102 #undef ISPRINT
103 #define ISPRINT(c) (ISASCII (c) && isprint (c))
104
105 struct quoting_options
106 {
107   /* Basic quoting style.  */
108   enum quoting_style style;
109
110   /* Quote the characters indicated by this bit vector even if the
111      quoting style would not normally require them to be quoted.  */
112   int quote_these_too[(UCHAR_MAX / INT_BITS) + 1];
113 };
114
115 /* Names of quoting styles.  */
116 char const *const quoting_style_args[] =
117 {
118   "literal",
119   "shell",
120   "shell-always",
121   "c",
122   "escape",
123   "locale",
124   "clocale",
125   0
126 };
127
128 /* Correspondences to quoting style names.  */
129 enum quoting_style const quoting_style_vals[] =
130 {
131   literal_quoting_style,
132   shell_quoting_style,
133   shell_always_quoting_style,
134   c_quoting_style,
135   escape_quoting_style,
136   locale_quoting_style,
137   clocale_quoting_style
138 };
139
140 /* The default quoting options.  */
141 static struct quoting_options default_quoting_options;
142
143 /* Allocate a new set of quoting options, with contents initially identical
144    to O if O is not null, or to the default if O is null.
145    It is the caller's responsibility to free the result.  */
146 struct quoting_options *
147 clone_quoting_options (struct quoting_options *o)
148 {
149   struct quoting_options *p
150     = (struct quoting_options *) xmalloc (sizeof (struct quoting_options));
151   *p = *(o ? o : &default_quoting_options);
152   return p;
153 }
154
155 /* Get the value of O's quoting style.  If O is null, use the default.  */
156 enum quoting_style
157 get_quoting_style (struct quoting_options *o)
158 {
159   return (o ? o : &default_quoting_options)->style;
160 }
161
162 /* In O (or in the default if O is null),
163    set the value of the quoting style to S.  */
164 void
165 set_quoting_style (struct quoting_options *o, enum quoting_style s)
166 {
167   (o ? o : &default_quoting_options)->style = s;
168 }
169
170 /* In O (or in the default if O is null),
171    set the value of the quoting options for character C to I.
172    Return the old value.  Currently, the only values defined for I are
173    0 (the default) and 1 (which means to quote the character even if
174    it would not otherwise be quoted).  */
175 int
176 set_char_quoting (struct quoting_options *o, char c, int i)
177 {
178   unsigned char uc = c;
179   int *p = (o ? o : &default_quoting_options)->quote_these_too + uc / INT_BITS;
180   int shift = uc % INT_BITS;
181   int r = (*p >> shift) & 1;
182   *p ^= ((i & 1) ^ r) << shift;
183   return r;
184 }
185
186 /* MSGID approximates a quotation mark.  Return its translation if it
187    has one; otherwise, return either it or "\"", depending on S.  */
188 static char const *
189 gettext_quote (char const *msgid, enum quoting_style s)
190 {
191   char const *translation = _(msgid);
192   if (translation == msgid && s == clocale_quoting_style)
193     translation = "\"";
194   return translation;
195 }
196
197 /* Place into buffer BUFFER (of size BUFFERSIZE) a quoted version of
198    argument ARG (of size ARGSIZE), using QUOTING_STYLE and the
199    non-quoting-style part of O to control quoting.
200    Terminate the output with a null character, and return the written
201    size of the output, not counting the terminating null.
202    If BUFFERSIZE is too small to store the output string, return the
203    value that would have been returned had BUFFERSIZE been large enough.
204    If ARGSIZE is -1, use the string length of the argument for ARGSIZE.
205
206    This function acts like quotearg_buffer (BUFFER, BUFFERSIZE, ARG,
207    ARGSIZE, O), except it uses QUOTING_STYLE instead of the quoting
208    style specified by O, and O may not be null.  */
209
210 static size_t
211 quotearg_buffer_restyled (char *buffer, size_t buffersize,
212                           char const *arg, size_t argsize,
213                           enum quoting_style quoting_style,
214                           struct quoting_options const *o)
215 {
216   size_t i;
217   size_t len = 0;
218   char const *quote_string = 0;
219   size_t quote_string_len = 0;
220   int backslash_escapes = 0;
221   int unibyte_locale = MB_CUR_MAX == 1;
222
223 #define STORE(c) \
224     do \
225       { \
226         if (len < buffersize) \
227           buffer[len] = (c); \
228         len++; \
229       } \
230     while (0)
231
232   switch (quoting_style)
233     {
234     case c_quoting_style:
235       STORE ('"');
236       backslash_escapes = 1;
237       quote_string = "\"";
238       quote_string_len = 1;
239       break;
240
241     case escape_quoting_style:
242       backslash_escapes = 1;
243       break;
244
245     case locale_quoting_style:
246     case clocale_quoting_style:
247       {
248         /* Get translations for open and closing quotation marks.
249
250            The message catalog should translate "`" to a left
251            quotation mark suitable for the locale, and similarly for
252            "'".  If the catalog has no translation,
253            locale_quoting_style quotes `like this', and
254            clocale_quoting_style quotes "like this".
255
256            For example, an American English Unicode locale should
257            translate "`" to U+201C (LEFT DOUBLE QUOTATION MARK), and
258            should translate "'" to U+201D (RIGHT DOUBLE QUOTATION
259            MARK).  A British English Unicode locale should instead
260            translate these to U+2018 (LEFT SINGLE QUOTATION MARK) and
261            U+2019 (RIGHT SINGLE QUOTATION MARK), respectively.  */
262
263         char const *left = gettext_quote (N_("`"), quoting_style);
264         char const *right = gettext_quote (N_("'"), quoting_style);
265         for (quote_string = left; *quote_string; quote_string++)
266           STORE (*quote_string);
267         backslash_escapes = 1;
268         quote_string = right;
269         quote_string_len = strlen (quote_string);
270       }
271       break;
272
273     case shell_always_quoting_style:
274       STORE ('\'');
275       quote_string = "'";
276       quote_string_len = 1;
277       break;
278
279     default:
280       break;
281     }
282
283   for (i = 0;  ! (argsize == (size_t) -1 ? arg[i] == '\0' : i == argsize);  i++)
284     {
285       unsigned char c;
286       unsigned char esc;
287
288       if (backslash_escapes
289           && quote_string_len
290           && i + quote_string_len <= argsize
291           && memcmp (arg + i, quote_string, quote_string_len) == 0)
292         STORE ('\\');
293
294       c = arg[i];
295       switch (c)
296         {
297         case '?':
298           switch (quoting_style)
299             {
300             case shell_quoting_style:
301               goto use_shell_always_quoting_style;
302
303             case c_quoting_style:
304               if (i + 2 < argsize && arg[i + 1] == '?')
305                 switch (arg[i + 2])
306                   {
307                   case '!': case '\'':
308                   case '(': case ')': case '-': case '/':
309                   case '<': case '=': case '>':
310                     /* Escape the second '?' in what would otherwise be
311                        a trigraph.  */
312                     i += 2;
313                     c = arg[i + 2];
314                     STORE ('?');
315                     STORE ('\\');
316                     STORE ('?');
317                     break;
318                   }
319               break;
320
321             default:
322               break;
323             }
324           break;
325
326         case ALERT_CHAR: esc = 'a'; goto c_escape;
327         case '\b': esc = 'b'; goto c_escape;
328         case '\f': esc = 'f'; goto c_escape;
329         case '\n': esc = 'n'; goto c_and_shell_escape;
330         case '\r': esc = 'r'; goto c_and_shell_escape;
331         case '\t': esc = 't'; goto c_and_shell_escape;
332         case '\v': esc = 'v'; goto c_escape;
333         case '\\': esc = c; goto c_and_shell_escape;
334
335         c_and_shell_escape:
336           if (quoting_style == shell_quoting_style)
337             goto use_shell_always_quoting_style;
338         c_escape:
339           if (backslash_escapes)
340             {
341               c = esc;
342               goto store_escape;
343             }
344           break;
345
346         case '#': case '~':
347           if (i != 0)
348             break;
349           /* Fall through.  */
350         case ' ':
351         case '!': /* special in bash */
352         case '"': case '$': case '&':
353         case '(': case ')': case '*': case ';':
354         case '<': case '>': case '[':
355         case '^': /* special in old /bin/sh, e.g. SunOS 4.1.4 */
356         case '`': case '|':
357           /* A shell special character.  In theory, '$' and '`' could
358              be the first bytes of multibyte characters, which means
359              we should check them with mbrtowc, but in practice this
360              doesn't happen so it's not worth worrying about.  */
361           if (quoting_style == shell_quoting_style)
362             goto use_shell_always_quoting_style;
363           break;
364
365         case '\'':
366           switch (quoting_style)
367             {
368             case shell_quoting_style:
369               goto use_shell_always_quoting_style;
370
371             case shell_always_quoting_style:
372               STORE ('\'');
373               STORE ('\\');
374               STORE ('\'');
375               break;
376
377             default:
378               break;
379             }
380           break;
381
382         case '%': case '+': case ',': case '-': case '.': case '/':
383         case '0': case '1': case '2': case '3': case '4': case '5':
384         case '6': case '7': case '8': case '9': case ':': case '=':
385         case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
386         case 'G': case 'H': case 'I': case 'J': case 'K': case 'L':
387         case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R':
388         case 'S': case 'T': case 'U': case 'V': case 'W': case 'X':
389         case 'Y': case 'Z': case ']': case '_': case 'a': case 'b':
390         case 'c': case 'd': case 'e': case 'f': case 'g': case 'h':
391         case 'i': case 'j': case 'k': case 'l': case 'm': case 'n':
392         case 'o': case 'p': case 'q': case 'r': case 's': case 't':
393         case 'u': case 'v': case 'w': case 'x': case 'y': case 'z':
394         case '{': case '}':
395           /* These characters don't cause problems, no matter what the
396              quoting style is.  They cannot start multibyte sequences.  */
397           break;
398
399         default:
400           /* If we have a multibyte sequence, copy it until we reach
401              its end, find an error, or come back to the initial shift
402              state.  For C-like styles, if the sequence has
403              unprintable characters, escape the whole sequence, since
404              we can't easily escape single characters within it.  */
405           {
406             /* Length of multibyte sequence found so far.  */
407             size_t m;
408
409             int printable;
410
411             if (unibyte_locale)
412               {
413                 m = 1;
414                 printable = ISPRINT (c);
415               }
416             else
417               {
418                 mbstate_t mbstate;
419                 memset (&mbstate, 0, sizeof mbstate);
420
421                 m = 0;
422                 printable = 1;
423                 if (argsize == (size_t) -1)
424                   argsize = strlen (arg);
425
426                 do
427                   {
428                     wchar_t w;
429                     size_t bytes = mbrtowc (&w, &arg[i + m],
430                                             argsize - (i + m), &mbstate);
431                     if (bytes == 0)
432                       break;
433                     else if (bytes == (size_t) -1)
434                       {
435                         printable = 0;
436                         break;
437                       }
438                     else if (bytes == (size_t) -2)
439                       {
440                         printable = 0;
441                         while (i + m < argsize && arg[i + m])
442                           m++;
443                         break;
444                       }
445                     else
446                       {
447                         if (! iswprint (w))
448                           printable = 0;
449                         m += bytes;
450                       }
451                   }
452                 while (! mbsinit (&mbstate));
453               }
454
455             if (1 < m || (backslash_escapes && ! printable))
456               {
457                 /* Output a multibyte sequence, or an escaped
458                    unprintable unibyte character.  */
459                 size_t ilim = i + m;
460
461                 for (;;)
462                   {
463                     if (backslash_escapes && ! printable)
464                       {
465                         STORE ('\\');
466                         STORE ('0' + (c >> 6));
467                         STORE ('0' + ((c >> 3) & 7));
468                         c = '0' + (c & 7);
469                       }
470                     if (ilim <= i + 1)
471                       break;
472                     STORE (c);
473                     c = arg[++i];
474                   }
475
476                 goto store_c;
477               }
478           }
479         }
480
481       if (! (backslash_escapes
482              && o->quote_these_too[c / INT_BITS] & (1 << (c % INT_BITS))))
483         goto store_c;
484
485     store_escape:
486       STORE ('\\');
487
488     store_c:
489       STORE (c);
490     }
491
492   if (quote_string)
493     for (; *quote_string; quote_string++)
494       STORE (*quote_string);
495
496   if (len < buffersize)
497     buffer[len] = '\0';
498   return len;
499
500  use_shell_always_quoting_style:
501   return quotearg_buffer_restyled (buffer, buffersize, arg, argsize,
502                                    shell_always_quoting_style, o);
503 }
504
505 /* Place into buffer BUFFER (of size BUFFERSIZE) a quoted version of
506    argument ARG (of size ARGSIZE), using O to control quoting.
507    If O is null, use the default.
508    Terminate the output with a null character, and return the written
509    size of the output, not counting the terminating null.
510    If BUFFERSIZE is too small to store the output string, return the
511    value that would have been returned had BUFFERSIZE been large enough.
512    If ARGSIZE is -1, use the string length of the argument for ARGSIZE.  */
513 size_t
514 quotearg_buffer (char *buffer, size_t buffersize,
515                  char const *arg, size_t argsize,
516                  struct quoting_options const *o)
517 {
518   struct quoting_options const *p = o ? o : &default_quoting_options;
519   return quotearg_buffer_restyled (buffer, buffersize, arg, argsize,
520                                    p->style, p);
521 }
522
523 /* Use storage slot N to return a quoted version of the string ARG.
524    OPTIONS specifies the quoting options.
525    The returned value points to static storage that can be
526    reused by the next call to this function with the same value of N.
527    N must be nonnegative.  N is deliberately declared with type "int"
528    to allow for future extensions (using negative values).  */
529 static char *
530 quotearg_n_options (int n, char const *arg,
531                     struct quoting_options const *options)
532 {
533   /* Preallocate a slot 0 buffer, so that the caller can always quote
534      one small component of a "memory exhausted" message in slot 0.  */
535   static char slot0[256];
536   static unsigned int nslots = 1;
537   struct slotvec
538     {
539       size_t size;
540       char *val;
541     };
542   static struct slotvec slotvec0 = {sizeof slot0, slot0};
543   static struct slotvec *slotvec = &slotvec0;
544
545   if (nslots <= n)
546     {
547       int n1 = n + 1;
548       size_t s = n1 * sizeof (struct slotvec);
549       if (! (0 < n1 && n1 == s / sizeof (struct slotvec)))
550         abort ();
551       if (slotvec == &slotvec0)
552         {
553           slotvec = (struct slotvec *) xmalloc (sizeof (struct slotvec));
554           *slotvec = slotvec0;
555         }
556       slotvec = (struct slotvec *) xrealloc (slotvec, s);
557       memset (slotvec + nslots, 0, (n1 - nslots) * sizeof (struct slotvec));
558       nslots = n;
559     }
560
561   {
562     size_t size = slotvec[n].size;
563     char *val = slotvec[n].val;
564     size_t qsize = quotearg_buffer (val, size, arg, (size_t) -1, options);
565
566     if (size <= qsize)
567       {
568         slotvec[n].size = size = qsize + 1;
569         slotvec[n].val = val = xrealloc (val == slot0 ? 0 : val, size);
570         quotearg_buffer (val, size, arg, (size_t) -1, options);
571       }
572
573     return val;
574   }
575 }
576
577 char *
578 quotearg_n (unsigned int n, char const *arg)
579 {
580   return quotearg_n_options (n, arg, &default_quoting_options);
581 }
582
583 char *
584 quotearg (char const *arg)
585 {
586   return quotearg_n (0, arg);
587 }
588
589 char *
590 quotearg_n_style (unsigned int n, enum quoting_style s, char const *arg)
591 {
592   struct quoting_options o;
593   o.style = s;
594   memset (o.quote_these_too, 0, sizeof o.quote_these_too);
595   return quotearg_n_options (n, arg, &o);
596 }
597
598 char *
599 quotearg_style (enum quoting_style s, char const *arg)
600 {
601   return quotearg_n_style (0, s, arg);
602 }
603
604 char *
605 quotearg_char (char const *arg, char ch)
606 {
607   struct quoting_options options;
608   options = default_quoting_options;
609   set_char_quoting (&options, ch, 1);
610   return quotearg_n_options (0, arg, &options);
611 }
612
613 char *
614 quotearg_colon (char const *arg)
615 {
616   return quotearg_char (arg, ':');
617 }