Blame lib/quotearg.c

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