Blame lib/quotearg.c

Packit 709fb3
/* quotearg.c - quote arguments for output
Packit 709fb3
Packit 709fb3
   Copyright (C) 1998-2002, 2004-2017 Free Software Foundation, Inc.
Packit 709fb3
Packit 709fb3
   This program is free software: you can redistribute it and/or modify
Packit 709fb3
   it under the terms of the GNU General Public License as published by
Packit 709fb3
   the Free Software Foundation; either version 3 of the License, or
Packit 709fb3
   (at your option) any later version.
Packit 709fb3
Packit 709fb3
   This program is distributed in the hope that it will be useful,
Packit 709fb3
   but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit 709fb3
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
Packit 709fb3
   GNU General Public License for more details.
Packit 709fb3
Packit 709fb3
   You should have received a copy of the GNU General Public License
Packit 709fb3
   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
Packit 709fb3
Packit 709fb3
/* Written by Paul Eggert <eggert@twinsun.com> */
Packit 709fb3
Packit 709fb3
/* Without this pragma, gcc 4.7.0 20111124 mistakenly suggests that
Packit 709fb3
   the quoting_options_from_style function might be candidate for
Packit 709fb3
   attribute 'pure'  */
Packit 709fb3
#if (__GNUC__ == 4 && 6 <= __GNUC_MINOR__) || 4 < __GNUC__
Packit 709fb3
# pragma GCC diagnostic ignored "-Wsuggest-attribute=pure"
Packit 709fb3
#endif
Packit 709fb3
Packit 709fb3
#include <config.h>
Packit 709fb3
Packit 709fb3
#include "quotearg.h"
Packit 709fb3
#include "quote.h"
Packit 709fb3
Packit 709fb3
#include "minmax.h"
Packit 709fb3
#include "xalloc.h"
Packit 709fb3
#include "c-strcaseeq.h"
Packit 709fb3
#include "localcharset.h"
Packit 709fb3
Packit 709fb3
#include <ctype.h>
Packit 709fb3
#include <errno.h>
Packit 709fb3
#include <limits.h>
Packit 709fb3
#include <stdbool.h>
Packit 709fb3
#include <stdint.h>
Packit 709fb3
#include <stdlib.h>
Packit 709fb3
#include <string.h>
Packit 709fb3
#include <wchar.h>
Packit 709fb3
#include <wctype.h>
Packit 709fb3
Packit 709fb3
#include "gettext.h"
Packit 709fb3
#define _(msgid) gettext (msgid)
Packit 709fb3
#define N_(msgid) msgid
Packit 709fb3
Packit 709fb3
#ifndef SIZE_MAX
Packit 709fb3
# define SIZE_MAX ((size_t) -1)
Packit 709fb3
#endif
Packit 709fb3
Packit 709fb3
#define INT_BITS (sizeof (int) * CHAR_BIT)
Packit 709fb3
Packit 709fb3
#ifndef FALLTHROUGH
Packit 709fb3
# if __GNUC__ < 7
Packit 709fb3
#  define FALLTHROUGH ((void) 0)
Packit 709fb3
# else
Packit 709fb3
#  define FALLTHROUGH __attribute__ ((__fallthrough__))
Packit 709fb3
# endif
Packit 709fb3
#endif
Packit 709fb3
Packit 709fb3
struct quoting_options
Packit 709fb3
{
Packit 709fb3
  /* Basic quoting style.  */
Packit 709fb3
  enum quoting_style style;
Packit 709fb3
Packit 709fb3
  /* Additional flags.  Bitwise combination of enum quoting_flags.  */
Packit 709fb3
  int flags;
Packit 709fb3
Packit 709fb3
  /* Quote the characters indicated by this bit vector even if the
Packit 709fb3
     quoting style would not normally require them to be quoted.  */
Packit 709fb3
  unsigned int quote_these_too[(UCHAR_MAX / INT_BITS) + 1];
Packit 709fb3
Packit 709fb3
  /* The left quote for custom_quoting_style.  */
Packit 709fb3
  char const *left_quote;
Packit 709fb3
Packit 709fb3
  /* The right quote for custom_quoting_style.  */
Packit 709fb3
  char const *right_quote;
Packit 709fb3
};
Packit 709fb3
Packit 709fb3
/* Names of quoting styles.  */
Packit 709fb3
char const *const quoting_style_args[] =
Packit 709fb3
{
Packit 709fb3
  "literal",
Packit 709fb3
  "shell",
Packit 709fb3
  "shell-always",
Packit 709fb3
  "shell-escape",
Packit 709fb3
  "shell-escape-always",
Packit 709fb3
  "c",
Packit 709fb3
  "c-maybe",
Packit 709fb3
  "escape",
Packit 709fb3
  "locale",
Packit 709fb3
  "clocale",
Packit 709fb3
  0
Packit 709fb3
};
Packit 709fb3
Packit 709fb3
/* Correspondences to quoting style names.  */
Packit 709fb3
enum quoting_style const quoting_style_vals[] =
Packit 709fb3
{
Packit 709fb3
  literal_quoting_style,
Packit 709fb3
  shell_quoting_style,
Packit 709fb3
  shell_always_quoting_style,
Packit 709fb3
  shell_escape_quoting_style,
Packit 709fb3
  shell_escape_always_quoting_style,
Packit 709fb3
  c_quoting_style,
Packit 709fb3
  c_maybe_quoting_style,
Packit 709fb3
  escape_quoting_style,
Packit 709fb3
  locale_quoting_style,
Packit 709fb3
  clocale_quoting_style
Packit 709fb3
};
Packit 709fb3
Packit 709fb3
/* The default quoting options.  */
Packit 709fb3
static struct quoting_options default_quoting_options;
Packit 709fb3
Packit 709fb3
/* Allocate a new set of quoting options, with contents initially identical
Packit 709fb3
   to O if O is not null, or to the default if O is null.
Packit 709fb3
   It is the caller's responsibility to free the result.  */
Packit 709fb3
struct quoting_options *
Packit 709fb3
clone_quoting_options (struct quoting_options *o)
Packit 709fb3
{
Packit 709fb3
  int e = errno;
Packit 709fb3
  struct quoting_options *p = xmemdup (o ? o : &default_quoting_options,
Packit 709fb3
                                       sizeof *o);
Packit 709fb3
  errno = e;
Packit 709fb3
  return p;
Packit 709fb3
}
Packit 709fb3
Packit 709fb3
/* Get the value of O's quoting style.  If O is null, use the default.  */
Packit 709fb3
enum quoting_style
Packit 709fb3
get_quoting_style (struct quoting_options const *o)
Packit 709fb3
{
Packit 709fb3
  return (o ? o : &default_quoting_options)->style;
Packit 709fb3
}
Packit 709fb3
Packit 709fb3
/* In O (or in the default if O is null),
Packit 709fb3
   set the value of the quoting style to S.  */
