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