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