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