1 /* quotearg.c - quote arguments for output
2
3 Copyright (C) 1998-2002, 2004-2012 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 *
clone_quoting_options(struct quoting_options * o)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
get_quoting_style(struct quoting_options * o)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
set_quoting_style(struct quoting_options * o,enum quoting_style s)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
set_char_quoting(struct quoting_options * o,char c,int i)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
set_quoting_flags(struct quoting_options * o,int i)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
set_custom_quoting(struct quoting_options * o,char const * left_quote,char const * right_quote)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!! */
quoting_options_from_style(enum quoting_style style)179 quoting_options_from_style (enum quoting_style style)
180 {
181 struct quoting_options o = { 0, 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 *
gettext_quote(char const * msgid,enum quoting_style s)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
quotearg_buffer_restyled(char * buffer,size_t buffersize,char const * arg,size_t argsize,enum quoting_style quoting_style,int flags,unsigned int const * quote_these_too,char const * left_quote,char const * right_quote)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 <= argsize
352 && memcmp (arg + i, quote_string, quote_string_len) == 0)
353 {
354 if (elide_outer_quotes)
355 goto force_outer_quoting_style;
356 is_right_quote = true;
357 }
358
359 c = arg[i];
360 switch (c)
361 {
362 case '\0':
363 if (backslash_escapes)
364 {
365 if (elide_outer_quotes)
366 goto force_outer_quoting_style;
367 STORE ('\\');
368 /* If quote_string were to begin with digits, we'd need to
369 test for the end of the arg as well. However, it's
370 hard to imagine any locale that would use digits in
371 quotes, and set_custom_quoting is documented not to
372 accept them. */
373 if (i + 1 < argsize && '0' <= arg[i + 1] && arg[i + 1] <= '9')
374 {
375 STORE ('0');
376 STORE ('0');
377 }
378 c = '0';
379 /* We don't have to worry that this last '0' will be
380 backslash-escaped because, again, quote_string should
381 not start with it and because quote_these_too is
382 documented as not accepting it. */
383 }
384 else if (flags & QA_ELIDE_NULL_BYTES)
385 continue;
386 break;
387
388 case '?':
389 switch (quoting_style)
390 {
391 case shell_always_quoting_style:
392 if (elide_outer_quotes)
393 goto force_outer_quoting_style;
394 break;
395
396 case c_quoting_style:
397 if ((flags & QA_SPLIT_TRIGRAPHS)
398 && i + 2 < argsize && arg[i + 1] == '?')
399 switch (arg[i + 2])
400 {
401 case '!': case '\'':
402 case '(': case ')': case '-': case '/':
403 case '<': case '=': case '>':
404 /* Escape the second '?' in what would otherwise be
405 a trigraph. */
406 if (elide_outer_quotes)
407 goto force_outer_quoting_style;
408 c = arg[i + 2];
409 i += 2;
410 STORE ('?');
411 STORE ('"');
412 STORE ('"');
413 STORE ('?');
414 break;
415
416 default:
417 break;
418 }
419 break;
420
421 default:
422 break;
423 }
424 break;
425
426 case '\a': esc = 'a'; goto c_escape;
427 case '\b': esc = 'b'; goto c_escape;
428 case '\f': esc = 'f'; goto c_escape;
429 case '\n': esc = 'n'; goto c_and_shell_escape;
430 case '\r': esc = 'r'; goto c_and_shell_escape;
431 case '\t': esc = 't'; goto c_and_shell_escape;
432 case '\v': esc = 'v'; goto c_escape;
433 case '\\': esc = c;
434 /* No need to escape the escape if we are trying to elide
435 outer quotes and nothing else is problematic. */
436 if (backslash_escapes && elide_outer_quotes && quote_string_len)
437 goto store_c;
438
439 c_and_shell_escape:
440 if (quoting_style == shell_always_quoting_style
441 && elide_outer_quotes)
442 goto force_outer_quoting_style;
443 /* Fall through. */
444 c_escape:
445 if (backslash_escapes)
446 {
447 c = esc;
448 goto store_escape;
449 }
450 break;
451
452 case '{': case '}': /* sometimes special if isolated */
453 if (! (argsize == SIZE_MAX ? arg[1] == '\0' : argsize == 1))
454 break;
455 /* Fall through. */
456 case '#': case '~':
457 if (i != 0)
458 break;
459 /* Fall through. */
460 case ' ':
461 case '!': /* special in bash */
462 case '"': case '$': case '&':
463 case '(': case ')': case '*': case ';':
464 case '<':
465 case '=': /* sometimes special in 0th or (with "set -k") later args */
466 case '>': case '[':
467 case '^': /* special in old /bin/sh, e.g. SunOS 4.1.4 */
468 case '`': case '|':
469 /* A shell special character. In theory, '$' and '`' could
470 be the first bytes of multibyte characters, which means
471 we should check them with mbrtowc, but in practice this
472 doesn't happen so it's not worth worrying about. */
473 if (quoting_style == shell_always_quoting_style
474 && elide_outer_quotes)
475 goto force_outer_quoting_style;
476 break;
477
478 case '\'':
479 if (quoting_style == shell_always_quoting_style)
480 {
481 if (elide_outer_quotes)
482 goto force_outer_quoting_style;
483 STORE ('\'');
484 STORE ('\\');
485 STORE ('\'');
486 }
487 break;
488
489 case '%': case '+': case ',': case '-': case '.': case '/':
490 case '0': case '1': case '2': case '3': case '4': case '5':
491 case '6': case '7': case '8': case '9': case ':':
492 case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
493 case 'G': case 'H': case 'I': case 'J': case 'K': case 'L':
494 case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R':
495 case 'S': case 'T': case 'U': case 'V': case 'W': case 'X':
496 case 'Y': case 'Z': case ']': case '_': case 'a': case 'b':
497 case 'c': case 'd': case 'e': case 'f': case 'g': case 'h':
498 case 'i': case 'j': case 'k': case 'l': case 'm': case 'n':
499 case 'o': case 'p': case 'q': case 'r': case 's': case 't':
500 case 'u': case 'v': case 'w': case 'x': case 'y': case 'z':
501 /* These characters don't cause problems, no matter what the
502 quoting style is. They cannot start multibyte sequences.
503 A digit or a special letter would cause trouble if it
504 appeared at the beginning of quote_string because we'd then
505 escape by prepending a backslash. However, it's hard to
506 imagine any locale that would use digits or letters as
507 quotes, and set_custom_quoting is documented not to accept
508 them. Also, a digit or a special letter would cause
509 trouble if it appeared in quote_these_too, but that's also
510 documented as not accepting them. */
511 break;
512
513 default:
514 /* If we have a multibyte sequence, copy it until we reach
515 its end, find an error, or come back to the initial shift
516 state. For C-like styles, if the sequence has
517 unprintable characters, escape the whole sequence, since
518 we can't easily escape single characters within it. */
519 {
520 /* Length of multibyte sequence found so far. */
521 size_t m;
522
523 bool printable;
524
525 if (unibyte_locale)
526 {
527 m = 1;
528 printable = isprint (c) != 0;
529 }
530 else
531 {
532 mbstate_t mbstate;
533 memset (&mbstate, 0, sizeof mbstate);
534
535 m = 0;
536 printable = true;
537 if (argsize == SIZE_MAX)
538 argsize = strlen (arg);
539
540 do
541 {
542 wchar_t w;
543 size_t bytes = mbrtowc (&w, &arg[i + m],
544 argsize - (i + m), &mbstate);
545 if (bytes == 0)
546 break;
547 else if (bytes == (size_t) -1)
548 {
549 printable = false;
550 break;
551 }
552 else if (bytes == (size_t) -2)
553 {
554 printable = false;
555 while (i + m < argsize && arg[i + m])
556 m++;
557 break;
558 }
559 else
560 {
561 /* Work around a bug with older shells that "see" a '\'
562 that is really the 2nd byte of a multibyte character.
563 In practice the problem is limited to ASCII
564 chars >= '@' that are shell special chars. */
565 if ('[' == 0x5b && elide_outer_quotes
566 && quoting_style == shell_always_quoting_style)
567 {
568 size_t j;
569 for (j = 1; j < bytes; j++)
570 switch (arg[i + m + j])
571 {
572 case '[': case '\\': case '^':
573 case '`': case '|':
574 goto force_outer_quoting_style;
575
576 default:
577 break;
578 }
579 }
580
581 if (! iswprint (w))
582 printable = false;
583 m += bytes;
584 }
585 }
586 while (! mbsinit (&mbstate));
587 }
588
589 if (1 < m || (backslash_escapes && ! printable))
590 {
591 /* Output a multibyte sequence, or an escaped
592 unprintable unibyte character. */
593 size_t ilim = i + m;
594
595 for (;;)
596 {
597 if (backslash_escapes && ! printable)
598 {
599 if (elide_outer_quotes)
600 goto force_outer_quoting_style;
601 STORE ('\\');
602 STORE ('0' + (c >> 6));
603 STORE ('0' + ((c >> 3) & 7));
604 c = '0' + (c & 7);
605 }
606 else if (is_right_quote)
607 {
608 STORE ('\\');
609 is_right_quote = false;
610 }
611 if (ilim <= i + 1)
612 break;
613 STORE (c);
614 c = arg[++i];
615 }
616
617 goto store_c;
618 }
619 }
620 }
621
622 if (! ((backslash_escapes || elide_outer_quotes)
623 && quote_these_too
624 && quote_these_too[c / INT_BITS] & (1 << (c % INT_BITS)))
625 && !is_right_quote)
626 goto store_c;
627
628 store_escape:
629 if (elide_outer_quotes)
630 goto force_outer_quoting_style;
631 STORE ('\\');
632
633 store_c:
634 STORE (c);
635 }
636
637 if (len == 0 && quoting_style == shell_always_quoting_style
638 && elide_outer_quotes)
639 goto force_outer_quoting_style;
640
641 if (quote_string && !elide_outer_quotes)
642 for (; *quote_string; quote_string++)
643 STORE (*quote_string);
644
645 if (len < buffersize)
646 buffer[len] = '\0';
647 return len;
648
649 force_outer_quoting_style:
650 /* Don't reuse quote_these_too, since the addition of outer quotes
651 sufficiently quotes the specified characters. */
652 return quotearg_buffer_restyled (buffer, buffersize, arg, argsize,
653 quoting_style,
654 flags & ~QA_ELIDE_OUTER_QUOTES, NULL,
655 left_quote, right_quote);
656 }
657
658 /* Place into buffer BUFFER (of size BUFFERSIZE) a quoted version of
659 argument ARG (of size ARGSIZE), using O to control quoting.
660 If O is null, use the default.
661 Terminate the output with a null character, and return the written
662 size of the output, not counting the terminating null.
663 If BUFFERSIZE is too small to store the output string, return the
664 value that would have been returned had BUFFERSIZE been large enough.
665 If ARGSIZE is SIZE_MAX, use the string length of the argument for
666 ARGSIZE. */
667 size_t
quotearg_buffer(char * buffer,size_t buffersize,char const * arg,size_t argsize,struct quoting_options const * o)668 quotearg_buffer (char *buffer, size_t buffersize,
669 char const *arg, size_t argsize,
670 struct quoting_options const *o)
671 {
672 struct quoting_options const *p = o ? o : &default_quoting_options;
673 int e = errno;
674 size_t r = quotearg_buffer_restyled (buffer, buffersize, arg, argsize,
675 p->style, p->flags, p->quote_these_too,
676 p->left_quote, p->right_quote);
677 errno = e;
678 return r;
679 }
680
681 /* Equivalent to quotearg_alloc (ARG, ARGSIZE, NULL, O). */
682 char *
quotearg_alloc(char const * arg,size_t argsize,struct quoting_options const * o)683 quotearg_alloc (char const *arg, size_t argsize,
684 struct quoting_options const *o)
685 {
686 return quotearg_alloc_mem (arg, argsize, NULL, o);
687 }
688
689 /* Like quotearg_buffer (..., ARG, ARGSIZE, O), except return newly
690 allocated storage containing the quoted string, and store the
691 resulting size into *SIZE, if non-NULL. The result can contain
692 embedded null bytes only if ARGSIZE is not SIZE_MAX, SIZE is not
693 NULL, and set_quoting_flags has not set the null byte elision
694 flag. */
695 char *
quotearg_alloc_mem(char const * arg,size_t argsize,size_t * size,struct quoting_options const * o)696 quotearg_alloc_mem (char const *arg, size_t argsize, size_t *size,
697 struct quoting_options const *o)
698 {
699 struct quoting_options const *p = o ? o : &default_quoting_options;
700 int e = errno;
701 /* Elide embedded null bytes if we can't return a size. */
702 int flags = p->flags | (size ? 0 : QA_ELIDE_NULL_BYTES);
703 size_t bufsize = quotearg_buffer_restyled (0, 0, arg, argsize, p->style,
704 flags, p->quote_these_too,
705 p->left_quote,
706 p->right_quote) + 1;
707 char *buf = xcharalloc (bufsize);
708 quotearg_buffer_restyled (buf, bufsize, arg, argsize, p->style, flags,
709 p->quote_these_too,
710 p->left_quote, p->right_quote);
711 errno = e;
712 if (size)
713 *size = bufsize - 1;
714 return buf;
715 }
716
717 /* A storage slot with size and pointer to a value. */
718 struct slotvec
719 {
720 size_t size;
721 char *val;
722 };
723
724 /* Preallocate a slot 0 buffer, so that the caller can always quote
725 one small component of a "memory exhausted" message in slot 0. */
726 static char slot0[256];
727 static unsigned int nslots = 1;
728 static struct slotvec slotvec0 = {sizeof slot0, slot0};
729 static struct slotvec *slotvec = &slotvec0;
730
731 void
quotearg_free(void)732 quotearg_free (void)
733 {
734 struct slotvec *sv = slotvec;
735 unsigned int i;
736 for (i = 1; i < nslots; i++)
737 free (sv[i].val);
738 if (sv[0].val != slot0)
739 {
740 free (sv[0].val);
741 slotvec0.size = sizeof slot0;
742 slotvec0.val = slot0;
743 }
744 if (sv != &slotvec0)
745 {
746 free (sv);
747 slotvec = &slotvec0;
748 }
749 nslots = 1;
750 }
751
752 /* Use storage slot N to return a quoted version of argument ARG.
753 ARG is of size ARGSIZE, but if that is SIZE_MAX, ARG is a
754 null-terminated string.
755 OPTIONS specifies the quoting options.
756 The returned value points to static storage that can be
757 reused by the next call to this function with the same value of N.
758 N must be nonnegative. N is deliberately declared with type "int"
759 to allow for future extensions (using negative values). */
760 static char *
quotearg_n_options(int n,char const * arg,size_t argsize,struct quoting_options const * options)761 quotearg_n_options (int n, char const *arg, size_t argsize,
762 struct quoting_options const *options)
763 {
764 int e = errno;
765
766 unsigned int n0 = n;
767 struct slotvec *sv = slotvec;
768
769 if (n < 0)
770 abort ();
771
772 if (nslots <= n0)
773 {
774 /* FIXME: technically, the type of n1 should be 'unsigned int',
775 but that evokes an unsuppressible warning from gcc-4.0.1 and
776 older. If gcc ever provides an option to suppress that warning,
777 revert to the original type, so that the test in xalloc_oversized
778 is once again performed only at compile time. */
779 size_t n1 = n0 + 1;
780 bool preallocated = (sv == &slotvec0);
781
782 if (xalloc_oversized (n1, sizeof *sv))
783 xalloc_die ();
784
785 slotvec = sv = xrealloc (preallocated ? NULL : sv, n1 * sizeof *sv);
786 if (preallocated)
787 *sv = slotvec0;
788 memset (sv + nslots, 0, (n1 - nslots) * sizeof *sv);
789 nslots = n1;
790 }
791
792 {
793 size_t size = sv[n].size;
794 char *val = sv[n].val;
795 /* Elide embedded null bytes since we don't return a size. */
796 int flags = options->flags | QA_ELIDE_NULL_BYTES;
797 size_t qsize = quotearg_buffer_restyled (val, size, arg, argsize,
798 options->style, flags,
799 options->quote_these_too,
800 options->left_quote,
801 options->right_quote);
802
803 if (size <= qsize)
804 {
805 sv[n].size = size = qsize + 1;
806 if (val != slot0)
807 free (val);
808 sv[n].val = val = xcharalloc (size);
809 quotearg_buffer_restyled (val, size, arg, argsize, options->style,
810 flags, options->quote_these_too,
811 options->left_quote,
812 options->right_quote);
813 }
814
815 errno = e;
816 return val;
817 }
818 }
819
820 char *
quotearg_n(int n,char const * arg)821 quotearg_n (int n, char const *arg)
822 {
823 return quotearg_n_options (n, arg, SIZE_MAX, &default_quoting_options);
824 }
825
826 char *
quotearg_n_mem(int n,char const * arg,size_t argsize)827 quotearg_n_mem (int n, char const *arg, size_t argsize)
828 {
829 return quotearg_n_options (n, arg, argsize, &default_quoting_options);
830 }
831
832 char *
quotearg(char const * arg)833 quotearg (char const *arg)
834 {
835 return quotearg_n (0, arg);
836 }
837
838 char *
quotearg_mem(char const * arg,size_t argsize)839 quotearg_mem (char const *arg, size_t argsize)
840 {
841 return quotearg_n_mem (0, arg, argsize);
842 }
843
844 char *
quotearg_n_style(int n,enum quoting_style s,char const * arg)845 quotearg_n_style (int n, enum quoting_style s, char const *arg)
846 {
847 struct quoting_options const o = quoting_options_from_style (s);
848 return quotearg_n_options (n, arg, SIZE_MAX, &o);
849 }
850
851 char *
quotearg_n_style_mem(int n,enum quoting_style s,char const * arg,size_t argsize)852 quotearg_n_style_mem (int n, enum quoting_style s,
853 char const *arg, size_t argsize)
854 {
855 struct quoting_options const o = quoting_options_from_style (s);
856 return quotearg_n_options (n, arg, argsize, &o);
857 }
858
859 char *
quotearg_style(enum quoting_style s,char const * arg)860 quotearg_style (enum quoting_style s, char const *arg)
861 {
862 return quotearg_n_style (0, s, arg);
863 }
864
865 char *
quotearg_style_mem(enum quoting_style s,char const * arg,size_t argsize)866 quotearg_style_mem (enum quoting_style s, char const *arg, size_t argsize)
867 {
868 return quotearg_n_style_mem (0, s, arg, argsize);
869 }
870
871 char *
quotearg_char_mem(char const * arg,size_t argsize,char ch)872 quotearg_char_mem (char const *arg, size_t argsize, char ch)
873 {
874 struct quoting_options options;
875 options = default_quoting_options;
876 set_char_quoting (&options, ch, 1);
877 return quotearg_n_options (0, arg, argsize, &options);
878 }
879
880 char *
quotearg_char(char const * arg,char ch)881 quotearg_char (char const *arg, char ch)
882 {
883 return quotearg_char_mem (arg, SIZE_MAX, ch);
884 }
885
886 char *
quotearg_colon(char const * arg)887 quotearg_colon (char const *arg)
888 {
889 return quotearg_char (arg, ':');
890 }
891
892 char *
quotearg_colon_mem(char const * arg,size_t argsize)893 quotearg_colon_mem (char const *arg, size_t argsize)
894 {
895 return quotearg_char_mem (arg, argsize, ':');
896 }
897
898 char *
quotearg_n_custom(int n,char const * left_quote,char const * right_quote,char const * arg)899 quotearg_n_custom (int n, char const *left_quote,
900 char const *right_quote, char const *arg)
901 {
902 return quotearg_n_custom_mem (n, left_quote, right_quote, arg,
903 SIZE_MAX);
904 }
905
906 char *
quotearg_n_custom_mem(int n,char const * left_quote,char const * right_quote,char const * arg,size_t argsize)907 quotearg_n_custom_mem (int n, char const *left_quote,
908 char const *right_quote,
909 char const *arg, size_t argsize)
910 {
911 struct quoting_options o = default_quoting_options;
912 set_custom_quoting (&o, left_quote, right_quote);
913 return quotearg_n_options (n, arg, argsize, &o);
914 }
915
916 char *
quotearg_custom(char const * left_quote,char const * right_quote,char const * arg)917 quotearg_custom (char const *left_quote, char const *right_quote,
918 char const *arg)
919 {
920 return quotearg_n_custom (0, left_quote, right_quote, arg);
921 }
922
923 char *
quotearg_custom_mem(char const * left_quote,char const * right_quote,char const * arg,size_t argsize)924 quotearg_custom_mem (char const *left_quote, char const *right_quote,
925 char const *arg, size_t argsize)
926 {
927 return quotearg_n_custom_mem (0, left_quote, right_quote, arg,
928 argsize);
929 }
930
931
932 /* The quoting option used by quote_n and quote. */
933 struct quoting_options quote_quoting_options =
934 {
935 locale_quoting_style,
936 0,
937 { 0 },
938 NULL, NULL
939 };
940
941 char const *
quote_n(int n,char const * name)942 quote_n (int n, char const *name)
943 {
944 return quotearg_n_options (n, name, SIZE_MAX, "e_quoting_options);
945 }
946
947 char const *
quote(char const * name)948 quote (char const *name)
949 {
950 return quote_n (0, name);
951 }
952