Blame lib/quotearg.c

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