1131554Stjr/* quotearg.c - quote arguments for output 2131554Stjr Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc. 3131554Stjr 4131554Stjr This program is free software; you can redistribute it and/or modify 5131554Stjr it under the terms of the GNU General Public License as published by 6131554Stjr the Free Software Foundation; either version 2, or (at your option) 7131554Stjr any later version. 8131554Stjr 9131554Stjr This program is distributed in the hope that it will be useful, 10131554Stjr but WITHOUT ANY WARRANTY; without even the implied warranty of 11131554Stjr MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12131554Stjr GNU General Public License for more details. 13131554Stjr 14131554Stjr You should have received a copy of the GNU General Public License 15131554Stjr along with this program; if not, write to the Free Software Foundation, 16131554Stjr Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ 17131554Stjr 18131554Stjr/* Written by Paul Eggert <eggert@twinsun.com> */ 19131554Stjr 20131554Stjr#if HAVE_CONFIG_H 21131554Stjr# include <config.h> 22131554Stjr#endif 23131554Stjr 24131554Stjr#if HAVE_STDDEF_H 25131554Stjr# include <stddef.h> /* For the definition of size_t on windows w/MSVC. */ 26131554Stjr#endif 27131554Stjr#include <sys/types.h> 28131554Stjr#include <quotearg.h> 29131554Stjr#include <xalloc.h> 30131554Stjr 31131554Stjr#include <ctype.h> 32131554Stjr 33131554Stjr#if ENABLE_NLS 34131554Stjr# include <libintl.h> 35131554Stjr# define _(text) gettext (text) 36131554Stjr#else 37131554Stjr# define _(text) text 38131554Stjr#endif 39131554Stjr#define N_(text) text 40131554Stjr 41131554Stjr#if HAVE_LIMITS_H 42131554Stjr# include <limits.h> 43131554Stjr#endif 44131554Stjr#ifndef CHAR_BIT 45131554Stjr# define CHAR_BIT 8 46131554Stjr#endif 47131554Stjr#ifndef UCHAR_MAX 48131554Stjr# define UCHAR_MAX ((unsigned char) -1) 49131554Stjr#endif 50131554Stjr 51131554Stjr#if HAVE_C_BACKSLASH_A 52131554Stjr# define ALERT_CHAR '\a' 53131554Stjr#else 54131554Stjr# define ALERT_CHAR '\7' 55131554Stjr#endif 56131554Stjr 57131554Stjr#if HAVE_STDLIB_H 58131554Stjr# include <stdlib.h> 59131554Stjr#endif 60131554Stjr 61131554Stjr#if HAVE_STRING_H 62131554Stjr# include <string.h> 63131554Stjr#endif 64131554Stjr 65131554Stjr#if HAVE_WCHAR_H 66131554Stjr# include <wchar.h> 67131554Stjr#endif 68131554Stjr 69131554Stjr#if !HAVE_MBRTOWC 70131554Stjr/* Disable multibyte processing entirely. Since MB_CUR_MAX is 1, the 71131554Stjr other macros are defined only for documentation and to satisfy C 72131554Stjr syntax. */ 73131554Stjr# undef MB_CUR_MAX 74131554Stjr# define MB_CUR_MAX 1 75131554Stjr# define mbrtowc(pwc, s, n, ps) ((*(pwc) = *(s)) != 0) 76131554Stjr# define mbsinit(ps) 1 77131554Stjr# define iswprint(wc) ISPRINT ((unsigned char) (wc)) 78131554Stjr#endif 79131554Stjr 80131554Stjr#ifndef iswprint 81131554Stjr# if HAVE_WCTYPE_H 82131554Stjr# include <wctype.h> 83131554Stjr# endif 84131554Stjr# if !defined iswprint && !HAVE_ISWPRINT 85131554Stjr# define iswprint(wc) 1 86131554Stjr# endif 87131554Stjr#endif 88131554Stjr 89131554Stjr#define INT_BITS (sizeof (int) * CHAR_BIT) 90131554Stjr 91131554Stjr#if defined (STDC_HEADERS) || (!defined (isascii) && !defined (HAVE_ISASCII)) 92131554Stjr# define IN_CTYPE_DOMAIN(c) 1 93131554Stjr#else 94131554Stjr# define IN_CTYPE_DOMAIN(c) isascii(c) 95131554Stjr#endif 96131554Stjr 97131554Stjr/* Undefine to protect against the definition in wctype.h of solaris2.6. */ 98131554Stjr#undef ISPRINT 99131554Stjr#define ISPRINT(c) (IN_CTYPE_DOMAIN (c) && isprint (c)) 100131554Stjr 101131554Stjrstruct quoting_options 102131554Stjr{ 103131554Stjr /* Basic quoting style. */ 104131554Stjr enum quoting_style style; 105131554Stjr 106131554Stjr /* Quote the characters indicated by this bit vector even if the 107131554Stjr quoting style would not normally require them to be quoted. */ 108131554Stjr int quote_these_too[(UCHAR_MAX / INT_BITS) + 1]; 109131554Stjr}; 110131554Stjr 111131554Stjr/* Names of quoting styles. */ 112131554Stjrchar const *const quoting_style_args[] = 113131554Stjr{ 114131554Stjr "literal", 115131554Stjr "shell", 116131554Stjr "shell-always", 117131554Stjr "c", 118131554Stjr "escape", 119131554Stjr "locale", 120131554Stjr "clocale", 121131554Stjr 0 122131554Stjr}; 123131554Stjr 124131554Stjr/* Correspondences to quoting style names. */ 125131554Stjrenum quoting_style const quoting_style_vals[] = 126131554Stjr{ 127131554Stjr literal_quoting_style, 128131554Stjr shell_quoting_style, 129131554Stjr shell_always_quoting_style, 130131554Stjr c_quoting_style, 131131554Stjr escape_quoting_style, 132131554Stjr locale_quoting_style, 133131554Stjr clocale_quoting_style 134131554Stjr}; 135131554Stjr 136131554Stjr/* The default quoting options. */ 137131554Stjrstatic struct quoting_options default_quoting_options; 138131554Stjr 139131554Stjr/* Allocate a new set of quoting options, with contents initially identical 140131554Stjr to O if O is not null, or to the default if O is null. 141131554Stjr It is the caller's responsibility to free the result. */ 142131554Stjrstruct quoting_options * 143131554Stjrclone_quoting_options (struct quoting_options *o) 144131554Stjr{ 145131554Stjr struct quoting_options *p 146131554Stjr = (struct quoting_options *) xmalloc (sizeof (struct quoting_options)); 147131554Stjr *p = *(o ? o : &default_quoting_options); 148131554Stjr return p; 149131554Stjr} 150131554Stjr 151131554Stjr/* Get the value of O's quoting style. If O is null, use the default. */ 152131554Stjrenum quoting_style 153131554Stjrget_quoting_style (struct quoting_options *o) 154131554Stjr{ 155131554Stjr return (o ? o : &default_quoting_options)->style; 156131554Stjr} 157131554Stjr 158131554Stjr/* In O (or in the default if O is null), 159131554Stjr set the value of the quoting style to S. */ 160131554Stjrvoid 161131554Stjrset_quoting_style (struct quoting_options *o, enum quoting_style s) 162131554Stjr{ 163131554Stjr (o ? o : &default_quoting_options)->style = s; 164131554Stjr} 165131554Stjr 166131554Stjr/* In O (or in the default if O is null), 167131554Stjr set the value of the quoting options for character C to I. 168131554Stjr Return the old value. Currently, the only values defined for I are 169131554Stjr 0 (the default) and 1 (which means to quote the character even if 170131554Stjr it would not otherwise be quoted). */ 171131554Stjrint 172131554Stjrset_char_quoting (struct quoting_options *o, char c, int i) 173131554Stjr{ 174131554Stjr unsigned char uc = c; 175131554Stjr int *p = (o ? o : &default_quoting_options)->quote_these_too + uc / INT_BITS; 176131554Stjr int shift = uc % INT_BITS; 177131554Stjr int r = (*p >> shift) & 1; 178131554Stjr *p ^= ((i & 1) ^ r) << shift; 179131554Stjr return r; 180131554Stjr} 181131554Stjr 182131554Stjr/* MSGID approximates a quotation mark. Return its translation if it 183131554Stjr has one; otherwise, return either it or "\"", depending on S. */ 184131554Stjrstatic char const * 185131554Stjrgettext_quote (char const *msgid, enum quoting_style s) 186131554Stjr{ 187131554Stjr char const *translation = _(msgid); 188131554Stjr if (translation == msgid && s == clocale_quoting_style) 189131554Stjr translation = "\""; 190131554Stjr return translation; 191131554Stjr} 192131554Stjr 193131554Stjr/* Place into buffer BUFFER (of size BUFFERSIZE) a quoted version of 194131554Stjr argument ARG (of size ARGSIZE), using QUOTING_STYLE and the 195131554Stjr non-quoting-style part of O to control quoting. 196131554Stjr Terminate the output with a null character, and return the written 197131554Stjr size of the output, not counting the terminating null. 198131554Stjr If BUFFERSIZE is too small to store the output string, return the 199131554Stjr value that would have been returned had BUFFERSIZE been large enough. 200131554Stjr If ARGSIZE is -1, use the string length of the argument for ARGSIZE. 201131554Stjr 202131554Stjr This function acts like quotearg_buffer (BUFFER, BUFFERSIZE, ARG, 203131554Stjr ARGSIZE, O), except it uses QUOTING_STYLE instead of the quoting 204131554Stjr style specified by O, and O may not be null. */ 205131554Stjr 206131554Stjrstatic size_t 207131554Stjrquotearg_buffer_restyled (char *buffer, size_t buffersize, 208131554Stjr char const *arg, size_t argsize, 209131554Stjr enum quoting_style quoting_style, 210131554Stjr struct quoting_options const *o) 211131554Stjr{ 212131554Stjr size_t i; 213131554Stjr size_t len = 0; 214131554Stjr char const *quote_string = 0; 215131554Stjr size_t quote_string_len = 0; 216131554Stjr int backslash_escapes = 0; 217131554Stjr int unibyte_locale = MB_CUR_MAX == 1; 218131554Stjr 219131554Stjr#define STORE(c) \ 220131554Stjr do \ 221131554Stjr { \ 222131554Stjr if (len < buffersize) \ 223131554Stjr buffer[len] = (c); \ 224131554Stjr len++; \ 225131554Stjr } \ 226131554Stjr while (0) 227131554Stjr 228131554Stjr switch (quoting_style) 229131554Stjr { 230131554Stjr case c_quoting_style: 231131554Stjr STORE ('"'); 232131554Stjr backslash_escapes = 1; 233131554Stjr quote_string = "\""; 234131554Stjr quote_string_len = 1; 235131554Stjr break; 236131554Stjr 237131554Stjr case escape_quoting_style: 238131554Stjr backslash_escapes = 1; 239131554Stjr break; 240131554Stjr 241131554Stjr case locale_quoting_style: 242131554Stjr case clocale_quoting_style: 243131554Stjr { 244131554Stjr /* Get translations for open and closing quotation marks. 245131554Stjr 246131554Stjr The message catalog should translate "`" to a left 247131554Stjr quotation mark suitable for the locale, and similarly for 248131554Stjr "'". If the catalog has no translation, 249131554Stjr locale_quoting_style quotes `like this', and 250131554Stjr clocale_quoting_style quotes "like this". 251131554Stjr 252131554Stjr For example, an American English Unicode locale should 253131554Stjr translate "`" to U+201C (LEFT DOUBLE QUOTATION MARK), and 254131554Stjr should translate "'" to U+201D (RIGHT DOUBLE QUOTATION 255131554Stjr MARK). A British English Unicode locale should instead 256131554Stjr translate these to U+2018 (LEFT SINGLE QUOTATION MARK) and 257131554Stjr U+2019 (RIGHT SINGLE QUOTATION MARK), respectively. */ 258131554Stjr 259131554Stjr char const *left = gettext_quote (N_("`"), quoting_style); 260131554Stjr char const *right = gettext_quote (N_("'"), quoting_style); 261131554Stjr for (quote_string = left; *quote_string; quote_string++) 262131554Stjr STORE (*quote_string); 263131554Stjr backslash_escapes = 1; 264131554Stjr quote_string = right; 265131554Stjr quote_string_len = strlen (quote_string); 266131554Stjr } 267131554Stjr break; 268131554Stjr 269131554Stjr case shell_always_quoting_style: 270131554Stjr STORE ('\''); 271131554Stjr quote_string = "'"; 272131554Stjr quote_string_len = 1; 273131554Stjr break; 274131554Stjr 275131554Stjr default: 276131554Stjr break; 277131554Stjr } 278131554Stjr 279131554Stjr for (i = 0; ! (argsize == (size_t) -1 ? arg[i] == '\0' : i == argsize); i++) 280131554Stjr { 281131554Stjr unsigned char c; 282131554Stjr unsigned char esc; 283131554Stjr 284131554Stjr if (backslash_escapes 285131554Stjr && quote_string_len 286131554Stjr && i + quote_string_len <= argsize 287131554Stjr && memcmp (arg + i, quote_string, quote_string_len) == 0) 288131554Stjr STORE ('\\'); 289131554Stjr 290131554Stjr c = arg[i]; 291131554Stjr switch (c) 292131554Stjr { 293131554Stjr case '?': 294131554Stjr switch (quoting_style) 295131554Stjr { 296131554Stjr case shell_quoting_style: 297131554Stjr goto use_shell_always_quoting_style; 298131554Stjr 299131554Stjr case c_quoting_style: 300131554Stjr if (i + 2 < argsize && arg[i + 1] == '?') 301131554Stjr switch (arg[i + 2]) 302131554Stjr { 303131554Stjr case '!': case '\'': 304131554Stjr case '(': case ')': case '-': case '/': 305131554Stjr case '<': case '=': case '>': 306131554Stjr /* Escape the second '?' in what would otherwise be 307131554Stjr a trigraph. */ 308131554Stjr i += 2; 309131554Stjr c = arg[i + 2]; 310131554Stjr STORE ('?'); 311131554Stjr STORE ('\\'); 312131554Stjr STORE ('?'); 313131554Stjr break; 314131554Stjr } 315131554Stjr break; 316131554Stjr 317131554Stjr default: 318131554Stjr break; 319131554Stjr } 320131554Stjr break; 321131554Stjr 322131554Stjr case ALERT_CHAR: esc = 'a'; goto c_escape; 323131554Stjr case '\b': esc = 'b'; goto c_escape; 324131554Stjr case '\f': esc = 'f'; goto c_escape; 325131554Stjr case '\n': esc = 'n'; goto c_and_shell_escape; 326131554Stjr case '\r': esc = 'r'; goto c_and_shell_escape; 327131554Stjr case '\t': esc = 't'; goto c_and_shell_escape; 328131554Stjr case '\v': esc = 'v'; goto c_escape; 329131554Stjr case '\\': esc = c; goto c_and_shell_escape; 330131554Stjr 331131554Stjr c_and_shell_escape: 332131554Stjr if (quoting_style == shell_quoting_style) 333131554Stjr goto use_shell_always_quoting_style; 334131554Stjr c_escape: 335131554Stjr if (backslash_escapes) 336131554Stjr { 337131554Stjr c = esc; 338131554Stjr goto store_escape; 339131554Stjr } 340131554Stjr break; 341131554Stjr 342131554Stjr case '#': case '~': 343131554Stjr if (i != 0) 344131554Stjr break; 345131554Stjr /* Fall through. */ 346131554Stjr case ' ': 347131554Stjr case '!': /* special in bash */ 348131554Stjr case '"': case '$': case '&': 349131554Stjr case '(': case ')': case '*': case ';': 350131554Stjr case '<': case '>': case '[': 351131554Stjr case '^': /* special in old /bin/sh, e.g. SunOS 4.1.4 */ 352131554Stjr case '`': case '|': 353131554Stjr /* A shell special character. In theory, '$' and '`' could 354131554Stjr be the first bytes of multibyte characters, which means 355131554Stjr we should check them with mbrtowc, but in practice this 356131554Stjr doesn't happen so it's not worth worrying about. */ 357131554Stjr if (quoting_style == shell_quoting_style) 358131554Stjr goto use_shell_always_quoting_style; 359131554Stjr break; 360131554Stjr 361131554Stjr case '\'': 362131554Stjr switch (quoting_style) 363131554Stjr { 364131554Stjr case shell_quoting_style: 365131554Stjr goto use_shell_always_quoting_style; 366131554Stjr 367131554Stjr case shell_always_quoting_style: 368131554Stjr STORE ('\''); 369131554Stjr STORE ('\\'); 370131554Stjr STORE ('\''); 371131554Stjr break; 372131554Stjr 373131554Stjr default: 374131554Stjr break; 375131554Stjr } 376131554Stjr break; 377131554Stjr 378131554Stjr case '%': case '+': case ',': case '-': case '.': case '/': 379131554Stjr case '0': case '1': case '2': case '3': case '4': case '5': 380131554Stjr case '6': case '7': case '8': case '9': case ':': case '=': 381131554Stjr case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': 382131554Stjr case 'G': case 'H': case 'I': case 'J': case 'K': case 'L': 383131554Stjr case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R': 384131554Stjr case 'S': case 'T': case 'U': case 'V': case 'W': case 'X': 385131554Stjr case 'Y': case 'Z': case ']': case '_': case 'a': case 'b': 386131554Stjr case 'c': case 'd': case 'e': case 'f': case 'g': case 'h': 387131554Stjr case 'i': case 'j': case 'k': case 'l': case 'm': case 'n': 388131554Stjr case 'o': case 'p': case 'q': case 'r': case 's': case 't': 389131554Stjr case 'u': case 'v': case 'w': case 'x': case 'y': case 'z': 390131554Stjr case '{': case '}': 391131554Stjr /* These characters don't cause problems, no matter what the 392131554Stjr quoting style is. They cannot start multibyte sequences. */ 393131554Stjr break; 394131554Stjr 395131554Stjr default: 396131554Stjr /* If we have a multibyte sequence, copy it until we reach 397131554Stjr its end, find an error, or come back to the initial shift 398131554Stjr state. For C-like styles, if the sequence has 399131554Stjr unprintable characters, escape the whole sequence, since 400131554Stjr we can't easily escape single characters within it. */ 401131554Stjr { 402131554Stjr /* Length of multibyte sequence found so far. */ 403131554Stjr size_t m; 404131554Stjr 405131554Stjr int printable; 406131554Stjr 407131554Stjr if (unibyte_locale) 408131554Stjr { 409131554Stjr m = 1; 410131554Stjr printable = ISPRINT (c); 411131554Stjr } 412131554Stjr else 413131554Stjr { 414131554Stjr mbstate_t mbstate; 415131554Stjr memset (&mbstate, 0, sizeof mbstate); 416131554Stjr 417131554Stjr m = 0; 418131554Stjr printable = 1; 419131554Stjr if (argsize == (size_t) -1) 420131554Stjr argsize = strlen (arg); 421131554Stjr 422131554Stjr do 423131554Stjr { 424131554Stjr wchar_t w; 425131554Stjr size_t bytes = mbrtowc (&w, &arg[i + m], 426131554Stjr argsize - (i + m), &mbstate); 427131554Stjr if (bytes == 0) 428131554Stjr break; 429131554Stjr else if (bytes == (size_t) -1) 430131554Stjr { 431131554Stjr printable = 0; 432131554Stjr break; 433131554Stjr } 434131554Stjr else if (bytes == (size_t) -2) 435131554Stjr { 436131554Stjr printable = 0; 437131554Stjr while (i + m < argsize && arg[i + m]) 438131554Stjr m++; 439131554Stjr break; 440131554Stjr } 441131554Stjr else 442131554Stjr { 443131554Stjr if (! iswprint (w)) 444131554Stjr printable = 0; 445131554Stjr m += bytes; 446131554Stjr } 447131554Stjr } 448131554Stjr while (! mbsinit (&mbstate)); 449131554Stjr } 450131554Stjr 451131554Stjr if (1 < m || (backslash_escapes && ! printable)) 452131554Stjr { 453131554Stjr /* Output a multibyte sequence, or an escaped 454131554Stjr unprintable unibyte character. */ 455131554Stjr size_t ilim = i + m; 456131554Stjr 457131554Stjr for (;;) 458131554Stjr { 459131554Stjr if (backslash_escapes && ! printable) 460131554Stjr { 461131554Stjr STORE ('\\'); 462131554Stjr STORE ('0' + (c >> 6)); 463131554Stjr STORE ('0' + ((c >> 3) & 7)); 464131554Stjr c = '0' + (c & 7); 465131554Stjr } 466131554Stjr if (ilim <= i + 1) 467131554Stjr break; 468131554Stjr STORE (c); 469131554Stjr c = arg[++i]; 470131554Stjr } 471131554Stjr 472131554Stjr goto store_c; 473131554Stjr } 474131554Stjr } 475131554Stjr } 476131554Stjr 477131554Stjr if (! (backslash_escapes 478131554Stjr && o->quote_these_too[c / INT_BITS] & (1 << (c % INT_BITS)))) 479131554Stjr goto store_c; 480131554Stjr 481131554Stjr store_escape: 482131554Stjr STORE ('\\'); 483131554Stjr 484131554Stjr store_c: 485131554Stjr STORE (c); 486131554Stjr } 487131554Stjr 488131554Stjr if (quote_string) 489131554Stjr for (; *quote_string; quote_string++) 490131554Stjr STORE (*quote_string); 491131554Stjr 492131554Stjr if (len < buffersize) 493131554Stjr buffer[len] = '\0'; 494131554Stjr return len; 495131554Stjr 496131554Stjr use_shell_always_quoting_style: 497131554Stjr return quotearg_buffer_restyled (buffer, buffersize, arg, argsize, 498131554Stjr shell_always_quoting_style, o); 499131554Stjr} 500131554Stjr 501131554Stjr/* Place into buffer BUFFER (of size BUFFERSIZE) a quoted version of 502131554Stjr argument ARG (of size ARGSIZE), using O to control quoting. 503131554Stjr If O is null, use the default. 504131554Stjr Terminate the output with a null character, and return the written 505131554Stjr size of the output, not counting the terminating null. 506131554Stjr If BUFFERSIZE is too small to store the output string, return the 507131554Stjr value that would have been returned had BUFFERSIZE been large enough. 508131554Stjr If ARGSIZE is -1, use the string length of the argument for ARGSIZE. */ 509131554Stjrsize_t 510131554Stjrquotearg_buffer (char *buffer, size_t buffersize, 511131554Stjr char const *arg, size_t argsize, 512131554Stjr struct quoting_options const *o) 513131554Stjr{ 514131554Stjr struct quoting_options const *p = o ? o : &default_quoting_options; 515131554Stjr return quotearg_buffer_restyled (buffer, buffersize, arg, argsize, 516131554Stjr p->style, p); 517131554Stjr} 518131554Stjr 519131554Stjr/* Use storage slot N to return a quoted version of the string ARG. 520131554Stjr OPTIONS specifies the quoting options. 521131554Stjr The returned value points to static storage that can be 522131554Stjr reused by the next call to this function with the same value of N. 523131554Stjr N must be nonnegative. N is deliberately declared with type "int" 524131554Stjr to allow for future extensions (using negative values). */ 525131554Stjrstatic char * 526131554Stjrquotearg_n_options (int n, char const *arg, 527131554Stjr struct quoting_options const *options) 528131554Stjr{ 529131554Stjr /* Preallocate a slot 0 buffer, so that the caller can always quote 530131554Stjr one small component of a "memory exhausted" message in slot 0. */ 531131554Stjr static char slot0[256]; 532131554Stjr static unsigned int nslots = 1; 533131554Stjr struct slotvec 534131554Stjr { 535131554Stjr size_t size; 536131554Stjr char *val; 537131554Stjr }; 538131554Stjr static struct slotvec slotvec0 = {sizeof slot0, slot0}; 539131554Stjr static struct slotvec *slotvec = &slotvec0; 540131554Stjr 541131554Stjr if (nslots <= n) 542131554Stjr { 543131554Stjr int n1 = n + 1; 544131554Stjr size_t s = n1 * sizeof (struct slotvec); 545131554Stjr if (! (0 < n1 && n1 == s / sizeof (struct slotvec))) 546131554Stjr abort (); 547131554Stjr if (slotvec == &slotvec0) 548131554Stjr { 549131554Stjr slotvec = (struct slotvec *) xmalloc (sizeof (struct slotvec)); 550131554Stjr *slotvec = slotvec0; 551131554Stjr } 552131554Stjr slotvec = (struct slotvec *) xrealloc (slotvec, s); 553131554Stjr memset (slotvec + nslots, 0, (n1 - nslots) * sizeof (struct slotvec)); 554131554Stjr nslots = n; 555131554Stjr } 556131554Stjr 557131554Stjr { 558131554Stjr size_t size = slotvec[n].size; 559131554Stjr char *val = slotvec[n].val; 560131554Stjr size_t qsize = quotearg_buffer (val, size, arg, (size_t) -1, options); 561131554Stjr 562131554Stjr if (size <= qsize) 563131554Stjr { 564131554Stjr slotvec[n].size = size = qsize + 1; 565131554Stjr slotvec[n].val = val = xrealloc (val == slot0 ? 0 : val, size); 566131554Stjr quotearg_buffer (val, size, arg, (size_t) -1, options); 567131554Stjr } 568131554Stjr 569131554Stjr return val; 570131554Stjr } 571131554Stjr} 572131554Stjr 573131554Stjrchar * 574131554Stjrquotearg_n (unsigned int n, char const *arg) 575131554Stjr{ 576131554Stjr return quotearg_n_options (n, arg, &default_quoting_options); 577131554Stjr} 578131554Stjr 579131554Stjrchar * 580131554Stjrquotearg (char const *arg) 581131554Stjr{ 582131554Stjr return quotearg_n (0, arg); 583131554Stjr} 584131554Stjr 585131554Stjrchar * 586131554Stjrquotearg_n_style (unsigned int n, enum quoting_style s, char const *arg) 587131554Stjr{ 588131554Stjr struct quoting_options o; 589131554Stjr o.style = s; 590131554Stjr memset (o.quote_these_too, 0, sizeof o.quote_these_too); 591131554Stjr return quotearg_n_options (n, arg, &o); 592131554Stjr} 593131554Stjr 594131554Stjrchar * 595131554Stjrquotearg_style (enum quoting_style s, char const *arg) 596131554Stjr{ 597131554Stjr return quotearg_n_style (0, s, arg); 598131554Stjr} 599131554Stjr 600131554Stjrchar * 601131554Stjrquotearg_char (char const *arg, char ch) 602131554Stjr{ 603131554Stjr struct quoting_options options; 604131554Stjr options = default_quoting_options; 605131554Stjr set_char_quoting (&options, ch, 1); 606131554Stjr return quotearg_n_options (0, arg, &options); 607131554Stjr} 608131554Stjr 609131554Stjrchar * 610131554Stjrquotearg_colon (char const *arg) 611131554Stjr{ 612131554Stjr return quotearg_char (arg, ':'); 613131554Stjr} 614