1cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project/* quotearg.c - quote arguments for output
2cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project
305436638acc7c010349a69c3395f1a57c642dc62Ying Wang   Copyright (C) 1998-2002, 2004-2012 Free Software Foundation, Inc.
4cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project
505436638acc7c010349a69c3395f1a57c642dc62Ying Wang   This program is free software: you can redistribute it and/or modify
6cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project   it under the terms of the GNU General Public License as published by
705436638acc7c010349a69c3395f1a57c642dc62Ying Wang   the Free Software Foundation; either version 3 of the License, or
805436638acc7c010349a69c3395f1a57c642dc62Ying Wang   (at your option) any later version.
9cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project
10cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project   This program is distributed in the hope that it will be useful,
11cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project   but WITHOUT ANY WARRANTY; without even the implied warranty of
12cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project   GNU General Public License for more details.
14cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project
15cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project   You should have received a copy of the GNU General Public License
1605436638acc7c010349a69c3395f1a57c642dc62Ying Wang   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
17cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project
18cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project/* Written by Paul Eggert <eggert@twinsun.com> */
19cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project
2005436638acc7c010349a69c3395f1a57c642dc62Ying Wang/* Without this pragma, gcc 4.7.0 20111124 mistakenly suggests that
2105436638acc7c010349a69c3395f1a57c642dc62Ying Wang   the quoting_options_from_style function might be candidate for
2205436638acc7c010349a69c3395f1a57c642dc62Ying Wang   attribute 'pure'  */
2305436638acc7c010349a69c3395f1a57c642dc62Ying Wang#if (__GNUC__ == 4 && 6 <= __GNUC_MINOR__) || 4 < __GNUC__
2405436638acc7c010349a69c3395f1a57c642dc62Ying Wang# pragma GCC diagnostic ignored "-Wsuggest-attribute=pure"
25cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project#endif
26cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project
2705436638acc7c010349a69c3395f1a57c642dc62Ying Wang#include <config.h>
2805436638acc7c010349a69c3395f1a57c642dc62Ying Wang
29cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project#include "quotearg.h"
3005436638acc7c010349a69c3395f1a57c642dc62Ying Wang#include "quote.h"
31cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project
32cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project#include "xalloc.h"
3305436638acc7c010349a69c3395f1a57c642dc62Ying Wang#include "c-strcaseeq.h"
3405436638acc7c010349a69c3395f1a57c642dc62Ying Wang#include "localcharset.h"
35cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project
36cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project#include <ctype.h>
37cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project#include <errno.h>
38cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project#include <limits.h>
39cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project#include <stdbool.h>
40cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project#include <stdlib.h>
41cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project#include <string.h>
4205436638acc7c010349a69c3395f1a57c642dc62Ying Wang#include <wchar.h>
4305436638acc7c010349a69c3395f1a57c642dc62Ying Wang#include <wctype.h>
44cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project
45cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project#include "gettext.h"
46cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project#define _(msgid) gettext (msgid)
47cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project#define N_(msgid) msgid
48cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project
49cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project#ifndef SIZE_MAX
50cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project# define SIZE_MAX ((size_t) -1)
51cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project#endif
52cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project
53cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project#define INT_BITS (sizeof (int) * CHAR_BIT)
54cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project
55cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Projectstruct quoting_options
56cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project{
57cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project  /* Basic quoting style.  */
58cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project  enum quoting_style style;
59cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project
6005436638acc7c010349a69c3395f1a57c642dc62Ying Wang  /* Additional flags.  Bitwise combination of enum quoting_flags.  */
6105436638acc7c010349a69c3395f1a57c642dc62Ying Wang  int flags;
6205436638acc7c010349a69c3395f1a57c642dc62Ying Wang
63cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project  /* Quote the characters indicated by this bit vector even if the
64cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project     quoting style would not normally require them to be quoted.  */
65cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project  unsigned int quote_these_too[(UCHAR_MAX / INT_BITS) + 1];
6605436638acc7c010349a69c3395f1a57c642dc62Ying Wang
6705436638acc7c010349a69c3395f1a57c642dc62Ying Wang  /* The left quote for custom_quoting_style.  */
6805436638acc7c010349a69c3395f1a57c642dc62Ying Wang  char const *left_quote;
6905436638acc7c010349a69c3395f1a57c642dc62Ying Wang
7005436638acc7c010349a69c3395f1a57c642dc62Ying Wang  /* The right quote for custom_quoting_style.  */
7105436638acc7c010349a69c3395f1a57c642dc62Ying Wang  char const *right_quote;
72cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project};
73cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project
74cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project/* Names of quoting styles.  */
75cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Projectchar const *const quoting_style_args[] =
76cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project{
77cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project  "literal",
78cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project  "shell",
79cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project  "shell-always",
80cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project  "c",
8105436638acc7c010349a69c3395f1a57c642dc62Ying Wang  "c-maybe",
82cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project  "escape",
83cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project  "locale",
84cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project  "clocale",
85cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project  0
86cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project};
87cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project
88cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project/* Correspondences to quoting style names.  */
89cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Projectenum quoting_style const quoting_style_vals[] =
90cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project{
91cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project  literal_quoting_style,
92cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project  shell_quoting_style,
93cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project  shell_always_quoting_style,
94cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project  c_quoting_style,
9505436638acc7c010349a69c3395f1a57c642dc62Ying Wang  c_maybe_quoting_style,
96cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project  escape_quoting_style,
97cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project  locale_quoting_style,
98cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project  clocale_quoting_style
99cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project};
100cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project
101cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project/* The default quoting options.  */
102cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Projectstatic struct quoting_options default_quoting_options;
103cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project
104cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project/* Allocate a new set of quoting options, with contents initially identical
105cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project   to O if O is not null, or to the default if O is null.
106cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project   It is the caller's responsibility to free the result.  */
107cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Projectstruct quoting_options *
108cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Projectclone_quoting_options (struct quoting_options *o)
109cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project{
110cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project  int e = errno;
11105436638acc7c010349a69c3395f1a57c642dc62Ying Wang  struct quoting_options *p = xmemdup (o ? o : &default_quoting_options,
11205436638acc7c010349a69c3395f1a57c642dc62Ying Wang                                       sizeof *o);
113cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project  errno = e;
114cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project  return p;
115cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project}
116cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project
117cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project/* Get the value of O's quoting style.  If O is null, use the default.  */
118cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Projectenum quoting_style
119cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Projectget_quoting_style (struct quoting_options *o)
120cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project{
121cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project  return (o ? o : &default_quoting_options)->style;
122cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project}
123cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project
124cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project/* In O (or in the default if O is null),
125cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project   set the value of the quoting style to S.  */
126cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Projectvoid
127cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Projectset_quoting_style (struct quoting_options *o, enum quoting_style s)
128cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project{
129cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project  (o ? o : &default_quoting_options)->style = s;
130cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project}
131cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project
132cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project/* In O (or in the default if O is null),
133cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project   set the value of the quoting options for character C to I.
134cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project   Return the old value.  Currently, the only values defined for I are
135cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project   0 (the default) and 1 (which means to quote the character even if
136cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project   it would not otherwise be quoted).  */
137cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Projectint
138cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Projectset_char_quoting (struct quoting_options *o, char c, int i)
139cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project{
140cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project  unsigned char uc = c;
141cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project  unsigned int *p =
142cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project    (o ? o : &default_quoting_options)->quote_these_too + uc / INT_BITS;
143cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project  int shift = uc % INT_BITS;
144cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project  int r = (*p >> shift) & 1;
145cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project  *p ^= ((i & 1) ^ r) << shift;
146cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project  return r;
147cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project}
148cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project
14905436638acc7c010349a69c3395f1a57c642dc62Ying Wang/* In O (or in the default if O is null),
15005436638acc7c010349a69c3395f1a57c642dc62Ying Wang   set the value of the quoting options flag to I, which can be a
15105436638acc7c010349a69c3395f1a57c642dc62Ying Wang   bitwise combination of enum quoting_flags, or 0 for default
15205436638acc7c010349a69c3395f1a57c642dc62Ying Wang   behavior.  Return the old value.  */
15305436638acc7c010349a69c3395f1a57c642dc62Ying Wangint
15405436638acc7c010349a69c3395f1a57c642dc62Ying Wangset_quoting_flags (struct quoting_options *o, int i)
15505436638acc7c010349a69c3395f1a57c642dc62Ying Wang{
15605436638acc7c010349a69c3395f1a57c642dc62Ying Wang  int r;
15705436638acc7c010349a69c3395f1a57c642dc62Ying Wang  if (!o)
15805436638acc7c010349a69c3395f1a57c642dc62Ying Wang    o = &default_quoting_options;
15905436638acc7c010349a69c3395f1a57c642dc62Ying Wang  r = o->flags;
16005436638acc7c010349a69c3395f1a57c642dc62Ying Wang  o->flags = i;
16105436638acc7c010349a69c3395f1a57c642dc62Ying Wang  return r;
16205436638acc7c010349a69c3395f1a57c642dc62Ying Wang}
16305436638acc7c010349a69c3395f1a57c642dc62Ying Wang
16405436638acc7c010349a69c3395f1a57c642dc62Ying Wangvoid
16505436638acc7c010349a69c3395f1a57c642dc62Ying Wangset_custom_quoting (struct quoting_options *o,
16605436638acc7c010349a69c3395f1a57c642dc62Ying Wang                    char const *left_quote, char const *right_quote)
16705436638acc7c010349a69c3395f1a57c642dc62Ying Wang{
16805436638acc7c010349a69c3395f1a57c642dc62Ying Wang  if (!o)
16905436638acc7c010349a69c3395f1a57c642dc62Ying Wang    o = &default_quoting_options;
17005436638acc7c010349a69c3395f1a57c642dc62Ying Wang  o->style = custom_quoting_style;
17105436638acc7c010349a69c3395f1a57c642dc62Ying Wang  if (!left_quote || !right_quote)
17205436638acc7c010349a69c3395f1a57c642dc62Ying Wang    abort ();
17305436638acc7c010349a69c3395f1a57c642dc62Ying Wang  o->left_quote = left_quote;
17405436638acc7c010349a69c3395f1a57c642dc62Ying Wang  o->right_quote = right_quote;
17505436638acc7c010349a69c3395f1a57c642dc62Ying Wang}
17605436638acc7c010349a69c3395f1a57c642dc62Ying Wang
17705436638acc7c010349a69c3395f1a57c642dc62Ying Wang/* Return quoting options for STYLE, with no extra quoting.  */
17805436638acc7c010349a69c3395f1a57c642dc62Ying Wangstatic struct quoting_options /* NOT PURE!! */
17905436638acc7c010349a69c3395f1a57c642dc62Ying Wangquoting_options_from_style (enum quoting_style style)
18005436638acc7c010349a69c3395f1a57c642dc62Ying Wang{
18105436638acc7c010349a69c3395f1a57c642dc62Ying Wang  struct quoting_options o = { 0, 0, { 0 }, NULL, NULL };
18205436638acc7c010349a69c3395f1a57c642dc62Ying Wang  if (style == custom_quoting_style)
18305436638acc7c010349a69c3395f1a57c642dc62Ying Wang    abort ();
18405436638acc7c010349a69c3395f1a57c642dc62Ying Wang  o.style = style;
18505436638acc7c010349a69c3395f1a57c642dc62Ying Wang  return o;
18605436638acc7c010349a69c3395f1a57c642dc62Ying Wang}
18705436638acc7c010349a69c3395f1a57c642dc62Ying Wang
188cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project/* MSGID approximates a quotation mark.  Return its translation if it
18905436638acc7c010349a69c3395f1a57c642dc62Ying Wang   has one; otherwise, return either it or "\"", depending on S.
19005436638acc7c010349a69c3395f1a57c642dc62Ying Wang
19105436638acc7c010349a69c3395f1a57c642dc62Ying Wang   S is either clocale_quoting_style or locale_quoting_style.  */
192cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Projectstatic char const *
193cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Projectgettext_quote (char const *msgid, enum quoting_style s)
194cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project{
195cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project  char const *translation = _(msgid);
19605436638acc7c010349a69c3395f1a57c642dc62Ying Wang  char const *locale_code;
19705436638acc7c010349a69c3395f1a57c642dc62Ying Wang
19805436638acc7c010349a69c3395f1a57c642dc62Ying Wang  if (translation != msgid)
19905436638acc7c010349a69c3395f1a57c642dc62Ying Wang    return translation;
20005436638acc7c010349a69c3395f1a57c642dc62Ying Wang
20105436638acc7c010349a69c3395f1a57c642dc62Ying Wang  /* For UTF-8 and GB-18030, use single quotes U+2018 and U+2019.
20205436638acc7c010349a69c3395f1a57c642dc62Ying Wang     Here is a list of other locales that include U+2018 and U+2019:
20305436638acc7c010349a69c3395f1a57c642dc62Ying Wang
20405436638acc7c010349a69c3395f1a57c642dc62Ying Wang        ISO-8859-7   0xA1                 KOI8-T       0x91
20505436638acc7c010349a69c3395f1a57c642dc62Ying Wang        CP869        0x8B                 CP874        0x91
20605436638acc7c010349a69c3395f1a57c642dc62Ying Wang        CP932        0x81 0x65            CP936        0xA1 0xAE
20705436638acc7c010349a69c3395f1a57c642dc62Ying Wang        CP949        0xA1 0xAE            CP950        0xA1 0xA5
20805436638acc7c010349a69c3395f1a57c642dc62Ying Wang        CP1250       0x91                 CP1251       0x91
20905436638acc7c010349a69c3395f1a57c642dc62Ying Wang        CP1252       0x91                 CP1253       0x91
21005436638acc7c010349a69c3395f1a57c642dc62Ying Wang        CP1254       0x91                 CP1255       0x91
21105436638acc7c010349a69c3395f1a57c642dc62Ying Wang        CP1256       0x91                 CP1257       0x91
21205436638acc7c010349a69c3395f1a57c642dc62Ying Wang        EUC-JP       0xA1 0xC6            EUC-KR       0xA1 0xAE
21305436638acc7c010349a69c3395f1a57c642dc62Ying Wang        EUC-TW       0xA1 0xE4            BIG5         0xA1 0xA5
21405436638acc7c010349a69c3395f1a57c642dc62Ying Wang        BIG5-HKSCS   0xA1 0xA5            EUC-CN       0xA1 0xAE
21505436638acc7c010349a69c3395f1a57c642dc62Ying Wang        GBK          0xA1 0xAE            Georgian-PS  0x91
21605436638acc7c010349a69c3395f1a57c642dc62Ying Wang        PT154        0x91
21705436638acc7c010349a69c3395f1a57c642dc62Ying Wang
21805436638acc7c010349a69c3395f1a57c642dc62Ying Wang     None of these is still in wide use; using iconv is overkill.  */
21905436638acc7c010349a69c3395f1a57c642dc62Ying Wang  locale_code = locale_charset ();
22005436638acc7c010349a69c3395f1a57c642dc62Ying Wang  if (STRCASEEQ (locale_code, "UTF-8", 'U','T','F','-','8',0,0,0,0))
22105436638acc7c010349a69c3395f1a57c642dc62Ying Wang    return msgid[0] == '`' ? "\xe2\x80\x98": "\xe2\x80\x99";
22205436638acc7c010349a69c3395f1a57c642dc62Ying Wang  if (STRCASEEQ (locale_code, "GB18030", 'G','B','1','8','0','3','0',0,0))
22305436638acc7c010349a69c3395f1a57c642dc62Ying Wang    return msgid[0] == '`' ? "\xa1\ae": "\xa1\xaf";
22405436638acc7c010349a69c3395f1a57c642dc62Ying Wang
22505436638acc7c010349a69c3395f1a57c642dc62Ying Wang  return (s == clocale_quoting_style ? "\"" : "'");
226cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project}
227cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project
228cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project/* Place into buffer BUFFER (of size BUFFERSIZE) a quoted version of
22905436638acc7c010349a69c3395f1a57c642dc62Ying Wang   argument ARG (of size ARGSIZE), using QUOTING_STYLE, FLAGS, and
23005436638acc7c010349a69c3395f1a57c642dc62Ying Wang   QUOTE_THESE_TOO to control quoting.
231cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project   Terminate the output with a null character, and return the written
232cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project   size of the output, not counting the terminating null.
233cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project   If BUFFERSIZE is too small to store the output string, return the
234cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project   value that would have been returned had BUFFERSIZE been large enough.
235cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project   If ARGSIZE is SIZE_MAX, use the string length of the argument for ARGSIZE.
236cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project
237cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project   This function acts like quotearg_buffer (BUFFER, BUFFERSIZE, ARG,
23805436638acc7c010349a69c3395f1a57c642dc62Ying Wang   ARGSIZE, O), except it breaks O into its component pieces and is
23905436638acc7c010349a69c3395f1a57c642dc62Ying Wang   not careful about errno.  */
240cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project
241cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Projectstatic size_t
242cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Projectquotearg_buffer_restyled (char *buffer, size_t buffersize,
24305436638acc7c010349a69c3395f1a57c642dc62Ying Wang                          char const *arg, size_t argsize,
24405436638acc7c010349a69c3395f1a57c642dc62Ying Wang                          enum quoting_style quoting_style, int flags,
24505436638acc7c010349a69c3395f1a57c642dc62Ying Wang                          unsigned int const *quote_these_too,
24605436638acc7c010349a69c3395f1a57c642dc62Ying Wang                          char const *left_quote,
24705436638acc7c010349a69c3395f1a57c642dc62Ying Wang                          char const *right_quote)
248cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project{
249cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project  size_t i;
250cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project  size_t len = 0;
251cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project  char const *quote_string = 0;
252cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project  size_t quote_string_len = 0;
253cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project  bool backslash_escapes = false;
254cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project  bool unibyte_locale = MB_CUR_MAX == 1;
25505436638acc7c010349a69c3395f1a57c642dc62Ying Wang  bool elide_outer_quotes = (flags & QA_ELIDE_OUTER_QUOTES) != 0;
256cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project
257cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project#define STORE(c) \
258cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project    do \
259cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project      { \
26005436638acc7c010349a69c3395f1a57c642dc62Ying Wang        if (len < buffersize) \
26105436638acc7c010349a69c3395f1a57c642dc62Ying Wang          buffer[len] = (c); \
26205436638acc7c010349a69c3395f1a57c642dc62Ying Wang        len++; \
263cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project      } \
264cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project    while (0)
265cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project
266cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project  switch (quoting_style)
267cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project    {
26805436638acc7c010349a69c3395f1a57c642dc62Ying Wang    case c_maybe_quoting_style:
26905436638acc7c010349a69c3395f1a57c642dc62Ying Wang      quoting_style = c_quoting_style;
27005436638acc7c010349a69c3395f1a57c642dc62Ying Wang      elide_outer_quotes = true;
27105436638acc7c010349a69c3395f1a57c642dc62Ying Wang      /* Fall through.  */
272cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project    case c_quoting_style:
27305436638acc7c010349a69c3395f1a57c642dc62Ying Wang      if (!elide_outer_quotes)
27405436638acc7c010349a69c3395f1a57c642dc62Ying Wang        STORE ('"');
275cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project      backslash_escapes = true;
276cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project      quote_string = "\"";
277cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project      quote_string_len = 1;
278cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project      break;
279cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project
280cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project    case escape_quoting_style:
281cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project      backslash_escapes = true;
28205436638acc7c010349a69c3395f1a57c642dc62Ying Wang      elide_outer_quotes = false;
283cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project      break;
284cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project
285cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project    case locale_quoting_style:
286cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project    case clocale_quoting_style:
28705436638acc7c010349a69c3395f1a57c642dc62Ying Wang    case custom_quoting_style:
288cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project      {
28905436638acc7c010349a69c3395f1a57c642dc62Ying Wang        if (quoting_style != custom_quoting_style)
29005436638acc7c010349a69c3395f1a57c642dc62Ying Wang          {
29105436638acc7c010349a69c3395f1a57c642dc62Ying Wang            /* TRANSLATORS:
29205436638acc7c010349a69c3395f1a57c642dc62Ying Wang               Get translations for open and closing quotation marks.
29305436638acc7c010349a69c3395f1a57c642dc62Ying Wang               The message catalog should translate "`" to a left
29405436638acc7c010349a69c3395f1a57c642dc62Ying Wang               quotation mark suitable for the locale, and similarly for
29505436638acc7c010349a69c3395f1a57c642dc62Ying Wang               "'".  For example, a French Unicode local should translate
29605436638acc7c010349a69c3395f1a57c642dc62Ying Wang               these to U+00AB (LEFT-POINTING DOUBLE ANGLE
29705436638acc7c010349a69c3395f1a57c642dc62Ying Wang               QUOTATION MARK), and U+00BB (RIGHT-POINTING DOUBLE ANGLE
29805436638acc7c010349a69c3395f1a57c642dc62Ying Wang               QUOTATION MARK), respectively.
29905436638acc7c010349a69c3395f1a57c642dc62Ying Wang
30005436638acc7c010349a69c3395f1a57c642dc62Ying Wang               If the catalog has no translation, we will try to
30105436638acc7c010349a69c3395f1a57c642dc62Ying Wang               use Unicode U+2018 (LEFT SINGLE QUOTATION MARK) and
30205436638acc7c010349a69c3395f1a57c642dc62Ying Wang               Unicode U+2019 (RIGHT SINGLE QUOTATION MARK).  If the
30305436638acc7c010349a69c3395f1a57c642dc62Ying Wang               current locale is not Unicode, locale_quoting_style
30405436638acc7c010349a69c3395f1a57c642dc62Ying Wang               will quote 'like this', and clocale_quoting_style will
30505436638acc7c010349a69c3395f1a57c642dc62Ying Wang               quote "like this".  You should always include translations
30605436638acc7c010349a69c3395f1a57c642dc62Ying Wang               for "`" and "'" even if U+2018 and U+2019 are appropriate
30705436638acc7c010349a69c3395f1a57c642dc62Ying Wang               for your locale.
30805436638acc7c010349a69c3395f1a57c642dc62Ying Wang
30905436638acc7c010349a69c3395f1a57c642dc62Ying Wang               If you don't know what to put here, please see
31005436638acc7c010349a69c3395f1a57c642dc62Ying Wang               <http://en.wikipedia.org/wiki/Quotation_marks_in_other_languages>
31105436638acc7c010349a69c3395f1a57c642dc62Ying Wang               and use glyphs suitable for your language.  */
31205436638acc7c010349a69c3395f1a57c642dc62Ying Wang            left_quote = gettext_quote (N_("`"), quoting_style);
31305436638acc7c010349a69c3395f1a57c642dc62Ying Wang            right_quote = gettext_quote (N_("'"), quoting_style);
31405436638acc7c010349a69c3395f1a57c642dc62Ying Wang          }
31505436638acc7c010349a69c3395f1a57c642dc62Ying Wang        if (!elide_outer_quotes)
31605436638acc7c010349a69c3395f1a57c642dc62Ying Wang          for (quote_string = left_quote; *quote_string; quote_string++)
31705436638acc7c010349a69c3395f1a57c642dc62Ying Wang            STORE (*quote_string);
31805436638acc7c010349a69c3395f1a57c642dc62Ying Wang        backslash_escapes = true;
31905436638acc7c010349a69c3395f1a57c642dc62Ying Wang        quote_string = right_quote;
32005436638acc7c010349a69c3395f1a57c642dc62Ying Wang        quote_string_len = strlen (quote_string);
321cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project      }
322cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project      break;
323cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project
32405436638acc7c010349a69c3395f1a57c642dc62Ying Wang    case shell_quoting_style:
32505436638acc7c010349a69c3395f1a57c642dc62Ying Wang      quoting_style = shell_always_quoting_style;
32605436638acc7c010349a69c3395f1a57c642dc62Ying Wang      elide_outer_quotes = true;
32705436638acc7c010349a69c3395f1a57c642dc62Ying Wang      /* Fall through.  */
328cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project    case shell_always_quoting_style:
32905436638acc7c010349a69c3395f1a57c642dc62Ying Wang      if (!elide_outer_quotes)
33005436638acc7c010349a69c3395f1a57c642dc62Ying Wang        STORE ('\'');
331cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project      quote_string = "'";
332cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project      quote_string_len = 1;
333cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project      break;
334cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project
33505436638acc7c010349a69c3395f1a57c642dc62Ying Wang    case literal_quoting_style:
33605436638acc7c010349a69c3395f1a57c642dc62Ying Wang      elide_outer_quotes = false;
337cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project      break;
33805436638acc7c010349a69c3395f1a57c642dc62Ying Wang
33905436638acc7c010349a69c3395f1a57c642dc62Ying Wang    default:
34005436638acc7c010349a69c3395f1a57c642dc62Ying Wang      abort ();
341cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project    }
342cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project
343cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project  for (i = 0;  ! (argsize == SIZE_MAX ? arg[i] == '\0' : i == argsize);  i++)
344cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project    {
345cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project      unsigned char c;
346cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project      unsigned char esc;
34705436638acc7c010349a69c3395f1a57c642dc62Ying Wang      bool is_right_quote = false;
348cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project
349cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project      if (backslash_escapes
35005436638acc7c010349a69c3395f1a57c642dc62Ying Wang          && quote_string_len
35105436638acc7c010349a69c3395f1a57c642dc62Ying Wang          && i + quote_string_len <= argsize
35205436638acc7c010349a69c3395f1a57c642dc62Ying Wang          && memcmp (arg + i, quote_string, quote_string_len) == 0)
35305436638acc7c010349a69c3395f1a57c642dc62Ying Wang        {
35405436638acc7c010349a69c3395f1a57c642dc62Ying Wang          if (elide_outer_quotes)
35505436638acc7c010349a69c3395f1a57c642dc62Ying Wang            goto force_outer_quoting_style;
35605436638acc7c010349a69c3395f1a57c642dc62Ying Wang          is_right_quote = true;
35705436638acc7c010349a69c3395f1a57c642dc62Ying Wang        }
358cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project
359cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project      c = arg[i];
360cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project      switch (c)
36105436638acc7c010349a69c3395f1a57c642dc62Ying Wang        {
36205436638acc7c010349a69c3395f1a57c642dc62Ying Wang        case '\0':
36305436638acc7c010349a69c3395f1a57c642dc62Ying Wang          if (backslash_escapes)
36405436638acc7c010349a69c3395f1a57c642dc62Ying Wang            {
36505436638acc7c010349a69c3395f1a57c642dc62Ying Wang              if (elide_outer_quotes)
36605436638acc7c010349a69c3395f1a57c642dc62Ying Wang                goto force_outer_quoting_style;
36705436638acc7c010349a69c3395f1a57c642dc62Ying Wang              STORE ('\\');
36805436638acc7c010349a69c3395f1a57c642dc62Ying Wang              /* If quote_string were to begin with digits, we'd need to
36905436638acc7c010349a69c3395f1a57c642dc62Ying Wang                 test for the end of the arg as well.  However, it's
37005436638acc7c010349a69c3395f1a57c642dc62Ying Wang                 hard to imagine any locale that would use digits in
37105436638acc7c010349a69c3395f1a57c642dc62Ying Wang                 quotes, and set_custom_quoting is documented not to
37205436638acc7c010349a69c3395f1a57c642dc62Ying Wang                 accept them.  */
37305436638acc7c010349a69c3395f1a57c642dc62Ying Wang              if (i + 1 < argsize && '0' <= arg[i + 1] && arg[i + 1] <= '9')
37405436638acc7c010349a69c3395f1a57c642dc62Ying Wang                {
37505436638acc7c010349a69c3395f1a57c642dc62Ying Wang                  STORE ('0');
37605436638acc7c010349a69c3395f1a57c642dc62Ying Wang                  STORE ('0');
37705436638acc7c010349a69c3395f1a57c642dc62Ying Wang                }
37805436638acc7c010349a69c3395f1a57c642dc62Ying Wang              c = '0';
37905436638acc7c010349a69c3395f1a57c642dc62Ying Wang              /* We don't have to worry that this last '0' will be
38005436638acc7c010349a69c3395f1a57c642dc62Ying Wang                 backslash-escaped because, again, quote_string should
38105436638acc7c010349a69c3395f1a57c642dc62Ying Wang                 not start with it and because quote_these_too is
38205436638acc7c010349a69c3395f1a57c642dc62Ying Wang                 documented as not accepting it.  */
38305436638acc7c010349a69c3395f1a57c642dc62Ying Wang            }
38405436638acc7c010349a69c3395f1a57c642dc62Ying Wang          else if (flags & QA_ELIDE_NULL_BYTES)
38505436638acc7c010349a69c3395f1a57c642dc62Ying Wang            continue;
38605436638acc7c010349a69c3395f1a57c642dc62Ying Wang          break;
38705436638acc7c010349a69c3395f1a57c642dc62Ying Wang
38805436638acc7c010349a69c3395f1a57c642dc62Ying Wang        case '?':
38905436638acc7c010349a69c3395f1a57c642dc62Ying Wang          switch (quoting_style)
39005436638acc7c010349a69c3395f1a57c642dc62Ying Wang            {
39105436638acc7c010349a69c3395f1a57c642dc62Ying Wang            case shell_always_quoting_style:
39205436638acc7c010349a69c3395f1a57c642dc62Ying Wang              if (elide_outer_quotes)
39305436638acc7c010349a69c3395f1a57c642dc62Ying Wang                goto force_outer_quoting_style;
39405436638acc7c010349a69c3395f1a57c642dc62Ying Wang              break;
39505436638acc7c010349a69c3395f1a57c642dc62Ying Wang
39605436638acc7c010349a69c3395f1a57c642dc62Ying Wang            case c_quoting_style:
39705436638acc7c010349a69c3395f1a57c642dc62Ying Wang              if ((flags & QA_SPLIT_TRIGRAPHS)
39805436638acc7c010349a69c3395f1a57c642dc62Ying Wang                  && i + 2 < argsize && arg[i + 1] == '?')
39905436638acc7c010349a69c3395f1a57c642dc62Ying Wang                switch (arg[i + 2])
40005436638acc7c010349a69c3395f1a57c642dc62Ying Wang                  {
40105436638acc7c010349a69c3395f1a57c642dc62Ying Wang                  case '!': case '\'':
40205436638acc7c010349a69c3395f1a57c642dc62Ying Wang                  case '(': case ')': case '-': case '/':
40305436638acc7c010349a69c3395f1a57c642dc62Ying Wang                  case '<': case '=': case '>':
40405436638acc7c010349a69c3395f1a57c642dc62Ying Wang                    /* Escape the second '?' in what would otherwise be
40505436638acc7c010349a69c3395f1a57c642dc62Ying Wang                       a trigraph.  */
40605436638acc7c010349a69c3395f1a57c642dc62Ying Wang                    if (elide_outer_quotes)
40705436638acc7c010349a69c3395f1a57c642dc62Ying Wang                      goto force_outer_quoting_style;
40805436638acc7c010349a69c3395f1a57c642dc62Ying Wang                    c = arg[i + 2];
40905436638acc7c010349a69c3395f1a57c642dc62Ying Wang                    i += 2;
41005436638acc7c010349a69c3395f1a57c642dc62Ying Wang                    STORE ('?');
41105436638acc7c010349a69c3395f1a57c642dc62Ying Wang                    STORE ('"');
41205436638acc7c010349a69c3395f1a57c642dc62Ying Wang                    STORE ('"');
41305436638acc7c010349a69c3395f1a57c642dc62Ying Wang                    STORE ('?');
41405436638acc7c010349a69c3395f1a57c642dc62Ying Wang                    break;
41505436638acc7c010349a69c3395f1a57c642dc62Ying Wang
41605436638acc7c010349a69c3395f1a57c642dc62Ying Wang                  default:
41705436638acc7c010349a69c3395f1a57c642dc62Ying Wang                    break;
41805436638acc7c010349a69c3395f1a57c642dc62Ying Wang                  }
41905436638acc7c010349a69c3395f1a57c642dc62Ying Wang              break;
42005436638acc7c010349a69c3395f1a57c642dc62Ying Wang
42105436638acc7c010349a69c3395f1a57c642dc62Ying Wang            default:
42205436638acc7c010349a69c3395f1a57c642dc62Ying Wang              break;
42305436638acc7c010349a69c3395f1a57c642dc62Ying Wang            }
42405436638acc7c010349a69c3395f1a57c642dc62Ying Wang          break;
42505436638acc7c010349a69c3395f1a57c642dc62Ying Wang
42605436638acc7c010349a69c3395f1a57c642dc62Ying Wang        case '\a': esc = 'a'; goto c_escape;
42705436638acc7c010349a69c3395f1a57c642dc62Ying Wang        case '\b': esc = 'b'; goto c_escape;
42805436638acc7c010349a69c3395f1a57c642dc62Ying Wang        case '\f': esc = 'f'; goto c_escape;
42905436638acc7c010349a69c3395f1a57c642dc62Ying Wang        case '\n': esc = 'n'; goto c_and_shell_escape;
43005436638acc7c010349a69c3395f1a57c642dc62Ying Wang        case '\r': esc = 'r'; goto c_and_shell_escape;
43105436638acc7c010349a69c3395f1a57c642dc62Ying Wang        case '\t': esc = 't'; goto c_and_shell_escape;
43205436638acc7c010349a69c3395f1a57c642dc62Ying Wang        case '\v': esc = 'v'; goto c_escape;
43305436638acc7c010349a69c3395f1a57c642dc62Ying Wang        case '\\': esc = c;
43405436638acc7c010349a69c3395f1a57c642dc62Ying Wang          /* No need to escape the escape if we are trying to elide
43505436638acc7c010349a69c3395f1a57c642dc62Ying Wang             outer quotes and nothing else is problematic.  */
43605436638acc7c010349a69c3395f1a57c642dc62Ying Wang          if (backslash_escapes && elide_outer_quotes && quote_string_len)
43705436638acc7c010349a69c3395f1a57c642dc62Ying Wang            goto store_c;
43805436638acc7c010349a69c3395f1a57c642dc62Ying Wang
43905436638acc7c010349a69c3395f1a57c642dc62Ying Wang        c_and_shell_escape:
44005436638acc7c010349a69c3395f1a57c642dc62Ying Wang          if (quoting_style == shell_always_quoting_style
44105436638acc7c010349a69c3395f1a57c642dc62Ying Wang              && elide_outer_quotes)
44205436638acc7c010349a69c3395f1a57c642dc62Ying Wang            goto force_outer_quoting_style;
44305436638acc7c010349a69c3395f1a57c642dc62Ying Wang          /* Fall through.  */
44405436638acc7c010349a69c3395f1a57c642dc62Ying Wang        c_escape:
44505436638acc7c010349a69c3395f1a57c642dc62Ying Wang          if (backslash_escapes)
44605436638acc7c010349a69c3395f1a57c642dc62Ying Wang            {
44705436638acc7c010349a69c3395f1a57c642dc62Ying Wang              c = esc;
44805436638acc7c010349a69c3395f1a57c642dc62Ying Wang              goto store_escape;
44905436638acc7c010349a69c3395f1a57c642dc62Ying Wang            }
45005436638acc7c010349a69c3395f1a57c642dc62Ying Wang          break;
45105436638acc7c010349a69c3395f1a57c642dc62Ying Wang
45205436638acc7c010349a69c3395f1a57c642dc62Ying Wang        case '{': case '}': /* sometimes special if isolated */
45305436638acc7c010349a69c3395f1a57c642dc62Ying Wang          if (! (argsize == SIZE_MAX ? arg[1] == '\0' : argsize == 1))
45405436638acc7c010349a69c3395f1a57c642dc62Ying Wang            break;
45505436638acc7c010349a69c3395f1a57c642dc62Ying Wang          /* Fall through.  */
45605436638acc7c010349a69c3395f1a57c642dc62Ying Wang        case '#': case '~':
45705436638acc7c010349a69c3395f1a57c642dc62Ying Wang          if (i != 0)
45805436638acc7c010349a69c3395f1a57c642dc62Ying Wang            break;
45905436638acc7c010349a69c3395f1a57c642dc62Ying Wang          /* Fall through.  */
46005436638acc7c010349a69c3395f1a57c642dc62Ying Wang        case ' ':
46105436638acc7c010349a69c3395f1a57c642dc62Ying Wang        case '!': /* special in bash */
46205436638acc7c010349a69c3395f1a57c642dc62Ying Wang        case '"': case '$': case '&':
46305436638acc7c010349a69c3395f1a57c642dc62Ying Wang        case '(': case ')': case '*': case ';':
46405436638acc7c010349a69c3395f1a57c642dc62Ying Wang        case '<':
46505436638acc7c010349a69c3395f1a57c642dc62Ying Wang        case '=': /* sometimes special in 0th or (with "set -k") later args */
46605436638acc7c010349a69c3395f1a57c642dc62Ying Wang        case '>': case '[':
46705436638acc7c010349a69c3395f1a57c642dc62Ying Wang        case '^': /* special in old /bin/sh, e.g. SunOS 4.1.4 */
46805436638acc7c010349a69c3395f1a57c642dc62Ying Wang        case '`': case '|':
46905436638acc7c010349a69c3395f1a57c642dc62Ying Wang          /* A shell special character.  In theory, '$' and '`' could
47005436638acc7c010349a69c3395f1a57c642dc62Ying Wang             be the first bytes of multibyte characters, which means
47105436638acc7c010349a69c3395f1a57c642dc62Ying Wang             we should check them with mbrtowc, but in practice this
47205436638acc7c010349a69c3395f1a57c642dc62Ying Wang             doesn't happen so it's not worth worrying about.  */
47305436638acc7c010349a69c3395f1a57c642dc62Ying Wang          if (quoting_style == shell_always_quoting_style
47405436638acc7c010349a69c3395f1a57c642dc62Ying Wang              && elide_outer_quotes)
47505436638acc7c010349a69c3395f1a57c642dc62Ying Wang            goto force_outer_quoting_style;
47605436638acc7c010349a69c3395f1a57c642dc62Ying Wang          break;
47705436638acc7c010349a69c3395f1a57c642dc62Ying Wang
47805436638acc7c010349a69c3395f1a57c642dc62Ying Wang        case '\'':
47905436638acc7c010349a69c3395f1a57c642dc62Ying Wang          if (quoting_style == shell_always_quoting_style)
48005436638acc7c010349a69c3395f1a57c642dc62Ying Wang            {
48105436638acc7c010349a69c3395f1a57c642dc62Ying Wang              if (elide_outer_quotes)
48205436638acc7c010349a69c3395f1a57c642dc62Ying Wang                goto force_outer_quoting_style;
48305436638acc7c010349a69c3395f1a57c642dc62Ying Wang              STORE ('\'');
48405436638acc7c010349a69c3395f1a57c642dc62Ying Wang              STORE ('\\');
48505436638acc7c010349a69c3395f1a57c642dc62Ying Wang              STORE ('\'');
48605436638acc7c010349a69c3395f1a57c642dc62Ying Wang            }
48705436638acc7c010349a69c3395f1a57c642dc62Ying Wang          break;
48805436638acc7c010349a69c3395f1a57c642dc62Ying Wang
48905436638acc7c010349a69c3395f1a57c642dc62Ying Wang        case '%': case '+': case ',': case '-': case '.': case '/':
49005436638acc7c010349a69c3395f1a57c642dc62Ying Wang        case '0': case '1': case '2': case '3': case '4': case '5':
49105436638acc7c010349a69c3395f1a57c642dc62Ying Wang        case '6': case '7': case '8': case '9': case ':':
49205436638acc7c010349a69c3395f1a57c642dc62Ying Wang        case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
49305436638acc7c010349a69c3395f1a57c642dc62Ying Wang        case 'G': case 'H': case 'I': case 'J': case 'K': case 'L':
49405436638acc7c010349a69c3395f1a57c642dc62Ying Wang        case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R':
49505436638acc7c010349a69c3395f1a57c642dc62Ying Wang        case 'S': case 'T': case 'U': case 'V': case 'W': case 'X':
49605436638acc7c010349a69c3395f1a57c642dc62Ying Wang        case 'Y': case 'Z': case ']': case '_': case 'a': case 'b':
49705436638acc7c010349a69c3395f1a57c642dc62Ying Wang        case 'c': case 'd': case 'e': case 'f': case 'g': case 'h':
49805436638acc7c010349a69c3395f1a57c642dc62Ying Wang        case 'i': case 'j': case 'k': case 'l': case 'm': case 'n':
49905436638acc7c010349a69c3395f1a57c642dc62Ying Wang        case 'o': case 'p': case 'q': case 'r': case 's': case 't':
50005436638acc7c010349a69c3395f1a57c642dc62Ying Wang        case 'u': case 'v': case 'w': case 'x': case 'y': case 'z':
50105436638acc7c010349a69c3395f1a57c642dc62Ying Wang          /* These characters don't cause problems, no matter what the
50205436638acc7c010349a69c3395f1a57c642dc62Ying Wang             quoting style is.  They cannot start multibyte sequences.
50305436638acc7c010349a69c3395f1a57c642dc62Ying Wang             A digit or a special letter would cause trouble if it
50405436638acc7c010349a69c3395f1a57c642dc62Ying Wang             appeared at the beginning of quote_string because we'd then
50505436638acc7c010349a69c3395f1a57c642dc62Ying Wang             escape by prepending a backslash.  However, it's hard to
50605436638acc7c010349a69c3395f1a57c642dc62Ying Wang             imagine any locale that would use digits or letters as
50705436638acc7c010349a69c3395f1a57c642dc62Ying Wang             quotes, and set_custom_quoting is documented not to accept
50805436638acc7c010349a69c3395f1a57c642dc62Ying Wang             them.  Also, a digit or a special letter would cause
50905436638acc7c010349a69c3395f1a57c642dc62Ying Wang             trouble if it appeared in quote_these_too, but that's also
51005436638acc7c010349a69c3395f1a57c642dc62Ying Wang             documented as not accepting them.  */
51105436638acc7c010349a69c3395f1a57c642dc62Ying Wang          break;
51205436638acc7c010349a69c3395f1a57c642dc62Ying Wang
51305436638acc7c010349a69c3395f1a57c642dc62Ying Wang        default:
51405436638acc7c010349a69c3395f1a57c642dc62Ying Wang          /* If we have a multibyte sequence, copy it until we reach
51505436638acc7c010349a69c3395f1a57c642dc62Ying Wang             its end, find an error, or come back to the initial shift
51605436638acc7c010349a69c3395f1a57c642dc62Ying Wang             state.  For C-like styles, if the sequence has
51705436638acc7c010349a69c3395f1a57c642dc62Ying Wang             unprintable characters, escape the whole sequence, since
51805436638acc7c010349a69c3395f1a57c642dc62Ying Wang             we can't easily escape single characters within it.  */
51905436638acc7c010349a69c3395f1a57c642dc62Ying Wang          {
52005436638acc7c010349a69c3395f1a57c642dc62Ying Wang            /* Length of multibyte sequence found so far.  */
52105436638acc7c010349a69c3395f1a57c642dc62Ying Wang            size_t m;
52205436638acc7c010349a69c3395f1a57c642dc62Ying Wang
52305436638acc7c010349a69c3395f1a57c642dc62Ying Wang            bool printable;
52405436638acc7c010349a69c3395f1a57c642dc62Ying Wang
52505436638acc7c010349a69c3395f1a57c642dc62Ying Wang            if (unibyte_locale)
52605436638acc7c010349a69c3395f1a57c642dc62Ying Wang              {
52705436638acc7c010349a69c3395f1a57c642dc62Ying Wang                m = 1;
52805436638acc7c010349a69c3395f1a57c642dc62Ying Wang                printable = isprint (c) != 0;
52905436638acc7c010349a69c3395f1a57c642dc62Ying Wang              }
53005436638acc7c010349a69c3395f1a57c642dc62Ying Wang            else
53105436638acc7c010349a69c3395f1a57c642dc62Ying Wang              {
53205436638acc7c010349a69c3395f1a57c642dc62Ying Wang                mbstate_t mbstate;
53305436638acc7c010349a69c3395f1a57c642dc62Ying Wang                memset (&mbstate, 0, sizeof mbstate);
53405436638acc7c010349a69c3395f1a57c642dc62Ying Wang
53505436638acc7c010349a69c3395f1a57c642dc62Ying Wang                m = 0;
53605436638acc7c010349a69c3395f1a57c642dc62Ying Wang                printable = true;
53705436638acc7c010349a69c3395f1a57c642dc62Ying Wang                if (argsize == SIZE_MAX)
53805436638acc7c010349a69c3395f1a57c642dc62Ying Wang                  argsize = strlen (arg);
53905436638acc7c010349a69c3395f1a57c642dc62Ying Wang
54005436638acc7c010349a69c3395f1a57c642dc62Ying Wang                do
54105436638acc7c010349a69c3395f1a57c642dc62Ying Wang                  {
54205436638acc7c010349a69c3395f1a57c642dc62Ying Wang                    wchar_t w;
54305436638acc7c010349a69c3395f1a57c642dc62Ying Wang                    size_t bytes = mbrtowc (&w, &arg[i + m],
54405436638acc7c010349a69c3395f1a57c642dc62Ying Wang                                            argsize - (i + m), &mbstate);
54505436638acc7c010349a69c3395f1a57c642dc62Ying Wang                    if (bytes == 0)
54605436638acc7c010349a69c3395f1a57c642dc62Ying Wang                      break;
54705436638acc7c010349a69c3395f1a57c642dc62Ying Wang                    else if (bytes == (size_t) -1)
54805436638acc7c010349a69c3395f1a57c642dc62Ying Wang                      {
54905436638acc7c010349a69c3395f1a57c642dc62Ying Wang                        printable = false;
55005436638acc7c010349a69c3395f1a57c642dc62Ying Wang                        break;
55105436638acc7c010349a69c3395f1a57c642dc62Ying Wang                      }
55205436638acc7c010349a69c3395f1a57c642dc62Ying Wang                    else if (bytes == (size_t) -2)
55305436638acc7c010349a69c3395f1a57c642dc62Ying Wang                      {
55405436638acc7c010349a69c3395f1a57c642dc62Ying Wang                        printable = false;
55505436638acc7c010349a69c3395f1a57c642dc62Ying Wang                        while (i + m < argsize && arg[i + m])
55605436638acc7c010349a69c3395f1a57c642dc62Ying Wang                          m++;
55705436638acc7c010349a69c3395f1a57c642dc62Ying Wang                        break;
55805436638acc7c010349a69c3395f1a57c642dc62Ying Wang                      }
55905436638acc7c010349a69c3395f1a57c642dc62Ying Wang                    else
56005436638acc7c010349a69c3395f1a57c642dc62Ying Wang                      {
56105436638acc7c010349a69c3395f1a57c642dc62Ying Wang                        /* Work around a bug with older shells that "see" a '\'
56205436638acc7c010349a69c3395f1a57c642dc62Ying Wang                           that is really the 2nd byte of a multibyte character.
56305436638acc7c010349a69c3395f1a57c642dc62Ying Wang                           In practice the problem is limited to ASCII
56405436638acc7c010349a69c3395f1a57c642dc62Ying Wang                           chars >= '@' that are shell special chars.  */
56505436638acc7c010349a69c3395f1a57c642dc62Ying Wang                        if ('[' == 0x5b && elide_outer_quotes
56605436638acc7c010349a69c3395f1a57c642dc62Ying Wang                            && quoting_style == shell_always_quoting_style)
56705436638acc7c010349a69c3395f1a57c642dc62Ying Wang                          {
56805436638acc7c010349a69c3395f1a57c642dc62Ying Wang                            size_t j;
56905436638acc7c010349a69c3395f1a57c642dc62Ying Wang                            for (j = 1; j < bytes; j++)
57005436638acc7c010349a69c3395f1a57c642dc62Ying Wang                              switch (arg[i + m + j])
57105436638acc7c010349a69c3395f1a57c642dc62Ying Wang                                {
57205436638acc7c010349a69c3395f1a57c642dc62Ying Wang                                case '[': case '\\': case '^':
57305436638acc7c010349a69c3395f1a57c642dc62Ying Wang                                case '`': case '|':
57405436638acc7c010349a69c3395f1a57c642dc62Ying Wang                                  goto force_outer_quoting_style;
57505436638acc7c010349a69c3395f1a57c642dc62Ying Wang
57605436638acc7c010349a69c3395f1a57c642dc62Ying Wang                                default:
57705436638acc7c010349a69c3395f1a57c642dc62Ying Wang                                  break;
57805436638acc7c010349a69c3395f1a57c642dc62Ying Wang                                }
57905436638acc7c010349a69c3395f1a57c642dc62Ying Wang                          }
58005436638acc7c010349a69c3395f1a57c642dc62Ying Wang
58105436638acc7c010349a69c3395f1a57c642dc62Ying Wang                        if (! iswprint (w))
58205436638acc7c010349a69c3395f1a57c642dc62Ying Wang                          printable = false;
58305436638acc7c010349a69c3395f1a57c642dc62Ying Wang                        m += bytes;
58405436638acc7c010349a69c3395f1a57c642dc62Ying Wang                      }
58505436638acc7c010349a69c3395f1a57c642dc62Ying Wang                  }
58605436638acc7c010349a69c3395f1a57c642dc62Ying Wang                while (! mbsinit (&mbstate));
58705436638acc7c010349a69c3395f1a57c642dc62Ying Wang              }
58805436638acc7c010349a69c3395f1a57c642dc62Ying Wang
58905436638acc7c010349a69c3395f1a57c642dc62Ying Wang            if (1 < m || (backslash_escapes && ! printable))
59005436638acc7c010349a69c3395f1a57c642dc62Ying Wang              {
59105436638acc7c010349a69c3395f1a57c642dc62Ying Wang                /* Output a multibyte sequence, or an escaped
59205436638acc7c010349a69c3395f1a57c642dc62Ying Wang                   unprintable unibyte character.  */
59305436638acc7c010349a69c3395f1a57c642dc62Ying Wang                size_t ilim = i + m;
59405436638acc7c010349a69c3395f1a57c642dc62Ying Wang
59505436638acc7c010349a69c3395f1a57c642dc62Ying Wang                for (;;)
59605436638acc7c010349a69c3395f1a57c642dc62Ying Wang                  {
59705436638acc7c010349a69c3395f1a57c642dc62Ying Wang                    if (backslash_escapes && ! printable)
59805436638acc7c010349a69c3395f1a57c642dc62Ying Wang                      {
59905436638acc7c010349a69c3395f1a57c642dc62Ying Wang                        if (elide_outer_quotes)
60005436638acc7c010349a69c3395f1a57c642dc62Ying Wang                          goto force_outer_quoting_style;
60105436638acc7c010349a69c3395f1a57c642dc62Ying Wang                        STORE ('\\');
60205436638acc7c010349a69c3395f1a57c642dc62Ying Wang                        STORE ('0' + (c >> 6));
60305436638acc7c010349a69c3395f1a57c642dc62Ying Wang                        STORE ('0' + ((c >> 3) & 7));
60405436638acc7c010349a69c3395f1a57c642dc62Ying Wang                        c = '0' + (c & 7);
60505436638acc7c010349a69c3395f1a57c642dc62Ying Wang                      }
60605436638acc7c010349a69c3395f1a57c642dc62Ying Wang                    else if (is_right_quote)
60705436638acc7c010349a69c3395f1a57c642dc62Ying Wang                      {
60805436638acc7c010349a69c3395f1a57c642dc62Ying Wang                        STORE ('\\');
60905436638acc7c010349a69c3395f1a57c642dc62Ying Wang                        is_right_quote = false;
61005436638acc7c010349a69c3395f1a57c642dc62Ying Wang                      }
61105436638acc7c010349a69c3395f1a57c642dc62Ying Wang                    if (ilim <= i + 1)
61205436638acc7c010349a69c3395f1a57c642dc62Ying Wang                      break;
61305436638acc7c010349a69c3395f1a57c642dc62Ying Wang                    STORE (c);
61405436638acc7c010349a69c3395f1a57c642dc62Ying Wang                    c = arg[++i];
61505436638acc7c010349a69c3395f1a57c642dc62Ying Wang                  }
61605436638acc7c010349a69c3395f1a57c642dc62Ying Wang
61705436638acc7c010349a69c3395f1a57c642dc62Ying Wang                goto store_c;
61805436638acc7c010349a69c3395f1a57c642dc62Ying Wang              }
61905436638acc7c010349a69c3395f1a57c642dc62Ying Wang          }
62005436638acc7c010349a69c3395f1a57c642dc62Ying Wang        }
62105436638acc7c010349a69c3395f1a57c642dc62Ying Wang
62205436638acc7c010349a69c3395f1a57c642dc62Ying Wang      if (! ((backslash_escapes || elide_outer_quotes)
62305436638acc7c010349a69c3395f1a57c642dc62Ying Wang             && quote_these_too
62405436638acc7c010349a69c3395f1a57c642dc62Ying Wang             && quote_these_too[c / INT_BITS] & (1 << (c % INT_BITS)))
62505436638acc7c010349a69c3395f1a57c642dc62Ying Wang          && !is_right_quote)
62605436638acc7c010349a69c3395f1a57c642dc62Ying Wang        goto store_c;
627cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project
628cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project    store_escape:
62905436638acc7c010349a69c3395f1a57c642dc62Ying Wang      if (elide_outer_quotes)
63005436638acc7c010349a69c3395f1a57c642dc62Ying Wang        goto force_outer_quoting_style;
631cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project      STORE ('\\');
632cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project
633cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project    store_c:
634cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project      STORE (c);
635cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project    }
636cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project
63705436638acc7c010349a69c3395f1a57c642dc62Ying Wang  if (len == 0 && quoting_style == shell_always_quoting_style
63805436638acc7c010349a69c3395f1a57c642dc62Ying Wang      && elide_outer_quotes)
63905436638acc7c010349a69c3395f1a57c642dc62Ying Wang    goto force_outer_quoting_style;
640cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project
64105436638acc7c010349a69c3395f1a57c642dc62Ying Wang  if (quote_string && !elide_outer_quotes)
642cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project    for (; *quote_string; quote_string++)
643cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project      STORE (*quote_string);
644cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project
645cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project  if (len < buffersize)
646cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project    buffer[len] = '\0';
647cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project  return len;
648cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project
64905436638acc7c010349a69c3395f1a57c642dc62Ying Wang force_outer_quoting_style:
65005436638acc7c010349a69c3395f1a57c642dc62Ying Wang  /* Don't reuse quote_these_too, since the addition of outer quotes
65105436638acc7c010349a69c3395f1a57c642dc62Ying Wang     sufficiently quotes the specified characters.  */
652cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project  return quotearg_buffer_restyled (buffer, buffersize, arg, argsize,
65305436638acc7c010349a69c3395f1a57c642dc62Ying Wang                                   quoting_style,
65405436638acc7c010349a69c3395f1a57c642dc62Ying Wang                                   flags & ~QA_ELIDE_OUTER_QUOTES, NULL,
65505436638acc7c010349a69c3395f1a57c642dc62Ying Wang                                   left_quote, right_quote);
656cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project}
657cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project
658cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project/* Place into buffer BUFFER (of size BUFFERSIZE) a quoted version of
659cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project   argument ARG (of size ARGSIZE), using O to control quoting.
660cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project   If O is null, use the default.
661cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project   Terminate the output with a null character, and return the written
662cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project   size of the output, not counting the terminating null.
663cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project   If BUFFERSIZE is too small to store the output string, return the
664cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project   value that would have been returned had BUFFERSIZE been large enough.
665cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project   If ARGSIZE is SIZE_MAX, use the string length of the argument for
666cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project   ARGSIZE.  */
667cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Projectsize_t
668cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Projectquotearg_buffer (char *buffer, size_t buffersize,
66905436638acc7c010349a69c3395f1a57c642dc62Ying Wang                 char const *arg, size_t argsize,
67005436638acc7c010349a69c3395f1a57c642dc62Ying Wang                 struct quoting_options const *o)
671cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project{
672cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project  struct quoting_options const *p = o ? o : &default_quoting_options;
673cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project  int e = errno;
674cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project  size_t r = quotearg_buffer_restyled (buffer, buffersize, arg, argsize,
67505436638acc7c010349a69c3395f1a57c642dc62Ying Wang                                       p->style, p->flags, p->quote_these_too,
67605436638acc7c010349a69c3395f1a57c642dc62Ying Wang                                       p->left_quote, p->right_quote);
677cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project  errno = e;
678cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project  return r;
679cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project}
680cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project
68105436638acc7c010349a69c3395f1a57c642dc62Ying Wang/* Equivalent to quotearg_alloc (ARG, ARGSIZE, NULL, O).  */
682cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Projectchar *
683cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Projectquotearg_alloc (char const *arg, size_t argsize,
68405436638acc7c010349a69c3395f1a57c642dc62Ying Wang                struct quoting_options const *o)
68505436638acc7c010349a69c3395f1a57c642dc62Ying Wang{
68605436638acc7c010349a69c3395f1a57c642dc62Ying Wang  return quotearg_alloc_mem (arg, argsize, NULL, o);
68705436638acc7c010349a69c3395f1a57c642dc62Ying Wang}
68805436638acc7c010349a69c3395f1a57c642dc62Ying Wang
68905436638acc7c010349a69c3395f1a57c642dc62Ying Wang/* Like quotearg_buffer (..., ARG, ARGSIZE, O), except return newly
69005436638acc7c010349a69c3395f1a57c642dc62Ying Wang   allocated storage containing the quoted string, and store the
69105436638acc7c010349a69c3395f1a57c642dc62Ying Wang   resulting size into *SIZE, if non-NULL.  The result can contain
69205436638acc7c010349a69c3395f1a57c642dc62Ying Wang   embedded null bytes only if ARGSIZE is not SIZE_MAX, SIZE is not
69305436638acc7c010349a69c3395f1a57c642dc62Ying Wang   NULL, and set_quoting_flags has not set the null byte elision
69405436638acc7c010349a69c3395f1a57c642dc62Ying Wang   flag.  */
69505436638acc7c010349a69c3395f1a57c642dc62Ying Wangchar *
69605436638acc7c010349a69c3395f1a57c642dc62Ying Wangquotearg_alloc_mem (char const *arg, size_t argsize, size_t *size,
69705436638acc7c010349a69c3395f1a57c642dc62Ying Wang                    struct quoting_options const *o)
698cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project{
69905436638acc7c010349a69c3395f1a57c642dc62Ying Wang  struct quoting_options const *p = o ? o : &default_quoting_options;
700cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project  int e = errno;
70105436638acc7c010349a69c3395f1a57c642dc62Ying Wang  /* Elide embedded null bytes if we can't return a size.  */
70205436638acc7c010349a69c3395f1a57c642dc62Ying Wang  int flags = p->flags | (size ? 0 : QA_ELIDE_NULL_BYTES);
70305436638acc7c010349a69c3395f1a57c642dc62Ying Wang  size_t bufsize = quotearg_buffer_restyled (0, 0, arg, argsize, p->style,
70405436638acc7c010349a69c3395f1a57c642dc62Ying Wang                                             flags, p->quote_these_too,
70505436638acc7c010349a69c3395f1a57c642dc62Ying Wang                                             p->left_quote,
70605436638acc7c010349a69c3395f1a57c642dc62Ying Wang                                             p->right_quote) + 1;
70705436638acc7c010349a69c3395f1a57c642dc62Ying Wang  char *buf = xcharalloc (bufsize);
70805436638acc7c010349a69c3395f1a57c642dc62Ying Wang  quotearg_buffer_restyled (buf, bufsize, arg, argsize, p->style, flags,
70905436638acc7c010349a69c3395f1a57c642dc62Ying Wang                            p->quote_these_too,
71005436638acc7c010349a69c3395f1a57c642dc62Ying Wang                            p->left_quote, p->right_quote);
711cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project  errno = e;
71205436638acc7c010349a69c3395f1a57c642dc62Ying Wang  if (size)
71305436638acc7c010349a69c3395f1a57c642dc62Ying Wang    *size = bufsize - 1;
714cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project  return buf;
715cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project}
716cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project
71705436638acc7c010349a69c3395f1a57c642dc62Ying Wang/* A storage slot with size and pointer to a value.  */
71805436638acc7c010349a69c3395f1a57c642dc62Ying Wangstruct slotvec
71905436638acc7c010349a69c3395f1a57c642dc62Ying Wang{
72005436638acc7c010349a69c3395f1a57c642dc62Ying Wang  size_t size;
72105436638acc7c010349a69c3395f1a57c642dc62Ying Wang  char *val;
72205436638acc7c010349a69c3395f1a57c642dc62Ying Wang};
72305436638acc7c010349a69c3395f1a57c642dc62Ying Wang
72405436638acc7c010349a69c3395f1a57c642dc62Ying Wang/* Preallocate a slot 0 buffer, so that the caller can always quote
72505436638acc7c010349a69c3395f1a57c642dc62Ying Wang   one small component of a "memory exhausted" message in slot 0.  */
72605436638acc7c010349a69c3395f1a57c642dc62Ying Wangstatic char slot0[256];
72705436638acc7c010349a69c3395f1a57c642dc62Ying Wangstatic unsigned int nslots = 1;
72805436638acc7c010349a69c3395f1a57c642dc62Ying Wangstatic struct slotvec slotvec0 = {sizeof slot0, slot0};
72905436638acc7c010349a69c3395f1a57c642dc62Ying Wangstatic struct slotvec *slotvec = &slotvec0;
73005436638acc7c010349a69c3395f1a57c642dc62Ying Wang
73105436638acc7c010349a69c3395f1a57c642dc62Ying Wangvoid
73205436638acc7c010349a69c3395f1a57c642dc62Ying Wangquotearg_free (void)
73305436638acc7c010349a69c3395f1a57c642dc62Ying Wang{
73405436638acc7c010349a69c3395f1a57c642dc62Ying Wang  struct slotvec *sv = slotvec;
73505436638acc7c010349a69c3395f1a57c642dc62Ying Wang  unsigned int i;
73605436638acc7c010349a69c3395f1a57c642dc62Ying Wang  for (i = 1; i < nslots; i++)
73705436638acc7c010349a69c3395f1a57c642dc62Ying Wang    free (sv[i].val);
73805436638acc7c010349a69c3395f1a57c642dc62Ying Wang  if (sv[0].val != slot0)
73905436638acc7c010349a69c3395f1a57c642dc62Ying Wang    {
74005436638acc7c010349a69c3395f1a57c642dc62Ying Wang      free (sv[0].val);
74105436638acc7c010349a69c3395f1a57c642dc62Ying Wang      slotvec0.size = sizeof slot0;
74205436638acc7c010349a69c3395f1a57c642dc62Ying Wang      slotvec0.val = slot0;
74305436638acc7c010349a69c3395f1a57c642dc62Ying Wang    }
74405436638acc7c010349a69c3395f1a57c642dc62Ying Wang  if (sv != &slotvec0)
74505436638acc7c010349a69c3395f1a57c642dc62Ying Wang    {
74605436638acc7c010349a69c3395f1a57c642dc62Ying Wang      free (sv);
74705436638acc7c010349a69c3395f1a57c642dc62Ying Wang      slotvec = &slotvec0;
74805436638acc7c010349a69c3395f1a57c642dc62Ying Wang    }
74905436638acc7c010349a69c3395f1a57c642dc62Ying Wang  nslots = 1;
75005436638acc7c010349a69c3395f1a57c642dc62Ying Wang}
75105436638acc7c010349a69c3395f1a57c642dc62Ying Wang
752cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project/* Use storage slot N to return a quoted version of argument ARG.
753cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project   ARG is of size ARGSIZE, but if that is SIZE_MAX, ARG is a
754cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project   null-terminated string.
755cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project   OPTIONS specifies the quoting options.
756cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project   The returned value points to static storage that can be
757cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project   reused by the next call to this function with the same value of N.
758cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project   N must be nonnegative.  N is deliberately declared with type "int"
759cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project   to allow for future extensions (using negative values).  */
760cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Projectstatic char *
761cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Projectquotearg_n_options (int n, char const *arg, size_t argsize,
76205436638acc7c010349a69c3395f1a57c642dc62Ying Wang                    struct quoting_options const *options)
763cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project{
764cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project  int e = errno;
765cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project
766cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project  unsigned int n0 = n;
76705436638acc7c010349a69c3395f1a57c642dc62Ying Wang  struct slotvec *sv = slotvec;
768cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project
769cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project  if (n < 0)
770cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project    abort ();
771cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project
772cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project  if (nslots <= n0)
773cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project    {
77405436638acc7c010349a69c3395f1a57c642dc62Ying Wang      /* FIXME: technically, the type of n1 should be 'unsigned int',
77505436638acc7c010349a69c3395f1a57c642dc62Ying Wang         but that evokes an unsuppressible warning from gcc-4.0.1 and
77605436638acc7c010349a69c3395f1a57c642dc62Ying Wang         older.  If gcc ever provides an option to suppress that warning,
77705436638acc7c010349a69c3395f1a57c642dc62Ying Wang         revert to the original type, so that the test in xalloc_oversized
77805436638acc7c010349a69c3395f1a57c642dc62Ying Wang         is once again performed only at compile time.  */
779cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project      size_t n1 = n0 + 1;
78005436638acc7c010349a69c3395f1a57c642dc62Ying Wang      bool preallocated = (sv == &slotvec0);
781cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project
78205436638acc7c010349a69c3395f1a57c642dc62Ying Wang      if (xalloc_oversized (n1, sizeof *sv))
78305436638acc7c010349a69c3395f1a57c642dc62Ying Wang        xalloc_die ();
784cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project
78505436638acc7c010349a69c3395f1a57c642dc62Ying Wang      slotvec = sv = xrealloc (preallocated ? NULL : sv, n1 * sizeof *sv);
78605436638acc7c010349a69c3395f1a57c642dc62Ying Wang      if (preallocated)
78705436638acc7c010349a69c3395f1a57c642dc62Ying Wang        *sv = slotvec0;
78805436638acc7c010349a69c3395f1a57c642dc62Ying Wang      memset (sv + nslots, 0, (n1 - nslots) * sizeof *sv);
789cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project      nslots = n1;
790cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project    }
791cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project
792cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project  {
79305436638acc7c010349a69c3395f1a57c642dc62Ying Wang    size_t size = sv[n].size;
79405436638acc7c010349a69c3395f1a57c642dc62Ying Wang    char *val = sv[n].val;
79505436638acc7c010349a69c3395f1a57c642dc62Ying Wang    /* Elide embedded null bytes since we don't return a size.  */
79605436638acc7c010349a69c3395f1a57c642dc62Ying Wang    int flags = options->flags | QA_ELIDE_NULL_BYTES;
79705436638acc7c010349a69c3395f1a57c642dc62Ying Wang    size_t qsize = quotearg_buffer_restyled (val, size, arg, argsize,
79805436638acc7c010349a69c3395f1a57c642dc62Ying Wang                                             options->style, flags,
79905436638acc7c010349a69c3395f1a57c642dc62Ying Wang                                             options->quote_these_too,
80005436638acc7c010349a69c3395f1a57c642dc62Ying Wang                                             options->left_quote,
80105436638acc7c010349a69c3395f1a57c642dc62Ying Wang                                             options->right_quote);
802cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project
803cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project    if (size <= qsize)
804cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project      {
80505436638acc7c010349a69c3395f1a57c642dc62Ying Wang        sv[n].size = size = qsize + 1;
80605436638acc7c010349a69c3395f1a57c642dc62Ying Wang        if (val != slot0)
80705436638acc7c010349a69c3395f1a57c642dc62Ying Wang          free (val);
80805436638acc7c010349a69c3395f1a57c642dc62Ying Wang        sv[n].val = val = xcharalloc (size);
80905436638acc7c010349a69c3395f1a57c642dc62Ying Wang        quotearg_buffer_restyled (val, size, arg, argsize, options->style,
81005436638acc7c010349a69c3395f1a57c642dc62Ying Wang                                  flags, options->quote_these_too,
81105436638acc7c010349a69c3395f1a57c642dc62Ying Wang                                  options->left_quote,
81205436638acc7c010349a69c3395f1a57c642dc62Ying Wang                                  options->right_quote);
813cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project      }
814cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project
815cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project    errno = e;
816cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project    return val;
817cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project  }
818cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project}
819cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project
820cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Projectchar *
821cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Projectquotearg_n (int n, char const *arg)
822cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project{
823cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project  return quotearg_n_options (n, arg, SIZE_MAX, &default_quoting_options);
824cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project}
825cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project
826cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Projectchar *
82705436638acc7c010349a69c3395f1a57c642dc62Ying Wangquotearg_n_mem (int n, char const *arg, size_t argsize)
82805436638acc7c010349a69c3395f1a57c642dc62Ying Wang{
82905436638acc7c010349a69c3395f1a57c642dc62Ying Wang  return quotearg_n_options (n, arg, argsize, &default_quoting_options);
83005436638acc7c010349a69c3395f1a57c642dc62Ying Wang}
83105436638acc7c010349a69c3395f1a57c642dc62Ying Wang
83205436638acc7c010349a69c3395f1a57c642dc62Ying Wangchar *
833cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Projectquotearg (char const *arg)
834cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project{
835cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project  return quotearg_n (0, arg);
836cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project}
837cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project
83805436638acc7c010349a69c3395f1a57c642dc62Ying Wangchar *
83905436638acc7c010349a69c3395f1a57c642dc62Ying Wangquotearg_mem (char const *arg, size_t argsize)
840cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project{
84105436638acc7c010349a69c3395f1a57c642dc62Ying Wang  return quotearg_n_mem (0, arg, argsize);
842cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project}
843cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project
844cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Projectchar *
845cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Projectquotearg_n_style (int n, enum quoting_style s, char const *arg)
846cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project{
847cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project  struct quoting_options const o = quoting_options_from_style (s);
848cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project  return quotearg_n_options (n, arg, SIZE_MAX, &o);
849cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project}
850cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project
851cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Projectchar *
852cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Projectquotearg_n_style_mem (int n, enum quoting_style s,
85305436638acc7c010349a69c3395f1a57c642dc62Ying Wang                      char const *arg, size_t argsize)
854cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project{
855cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project  struct quoting_options const o = quoting_options_from_style (s);
856cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project  return quotearg_n_options (n, arg, argsize, &o);
857cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project}
858cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project
859cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Projectchar *
860cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Projectquotearg_style (enum quoting_style s, char const *arg)
861cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project{
862cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project  return quotearg_n_style (0, s, arg);
863cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project}
864cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project
865cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Projectchar *
86605436638acc7c010349a69c3395f1a57c642dc62Ying Wangquotearg_style_mem (enum quoting_style s, char const *arg, size_t argsize)
86705436638acc7c010349a69c3395f1a57c642dc62Ying Wang{
86805436638acc7c010349a69c3395f1a57c642dc62Ying Wang  return quotearg_n_style_mem (0, s, arg, argsize);
86905436638acc7c010349a69c3395f1a57c642dc62Ying Wang}
87005436638acc7c010349a69c3395f1a57c642dc62Ying Wang
87105436638acc7c010349a69c3395f1a57c642dc62Ying Wangchar *
87205436638acc7c010349a69c3395f1a57c642dc62Ying Wangquotearg_char_mem (char const *arg, size_t argsize, char ch)
873cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project{
874cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project  struct quoting_options options;
875cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project  options = default_quoting_options;
876cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project  set_char_quoting (&options, ch, 1);
87705436638acc7c010349a69c3395f1a57c642dc62Ying Wang  return quotearg_n_options (0, arg, argsize, &options);
87805436638acc7c010349a69c3395f1a57c642dc62Ying Wang}
87905436638acc7c010349a69c3395f1a57c642dc62Ying Wang
88005436638acc7c010349a69c3395f1a57c642dc62Ying Wangchar *
88105436638acc7c010349a69c3395f1a57c642dc62Ying Wangquotearg_char (char const *arg, char ch)
88205436638acc7c010349a69c3395f1a57c642dc62Ying Wang{
88305436638acc7c010349a69c3395f1a57c642dc62Ying Wang  return quotearg_char_mem (arg, SIZE_MAX, ch);
884cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project}
885cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project
886cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Projectchar *
887cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Projectquotearg_colon (char const *arg)
888cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project{
889cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project  return quotearg_char (arg, ':');
890cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project}
89105436638acc7c010349a69c3395f1a57c642dc62Ying Wang
89205436638acc7c010349a69c3395f1a57c642dc62Ying Wangchar *
89305436638acc7c010349a69c3395f1a57c642dc62Ying Wangquotearg_colon_mem (char const *arg, size_t argsize)
89405436638acc7c010349a69c3395f1a57c642dc62Ying Wang{
89505436638acc7c010349a69c3395f1a57c642dc62Ying Wang  return quotearg_char_mem (arg, argsize, ':');
89605436638acc7c010349a69c3395f1a57c642dc62Ying Wang}
89705436638acc7c010349a69c3395f1a57c642dc62Ying Wang
89805436638acc7c010349a69c3395f1a57c642dc62Ying Wangchar *
89905436638acc7c010349a69c3395f1a57c642dc62Ying Wangquotearg_n_custom (int n, char const *left_quote,
90005436638acc7c010349a69c3395f1a57c642dc62Ying Wang                   char const *right_quote, char const *arg)
90105436638acc7c010349a69c3395f1a57c642dc62Ying Wang{
90205436638acc7c010349a69c3395f1a57c642dc62Ying Wang  return quotearg_n_custom_mem (n, left_quote, right_quote, arg,
90305436638acc7c010349a69c3395f1a57c642dc62Ying Wang                                SIZE_MAX);
90405436638acc7c010349a69c3395f1a57c642dc62Ying Wang}
90505436638acc7c010349a69c3395f1a57c642dc62Ying Wang
90605436638acc7c010349a69c3395f1a57c642dc62Ying Wangchar *
90705436638acc7c010349a69c3395f1a57c642dc62Ying Wangquotearg_n_custom_mem (int n, char const *left_quote,
90805436638acc7c010349a69c3395f1a57c642dc62Ying Wang                       char const *right_quote,
90905436638acc7c010349a69c3395f1a57c642dc62Ying Wang                       char const *arg, size_t argsize)
91005436638acc7c010349a69c3395f1a57c642dc62Ying Wang{
91105436638acc7c010349a69c3395f1a57c642dc62Ying Wang  struct quoting_options o = default_quoting_options;
91205436638acc7c010349a69c3395f1a57c642dc62Ying Wang  set_custom_quoting (&o, left_quote, right_quote);
91305436638acc7c010349a69c3395f1a57c642dc62Ying Wang  return quotearg_n_options (n, arg, argsize, &o);
91405436638acc7c010349a69c3395f1a57c642dc62Ying Wang}
91505436638acc7c010349a69c3395f1a57c642dc62Ying Wang
91605436638acc7c010349a69c3395f1a57c642dc62Ying Wangchar *
91705436638acc7c010349a69c3395f1a57c642dc62Ying Wangquotearg_custom (char const *left_quote, char const *right_quote,
91805436638acc7c010349a69c3395f1a57c642dc62Ying Wang                 char const *arg)
91905436638acc7c010349a69c3395f1a57c642dc62Ying Wang{
92005436638acc7c010349a69c3395f1a57c642dc62Ying Wang  return quotearg_n_custom (0, left_quote, right_quote, arg);
92105436638acc7c010349a69c3395f1a57c642dc62Ying Wang}
92205436638acc7c010349a69c3395f1a57c642dc62Ying Wang
92305436638acc7c010349a69c3395f1a57c642dc62Ying Wangchar *
92405436638acc7c010349a69c3395f1a57c642dc62Ying Wangquotearg_custom_mem (char const *left_quote, char const *right_quote,
92505436638acc7c010349a69c3395f1a57c642dc62Ying Wang                     char const *arg, size_t argsize)
92605436638acc7c010349a69c3395f1a57c642dc62Ying Wang{
92705436638acc7c010349a69c3395f1a57c642dc62Ying Wang  return quotearg_n_custom_mem (0, left_quote, right_quote, arg,
92805436638acc7c010349a69c3395f1a57c642dc62Ying Wang                                argsize);
92905436638acc7c010349a69c3395f1a57c642dc62Ying Wang}
93005436638acc7c010349a69c3395f1a57c642dc62Ying Wang
93105436638acc7c010349a69c3395f1a57c642dc62Ying Wang
93205436638acc7c010349a69c3395f1a57c642dc62Ying Wang/* The quoting option used by the functions of quote.h.  */
93305436638acc7c010349a69c3395f1a57c642dc62Ying Wangstruct quoting_options quote_quoting_options =
93405436638acc7c010349a69c3395f1a57c642dc62Ying Wang  {
93505436638acc7c010349a69c3395f1a57c642dc62Ying Wang    locale_quoting_style,
93605436638acc7c010349a69c3395f1a57c642dc62Ying Wang    0,
93705436638acc7c010349a69c3395f1a57c642dc62Ying Wang    { 0 },
93805436638acc7c010349a69c3395f1a57c642dc62Ying Wang    NULL, NULL
93905436638acc7c010349a69c3395f1a57c642dc62Ying Wang  };
94005436638acc7c010349a69c3395f1a57c642dc62Ying Wang
94105436638acc7c010349a69c3395f1a57c642dc62Ying Wangchar const *
94205436638acc7c010349a69c3395f1a57c642dc62Ying Wangquote_n_mem (int n, char const *arg, size_t argsize)
94305436638acc7c010349a69c3395f1a57c642dc62Ying Wang{
94405436638acc7c010349a69c3395f1a57c642dc62Ying Wang  return quotearg_n_options (n, arg, argsize, &quote_quoting_options);
94505436638acc7c010349a69c3395f1a57c642dc62Ying Wang}
94605436638acc7c010349a69c3395f1a57c642dc62Ying Wang
94705436638acc7c010349a69c3395f1a57c642dc62Ying Wangchar const *
94805436638acc7c010349a69c3395f1a57c642dc62Ying Wangquote_mem (char const *arg, size_t argsize)
94905436638acc7c010349a69c3395f1a57c642dc62Ying Wang{
95005436638acc7c010349a69c3395f1a57c642dc62Ying Wang  return quote_n_mem (0, arg, argsize);
95105436638acc7c010349a69c3395f1a57c642dc62Ying Wang}
95205436638acc7c010349a69c3395f1a57c642dc62Ying Wang
95305436638acc7c010349a69c3395f1a57c642dc62Ying Wangchar const *
95405436638acc7c010349a69c3395f1a57c642dc62Ying Wangquote_n (int n, char const *arg)
95505436638acc7c010349a69c3395f1a57c642dc62Ying Wang{
95605436638acc7c010349a69c3395f1a57c642dc62Ying Wang  return quote_n_mem (n, arg, SIZE_MAX);
95705436638acc7c010349a69c3395f1a57c642dc62Ying Wang}
95805436638acc7c010349a69c3395f1a57c642dc62Ying Wang
95905436638acc7c010349a69c3395f1a57c642dc62Ying Wangchar const *
96005436638acc7c010349a69c3395f1a57c642dc62Ying Wangquote (char const *arg)
96105436638acc7c010349a69c3395f1a57c642dc62Ying Wang{
96205436638acc7c010349a69c3395f1a57c642dc62Ying Wang  return quote_n (0, arg);
96305436638acc7c010349a69c3395f1a57c642dc62Ying Wang}
964