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