Packit 709fb3
void
Packit 709fb3
set_quoting_style (struct quoting_options *o, enum quoting_style s)
Packit 709fb3
{
Packit 709fb3
  (o ? o : &default_quoting_options)->style = s;
Packit 709fb3
}
Packit 709fb3
Packit 709fb3
/* In O (or in the default if O is null),
Packit 709fb3
   set the value of the quoting options for character C to I.
Packit 709fb3
   Return the old value.  Currently, the only values defined for I are
Packit 709fb3
   0 (the default) and 1 (which means to quote the character even if
Packit 709fb3
   it would not otherwise be quoted).  */
Packit 709fb3
int
Packit 709fb3
set_char_quoting (struct quoting_options *o, char c, int i)
Packit 709fb3
{
Packit 709fb3
  unsigned char uc = c;
Packit 709fb3
  unsigned int *p =
Packit 709fb3
    (o ? o : &default_quoting_options)->quote_these_too + uc / INT_BITS;
Packit 709fb3
  int shift = uc % INT_BITS;
Packit 709fb3
  int r = (*p >> shift) & 1;
Packit 709fb3
  *p ^= ((i & 1) ^ r) << shift;
Packit 709fb3
  return r;
Packit 709fb3
}
Packit 709fb3
Packit 709fb3
/* In O (or in the default if O is null),
Packit 709fb3
   set the value of the quoting options flag to I, which can be a
Packit 709fb3
   bitwise combination of enum quoting_flags, or 0 for default
Packit 709fb3
   behavior.  Return the old value.  */
Packit 709fb3
int
Packit 709fb3
set_quoting_flags (struct quoting_options *o, int i)
Packit 709fb3
{
Packit 709fb3
  int r;
Packit 709fb3
  if (!o)
Packit 709fb3
    o = &default_quoting_options;
Packit 709fb3
  r = o->flags;
Packit 709fb3
  o->flags = i;
Packit 709fb3
  return r;
Packit 709fb3
}
Packit 709fb3
Packit 709fb3
void
Packit 709fb3
set_custom_quoting (struct quoting_options *o,
Packit 709fb3
                    char const *left_quote, char const *right_quote)
Packit 709fb3
{
Packit 709fb3
  if (!o)
Packit 709fb3
    o = &default_quoting_options;
Packit 709fb3
  o->style = custom_quoting_style;
Packit 709fb3
  if (!left_quote || !right_quote)
Packit 709fb3
    abort ();
Packit 709fb3
  o->left_quote = left_quote;
Packit 709fb3
  o->right_quote = right_quote;
Packit 709fb3
}
Packit 709fb3
Packit 709fb3
/* Return quoting options for STYLE, with no extra quoting.  */
Packit 709fb3
static struct quoting_options /* NOT PURE!! */
Packit 709fb3
quoting_options_from_style (enum quoting_style style)
Packit 709fb3
{
Packit 709fb3
  struct quoting_options o = { literal_quoting_style, 0, { 0 }, NULL, NULL };
Packit 709fb3
  if (style == custom_quoting_style)
Packit 709fb3
    abort ();
Packit 709fb3
  o.style = style;
Packit 709fb3
  return o;
Packit 709fb3
}
Packit 709fb3
Packit 709fb3
/* MSGID approximates a quotation mark.  Return its translation if it
Packit 709fb3
   has one; otherwise, return either it or "\"", depending on S.
Packit 709fb3
Packit 709fb3
   S is either clocale_quoting_style or locale_quoting_style.  */
Packit 709fb3
static char const *
Packit 709fb3
gettext_quote (char const *msgid, enum quoting_style s)
Packit 709fb3
{
Packit 709fb3
  char const *translation = _(msgid);
Packit 709fb3
  char const *locale_code;
Packit 709fb3
Packit 709fb3
  if (translation != msgid)
Packit 709fb3
    return translation;
Packit 709fb3
Packit 709fb3
  /* For UTF-8 and GB-18030, use single quotes U+2018 and U+2019.
Packit 709fb3
     Here is a list of other locales that include U+2018 and U+2019:
Packit 709fb3
Packit 709fb3
        ISO-8859-7   0xA1                 KOI8-T       0x91
Packit 709fb3
        CP869        0x8B                 CP874        0x91
Packit 709fb3
        CP932        0x81 0x65            CP936        0xA1 0xAE
Packit 709fb3
        CP949        0xA1 0xAE            CP950        0xA1 0xA5
Packit 709fb3
        CP1250       0x91                 CP1251       0x91
Packit 709fb3
        CP1252       0x91                 CP1253       0x91
Packit 709fb3
        CP1254       0x91                 CP1255       0x91
Packit 709fb3
        CP1256       0x91                 CP1257       0x91
Packit 709fb3
        EUC-JP       0xA1 0xC6            EUC-KR       0xA1 0xAE
Packit 709fb3
        EUC-TW       0xA1 0xE4            BIG5         0xA1 0xA5
Packit 709fb3
        BIG5-HKSCS   0xA1 0xA5            EUC-CN       0xA1 0xAE
Packit 709fb3
        GBK          0xA1 0xAE            Georgian-PS  0x91
Packit 709fb3
        PT154        0x91
Packit 709fb3
Packit 709fb3
     None of these is still in wide use; using iconv is overkill.  */
Packit 709fb3
  locale_code = locale_charset ();
Packit 709fb3
  if (STRCASEEQ (locale_code, "UTF-8", 'U','T','F','-','8',0,0,0,0))
Packit 709fb3
    return msgid[0] == '`' ? "\xe2\x80\x98": "\xe2\x80\x99";
Packit 709fb3
  if (STRCASEEQ (locale_code, "GB18030", 'G','B','1','8','0','3','0',0,0))
Packit 709fb3
    return msgid[0] == '`' ? "\xa1\ae": "\xa1\xaf";
Packit 709fb3
Packit 709fb3
  return (s == clocale_quoting_style ? "\"" : "'");
Packit 709fb3
}
Packit 709fb3
Packit 709fb3
/* Place into buffer BUFFER (of size BUFFERSIZE) a quoted version of
Packit 709fb3
   argument ARG (of size ARGSIZE), using QUOTING_STYLE, FLAGS, and
Packit 709fb3
   QUOTE_THESE_TOO to control quoting.
Packit 709fb3
   Terminate the output with a null character, and return the written
Packit 709fb3
   size of the output, not counting the terminating null.
Packit 709fb3
   If BUFFERSIZE is too small to store the output string, return the
Packit 709fb3
   value that would have been returned had BUFFERSIZE been large enough.
Packit 709fb3
   If ARGSIZE is SIZE_MAX, use the string length of the argument for ARGSIZE.
Packit 709fb3
Packit 709fb3
   This function acts like quotearg_buffer (BUFFER, BUFFERSIZE, ARG,
Packit 709fb3
   ARGSIZE, O), except it breaks O into its component pieces and is
Packit 709fb3
   not careful about errno.  */
Packit 709fb3
Packit 709fb3
static size_t
Packit 709fb3
quotearg_buffer_restyled (char *buffer, size_t buffersize,
Packit 709fb3
                          char const *arg, size_t argsize,
Packit 709fb3
                          enum quoting_style quoting_style, int flags,
Packit 709fb3
                          unsigned int const *quote_these_too,
Packit 709fb3
                          char const *left_quote,
Packit 709fb3
                          char const *right_quote)
