Make inclusion of <wchar.h> independent of whether
[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
37 #if HAVE_LIMITS_H
38 # include <limits.h>
39 #endif
40 #ifndef CHAR_BIT
41 # define CHAR_BIT 8
42 #endif
43 #ifndef UCHAR_MAX
44 # define UCHAR_MAX ((unsigned char) -1)
45 #endif
46
47 #if HAVE_C_BACKSLASH_A
48 # define ALERT_CHAR '\a'
49 #else
50 # define ALERT_CHAR '\7'
51 #endif
52
53 #if HAVE_STDLIB_H
54 # include <stdlib.h>
55 #endif
56
57 #if HAVE_STRING_H
58 # include <string.h>
59 #endif
60
61 #if HAVE_WCHAR_H
62 # include <wchar.h>
63 #endif
64
65 #if HAVE_MBRTOWC && HAVE_WCHAR_H
66 # if !HAVE_MBSTATE_T_OBJECT
67 #  define mbrtowc(pwc, s, n, ps) (mbrtowc) (pwc, s, n, 0)
68 # endif
69 #else
70 # define mbrtowc(pwc, s, n, ps) ((*(pwc) = *(s)) != 0)
71 # define mbsinit(ps) 1
72 # define iswprint(wc) ISPRINT ((unsigned char) (wc))
73 #endif
74
75 #ifndef iswprint
76 # if HAVE_WCTYPE_H
77 #  include <wctype.h>
78 # endif
79 # if !defined iswprint && !HAVE_ISWPRINT
80 #  define iswprint(wc) 1
81 # endif
82 #endif
83
84 #define INT_BITS (sizeof (int) * CHAR_BIT)
85
86 #if defined (STDC_HEADERS) || (!defined (isascii) && !defined (HAVE_ISASCII))
87 /* Undefine to protect against the definition in wctype.h of solaris2.6.   */
88 # undef ISASCII
89 # define ISASCII(c) 1
90 #else
91 # define ISASCII(c) isascii (c)
92 #endif
93 /* Undefine to protect against the definition in wctype.h of solaris2.6.   */
94 #undef ISPRINT
95 #define ISPRINT(c) (ISASCII (c) && isprint (c))
96
97 struct quoting_options
98 {
99   /* Basic quoting style.  */
100   enum quoting_style style;
101
102   /* Quote the characters indicated by this bit vector even if the
103      quoting style would not normally require them to be quoted.  */
104   int quote_these_too[((UCHAR_MAX + 1) / INT_BITS
105                        + ((UCHAR_MAX + 1) % INT_BITS != 0))];
106 };
107
108 /* Names of quoting styles.  */
109 char const *const quoting_style_args[] =
110 {
111   "literal",
112   "shell",
113   "shell-always",
114   "c",
115   "escape",
116   "locale",
117   0
118 };
119
120 /* Correspondences to quoting style names.  */
121 enum quoting_style const quoting_style_vals[] =
122 {
123   literal_quoting_style,
124   shell_quoting_style,
125   shell_always_quoting_style,
126   c_quoting_style,
127   escape_quoting_style,
128   locale_quoting_style
129 };
130
131 /* The default quoting options.  */
132 static struct quoting_options default_quoting_options;
133
134 /* Allocate a new set of quoting options, with contents initially identical
135    to O if O is not null, or to the default if O is null.
136    It is the caller's responsibility to free the result.  */
137 struct quoting_options *
138 clone_quoting_options (struct quoting_options *o)
139 {
140   struct quoting_options *p
141     = (struct quoting_options *) xmalloc (sizeof (struct quoting_options));
142   *p = *(o ? o : &default_quoting_options);
143   return p;
144 }
145
146 /* Get the value of O's quoting style.  If O is null, use the default.  */
147 enum quoting_style
148 get_quoting_style (struct quoting_options *o)
149 {
150   return (o ? o : &default_quoting_options)->style;
151 }
152
153 /* In O (or in the default if O is null),
154    set the value of the quoting style to S.  */
155 void
156 set_quoting_style (struct quoting_options *o, enum quoting_style s)
157 {
158   (o ? o : &default_quoting_options)->style = s;
159 }
160
161 /* In O (or in the default if O is null),
162    set the value of the quoting options for character C to I.
163    Return the old value.  Currently, the only values defined for I are
164    0 (the default) and 1 (which means to quote the character even if
165    it would not otherwise be quoted).  */
166 int
167 set_char_quoting (struct quoting_options *o, char c, int i)
168 {
169   unsigned char uc = c;
170   int *p = (o ? o : &default_quoting_options)->quote_these_too + uc / INT_BITS;
171   int shift = uc % INT_BITS;
172   int r = (*p >> shift) & 1;
173   *p ^= ((i & 1) ^ r) << shift;
174   return r;
175 }
176
177 /* Place into buffer BUFFER (of size BUFFERSIZE) a quoted version of
178    argument ARG (of size ARGSIZE), using QUOTING_STYLE and the
179    non-quoting-style 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 -1, 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 instead of the quoting
188    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,
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   int backslash_escapes = 0;
201
202 #define STORE(c) \
203     do \
204       { \
205         if (len < buffersize) \
206           buffer[len] = (c); \
207         len++; \
208       } \
209     while (0)
210
211   switch (quoting_style)
212     {
213     case c_quoting_style:
214       STORE ('"');
215       backslash_escapes = 1;
216       quote_string = "\"";
217       quote_string_len = 1;
218       break;
219
220     case escape_quoting_style:
221       backslash_escapes = 1;
222       break;
223
224     case locale_quoting_style:
225       for (quote_string = _("`"); *quote_string; quote_string++)
226         STORE (*quote_string);
227       backslash_escapes = 1;
228       quote_string = _("'");
229       quote_string_len = strlen (quote_string);
230       break;
231
232     case shell_always_quoting_style:
233       STORE ('\'');
234       quote_string = "'";
235       quote_string_len = 1;
236       break;
237
238     default:
239       break;
240     }
241
242   for (i = 0;  ! (argsize == (size_t) -1 ? arg[i] == '\0' : i == argsize);  i++)
243     {
244       unsigned char c;
245       unsigned char esc;
246
247       if (backslash_escapes
248           && quote_string_len
249           && i + quote_string_len <= argsize
250           && memcmp (arg + i, quote_string, quote_string_len) == 0)
251         STORE ('\\');
252
253       c = arg[i];
254       switch (c)
255         {
256         case '?':
257           switch (quoting_style)
258             {
259             case shell_quoting_style:
260               goto use_shell_always_quoting_style;
261
262             case c_quoting_style:
263               if (i + 2 < argsize && arg[i + 1] == '?')
264                 switch (arg[i + 2])
265                   {
266                   case '!': case '\'':
267                   case '(': case ')': case '-': case '/':
268                   case '<': case '=': case '>':
269                     /* Escape the second '?' in what would otherwise be
270                        a trigraph.  */
271                     i += 2;
272                     c = arg[i + 2];
273                     STORE ('?');
274                     STORE ('\\');
275                     STORE ('?');
276                     break;
277                   }
278               break;
279
280             default:
281               break;
282             }
283           break;
284
285         case ALERT_CHAR: esc = 'a'; goto c_escape;
286         case '\b': esc = 'b'; goto c_escape;
287         case '\f': esc = 'f'; goto c_escape;
288         case '\n': esc = 'n'; goto c_and_shell_escape;
289         case '\r': esc = 'r'; goto c_and_shell_escape;
290         case '\t': esc = 't'; goto c_and_shell_escape;
291         case '\v': esc = 'v'; goto c_escape;
292         case '\\': esc = c; goto c_and_shell_escape;
293
294         c_and_shell_escape:
295           if (quoting_style == shell_quoting_style)
296             goto use_shell_always_quoting_style;
297         c_escape:
298           if (backslash_escapes)
299             {
300               c = esc;
301               goto store_escape;
302             }
303           break;
304
305         case '#': case '~':
306           if (i != 0)
307             break;
308           /* Fall through.  */
309         case ' ':
310         case '!': /* special in bash */
311         case '"': case '$': case '&':
312         case '(': case ')': case '*': case ';':
313         case '<': case '>': case '[':
314         case '^': /* special in old /bin/sh, e.g. SunOS 4.1.4 */
315         case '`': case '|':
316           /* A shell special character.  In theory, '$' and '`' could
317              be the first bytes of multibyte characters, which means
318              we should check them with mbrtowc, but in practice this
319              doesn't happen so it's not worth worrying about.  */
320           if (quoting_style == shell_quoting_style)
321             goto use_shell_always_quoting_style;
322           break;
323
324         case '\'':
325           switch (quoting_style)
326             {
327             case shell_quoting_style:
328               goto use_shell_always_quoting_style;
329
330             case shell_always_quoting_style:
331               STORE ('\'');
332               STORE ('\\');
333               STORE ('\'');
334               break;
335
336             default:
337               break;
338             }
339           break;
340
341         case '%': case '+': case ',': case '-': case '.': case '/':
342         case '0': case '1': case '2': case '3': case '4': case '5':
343         case '6': case '7': case '8': case '9': case ':': case '=':
344         case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
345         case 'G': case 'H': case 'I': case 'J': case 'K': case 'L':
346         case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R':
347         case 'S': case 'T': case 'U': case 'V': case 'W': case 'X':
348         case 'Y': case 'Z': case ']': case '_': case 'a': case 'b':
349         case 'c': case 'd': case 'e': case 'f': case 'g': case 'h':
350         case 'i': case 'j': case 'k': case 'l': case 'm': case 'n':
351         case 'o': case 'p': case 'q': case 'r': case 's': case 't':
352         case 'u': case 'v': case 'w': case 'x': case 'y': case 'z':
353         case '{': case '}':
354           /* These characters don't cause problems, no matter what the
355              quoting style is.  They cannot start multibyte sequences.  */
356           break;
357
358         default:
359           /* If we have a multibyte sequence, copy it until we reach
360              its end, find an error, or come back to the initial shift
361              state.  For C-like styles, if the sequence has
362              unprintable characters, escape the whole sequence, since
363              we can't easily escape single characters within it.  */
364           {
365             /* Length of multibyte sequence found so far.  */
366             size_t m = 0;
367
368             int printable = 1;
369             mbstate_t mbstate;
370             memset (&mbstate, 0, sizeof mbstate);
371
372             if (argsize == (size_t) -1)
373               argsize = strlen (arg);
374
375             do
376               {
377                 wchar_t w;
378                 size_t bytes = mbrtowc (&w, &arg[i + m],
379                                         argsize - (i + m), &mbstate);
380                 if (bytes == 0)
381                   break;
382                 else if (bytes == (size_t) -1)
383                   {
384                     printable = 0;
385                     break;
386                   }
387                 else if (bytes == (size_t) -2)
388                   {
389                     printable = 0;
390                     while (i + m < argsize && arg[i + m])
391                       m++;
392                     break;
393                   }
394                 else
395                   {
396                     if (! iswprint (w))
397                       printable = 0;
398                     m += bytes;
399                   }
400               }
401             while (! mbsinit (&mbstate));
402
403             if (m <= 1)
404               {
405                 /* Escape a unibyte character like a multibyte
406                    sequence if using backslash escapes, and if the
407                    character is not printable.  */
408                 m = backslash_escapes && ! ISPRINT (c);
409                 printable = 0;
410               }
411
412             if (m)
413               {
414                 /* Output a multibyte sequence, or an escaped
415                    unprintable unibyte character.  */
416                 size_t imax = i + m - 1;
417
418                 for (;;)
419                   {
420                     if (backslash_escapes && ! printable)
421                       {
422                         STORE ('\\');
423                         STORE ('0' + (c >> 6));
424                         STORE ('0' + ((c >> 3) & 7));
425                         c = '0' + (c & 7);
426                       }
427                     if (i == imax)
428                       break;
429                     STORE (c);
430                     c = arg[++i];
431                   }
432
433                 goto store_c;
434               }
435           }
436         }
437
438       if (! (backslash_escapes
439              && o->quote_these_too[c / INT_BITS] & (1 << (c % INT_BITS))))
440         goto store_c;
441
442     store_escape:
443       STORE ('\\');
444
445     store_c:
446       STORE (c);
447     }
448
449   if (quote_string)
450     for (; *quote_string; quote_string++)
451       STORE (*quote_string);
452
453   if (len < buffersize)
454     buffer[len] = '\0';
455   return len;
456
457  use_shell_always_quoting_style:
458   return quotearg_buffer_restyled (buffer, buffersize, arg, argsize,
459                                    shell_always_quoting_style, o);
460 }
461
462 /* Place into buffer BUFFER (of size BUFFERSIZE) a quoted version of
463    argument ARG (of size ARGSIZE), using O to control quoting.
464    If O is null, use the default.
465    Terminate the output with a null character, and return the written
466    size of the output, not counting the terminating null.
467    If BUFFERSIZE is too small to store the output string, return the
468    value that would have been returned had BUFFERSIZE been large enough.
469    If ARGSIZE is -1, use the string length of the argument for ARGSIZE.  */
470 size_t
471 quotearg_buffer (char *buffer, size_t buffersize,
472                  char const *arg, size_t argsize,
473                  struct quoting_options const *o)
474 {
475   struct quoting_options const *p = o ? o : &default_quoting_options;
476   return quotearg_buffer_restyled (buffer, buffersize, arg, argsize,
477                                    p->style, p);
478 }
479
480 /* Use storage slot N to return a quoted version of the string ARG.
481    OPTIONS specifies the quoting options.
482    The returned value points to static storage that can be
483    reused by the next call to this function with the same value of N.
484    N must be nonnegative.  N is deliberately declared with type `int'
485    to allow for future extensions (using negative values).  */
486 static char *
487 quotearg_n_options (int n, char const *arg,
488                     struct quoting_options const *options)
489 {
490   static unsigned int nslots;
491   static struct slotvec
492     {
493       size_t size;
494       char *val;
495     } *slotvec;
496
497   if (nslots <= n)
498     {
499       int n1 = n + 1;
500       size_t s = n1 * sizeof (struct slotvec);
501       if (! (0 < n1 && n1 == s / sizeof (struct slotvec)))
502         abort ();
503       slotvec = (struct slotvec *) xrealloc (slotvec, s);
504       memset (slotvec + nslots, 0, (n1 - nslots) * sizeof (struct slotvec));
505       nslots = n;
506     }
507
508   {
509     size_t size = slotvec[n].size;
510     char *val = slotvec[n].val;
511     size_t qsize = quotearg_buffer (val, size, arg, (size_t) -1, options);
512
513     if (size <= qsize)
514       {
515         slotvec[n].size = size = qsize + 1;
516         slotvec[n].val = val = xrealloc (val, size);
517         quotearg_buffer (val, size, arg, (size_t) -1, options);
518       }
519
520     return val;
521   }
522 }
523
524 char *
525 quotearg_n (unsigned int n, char const *arg)
526 {
527   return quotearg_n_options (n, arg, &default_quoting_options);
528 }
529
530 char *
531 quotearg (char const *arg)
532 {
533   return quotearg_n (0, arg);
534 }
535
536 char *
537 quotearg_n_style (unsigned int n, enum quoting_style s, char const *arg)
538 {
539   struct quoting_options o;
540   o.style = s;
541   memset (o.quote_these_too, 0, sizeof o.quote_these_too);
542   return quotearg_n_options (n, arg, &o);
543 }
544
545 char *
546 quotearg_style (enum quoting_style s, char const *arg)
547 {
548   return quotearg_n_style (0, s, arg);
549 }
550
551 char *
552 quotearg_char (char const *arg, char ch)
553 {
554   struct quoting_options options;
555   options = default_quoting_options;
556   set_char_quoting (&options, ch, 1);
557   return quotearg_n_options (0, arg, &options);
558 }
559
560 char *
561 quotearg_colon (char const *arg)
562 {
563   return quotearg_char (arg, ':');
564 }