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