Packit 709fb3
{
Packit 709fb3
  size_t i;
Packit 709fb3
  size_t len = 0;
Packit 709fb3
  size_t orig_buffersize = 0;
Packit 709fb3
  char const *quote_string = 0;
Packit 709fb3
  size_t quote_string_len = 0;
Packit 709fb3
  bool backslash_escapes = false;
Packit 709fb3
  bool unibyte_locale = MB_CUR_MAX == 1;
Packit 709fb3
  bool elide_outer_quotes = (flags & QA_ELIDE_OUTER_QUOTES) != 0;
Packit 709fb3
  bool pending_shell_escape_end = false;
Packit 709fb3
  bool encountered_single_quote = false;
Packit 709fb3
  bool all_c_and_shell_quote_compat = true;
Packit 709fb3
Packit 709fb3
#define STORE(c) \
Packit 709fb3
    do \
Packit 709fb3
      { \
Packit 709fb3
        if (len < buffersize) \
Packit 709fb3
          buffer[len] = (c); \
Packit 709fb3
        len++; \
Packit 709fb3
      } \
Packit 709fb3
    while (0)
Packit 709fb3
Packit 709fb3
#define START_ESC() \
Packit 709fb3
    do \
Packit 709fb3
      { \
Packit 709fb3
        if (elide_outer_quotes) \
Packit 709fb3
          goto force_outer_quoting_style; \
Packit 709fb3
        escaping = true; \
Packit 709fb3
        if (quoting_style == shell_always_quoting_style \
Packit 709fb3
            && ! pending_shell_escape_end) \
Packit 709fb3
          { \
Packit 709fb3
            STORE ('\''); \
Packit 709fb3
            STORE ('$'); \
Packit 709fb3
            STORE ('\''); \
Packit 709fb3
            pending_shell_escape_end = true; \
Packit 709fb3
          } \
Packit 709fb3
        STORE ('\\'); \
Packit 709fb3
      } \
Packit 709fb3
    while (0)
Packit 709fb3
Packit 709fb3
#define END_ESC() \
Packit 709fb3
    do \
Packit 709fb3
      { \
Packit 709fb3
        if (pending_shell_escape_end && ! escaping) \
Packit 709fb3
          { \
Packit 709fb3
            STORE ('\''); \
Packit 709fb3
            STORE ('\''); \
Packit 709fb3
            pending_shell_escape_end = false; \
Packit 709fb3
          } \
Packit 709fb3
      } \
Packit 709fb3
    while (0)
Packit 709fb3
Packit 709fb3
 process_input:
Packit 709fb3
Packit 709fb3
  switch (quoting_style)
Packit 709fb3
    {
Packit 709fb3
    case c_maybe_quoting_style:
Packit 709fb3
      quoting_style = c_quoting_style;
Packit 709fb3
      elide_outer_quotes = true;
Packit 709fb3
      FALLTHROUGH;
Packit 709fb3
    case c_quoting_style:
Packit 709fb3
      if (!elide_outer_quotes)
Packit 709fb3
        STORE ('"');
Packit 709fb3
      backslash_escapes = true;
Packit 709fb3
      quote_string = "\"";
Packit 709fb3
      quote_string_len = 1;
Packit 709fb3
      break;
Packit 709fb3
Packit 709fb3
    case escape_quoting_style:
Packit 709fb3
      backslash_escapes = true;
Packit 709fb3
      elide_outer_quotes = false;
Packit 709fb3
      break;
Packit 709fb3
Packit 709fb3
    case locale_quoting_style:
Packit 709fb3
    case clocale_quoting_style:
Packit 709fb3
    case custom_quoting_style:
Packit 709fb3
      {
Packit 709fb3
        if (quoting_style != custom_quoting_style)
Packit 709fb3
          {
Packit 709fb3
            /* TRANSLATORS:
Packit 709fb3
               Get translations for open and closing quotation marks.
Packit 709fb3
               The message catalog should translate "`" to a left
Packit 709fb3
               quotation mark suitable for the locale, and similarly for
Packit 709fb3
               "'".  For example, a French Unicode local should translate
Packit 709fb3
               these to U+00AB (LEFT-POINTING DOUBLE ANGLE
Packit 709fb3
               QUOTATION MARK), and U+00BB (RIGHT-POINTING DOUBLE ANGLE
Packit 709fb3
               QUOTATION MARK), respectively.
Packit 709fb3
Packit 709fb3
               If the catalog has no translation, we will try to
Packit 709fb3
               use Unicode U+2018 (LEFT SINGLE QUOTATION MARK) and
Packit 709fb3
               Unicode U+2019 (RIGHT SINGLE QUOTATION MARK).  If the
Packit 709fb3
               current locale is not Unicode, locale_quoting_style
Packit 709fb3
               will quote 'like this', and clocale_quoting_style will
Packit 709fb3
               quote "like this".  You should always include translations
Packit 709fb3
               for "`" and "'" even if U+2018 and U+2019 are appropriate
Packit 709fb3
               for your locale.
Packit 709fb3
Packit 709fb3
               If you don't know what to put here, please see
Packit 709fb3
               <http://en.wikipedia.org/wiki/Quotation_marks_in_other_languages>
Packit 709fb3
               and use glyphs suitable for your language.  */
Packit 709fb3
            left_quote = gettext_quote (N_("`"), quoting_style);
Packit 709fb3
            right_quote = gettext_quote (N_("'"), quoting_style);
Packit 709fb3
          }
Packit 709fb3
        if (!elide_outer_quotes)
Packit 709fb3
          for (quote_string = left_quote; *quote_string; quote_string++)
Packit 709fb3
            STORE (*quote_string);
Packit 709fb3
        backslash_escapes = true;
Packit 709fb3
        quote_string = right_quote;
Packit 709fb3
        quote_string_len = strlen (quote_string);
Packit 709fb3
      }
Packit 709fb3
      break;
Packit 709fb3
Packit 709fb3
    case shell_escape_quoting_style:
Packit 709fb3
      backslash_escapes = true;
Packit 709fb3
      FALLTHROUGH;
Packit 709fb3
    case shell_quoting_style:
Packit 709fb3
      elide_outer_quotes = true;
Packit 709fb3
      FALLTHROUGH;
Packit 709fb3
    case shell_escape_always_quoting_style:
Packit 709fb3
      if (!elide_outer_quotes)
Packit 709fb3
        backslash_escapes = true;
Packit 709fb3
      FALLTHROUGH;
Packit 709fb3
    case shell_always_quoting_style:
Packit 709fb3
      quoting_style = shell_always_quoting_style;
Packit 709fb3
      if (!elide_outer_quotes)
Packit 709fb3
        STORE ('\'');
Packit 709fb3
      quote_string = "'";
Packit 709fb3
      quote_string_len = 1;
Packit 709fb3
      break;
Packit 709fb3
Packit 709fb3
    case literal_quoting_style:
Packit 709fb3
      elide_outer_quotes = false;
Packit 709fb3
      break;
Packit 709fb3
Packit 709fb3
    default:
Packit 709fb3
      abort ();
Packit 709fb3
    }
Packit 709fb3
Packit 709fb3
  for (i = 0;  ! (argsize == SIZE_MAX ? arg[i] == '\0' : i == argsize);  i++)
Packit 709fb3
    {
Packit 709fb3
      unsigned char c;
Packit 709fb3
      unsigned char esc;
Packit 709fb3
      bool is_right_quote = false;
Packit 709fb3
      bool escaping = false;
Packit 709fb3
      bool c_and_shell_quote_compat = false;
Packit 709fb3
Packit 709fb3
      if (backslash_escapes
Packit 709fb3
          && quoting_style != shell_always_quoting_style
Packit 709fb3
          && quote_string_len
Packit 709fb3
          && (i + quote_string_len
Packit 709fb3
              <= (argsize == SIZE_MAX && 1 < quote_string_len
Packit 709fb3
                  /* Use strlen only if we must: when argsize is SIZE_MAX,
Packit 709fb3
                     and when the quote string is more than 1 byte long.
Packit 709fb3
                     If we do call strlen, save the result.  */
Packit 709fb3
                  ? (argsize = strlen (arg)) : argsize))
Packit 709fb3
          && memcmp (arg + i, quote_string, quote_string_len) == 0)
Packit 709fb3
        {
Packit 709fb3
          if (elide_outer_quotes)
Packit 709fb3
            goto force_outer_quoting_style;
Packit 709fb3
          is_right_quote = true;
Packit 709fb3
        }
Packit 709fb3
Packit 709fb3
      c = arg[i];
Packit 709fb3
      switch (c)
Packit 709fb3
        {
Packit 709fb3
        case '\0':
Packit 709fb3
          if (backslash_escapes)
Packit 709fb3
            {
Packit 709fb3
              START_ESC ();
Packit 709fb3
              /* If quote_string were to begin with digits, we'd need to
Packit 709fb3
                 test for the end of the arg as well.  However, it's
Packit 709fb3
                 hard to imagine any locale that would use digits in
Packit 709fb3
                 quotes, and set_custom_quoting is documented not to
Packit 709fb3
                 accept them.  Use only a single \0 with shell-escape
Packit 709fb3
                 as currently digits are not printed within $'...'  */
Packit 709fb3
              if (quoting_style != shell_always_quoting_style
Packit 709fb3
                  && i + 1 < argsize && '0' <= arg[i + 1] && arg[i + 1] <= '9')
Packit 709fb3
                {
Packit 709fb3
                  STORE ('0');
Packit 709fb3
                  STORE ('0');
Packit 709fb3
                }
Packit 709fb3
              c = '0';
Packit 709fb3
              /* We don't have to worry that this last '0' will be
Packit 709fb3
                 backslash-escaped because, again, quote_string should
Packit 709fb3
                 not start with it and because quote_these_too is
Packit 709fb3
                 documented as not accepting it.  */
Packit 709fb3
            }
Packit 709fb3
          else if (flags & QA_ELIDE_NULL_BYTES)
Packit 709fb3
            continue;
Packit 709fb3
          break;
Packit 709fb3
Packit 709fb3
        case '?':
Packit 709fb3
          switch (quoting_style)
Packit 709fb3
            {
Packit 709fb3
            case shell_always_quoting_style:
Packit 709fb3
              if (elide_outer_quotes)
Packit 709fb3
                goto force_outer_quoting_style;
Packit 709fb3
              break;
Packit 709fb3
Packit 709fb3
            case c_quoting_style:
Packit 709fb3
              if ((flags & QA_SPLIT_TRIGRAPHS)
Packit 709fb3
                  && i + 2 < argsize && arg[i + 1] == '?')
Packit 709fb3
                switch (arg[i + 2])
Packit 709fb3
                  {
Packit 709fb3
                  case '!': case '\'':
Packit 709fb3
                  case '(': case ')': case '-': case '/':
Packit 709fb3
                  case '<': case '=': case '>':
Packit 709fb3
                    /* Escape the second '?' in what would otherwise be
Packit 709fb3
                       a trigraph.  */
Packit 709fb3
                    if (elide_outer_quotes)
Packit 709fb3
                      goto force_outer_quoting_style;
Packit 709fb3
                    c = arg[i + 2];
Packit 709fb3
                    i += 2;
Packit 709fb3
                    STORE ('?');
Packit 709fb3
                    STORE ('"');
Packit 709fb3
                    STORE ('"');
Packit 709fb3
                    STORE ('?');
Packit 709fb3
                    break;
Packit 709fb3
Packit 709fb3
                  default:
Packit 709fb3
                    break;
Packit 709fb3
                  }
Packit 709fb3
              break;
Packit 709fb3
Packit 709fb3
            default:
Packit 709fb3
              break;
Packit 709fb3
            }
Packit 709fb3
          break;
Packit 709fb3
Packit 709fb3
        case '\a': esc = 'a'; goto c_escape;
Packit 709fb3
        case '\b': esc = 'b'; goto c_escape;
Packit 709fb3
        case '\f': esc = 'f'; goto c_escape;
Packit 709fb3
        case '\n': esc = 'n'; goto c_and_shell_escape;
Packit 709fb3
        case '\r': esc = 'r'; goto c_and_shell_escape;
Packit 709fb3
        case '\t': esc = 't'; goto c_and_shell_escape;
Packit 709fb3
        case '\v': esc = 'v'; goto c_escape;
Packit 709fb3
        case '\\': esc = c;
Packit 709fb3
          /* Never need to escape '\' in shell case.  */
Packit 709fb3
          if (quoting_style == shell_always_quoting_style)
Packit 709fb3
            {
Packit 709fb3
              if (elide_outer_quotes)
Packit 709fb3
                goto force_outer_quoting_style;
Packit 709fb3
              goto store_c;
Packit 709fb3
            }
Packit 709fb3
Packit 709fb3
          /* No need to escape the escape if we are trying to elide
Packit 709fb3
             outer quotes and nothing else is problematic.  */
Packit 709fb3
          if (backslash_escapes && elide_outer_quotes && quote_string_len)
Packit 709fb3
            goto store_c;
Packit 709fb3
Packit 709fb3
        c_and_shell_escape:
Packit 709fb3
          if (quoting_style == shell_always_quoting_style
Packit 709fb3
              && elide_outer_quotes)
Packit 709fb3
            goto force_outer_quoting_style;
Packit 709fb3
          /* fall through */
Packit 709fb3
        c_escape:
Packit 709fb3
          if (backslash_escapes)
Packit 709fb3
            {
Packit 709fb3
              c = esc;
Packit 709fb3
              goto store_escape;
Packit 709fb3
            }
Packit 709fb3
          break;
Packit 709fb3
Packit 709fb3
        case '{': case '}': /* sometimes special if isolated */
Packit 709fb3
          if (! (argsize == SIZE_MAX ? arg[1] == '\0' : argsize == 1))
Packit 709fb3
            break;
Packit 709fb3
          FALLTHROUGH;
Packit 709fb3
        case '#': case '~':
Packit 709fb3
          if (i != 0)
Packit 709fb3
            break;
Packit 709fb3
          FALLTHROUGH;
Packit 709fb3
        case ' ':
Packit 709fb3
          c_and_shell_quote_compat = true;
Packit 709fb3
          FALLTHROUGH;
Packit 709fb3
        case '!': /* special in bash */
Packit 709fb3
        case '"': case '$': case '&':
Packit 709fb3
        case '(': case ')': case '*': case ';':
Packit 709fb3
        case '<':
Packit 709fb3
        case '=': /* sometimes special in 0th or (with "set -k") later args */
Packit 709fb3
        case '>': case '[':
Packit 709fb3
        case '^': /* special in old /bin/sh, e.g. SunOS 4.1.4 */
Packit 709fb3
        case '`': case '|':
Packit 709fb3
          /* A shell special character.  In theory, '$' and '`' could
Packit 709fb3
             be the first bytes of multibyte characters, which means
Packit 709fb3
             we should check them with mbrtowc, but in practice this
Packit 709fb3
             doesn't happen so it's not worth worrying about.  */
Packit 709fb3
          if (quoting_style == shell_always_quoting_style
Packit 709fb3
              && elide_outer_quotes)
Packit 709fb3
            goto force_outer_quoting_style;
Packit 709fb3
          break;
Packit 709fb3
Packit 709fb3
        case '\'':
Packit 709fb3
          encountered_single_quote = true;
Packit 709fb3
          c_and_shell_quote_compat = true;
Packit 709fb3
          if (quoting_style == shell_always_quoting_style)
Packit 709fb3
            {
Packit 709fb3
              if (elide_outer_quotes)
Packit 709fb3
                goto force_outer_quoting_style;
Packit 709fb3
Packit 709fb3
              if (buffersize && ! orig_buffersize)
Packit 709fb3
                {
Packit 709fb3
                  /* Just scan string to see if supports a more concise
Packit 709fb3
                     representation, rather than writing a longer string
Packit 709fb3
                     but returning the length of the more concise form.  */
Packit 709fb3
                  orig_buffersize = buffersize;
Packit 709fb3
                  buffersize = 0;
Packit 709fb3
                }
Packit 709fb3
Packit 709fb3
              STORE ('\'');
Packit 709fb3
              STORE ('\\');
Packit 709fb3
              STORE ('\'');
Packit 709fb3
              pending_shell_escape_end = false;
Packit 709fb3
            }
Packit 709fb3
          break;
Packit 709fb3
Packit 709fb3
        case '%': case '+': case ',': case '-': case '.': case '/':
Packit 709fb3
        case '0': case '1': case '2': case '3': case '4': case '5':
Packit 709fb3
        case '6': case '7': case '8': case '9': case ':':
Packit 709fb3
        case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
Packit 709fb3
        case 'G': case 'H': case 'I': case 'J': case 'K': case 'L':
Packit 709fb3
        case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R':
Packit 709fb3
        case 'S': case 'T': case 'U': case 'V': case 'W': case 'X':
Packit 709fb3
        case 'Y': case 'Z': case ']': case '_': case 'a': case 'b':
Packit 709fb3
        case 'c': case 'd': case 'e': case 'f': case 'g': case 'h':
Packit 709fb3
        case 'i': case 'j': case 'k': case 'l': case 'm': case 'n':
Packit 709fb3
        case 'o': case 'p': case 'q': case 'r': case 's': case 't':
Packit 709fb3
        case 'u': case 'v': case 'w': case 'x': case 'y': case 'z':
Packit 709fb3
          /* These characters don't cause problems, no matter what the
Packit 709fb3
             quoting style is.  They cannot start multibyte sequences.
Packit 709fb3
             A digit or a special letter would cause trouble if it
Packit 709fb3
             appeared at the beginning of quote_string because we'd then
Packit 709fb3
             escape by prepending a backslash.  However, it's hard to
Packit 709fb3
             imagine any locale that would use digits or letters as
Packit 709fb3
             quotes, and set_custom_quoting is documented not to accept
Packit 709fb3
             them.  Also, a digit or a special letter would cause
Packit 709fb3
             trouble if it appeared in quote_these_too, but that's also
Packit 709fb3
             documented as not accepting them.  */
Packit 709fb3
          c_and_shell_quote_compat = true;
Packit 709fb3
          break;
Packit 709fb3
Packit 709fb3
        default:
Packit 709fb3
          /* If we have a multibyte sequence, copy it until we reach
Packit 709fb3
             its end, find an error, or come back to the initial shift
Packit 709fb3
             state.  For C-like styles, if the sequence has
Packit 709fb3
             unprintable characters, escape the whole sequence, since
Packit 709fb3
             we can't easily escape single characters within it.  */
Packit 709fb3
          {
Packit 709fb3
            /* Length of multibyte sequence found so far.  */
Packit 709fb3
            size_t m;
Packit 709fb3
Packit 709fb3
            bool printable;
Packit 709fb3
Packit 709fb3
            if (unibyte_locale)
Packit 709fb3
              {
Packit 709fb3
                m = 1;
Packit 709fb3
                printable = isprint (c) != 0;
Packit 709fb3
              }
Packit 709fb3
            else
Packit 709fb3
              {
Packit 709fb3
                mbstate_t mbstate;
Packit 709fb3
                memset (&mbstate, 0, sizeof mbstate);
Packit 709fb3
Packit 709fb3
                m = 0;
Packit 709fb3
                printable = true;
Packit 709fb3
                if (argsize == SIZE_MAX)
Packit 709fb3
                  argsize = strlen (arg);
Packit 709fb3
Packit 709fb3
                do
Packit 709fb3
                  {
Packit 709fb3
                    wchar_t w;
Packit 709fb3
                    size_t bytes = mbrtowc (&w, &arg[i + m],
Packit 709fb3
                                            argsize - (i + m), &mbstate);
Packit 709fb3
                    if (bytes == 0)
Packit 709fb3
                      break;
Packit 709fb3
                    else if (bytes == (size_t) -1)
Packit 709fb3
                      {
Packit 709fb3
                        printable = false;
Packit 709fb3
                        break;
Packit 709fb3
                      }
Packit 709fb3
                    else if (bytes == (size_t) -2)
Packit 709fb3
                      {
Packit 709fb3
                        printable = false;
Packit 709fb3
                        while (i + m < argsize && arg[i + m])
Packit 709fb3
                          m++;
Packit 709fb3
                        break;
Packit 709fb3
                      }
Packit 709fb3
                    else
Packit 709fb3
                      {
Packit 709fb3
                        /* Work around a bug with older shells that "see" a '\'
Packit 709fb3
                           that is really the 2nd byte of a multibyte character.
Packit 709fb3
                           In practice the problem is limited to ASCII
Packit 709fb3
                           chars >= '@' that are shell special chars.  */
Packit 709fb3
                        if ('[' == 0x5b && elide_outer_quotes
Packit 709fb3
                            && quoting_style == shell_always_quoting_style)
Packit 709fb3
                          {
Packit 709fb3
                            size_t j;
Packit 709fb3
                            for (j = 1; j < bytes; j++)
Packit 709fb3
                              switch (arg[i + m + j])
Packit 709fb3
                                {
Packit 709fb3
                                case '[': case '\\': case '^':
Packit 709fb3
                                case '`': case '|':
Packit 709fb3
                                  goto force_outer_quoting_style;
Packit 709fb3
Packit 709fb3
                                default:
Packit 709fb3
                                  break;
Packit 709fb3
                                }
Packit 709fb3
                          }
Packit 709fb3
Packit 709fb3
                        if (! iswprint (w))
Packit 709fb3
                          printable = false;
Packit 709fb3
                        m += bytes;
Packit 709fb3
                      }
Packit 709fb3
                  }
Packit 709fb3
                while (! mbsinit (&mbstate));
Packit 709fb3
              }
Packit 709fb3
Packit 709fb3
            c_and_shell_quote_compat = printable;
Packit 709fb3
Packit 709fb3
            if (1 < m || (backslash_escapes && ! printable))
Packit 709fb3
              {
Packit 709fb3
                /* Output a multibyte sequence, or an escaped
Packit 709fb3
                   unprintable unibyte character.  */
Packit 709fb3
                size_t ilim = i + m;
Packit 709fb3
Packit 709fb3
                for (;;)
Packit 709fb3
                  {
Packit 709fb3
                    if (backslash_escapes && ! printable)
Packit 709fb3
                      {
Packit 709fb3
                        START_ESC ();
Packit 709fb3
                        STORE ('0' + (c >> 6));
Packit 709fb3
                        STORE ('0' + ((c >> 3) & 7));
Packit 709fb3
                        c = '0' + (c & 7);
Packit 709fb3
                      }
Packit 709fb3
                    else if (is_right_quote)
Packit 709fb3
                      {
Packit 709fb3
                        STORE ('\\');
Packit 709fb3
                        is_right_quote = false;
Packit 709fb3
                      }
Packit 709fb3
                    if (ilim <= i + 1)
Packit 709fb3
                      break;
Packit 709fb3
                    END_ESC ();
Packit 709fb3
                    STORE (c);
Packit 709fb3
                    c = arg[++i];
Packit 709fb3
                  }
Packit 709fb3
Packit 709fb3
                goto store_c;
Packit 709fb3
              }
Packit 709fb3
          }
Packit 709fb3
        }
Packit 709fb3
Packit 709fb3
      if (! (((backslash_escapes && quoting_style != shell_always_quoting_style)
Packit 709fb3
              || elide_outer_quotes)
Packit 709fb3
             && quote_these_too
Packit 709fb3
             && quote_these_too[c / INT_BITS] >> (c % INT_BITS) & 1)
Packit 709fb3
          && !is_right_quote)
Packit 709fb3
        goto store_c;
Packit 709fb3
Packit 709fb3
    store_escape:
Packit 709fb3
      START_ESC ();
Packit 709fb3
Packit 709fb3
    store_c:
Packit 709fb3
      END_ESC ();
Packit 709fb3
      STORE (c);
Packit 709fb3
Packit 709fb3
      if (! c_and_shell_quote_compat)
Packit 709fb3
        all_c_and_shell_quote_compat = false;
Packit 709fb3
    }
Packit 709fb3
Packit 709fb3
  if (len == 0 && quoting_style == shell_always_quoting_style
Packit 709fb3
      && elide_outer_quotes)
Packit 709fb3
    goto force_outer_quoting_style;
Packit 709fb3
Packit 709fb3
  /* Single shell quotes (') are commonly enough used as an apostrophe,
Packit 709fb3
     that we attempt to minimize the quoting in this case.  Note itʼs
Packit 709fb3
     better to use the apostrophe modifier "\u02BC" if possible, as that
Packit 709fb3
     renders better and works with the word match regex \W+ etc.  */
Packit 709fb3
  if (quoting_style == shell_always_quoting_style && ! elide_outer_quotes
Packit 709fb3
      && encountered_single_quote)
Packit 709fb3
    {
Packit 709fb3
      if (all_c_and_shell_quote_compat)
Packit 709fb3
        return quotearg_buffer_restyled (buffer, orig_buffersize, arg, argsize,
Packit 709fb3
                                         c_quoting_style,
Packit 709fb3
                                         flags, quote_these_too,
Packit 709fb3
                                         left_quote, right_quote);
Packit 709fb3
      else if (! buffersize && orig_buffersize)
Packit 709fb3
        {
Packit 709fb3
          /* Disable read-only scan, and reprocess to write quoted string.  */
Packit 709fb3
          buffersize = orig_buffersize;
Packit 709fb3
          len = 0;
Packit 709fb3
          goto process_input;
Packit 709fb3
        }
Packit 709fb3
    }
Packit 709fb3
Packit 709fb3
  if (quote_string && !elide_outer_quotes)
Packit 709fb3
    for (; *quote_string; quote_string++)
Packit 709fb3
      STORE (*quote_string);
Packit 709fb3
Packit 709fb3
  if (len < buffersize)
Packit 709fb3
    buffer[len] = '\0';
Packit 709fb3
  return len;
Packit 709fb3
Packit 709fb3
 force_outer_quoting_style:
Packit 709fb3
  /* Don't reuse quote_these_too, since the addition of outer quotes
Packit 709fb3
     sufficiently quotes the specified characters.  */
Packit 709fb3
  if (quoting_style == shell_always_quoting_style && backslash_escapes)
Packit 709fb3
    quoting_style = shell_escape_always_quoting_style;
Packit 709fb3
  return quotearg_buffer_restyled (buffer, buffersize, arg, argsize,
Packit 709fb3
                                   quoting_style,
Packit 709fb3
                                   flags & ~QA_ELIDE_OUTER_QUOTES, NULL,
Packit 709fb3
                                   left_quote, right_quote);
Packit 709fb3
}
Packit 709fb3
Packit 709fb3
/* Place into buffer BUFFER (of size BUFFERSIZE) a quoted version of
Packit 709fb3
   argument ARG (of size ARGSIZE), using O to control quoting.
Packit 709fb3
   If O is null, use the default.
Packit 709fb3
   Terminate the output with a null character, and return the written
Packit 709fb3
   size of the output, not counting the terminating null.
Packit 709fb3
   If BUFFERSIZE is too small to store the output string, return the
Packit 709fb3
   value that would have been returned had BUFFERSIZE been large enough.
Packit 709fb3
   If ARGSIZE is SIZE_MAX, use the string length of the argument for
Packit 709fb3
   ARGSIZE.  */
