Blame lib/quotearg.c.covscan

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