1 /* quotearg.c - quote arguments for output 2 3 Copyright (C) 1998-2002, 2004-2015 Free Software Foundation, Inc. 4 5 This program is free software: you can redistribute it and/or modify 6 it under the terms of the GNU General Public License as published by 7 the Free Software Foundation; either version 3 of the License, or 8 (at your option) any later version. 9 10 This program is distributed in the hope that it will be useful, 11 but WITHOUT ANY WARRANTY; without even the implied warranty of 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 GNU General Public License for more details. 14 15 You should have received a copy of the GNU General Public License 16 along with this program. If not, see <http://www.gnu.org/licenses/>. */ 17 18 /* Written by Paul Eggert <eggert@twinsun.com> */ 19 20 /* Without this pragma, gcc 4.7.0 20111124 mistakenly suggests that 21 the quoting_options_from_style function might be candidate for 22 attribute 'pure' */ 23 #if (__GNUC__ == 4 && 6 <= __GNUC_MINOR__) || 4 < __GNUC__ 24 # pragma GCC diagnostic ignored "-Wsuggest-attribute=pure" 25 #endif 26 27 #include <config.h> 28 29 #include "quotearg.h" 30 #include "quote.h" 31 32 #include "xalloc.h" 33 #include "c-strcaseeq.h" 34 #include "localcharset.h" 35 36 #include <ctype.h> 37 #include <errno.h> 38 #include <limits.h> 39 #include <stdbool.h> 40 #include <stdlib.h> 41 #include <string.h> 42 #include <wchar.h> 43 #include <wctype.h> 44 45 #include "gettext.h" 46 #define _(msgid) gettext (msgid) 47 #define N_(msgid) msgid 48 49 #ifndef SIZE_MAX 50 # define SIZE_MAX ((size_t) -1) 51 #endif 52 53 #define INT_BITS (sizeof (int) * CHAR_BIT) 54 55 struct quoting_options 56 { 57 /* Basic quoting style. */ 58 enum quoting_style style; 59 60 /* Additional flags. Bitwise combination of enum quoting_flags. */ 61 int flags; 62 63 /* Quote the characters indicated by this bit vector even if the 64 quoting style would not normally require them to be quoted. */ 65 unsigned int quote_these_too[(UCHAR_MAX / INT_BITS) + 1]; 66 67 /* The left quote for custom_quoting_style. */ 68 char const *left_quote; 69 70 /* The right quote for custom_quoting_style. */ 71 char const *right_quote; 72 }; 73 74 /* Names of quoting styles. */ 75 char const *const quoting_style_args[] = 76 { 77 "literal", 78 "shell", 79 "shell-always", 80 "c", 81 "c-maybe", 82 "escape", 83 "locale", 84 "clocale", 85 0 86 }; 87 88 /* Correspondences to quoting style names. */ 89 enum quoting_style const quoting_style_vals[] = 90 { 91 literal_quoting_style, 92 shell_quoting_style, 93 shell_always_quoting_style, 94 c_quoting_style, 95 c_maybe_quoting_style, 96 escape_quoting_style, 97 locale_quoting_style, 98 clocale_quoting_style 99 }; 100 101 /* The default quoting options. */ 102 static struct quoting_options default_quoting_options; 103 104 /* Allocate a new set of quoting options, with contents initially identical 105 to O if O is not null, or to the default if O is null. 106 It is the caller's responsibility to free the result. */ 107 struct quoting_options * 108 clone_quoting_options (struct quoting_options *o) 109 { 110 int e = errno; 111 struct quoting_options *p = xmemdup (o ? o : &default_quoting_options, 112 sizeof *o); 113 errno = e; 114 return p; 115 } 116 117 /* Get the value of O's quoting style. If O is null, use the default. */ 118 enum quoting_style 119 get_quoting_style (struct quoting_options *o) 120 { 121 return (o ? o : &default_quoting_options)->style; 122 } 123 124 /* In O (or in the default if O is null), 125 set the value of the quoting style to S. */ 126 void 127 set_quoting_style (struct quoting_options *o, enum quoting_style s) 128 { 129 (o ? o : &default_quoting_options)->style = s; 130 } 131 132 /* In O (or in the default if O is null), 133 set the value of the quoting options for character C to I. 134 Return the old value. Currently, the only values defined for I are 135 0 (the default) and 1 (which means to quote the character even if 136 it would not otherwise be quoted). */ 137 int 138 set_char_quoting (struct quoting_options *o, char c, int i) 139 { 140 unsigned char uc = c; 141 unsigned int *p = 142 (o ? o : &default_quoting_options)->quote_these_too + uc / INT_BITS; 143 int shift = uc % INT_BITS; 144 int r = (*p >> shift) & 1; 145 *p ^= ((i & 1) ^ r) << shift; 146 return r; 147 } 148 149 /* In O (or in the default if O is null), 150 set the value of the quoting options flag to I, which can be a 151 bitwise combination of enum quoting_flags, or 0 for default 152 behavior. Return the old value. */ 153 int 154 set_quoting_flags (struct quoting_options *o, int i) 155 { 156 int r; 157 if (!o) 158 o = &default_quoting_options; 159 r = o->flags; 160 o->flags = i; 161 return r; 162 } 163 164 void 165 set_custom_quoting (struct quoting_options *o, 166 char const *left_quote, char const *right_quote) 167 { 168 if (!o) 169 o = &default_quoting_options; 170 o->style = custom_quoting_style; 171 if (!left_quote || !right_quote) 172 abort (); 173 o->left_quote = left_quote; 174 o->right_quote = right_quote; 175 } 176 177 /* Return quoting options for STYLE, with no extra quoting. */ 178 static struct quoting_options /* NOT PURE!! */ 179 quoting_options_from_style (enum quoting_style style) 180 { 181 struct quoting_options o = { literal_quoting_style, 0, { 0 }, NULL, NULL }; 182 if (style == custom_quoting_style) 183 abort (); 184 o.style = style; 185 return o; 186 } 187 188 /* MSGID approximates a quotation mark. Return its translation if it 189 has one; otherwise, return either it or "\"", depending on S. 190 191 S is either clocale_quoting_style or locale_quoting_style. */ 192 static char const * 193 gettext_quote (char const *msgid, enum quoting_style s) 194 { 195 char const *translation = _(msgid); 196 char const *locale_code; 197 198 if (translation != msgid) 199 return translation; 200 201 /* For UTF-8 and GB-18030, use single quotes U+2018 and U+2019. 202 Here is a list of other locales that include U+2018 and U+2019: 203 204 ISO-8859-7 0xA1 KOI8-T 0x91 205 CP869 0x8B CP874 0x91 206 CP932 0x81 0x65 CP936 0xA1 0xAE 207 CP949 0xA1 0xAE CP950 0xA1 0xA5 208 CP1250 0x91 CP1251 0x91 209 CP1252 0x91 CP1253 0x91 210 CP1254 0x91 CP1255 0x91 211 CP1256 0x91 CP1257 0x91 212 EUC-JP 0xA1 0xC6 EUC-KR 0xA1 0xAE 213 EUC-TW 0xA1 0xE4 BIG5 0xA1 0xA5 214 BIG5-HKSCS 0xA1 0xA5 EUC-CN 0xA1 0xAE 215 GBK 0xA1 0xAE Georgian-PS 0x91 216 PT154 0x91 217 218 None of these is still in wide use; using iconv is overkill. */ 219 locale_code = locale_charset (); 220 if (STRCASEEQ (locale_code, "UTF-8", 'U','T','F','-','8',0,0,0,0)) 221 return msgid[0] == '`' ? "\xe2\x80\x98": "\xe2\x80\x99"; 222 if (STRCASEEQ (locale_code, "GB18030", 'G','B','1','8','0','3','0',0,0)) 223 return msgid[0] == '`' ? "\xa1\ae": "\xa1\xaf"; 224 225 return (s == clocale_quoting_style ? "\"" : "'"); 226 } 227 228 /* Place into buffer BUFFER (of size BUFFERSIZE) a quoted version of 229 argument ARG (of size ARGSIZE), using QUOTING_STYLE, FLAGS, and 230 QUOTE_THESE_TOO to control quoting. 231 Terminate the output with a null character, and return the written 232 size of the output, not counting the terminating null. 233 If BUFFERSIZE is too small to store the output string, return the 234 value that would have been returned had BUFFERSIZE been large enough. 235 If ARGSIZE is SIZE_MAX, use the string length of the argument for ARGSIZE. 236 237 This function acts like quotearg_buffer (BUFFER, BUFFERSIZE, ARG, 238 ARGSIZE, O), except it breaks O into its component pieces and is 239 not careful about errno. */ 240 241 static size_t 242 quotearg_buffer_restyled (char *buffer, size_t buffersize, 243 char const *arg, size_t argsize, 244 enum quoting_style quoting_style, int flags, 245 unsigned int const *quote_these_too, 246 char const *left_quote, 247 char const *right_quote) 248 { 249 size_t i; 250 size_t len = 0; 251 char const *quote_string = 0; 252 size_t quote_string_len = 0; 253 bool backslash_escapes = false; 254 bool unibyte_locale = MB_CUR_MAX == 1; 255 bool elide_outer_quotes = (flags & QA_ELIDE_OUTER_QUOTES) != 0; 256 257 #define STORE(c) \ 258 do \ 259 { \ 260 if (len < buffersize) \ 261 buffer[len] = (c); \ 262 len++; \ 263 } \ 264 while (0) 265 266 switch (quoting_style) 267 { 268 case c_maybe_quoting_style: 269 quoting_style = c_quoting_style; 270 elide_outer_quotes = true; 271 /* Fall through. */ 272 case c_quoting_style: 273 if (!elide_outer_quotes) 274 STORE ('"'); 275 backslash_escapes = true; 276 quote_string = "\""; 277 quote_string_len = 1; 278 break; 279 280 case escape_quoting_style: 281 backslash_escapes = true; 282 elide_outer_quotes = false; 283 break; 284 285 case locale_quoting_style: 286 case clocale_quoting_style: 287 case custom_quoting_style: 288 { 289 if (quoting_style != custom_quoting_style) 290 { 291 /* TRANSLATORS: 292 Get translations for open and closing quotation marks. 293 The message catalog should translate "`" to a left 294 quotation mark suitable for the locale, and similarly for 295 "'". For example, a French Unicode local should translate 296 these to U+00AB (LEFT-POINTING DOUBLE ANGLE 297 QUOTATION MARK), and U+00BB (RIGHT-POINTING DOUBLE ANGLE 298 QUOTATION MARK), respectively. 299 300 If the catalog has no translation, we will try to 301 use Unicode U+2018 (LEFT SINGLE QUOTATION MARK) and 302 Unicode U+2019 (RIGHT SINGLE QUOTATION MARK). If the 303 current locale is not Unicode, locale_quoting_style 304 will quote 'like this', and clocale_quoting_style will 305 quote "like this". You should always include translations 306 for "`" and "'" even if U+2018 and U+2019 are appropriate 307 for your locale. 308 309 If you don't know what to put here, please see 310 <http://en.wikipedia.org/wiki/Quotation_marks_in_other_languages> 311 and use glyphs suitable for your language. */ 312 left_quote = gettext_quote (N_("`"), quoting_style); 313 right_quote = gettext_quote (N_("'"), quoting_style); 314 } 315 if (!elide_outer_quotes) 316 for (quote_string = left_quote; *quote_string; quote_string++) 317 STORE (*quote_string); 318 backslash_escapes = true; 319 quote_string = right_quote; 320 quote_string_len = strlen (quote_string); 321 } 322 break; 323 324 case shell_quoting_style: 325 quoting_style = shell_always_quoting_style; 326 elide_outer_quotes = true; 327 /* Fall through. */ 328 case shell_always_quoting_style: 329 if (!elide_outer_quotes) 330 STORE ('\''); 331 quote_string = "'"; 332 quote_string_len = 1; 333 break; 334 335 case literal_quoting_style: 336 elide_outer_quotes = false; 337 break; 338 339 default: 340 abort (); 341 } 342 343 for (i = 0; ! (argsize == SIZE_MAX ? arg[i] == '\0' : i == argsize); i++) 344 { 345 unsigned char c; 346 unsigned char esc; 347 bool is_right_quote = false; 348 349 if (backslash_escapes 350 && quote_string_len 351 && (i + quote_string_len 352 <= (argsize == SIZE_MAX && 1 < quote_string_len 353 /* Use strlen only if we must: when argsize is SIZE_MAX, 354 and when the quote string is more than 1 byte long. 355 If we do call strlen, save the result. */ 356 ? (argsize = strlen (arg)) : argsize)) 357 && memcmp (arg + i, quote_string, quote_string_len) == 0) 358 { 359 if (elide_outer_quotes) 360 goto force_outer_quoting_style; 361 is_right_quote = true; 362 } 363 364 c = arg[i]; 365 switch (c) 366 { 367 case '\0': 368 if (backslash_escapes) 369 { 370 if (elide_outer_quotes) 371 goto force_outer_quoting_style; 372 STORE ('\\'); 373 /* If quote_string were to begin with digits, we'd need to 374 test for the end of the arg as well. However, it's 375 hard to imagine any locale that would use digits in 376 quotes, and set_custom_quoting is documented not to 377 accept them. */ 378 if (i + 1 < argsize && '0' <= arg[i + 1] && arg[i + 1] <= '9') 379 { 380 STORE ('0'); 381 STORE ('0'); 382 } 383 c = '0'; 384 /* We don't have to worry that this last '0' will be 385 backslash-escaped because, again, quote_string should 386 not start with it and because quote_these_too is 387 documented as not accepting it. */ 388 } 389 else if (flags & QA_ELIDE_NULL_BYTES) 390 continue; 391 break; 392 393 case '?': 394 switch (quoting_style) 395 { 396 case shell_always_quoting_style: 397 if (elide_outer_quotes) 398 goto force_outer_quoting_style; 399 break; 400 401 case c_quoting_style: 402 if ((flags & QA_SPLIT_TRIGRAPHS) 403 && i + 2 < argsize && arg[i + 1] == '?') 404 switch (arg[i + 2]) 405 { 406 case '!': case '\'': 407 case '(': case ')': case '-': case '/': 408 case '<': case '=': case '>': 409 /* Escape the second '?' in what would otherwise be 410 a trigraph. */ 411 if (elide_outer_quotes) 412 goto force_outer_quoting_style; 413 c = arg[i + 2]; 414 i += 2; 415 STORE ('?'); 416 STORE ('"'); 417 STORE ('"'); 418 STORE ('?'); 419 break; 420 421 default: 422 break; 423 } 424 break; 425 426 default: 427 break; 428 } 429 break; 430 431 case '\a': esc = 'a'; goto c_escape; 432 case '\b': esc = 'b'; goto c_escape; 433 case '\f': esc = 'f'; goto c_escape; 434 case '\n': esc = 'n'; goto c_and_shell_escape; 435 case '\r': esc = 'r'; goto c_and_shell_escape; 436 case '\t': esc = 't'; goto c_and_shell_escape; 437 case '\v': esc = 'v'; goto c_escape; 438 case '\\': esc = c; 439 /* No need to escape the escape if we are trying to elide 440 outer quotes and nothing else is problematic. */ 441 if (backslash_escapes && elide_outer_quotes && quote_string_len) 442 goto store_c; 443 444 c_and_shell_escape: 445 if (quoting_style == shell_always_quoting_style 446 && elide_outer_quotes) 447 goto force_outer_quoting_style; 448 /* Fall through. */ 449 c_escape: 450 if (backslash_escapes) 451 { 452 c = esc; 453 goto store_escape; 454 } 455 break; 456 457 case '{': case '}': /* sometimes special if isolated */ 458 if (! (argsize == SIZE_MAX ? arg[1] == '\0' : argsize == 1)) 459 break; 460 /* Fall through. */ 461 case '#': case '~': 462 if (i != 0) 463 break; 464 /* Fall through. */ 465 case ' ': 466 case '!': /* special in bash */ 467 case '"': case '$': case '&': 468 case '(': case ')': case '*': case ';': 469 case '<': 470 case '=': /* sometimes special in 0th or (with "set -k") later args */ 471 case '>': case '[': 472 case '^': /* special in old /bin/sh, e.g. SunOS 4.1.4 */ 473 case '`': case '|': 474 /* A shell special character. In theory, '$' and '`' could 475 be the first bytes of multibyte characters, which means 476 we should check them with mbrtowc, but in practice this 477 doesn't happen so it's not worth worrying about. */ 478 if (quoting_style == shell_always_quoting_style 479 && elide_outer_quotes) 480 goto force_outer_quoting_style; 481 break; 482 483 case '\'': 484 if (quoting_style == shell_always_quoting_style) 485 { 486 if (elide_outer_quotes) 487 goto force_outer_quoting_style; 488 STORE ('\''); 489 STORE ('\\'); 490 STORE ('\''); 491 } 492 break; 493 494 case '%': case '+': case ',': case '-': case '.': case '/': 495 case '0': case '1': case '2': case '3': case '4': case '5': 496 case '6': case '7': case '8': case '9': case ':': 497 case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': 498 case 'G': case 'H': case 'I': case 'J': case 'K': case 'L': 499 case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R': 500 case 'S': case 'T': case 'U': case 'V': case 'W': case 'X': 501 case 'Y': case 'Z': case ']': case '_': case 'a': case 'b': 502 case 'c': case 'd': case 'e': case 'f': case 'g': case 'h': 503 case 'i': case 'j': case 'k': case 'l': case 'm': case 'n': 504 case 'o': case 'p': case 'q': case 'r': case 's': case 't': 505 case 'u': case 'v': case 'w': case 'x': case 'y': case 'z': 506 /* These characters don't cause problems, no matter what the 507 quoting style is. They cannot start multibyte sequences. 508 A digit or a special letter would cause trouble if it 509 appeared at the beginning of quote_string because we'd then 510 escape by prepending a backslash. However, it's hard to 511 imagine any locale that would use digits or letters as 512 quotes, and set_custom_quoting is documented not to accept 513 them. Also, a digit or a special letter would cause 514 trouble if it appeared in quote_these_too, but that's also 515 documented as not accepting them. */ 516 break; 517 518 default: 519 /* If we have a multibyte sequence, copy it until we reach 520 its end, find an error, or come back to the initial shift 521 state. For C-like styles, if the sequence has 522 unprintable characters, escape the whole sequence, since 523 we can't easily escape single characters within it. */ 524 { 525 /* Length of multibyte sequence found so far. */ 526 size_t m; 527 528 bool printable; 529 530 if (unibyte_locale) 531 { 532 m = 1; 533 printable = isprint (c) != 0; 534 } 535 else 536 { 537 mbstate_t mbstate; 538 memset (&mbstate, 0, sizeof mbstate); 539 540 m = 0; 541 printable = true; 542 if (argsize == SIZE_MAX) 543 argsize = strlen (arg); 544 545 do 546 { 547 wchar_t w; 548 size_t bytes = mbrtowc (&w, &arg[i + m], 549 argsize - (i + m), &mbstate); 550 if (bytes == 0) 551 break; 552 else if (bytes == (size_t) -1) 553 { 554 printable = false; 555 break; 556 } 557 else if (bytes == (size_t) -2) 558 { 559 printable = false; 560 while (i + m < argsize && arg[i + m]) 561 m++; 562 break; 563 } 564 else 565 { 566 /* Work around a bug with older shells that "see" a '\' 567 that is really the 2nd byte of a multibyte character. 568 In practice the problem is limited to ASCII 569 chars >= '@' that are shell special chars. */ 570 if ('[' == 0x5b && elide_outer_quotes 571 && quoting_style == shell_always_quoting_style) 572 { 573 size_t j; 574 for (j = 1; j < bytes; j++) 575 switch (arg[i + m + j]) 576 { 577 case '[': case '\\': case '^': 578 case '`': case '|': 579 goto force_outer_quoting_style; 580 581 default: 582 break; 583 } 584 } 585 586 if (! iswprint (w)) 587 printable = false; 588 m += bytes; 589 } 590 } 591 while (! mbsinit (&mbstate)); 592 } 593 594 if (1 < m || (backslash_escapes && ! printable)) 595 { 596 /* Output a multibyte sequence, or an escaped 597 unprintable unibyte character. */ 598 size_t ilim = i + m; 599 600 for (;;) 601 { 602 if (backslash_escapes && ! printable) 603 { 604 if (elide_outer_quotes) 605 goto force_outer_quoting_style; 606 STORE ('\\'); 607 STORE ('0' + (c >> 6)); 608 STORE ('0' + ((c >> 3) & 7)); 609 c = '0' + (c & 7); 610 } 611 else if (is_right_quote) 612 { 613 STORE ('\\'); 614 is_right_quote = false; 615 } 616 if (ilim <= i + 1) 617 break; 618 STORE (c); 619 c = arg[++i]; 620 } 621 622 goto store_c; 623 } 624 } 625 } 626 627 if (! ((backslash_escapes || elide_outer_quotes) 628 && quote_these_too 629 && quote_these_too[c / INT_BITS] >> (c % INT_BITS) & 1) 630 && !is_right_quote) 631 goto store_c; 632 633 store_escape: 634 if (elide_outer_quotes) 635 goto force_outer_quoting_style; 636 STORE ('\\'); 637 638 store_c: 639 STORE (c); 640 } 641 642 if (len == 0 && quoting_style == shell_always_quoting_style 643 && elide_outer_quotes) 644 goto force_outer_quoting_style; 645 646 if (quote_string && !elide_outer_quotes) 647 for (; *quote_string; quote_string++) 648 STORE (*quote_string); 649 650 if (len < buffersize) 651 buffer[len] = '\0'; 652 return len; 653 654 force_outer_quoting_style: 655 /* Don't reuse quote_these_too, since the addition of outer quotes 656 sufficiently quotes the specified characters. */ 657 return quotearg_buffer_restyled (buffer, buffersize, arg, argsize, 658 quoting_style, 659 flags & ~QA_ELIDE_OUTER_QUOTES, NULL, 660 left_quote, right_quote); 661 } 662 663 /* Place into buffer BUFFER (of size BUFFERSIZE) a quoted version of 664 argument ARG (of size ARGSIZE), using O to control quoting. 665 If O is null, use the default. 666 Terminate the output with a null character, and return the written 667 size of the output, not counting the terminating null. 668 If BUFFERSIZE is too small to store the output string, return the 669 value that would have been returned had BUFFERSIZE been large enough. 670 If ARGSIZE is SIZE_MAX, use the string length of the argument for 671 ARGSIZE. */ 672 size_t 673 quotearg_buffer (char *buffer, size_t buffersize, 674 char const *arg, size_t argsize, 675 struct quoting_options const *o) 676 { 677 struct quoting_options const *p = o ? o : &default_quoting_options; 678 int e = errno; 679 size_t r = quotearg_buffer_restyled (buffer, buffersize, arg, argsize, 680 p->style, p->flags, p->quote_these_too, 681 p->left_quote, p->right_quote); 682 errno = e; 683 return r; 684 } 685 686 /* Equivalent to quotearg_alloc (ARG, ARGSIZE, NULL, O). */ 687 char * 688 quotearg_alloc (char const *arg, size_t argsize, 689 struct quoting_options const *o) 690 { 691 return quotearg_alloc_mem (arg, argsize, NULL, o); 692 } 693 694 /* Like quotearg_buffer (..., ARG, ARGSIZE, O), except return newly 695 allocated storage containing the quoted string, and store the 696 resulting size into *SIZE, if non-NULL. The result can contain 697 embedded null bytes only if ARGSIZE is not SIZE_MAX, SIZE is not 698 NULL, and set_quoting_flags has not set the null byte elision 699 flag. */ 700 char * 701 quotearg_alloc_mem (char const *arg, size_t argsize, size_t *size, 702 struct quoting_options const *o) 703 { 704 struct quoting_options const *p = o ? o : &default_quoting_options; 705 int e = errno; 706 /* Elide embedded null bytes if we can't return a size. */ 707 int flags = p->flags | (size ? 0 : QA_ELIDE_NULL_BYTES); 708 size_t bufsize = quotearg_buffer_restyled (0, 0, arg, argsize, p->style, 709 flags, p->quote_these_too, 710 p->left_quote, 711 p->right_quote) + 1; 712 char *buf = xcharalloc (bufsize); 713 quotearg_buffer_restyled (buf, bufsize, arg, argsize, p->style, flags, 714 p->quote_these_too, 715 p->left_quote, p->right_quote); 716 errno = e; 717 if (size) 718 *size = bufsize - 1; 719 return buf; 720 } 721 722 /* A storage slot with size and pointer to a value. */ 723 struct slotvec 724 { 725 size_t size; 726 char *val; 727 }; 728 729 /* Preallocate a slot 0 buffer, so that the caller can always quote 730 one small component of a "memory exhausted" message in slot 0. */ 731 static char slot0[256]; 732 static unsigned int nslots = 1; 733 static struct slotvec slotvec0 = {sizeof slot0, slot0}; 734 static struct slotvec *slotvec = &slotvec0; 735 736 void 737 quotearg_free (void) 738 { 739 struct slotvec *sv = slotvec; 740 unsigned int i; 741 for (i = 1; i < nslots; i++) 742 free (sv[i].val); 743 if (sv[0].val != slot0) 744 { 745 free (sv[0].val); 746 slotvec0.size = sizeof slot0; 747 slotvec0.val = slot0; 748 } 749 if (sv != &slotvec0) 750 { 751 free (sv); 752 slotvec = &slotvec0; 753 } 754 nslots = 1; 755 } 756 757 /* Use storage slot N to return a quoted version of argument ARG. 758 ARG is of size ARGSIZE, but if that is SIZE_MAX, ARG is a 759 null-terminated string. 760 OPTIONS specifies the quoting options. 761 The returned value points to static storage that can be 762 reused by the next call to this function with the same value of N. 763 N must be nonnegative. N is deliberately declared with type "int" 764 to allow for future extensions (using negative values). */ 765 static char * 766 quotearg_n_options (int n, char const *arg, size_t argsize, 767 struct quoting_options const *options) 768 { 769 int e = errno; 770 771 unsigned int n0 = n; 772 struct slotvec *sv = slotvec; 773 774 if (n < 0) 775 abort (); 776 777 if (nslots <= n0) 778 { 779 /* FIXME: technically, the type of n1 should be 'unsigned int', 780 but that evokes an unsuppressible warning from gcc-4.0.1 and 781 older. If gcc ever provides an option to suppress that warning, 782 revert to the original type, so that the test in xalloc_oversized 783 is once again performed only at compile time. */ 784 size_t n1 = n0 + 1; 785 bool preallocated = (sv == &slotvec0); 786 787 if (xalloc_oversized (n1, sizeof *sv)) 788 xalloc_die (); 789 790 slotvec = sv = xrealloc (preallocated ? NULL : sv, n1 * sizeof *sv); 791 if (preallocated) 792 *sv = slotvec0; 793 memset (sv + nslots, 0, (n1 - nslots) * sizeof *sv); 794 nslots = n1; 795 } 796 797 { 798 size_t size = sv[n].size; 799 char *val = sv[n].val; 800 /* Elide embedded null bytes since we don't return a size. */ 801 int flags = options->flags | QA_ELIDE_NULL_BYTES; 802 size_t qsize = quotearg_buffer_restyled (val, size, arg, argsize, 803 options->style, flags, 804 options->quote_these_too, 805 options->left_quote, 806 options->right_quote); 807 808 if (size <= qsize) 809 { 810 sv[n].size = size = qsize + 1; 811 if (val != slot0) 812 free (val); 813 sv[n].val = val = xcharalloc (size); 814 quotearg_buffer_restyled (val, size, arg, argsize, options->style, 815 flags, options->quote_these_too, 816 options->left_quote, 817 options->right_quote); 818 } 819 820 errno = e; 821 return val; 822 } 823 } 824 825 char * 826 quotearg_n (int n, char const *arg) 827 { 828 return quotearg_n_options (n, arg, SIZE_MAX, &default_quoting_options); 829 } 830 831 char * 832 quotearg_n_mem (int n, char const *arg, size_t argsize) 833 { 834 return quotearg_n_options (n, arg, argsize, &default_quoting_options); 835 } 836 837 char * 838 quotearg (char const *arg) 839 { 840 return quotearg_n (0, arg); 841 } 842 843 char * 844 quotearg_mem (char const *arg, size_t argsize) 845 { 846 return quotearg_n_mem (0, arg, argsize); 847 } 848 849 char * 850 quotearg_n_style (int n, enum quoting_style s, char const *arg) 851 { 852 struct quoting_options const o = quoting_options_from_style (s); 853 return quotearg_n_options (n, arg, SIZE_MAX, &o); 854 } 855 856 char * 857 quotearg_n_style_mem (int n, enum quoting_style s, 858 char const *arg, size_t argsize) 859 { 860 struct quoting_options const o = quoting_options_from_style (s); 861 return quotearg_n_options (n, arg, argsize, &o); 862 } 863 864 char * 865 quotearg_style (enum quoting_style s, char const *arg) 866 { 867 return quotearg_n_style (0, s, arg); 868 } 869 870 char * 871 quotearg_style_mem (enum quoting_style s, char const *arg, size_t argsize) 872 { 873 return quotearg_n_style_mem (0, s, arg, argsize); 874 } 875 876 char * 877 quotearg_char_mem (char const *arg, size_t argsize, char ch) 878 { 879 struct quoting_options options; 880 options = default_quoting_options; 881 set_char_quoting (&options, ch, 1); 882 return quotearg_n_options (0, arg, argsize, &options); 883 } 884 885 char * 886 quotearg_char (char const *arg, char ch) 887 { 888 return quotearg_char_mem (arg, SIZE_MAX, ch); 889 } 890 891 char * 892 quotearg_colon (char const *arg) 893 { 894 return quotearg_char (arg, ':'); 895 } 896 897 char * 898 quotearg_colon_mem (char const *arg, size_t argsize) 899 { 900 return quotearg_char_mem (arg, argsize, ':'); 901 } 902 903 char * 904 quotearg_n_custom (int n, char const *left_quote, 905 char const *right_quote, char const *arg) 906 { 907 return quotearg_n_custom_mem (n, left_quote, right_quote, arg, 908 SIZE_MAX); 909 } 910 911 char * 912 quotearg_n_custom_mem (int n, char const *left_quote, 913 char const *right_quote, 914 char const *arg, size_t argsize) 915 { 916 struct quoting_options o = default_quoting_options; 917 set_custom_quoting (&o, left_quote, right_quote); 918 return quotearg_n_options (n, arg, argsize, &o); 919 } 920 921 char * 922 quotearg_custom (char const *left_quote, char const *right_quote, 923 char const *arg) 924 { 925 return quotearg_n_custom (0, left_quote, right_quote, arg); 926 } 927 928 char * 929 quotearg_custom_mem (char const *left_quote, char const *right_quote, 930 char const *arg, size_t argsize) 931 { 932 return quotearg_n_custom_mem (0, left_quote, right_quote, arg, 933 argsize); 934 } 935 936 937 /* The quoting option used by the functions of quote.h. */ 938 struct quoting_options quote_quoting_options = 939 { 940 locale_quoting_style, 941 0, 942 { 0 }, 943 NULL, NULL 944 }; 945 946 char const * 947 quote_n_mem (int n, char const *arg, size_t argsize) 948 { 949 return quotearg_n_options (n, arg, argsize, "e_quoting_options); 950 } 951 952 char const * 953 quote_mem (char const *arg, size_t argsize) 954 { 955 return quote_n_mem (0, arg, argsize); 956 } 957 958 char const * 959 quote_n (int n, char const *arg) 960 { 961 return quote_n_mem (n, arg, SIZE_MAX); 962 } 963 964 char const * 965 quote (char const *arg) 966 { 967 return quote_n (0, arg); 968 } 969