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