Packit 709fb3
size_t
Packit 709fb3
quotearg_buffer (char *buffer, size_t buffersize,
Packit 709fb3
                 char const *arg, size_t argsize,
Packit 709fb3
                 struct quoting_options const *o)
Packit 709fb3
{
Packit 709fb3
  struct quoting_options const *p = o ? o : &default_quoting_options;
Packit 709fb3
  int e = errno;
Packit 709fb3
  size_t r = quotearg_buffer_restyled (buffer, buffersize, arg, argsize,
Packit 709fb3
                                       p->style, p->flags, p->quote_these_too,
Packit 709fb3
                                       p->left_quote, p->right_quote);
Packit 709fb3
  errno = e;
Packit 709fb3
  return r;
Packit 709fb3
}
Packit 709fb3
Packit 709fb3
/* Equivalent to quotearg_alloc (ARG, ARGSIZE, NULL, O).  */
Packit 709fb3
char *
Packit 709fb3
quotearg_alloc (char const *arg, size_t argsize,
Packit 709fb3
                struct quoting_options const *o)
Packit 709fb3
{
Packit 709fb3
  return quotearg_alloc_mem (arg, argsize, NULL, o);
Packit 709fb3
}
Packit 709fb3
Packit 709fb3
/* Like quotearg_buffer (..., ARG, ARGSIZE, O), except return newly
Packit 709fb3
   allocated storage containing the quoted string, and store the
Packit 709fb3
   resulting size into *SIZE, if non-NULL.  The result can contain
Packit 709fb3
   embedded null bytes only if ARGSIZE is not SIZE_MAX, SIZE is not
Packit 709fb3
   NULL, and set_quoting_flags has not set the null byte elision
Packit 709fb3
   flag.  */
