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