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, "e_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