Packit 709fb3
char *
Packit 709fb3
quotearg_alloc_mem (char const *arg, size_t argsize, size_t *size,
Packit 709fb3
                    struct quoting_options const *o)
Packit 709fb3
{
Packit 709fb3
  struct quoting_options const *p = o ? o : &default_quoting_options;
Packit 709fb3
  int e = errno;
Packit 709fb3
  /* Elide embedded null bytes if we can't return a size.  */
Packit 709fb3
  int flags = p->flags | (size ? 0 : QA_ELIDE_NULL_BYTES);
Packit 709fb3
  size_t bufsize = quotearg_buffer_restyled (0, 0, arg, argsize, p->style,
Packit 709fb3
                                             flags, p->quote_these_too,
Packit 709fb3
                                             p->left_quote,
Packit 709fb3
                                             p->right_quote) + 1;
Packit 709fb3
  char *buf = xcharalloc (bufsize);
Packit 709fb3
  quotearg_buffer_restyled (buf, bufsize, arg, argsize, p->style, flags,
Packit 709fb3
                            p->quote_these_too,
Packit 709fb3
                            p->left_quote, p->right_quote);
Packit 709fb3
  errno = e;
Packit 709fb3
  if (size)
Packit 709fb3
    *size = bufsize - 1;
Packit 709fb3
  return buf;
Packit 709fb3
}
Packit 709fb3
Packit 709fb3
/* A storage slot with size and pointer to a value.  */
Packit 709fb3
struct slotvec
Packit 709fb3
{
Packit 709fb3
  size_t size;
Packit 709fb3
  char *val;
Packit 709fb3
};
Packit 709fb3
Packit 709fb3
/* Preallocate a slot 0 buffer, so that the caller can always quote
Packit 709fb3
   one small component of a "memory exhausted" message in slot 0.  */
Packit 709fb3
static char slot0[256];
Packit 709fb3
static int nslots = 1;
Packit 709fb3
static struct slotvec slotvec0 = {sizeof slot0, slot0};
Packit 709fb3
static struct slotvec *slotvec = &slotvec0;
Packit 709fb3
Packit 709fb3
void
Packit 709fb3
quotearg_free (void)
Packit 709fb3
{
Packit 709fb3
  struct slotvec *sv = slotvec;
Packit 709fb3
  int i;
Packit 709fb3
  for (i = 1; i < nslots; i++)
Packit 709fb3
    free (sv[i].val);
Packit 709fb3
  if (sv[0].val != slot0)
Packit 709fb3
    {
Packit 709fb3
      free (sv[0].val);
Packit 709fb3
      slotvec0.size = sizeof slot0;
Packit 709fb3
      slotvec0.val = slot0;
Packit 709fb3
    }
Packit 709fb3
  if (sv != &slotvec0)
Packit 709fb3
    {
Packit 709fb3
      free (sv);
Packit 709fb3
      slotvec = &slotvec0;
Packit 709fb3
    }
Packit 709fb3
  nslots = 1;
Packit 709fb3
}
Packit 709fb3
Packit 709fb3
/* Use storage slot N to return a quoted version of argument ARG.
Packit 709fb3
   ARG is of size ARGSIZE, but if that is SIZE_MAX, ARG is a
Packit 709fb3
   null-terminated string.
Packit 709fb3
   OPTIONS specifies the quoting options.
Packit 709fb3
   The returned value points to static storage that can be
Packit 709fb3
   reused by the next call to this function with the same value of N.
Packit 709fb3
   N must be nonnegative.  N is deliberately declared with type "int"
Packit 709fb3
   to allow for future extensions (using negative values).  */
Packit 709fb3
static char *
Packit 709fb3
quotearg_n_options (int n, char const *arg, size_t argsize,
Packit 709fb3
                    struct quoting_options const *options)
Packit 709fb3
{
Packit 709fb3
  int e = errno;
Packit 709fb3
Packit 709fb3
  struct slotvec *sv = slotvec;
Packit 709fb3
Packit 709fb3
  if (n < 0)
Packit 709fb3
    abort ();
Packit 709fb3
Packit 709fb3
  if (nslots <= n)
Packit 709fb3
    {
Packit 709fb3
      bool preallocated = (sv == &slotvec0);
Packit 709fb3
Packit 709fb3
      if (MIN (INT_MAX, MIN (PTRDIFF_MAX, SIZE_MAX) / sizeof *sv) <= n)
Packit 709fb3
        xalloc_die ();
Packit 709fb3
Packit 709fb3
      slotvec = sv = xrealloc (preallocated ? NULL : sv, (n + 1) * sizeof *sv);
Packit 709fb3
      if (preallocated)
Packit 709fb3
        *sv = slotvec0;
Packit 709fb3
      memset (sv + nslots, 0, (n + 1 - nslots) * sizeof *sv);
Packit 709fb3
      nslots = n + 1;
Packit 709fb3
    }
Packit 709fb3
Packit 709fb3
  {
Packit 709fb3
    size_t size = sv[n].size;
Packit 709fb3
    char *val = sv[n].val;
Packit 709fb3
    /* Elide embedded null bytes since we don't return a size.  */
Packit 709fb3
    int flags = options->flags | QA_ELIDE_NULL_BYTES;
Packit 709fb3
    size_t qsize = quotearg_buffer_restyled (val, size, arg, argsize,
Packit 709fb3
                                             options->style, flags,
Packit 709fb3
                                             options->quote_these_too,
Packit 709fb3
                                             options->left_quote,
Packit 709fb3
                                             options->right_quote);
Packit 709fb3
Packit 709fb3
    if (size <= qsize)
Packit 709fb3
      {
Packit 709fb3
        sv[n].size = size = qsize + 1;
Packit 709fb3
        if (val != slot0)
Packit 709fb3
          free (val);
Packit 709fb3
        sv[n].val = val = xcharalloc (size);
Packit 709fb3
        quotearg_buffer_restyled (val, size, arg, argsize, options->style,
Packit 709fb3
                                  flags, options->quote_these_too,
Packit 709fb3
                                  options->left_quote,
Packit 709fb3
                                  options->right_quote);
Packit 709fb3
      }
Packit 709fb3
Packit 709fb3
    errno = e;
Packit 709fb3
    return val;
Packit 709fb3
  }
Packit 709fb3
}
Packit 709fb3
Packit 709fb3
char *
Packit 709fb3
quotearg_n (int n, char const *arg)
Packit 709fb3
{
Packit 709fb3
  return quotearg_n_options (n, arg, SIZE_MAX, &default_quoting_options);
Packit 709fb3
}
Packit 709fb3
Packit 709fb3
char *
Packit 709fb3
quotearg_n_mem (int n, char const *arg, size_t argsize)
Packit 709fb3
{
Packit 709fb3
  return quotearg_n_options (n, arg, argsize, &default_quoting_options);
Packit 709fb3
}
Packit 709fb3
Packit 709fb3
char *
Packit 709fb3
quotearg (char const *arg)
Packit 709fb3
{
Packit 709fb3
  return quotearg_n (0, arg);
Packit 709fb3
}
Packit 709fb3
Packit 709fb3
char *
Packit 709fb3
quotearg_mem (char const *arg, size_t argsize)
Packit 709fb3
{
Packit 709fb3
  return quotearg_n_mem (0, arg, argsize);
Packit 709fb3
}
Packit 709fb3
Packit 709fb3
char *
Packit 709fb3
quotearg_n_style (int n, enum quoting_style s, char const *arg)
Packit 709fb3
{
Packit 709fb3
  struct quoting_options const o = quoting_options_from_style (s);
Packit 709fb3
  return quotearg_n_options (n, arg, SIZE_MAX, &o);
Packit 709fb3
}
Packit 709fb3
Packit 709fb3
char *
Packit 709fb3
quotearg_n_style_mem (int n, enum quoting_style s,
Packit 709fb3
                      char const *arg, size_t argsize)
Packit 709fb3
{
Packit 709fb3
  struct quoting_options const o = quoting_options_from_style (s);
Packit 709fb3
  return quotearg_n_options (n, arg, argsize, &o);
Packit 709fb3
}
Packit 709fb3
Packit 709fb3
char *
Packit 709fb3
quotearg_style (enum quoting_style s, char const *arg)
Packit 709fb3
{
Packit 709fb3
  return quotearg_n_style (0, s, arg);
Packit 709fb3
}
Packit 709fb3
Packit 709fb3
char *
Packit 709fb3
quotearg_style_mem (enum quoting_style s, char const *arg, size_t argsize)
Packit 709fb3
{
Packit 709fb3
  return quotearg_n_style_mem (0, s, arg, argsize);
Packit 709fb3
}
Packit 709fb3
Packit 709fb3
char *
Packit 709fb3
quotearg_char_mem (char const *arg, size_t argsize, char ch)
Packit 709fb3
{
Packit 709fb3
  struct quoting_options options;
Packit 709fb3
  options = default_quoting_options;
Packit 709fb3
  set_char_quoting (&options, ch, 1);
Packit 709fb3
  return quotearg_n_options (0, arg, argsize, &options);
Packit 709fb3
}
Packit 709fb3
Packit 709fb3
char *
Packit 709fb3
quotearg_char (char const *arg, char ch)
Packit 709fb3
{
Packit 709fb3
  return quotearg_char_mem (arg, SIZE_MAX, ch);
Packit 709fb3
}
Packit 709fb3
Packit 709fb3
char *
Packit 709fb3
quotearg_colon (char const *arg)
Packit 709fb3
{
Packit 709fb3
  return quotearg_char (arg, ':');
Packit 709fb3
}
Packit 709fb3
Packit 709fb3
char *
Packit 709fb3
quotearg_colon_mem (char const *arg, size_t argsize)
Packit 709fb3
{
Packit 709fb3
  return quotearg_char_mem (arg, argsize, ':');
Packit 709fb3
}
Packit 709fb3
Packit 709fb3
char *
Packit 709fb3
quotearg_n_style_colon (int n, enum quoting_style s, char const *arg)
Packit 709fb3
{
Packit 709fb3
  struct quoting_options options;
Packit 709fb3
  options = quoting_options_from_style (s);
Packit 709fb3
  set_char_quoting (&options, ':', 1);
Packit 709fb3
  return quotearg_n_options (n, arg, SIZE_MAX, &options);
Packit 709fb3
}
Packit 709fb3
Packit 709fb3
char *
Packit 709fb3
quotearg_n_custom (int n, char const *left_quote,
Packit 709fb3
                   char const *right_quote, char const *arg)
Packit 709fb3
{
Packit 709fb3
  return quotearg_n_custom_mem (n, left_quote, right_quote, arg,
Packit 709fb3
                                SIZE_MAX);
Packit 709fb3
}
Packit 709fb3
Packit 709fb3
char *
Packit 709fb3
quotearg_n_custom_mem (int n, char const *left_quote,
Packit 709fb3
                       char const *right_quote,
Packit 709fb3
                       char const *arg, size_t argsize)
Packit 709fb3
{
Packit 709fb3
  struct quoting_options o = default_quoting_options;
Packit 709fb3
  set_custom_quoting (&o, left_quote, right_quote);
Packit 709fb3
  return quotearg_n_options (n, arg, argsize, &o);
Packit 709fb3
}
Packit 709fb3
Packit 709fb3
char *
Packit 709fb3
quotearg_custom (char const *left_quote, char const *right_quote,
Packit 709fb3
                 char const *arg)
Packit 709fb3
{
Packit 709fb3
  return quotearg_n_custom (0, left_quote, right_quote, arg);
Packit 709fb3
}
Packit 709fb3
Packit 709fb3
char *
Packit 709fb3
quotearg_custom_mem (char const *left_quote, char const *right_quote,
Packit 709fb3
                     char const *arg, size_t argsize)
Packit 709fb3
{
Packit 709fb3
  return quotearg_n_custom_mem (0, left_quote, right_quote, arg,
Packit 709fb3
                                argsize);
Packit 709fb3
}
Packit 709fb3
Packit 709fb3
Packit 709fb3
/* The quoting option used by the functions of quote.h.  */
Packit 709fb3
struct quoting_options quote_quoting_options =
Packit 709fb3
  {
Packit 709fb3
    locale_quoting_style,
Packit 709fb3
    0,
Packit 709fb3
    { 0 },
Packit 709fb3
    NULL, NULL
Packit 709fb3
  };
Packit 709fb3
Packit 709fb3
char const *
Packit 709fb3
quote_n_mem (int n, char const *arg, size_t argsize)
Packit 709fb3
{
Packit 709fb3
  return quotearg_n_options (n, arg, argsize, &quote_quoting_options);
Packit 709fb3
}
Packit 709fb3
Packit 709fb3
char const *
Packit 709fb3
quote_mem (char const *arg, size_t argsize)
Packit 709fb3
{
Packit 709fb3
  return quote_n_mem (0, arg, argsize);
Packit 709fb3
}
Packit 709fb3
Packit 709fb3
char const *
Packit 709fb3
quote_n (int n, char const *arg)
Packit 709fb3
{
Packit 709fb3
  return quote_n_mem (n, arg, SIZE_MAX);
Packit 709fb3
}
Packit 709fb3
Packit 709fb3
char const *
Packit 709fb3
quote (char const *arg)
Packit 709fb3
{
Packit 709fb3
  return quote_n (0, arg);
Packit 709fb3
}