get-rusage-data tests: Avoid failure on Linux/glibc.
[gnulib/ericb.git] / lib / quotearg.c
blob26903c711aa7088c31d7b58669389df105e91a2d
1 /* quotearg.c - quote arguments for output
3 Copyright (C) 1998-2002, 2004-2017 Free Software Foundation, Inc.
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.
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.
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/>. */
18 /* Written by Paul Eggert <eggert@twinsun.com> */
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
27 #include <config.h>
29 #include "quotearg.h"
30 #include "quote.h"
32 #include "minmax.h"
33 #include "xalloc.h"
34 #include "c-strcaseeq.h"
35 #include "localcharset.h"
37 #include <ctype.h>
38 #include <errno.h>
39 #include <limits.h>
40 #include <stdbool.h>
41 #include <stdint.h>
42 #include <stdlib.h>
43 #include <string.h>
44 #include <wchar.h>
45 #include <wctype.h>
47 #include "gettext.h"
48 #define _(msgid) gettext (msgid)
49 #define N_(msgid) msgid
51 #ifndef SIZE_MAX
52 # define SIZE_MAX ((size_t) -1)
53 #endif
55 #define INT_BITS (sizeof (int) * CHAR_BIT)
57 struct quoting_options
59 /* Basic quoting style. */
60 enum quoting_style style;
62 /* Additional flags. Bitwise combination of enum quoting_flags. */
63 int flags;
65 /* Quote the characters indicated by this bit vector even if the
66 quoting style would not normally require them to be quoted. */
67 unsigned int quote_these_too[(UCHAR_MAX / INT_BITS) + 1];
69 /* The left quote for custom_quoting_style. */
70 char const *left_quote;
72 /* The right quote for custom_quoting_style. */
73 char const *right_quote;
76 /* Names of quoting styles. */
77 char const *const quoting_style_args[] =
79 "literal",
80 "shell",
81 "shell-always",
82 "shell-escape",
83 "shell-escape-always",
84 "c",
85 "c-maybe",
86 "escape",
87 "locale",
88 "clocale",
92 /* Correspondences to quoting style names. */
93 enum quoting_style const quoting_style_vals[] =
95 literal_quoting_style,
96 shell_quoting_style,
97 shell_always_quoting_style,
98 shell_escape_quoting_style,
99 shell_escape_always_quoting_style,
100 c_quoting_style,
101 c_maybe_quoting_style,
102 escape_quoting_style,
103 locale_quoting_style,
104 clocale_quoting_style
107 /* The default quoting options. */
108 static struct quoting_options default_quoting_options;
110 /* Allocate a new set of quoting options, with contents initially identical
111 to O if O is not null, or to the default if O is null.
112 It is the caller's responsibility to free the result. */
113 struct quoting_options *
114 clone_quoting_options (struct quoting_options *o)
116 int e = errno;
117 struct quoting_options *p = xmemdup (o ? o : &default_quoting_options,
118 sizeof *o);
119 errno = e;
120 return p;
123 /* Get the value of O's quoting style. If O is null, use the default. */
124 enum quoting_style
125 get_quoting_style (struct quoting_options const *o)
127 return (o ? o : &default_quoting_options)->style;
130 /* In O (or in the default if O is null),
131 set the value of the quoting style to S. */
132 void
133 set_quoting_style (struct quoting_options *o, enum quoting_style s)
135 (o ? o : &default_quoting_options)->style = s;
138 /* In O (or in the default if O is null),
139 set the value of the quoting options for character C to I.
140 Return the old value. Currently, the only values defined for I are
141 0 (the default) and 1 (which means to quote the character even if
142 it would not otherwise be quoted). */
144 set_char_quoting (struct quoting_options *o, char c, int i)
146 unsigned char uc = c;
147 unsigned int *p =
148 (o ? o : &default_quoting_options)->quote_these_too + uc / INT_BITS;
149 int shift = uc % INT_BITS;
150 int r = (*p >> shift) & 1;
151 *p ^= ((i & 1) ^ r) << shift;
152 return r;
155 /* In O (or in the default if O is null),
156 set the value of the quoting options flag to I, which can be a
157 bitwise combination of enum quoting_flags, or 0 for default
158 behavior. Return the old value. */
160 set_quoting_flags (struct quoting_options *o, int i)
162 int r;
163 if (!o)
164 o = &default_quoting_options;
165 r = o->flags;
166 o->flags = i;
167 return r;
170 void
171 set_custom_quoting (struct quoting_options *o,
172 char const *left_quote, char const *right_quote)
174 if (!o)
175 o = &default_quoting_options;
176 o->style = custom_quoting_style;
177 if (!left_quote || !right_quote)
178 abort ();
179 o->left_quote = left_quote;
180 o->right_quote = right_quote;
183 /* Return quoting options for STYLE, with no extra quoting. */
184 static struct quoting_options /* NOT PURE!! */
185 quoting_options_from_style (enum quoting_style style)
187 struct quoting_options o = { literal_quoting_style, 0, { 0 }, NULL, NULL };
188 if (style == custom_quoting_style)
189 abort ();
190 o.style = style;
191 return o;
194 /* MSGID approximates a quotation mark. Return its translation if it
195 has one; otherwise, return either it or "\"", depending on S.
197 S is either clocale_quoting_style or locale_quoting_style. */
198 static char const *
199 gettext_quote (char const *msgid, enum quoting_style s)
201 char const *translation = _(msgid);
202 char const *locale_code;
204 if (translation != msgid)
205 return translation;
207 /* For UTF-8 and GB-18030, use single quotes U+2018 and U+2019.
208 Here is a list of other locales that include U+2018 and U+2019:
210 ISO-8859-7 0xA1 KOI8-T 0x91
211 CP869 0x8B CP874 0x91
212 CP932 0x81 0x65 CP936 0xA1 0xAE
213 CP949 0xA1 0xAE CP950 0xA1 0xA5
214 CP1250 0x91 CP1251 0x91
215 CP1252 0x91 CP1253 0x91
216 CP1254 0x91 CP1255 0x91
217 CP1256 0x91 CP1257 0x91
218 EUC-JP 0xA1 0xC6 EUC-KR 0xA1 0xAE
219 EUC-TW 0xA1 0xE4 BIG5 0xA1 0xA5
220 BIG5-HKSCS 0xA1 0xA5 EUC-CN 0xA1 0xAE
221 GBK 0xA1 0xAE Georgian-PS 0x91
222 PT154 0x91
224 None of these is still in wide use; using iconv is overkill. */
225 locale_code = locale_charset ();
226 if (STRCASEEQ (locale_code, "UTF-8", 'U','T','F','-','8',0,0,0,0))
227 return msgid[0] == '`' ? "\xe2\x80\x98": "\xe2\x80\x99";
228 if (STRCASEEQ (locale_code, "GB18030", 'G','B','1','8','0','3','0',0,0))
229 return msgid[0] == '`' ? "\xa1\ae": "\xa1\xaf";
231 return (s == clocale_quoting_style ? "\"" : "'");
234 /* Place into buffer BUFFER (of size BUFFERSIZE) a quoted version of
235 argument ARG (of size ARGSIZE), using QUOTING_STYLE, FLAGS, and
236 QUOTE_THESE_TOO to control quoting.
237 Terminate the output with a null character, and return the written
238 size of the output, not counting the terminating null.
239 If BUFFERSIZE is too small to store the output string, return the
240 value that would have been returned had BUFFERSIZE been large enough.
241 If ARGSIZE is SIZE_MAX, use the string length of the argument for ARGSIZE.
243 This function acts like quotearg_buffer (BUFFER, BUFFERSIZE, ARG,
244 ARGSIZE, O), except it breaks O into its component pieces and is
245 not careful about errno. */
247 static size_t
248 quotearg_buffer_restyled (char *buffer, size_t buffersize,
249 char const *arg, size_t argsize,
250 enum quoting_style quoting_style, int flags,
251 unsigned int const *quote_these_too,
252 char const *left_quote,
253 char const *right_quote)
255 size_t i;
256 size_t len = 0;
257 size_t orig_buffersize = 0;
258 char const *quote_string = 0;
259 size_t quote_string_len = 0;
260 bool backslash_escapes = false;
261 bool unibyte_locale = MB_CUR_MAX == 1;
262 bool elide_outer_quotes = (flags & QA_ELIDE_OUTER_QUOTES) != 0;
263 bool pending_shell_escape_end = false;
264 bool encountered_single_quote = false;
265 bool all_c_and_shell_quote_compat = true;
267 #define STORE(c) \
268 do \
270 if (len < buffersize) \
271 buffer[len] = (c); \
272 len++; \
274 while (0)
276 #define START_ESC() \
277 do \
279 if (elide_outer_quotes) \
280 goto force_outer_quoting_style; \
281 escaping = true; \
282 if (quoting_style == shell_always_quoting_style \
283 && ! pending_shell_escape_end) \
285 STORE ('\''); \
286 STORE ('$'); \
287 STORE ('\''); \
288 pending_shell_escape_end = true; \
290 STORE ('\\'); \
292 while (0)
294 #define END_ESC() \
295 do \
297 if (pending_shell_escape_end && ! escaping) \
299 STORE ('\''); \
300 STORE ('\''); \
301 pending_shell_escape_end = false; \
304 while (0)
306 process_input:
308 switch (quoting_style)
310 case c_maybe_quoting_style:
311 quoting_style = c_quoting_style;
312 elide_outer_quotes = true;
313 /* Fall through. */
314 case c_quoting_style:
315 if (!elide_outer_quotes)
316 STORE ('"');
317 backslash_escapes = true;
318 quote_string = "\"";
319 quote_string_len = 1;
320 break;
322 case escape_quoting_style:
323 backslash_escapes = true;
324 elide_outer_quotes = false;
325 break;
327 case locale_quoting_style:
328 case clocale_quoting_style:
329 case custom_quoting_style:
331 if (quoting_style != custom_quoting_style)
333 /* TRANSLATORS:
334 Get translations for open and closing quotation marks.
335 The message catalog should translate "`" to a left
336 quotation mark suitable for the locale, and similarly for
337 "'". For example, a French Unicode local should translate
338 these to U+00AB (LEFT-POINTING DOUBLE ANGLE
339 QUOTATION MARK), and U+00BB (RIGHT-POINTING DOUBLE ANGLE
340 QUOTATION MARK), respectively.
342 If the catalog has no translation, we will try to
343 use Unicode U+2018 (LEFT SINGLE QUOTATION MARK) and
344 Unicode U+2019 (RIGHT SINGLE QUOTATION MARK). If the
345 current locale is not Unicode, locale_quoting_style
346 will quote 'like this', and clocale_quoting_style will
347 quote "like this". You should always include translations
348 for "`" and "'" even if U+2018 and U+2019 are appropriate
349 for your locale.
351 If you don't know what to put here, please see
352 <http://en.wikipedia.org/wiki/Quotation_marks_in_other_languages>
353 and use glyphs suitable for your language. */
354 left_quote = gettext_quote (N_("`"), quoting_style);
355 right_quote = gettext_quote (N_("'"), quoting_style);
357 if (!elide_outer_quotes)
358 for (quote_string = left_quote; *quote_string; quote_string++)
359 STORE (*quote_string);
360 backslash_escapes = true;
361 quote_string = right_quote;
362 quote_string_len = strlen (quote_string);
364 break;
366 case shell_escape_quoting_style:
367 backslash_escapes = true;
368 /* Fall through. */
369 case shell_quoting_style:
370 elide_outer_quotes = true;
371 /* Fall through. */
372 case shell_escape_always_quoting_style:
373 if (!elide_outer_quotes)
374 backslash_escapes = true;
375 /* Fall through. */
376 case shell_always_quoting_style:
377 quoting_style = shell_always_quoting_style;
378 if (!elide_outer_quotes)
379 STORE ('\'');
380 quote_string = "'";
381 quote_string_len = 1;
382 break;
384 case literal_quoting_style:
385 elide_outer_quotes = false;
386 break;
388 default:
389 abort ();
392 for (i = 0; ! (argsize == SIZE_MAX ? arg[i] == '\0' : i == argsize); i++)
394 unsigned char c;
395 unsigned char esc;
396 bool is_right_quote = false;
397 bool escaping = false;
398 bool c_and_shell_quote_compat = false;
400 if (backslash_escapes
401 && quoting_style != shell_always_quoting_style
402 && quote_string_len
403 && (i + quote_string_len
404 <= (argsize == SIZE_MAX && 1 < quote_string_len
405 /* Use strlen only if we must: when argsize is SIZE_MAX,
406 and when the quote string is more than 1 byte long.
407 If we do call strlen, save the result. */
408 ? (argsize = strlen (arg)) : argsize))
409 && memcmp (arg + i, quote_string, quote_string_len) == 0)
411 if (elide_outer_quotes)
412 goto force_outer_quoting_style;
413 is_right_quote = true;
416 c = arg[i];
417 switch (c)
419 case '\0':
420 if (backslash_escapes)
422 START_ESC ();
423 /* If quote_string were to begin with digits, we'd need to
424 test for the end of the arg as well. However, it's
425 hard to imagine any locale that would use digits in
426 quotes, and set_custom_quoting is documented not to
427 accept them. Use only a single \0 with shell-escape
428 as currently digits are not printed within $'...' */
429 if (quoting_style != shell_always_quoting_style
430 && i + 1 < argsize && '0' <= arg[i + 1] && arg[i + 1] <= '9')
432 STORE ('0');
433 STORE ('0');
435 c = '0';
436 /* We don't have to worry that this last '0' will be
437 backslash-escaped because, again, quote_string should
438 not start with it and because quote_these_too is
439 documented as not accepting it. */
441 else if (flags & QA_ELIDE_NULL_BYTES)
442 continue;
443 break;
445 case '?':
446 switch (quoting_style)
448 case shell_always_quoting_style:
449 if (elide_outer_quotes)
450 goto force_outer_quoting_style;
451 break;
453 case c_quoting_style:
454 if ((flags & QA_SPLIT_TRIGRAPHS)
455 && i + 2 < argsize && arg[i + 1] == '?')
456 switch (arg[i + 2])
458 case '!': case '\'':
459 case '(': case ')': case '-': case '/':
460 case '<': case '=': case '>':
461 /* Escape the second '?' in what would otherwise be
462 a trigraph. */
463 if (elide_outer_quotes)
464 goto force_outer_quoting_style;
465 c = arg[i + 2];
466 i += 2;
467 STORE ('?');
468 STORE ('"');
469 STORE ('"');
470 STORE ('?');
471 break;
473 default:
474 break;
476 break;
478 default:
479 break;
481 break;
483 case '\a': esc = 'a'; goto c_escape;
484 case '\b': esc = 'b'; goto c_escape;
485 case '\f': esc = 'f'; goto c_escape;
486 case '\n': esc = 'n'; goto c_and_shell_escape;
487 case '\r': esc = 'r'; goto c_and_shell_escape;
488 case '\t': esc = 't'; goto c_and_shell_escape;
489 case '\v': esc = 'v'; goto c_escape;
490 case '\\': esc = c;
491 /* Never need to escape '\' in shell case. */
492 if (quoting_style == shell_always_quoting_style)
494 if (elide_outer_quotes)
495 goto force_outer_quoting_style;
496 goto store_c;
499 /* No need to escape the escape if we are trying to elide
500 outer quotes and nothing else is problematic. */
501 if (backslash_escapes && elide_outer_quotes && quote_string_len)
502 goto store_c;
504 c_and_shell_escape:
505 if (quoting_style == shell_always_quoting_style
506 && elide_outer_quotes)
507 goto force_outer_quoting_style;
508 /* Fall through. */
509 c_escape:
510 if (backslash_escapes)
512 c = esc;
513 goto store_escape;
515 break;
517 case '{': case '}': /* sometimes special if isolated */
518 if (! (argsize == SIZE_MAX ? arg[1] == '\0' : argsize == 1))
519 break;
520 /* Fall through. */
521 case '#': case '~':
522 if (i != 0)
523 break;
524 /* Fall through. */
525 case ' ':
526 c_and_shell_quote_compat = true;
527 /* Fall through. */
528 case '!': /* special in bash */
529 case '"': case '$': case '&':
530 case '(': case ')': case '*': case ';':
531 case '<':
532 case '=': /* sometimes special in 0th or (with "set -k") later args */
533 case '>': case '[':
534 case '^': /* special in old /bin/sh, e.g. SunOS 4.1.4 */
535 case '`': case '|':
536 /* A shell special character. In theory, '$' and '`' could
537 be the first bytes of multibyte characters, which means
538 we should check them with mbrtowc, but in practice this
539 doesn't happen so it's not worth worrying about. */
540 if (quoting_style == shell_always_quoting_style
541 && elide_outer_quotes)
542 goto force_outer_quoting_style;
543 break;
545 case '\'':
546 encountered_single_quote = true;
547 c_and_shell_quote_compat = true;
548 if (quoting_style == shell_always_quoting_style)
550 if (elide_outer_quotes)
551 goto force_outer_quoting_style;
553 if (buffersize && ! orig_buffersize)
555 /* Just scan string to see if supports a more concise
556 representation, rather than writing a longer string
557 but returning the length of the more concise form. */
558 orig_buffersize = buffersize;
559 buffersize = 0;
562 STORE ('\'');
563 STORE ('\\');
564 STORE ('\'');
565 pending_shell_escape_end = false;
567 break;
569 case '%': case '+': case ',': case '-': case '.': case '/':
570 case '0': case '1': case '2': case '3': case '4': case '5':
571 case '6': case '7': case '8': case '9': case ':':
572 case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
573 case 'G': case 'H': case 'I': case 'J': case 'K': case 'L':
574 case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R':
575 case 'S': case 'T': case 'U': case 'V': case 'W': case 'X':
576 case 'Y': case 'Z': case ']': case '_': case 'a': case 'b':
577 case 'c': case 'd': case 'e': case 'f': case 'g': case 'h':
578 case 'i': case 'j': case 'k': case 'l': case 'm': case 'n':
579 case 'o': case 'p': case 'q': case 'r': case 's': case 't':
580 case 'u': case 'v': case 'w': case 'x': case 'y': case 'z':
581 /* These characters don't cause problems, no matter what the
582 quoting style is. They cannot start multibyte sequences.
583 A digit or a special letter would cause trouble if it
584 appeared at the beginning of quote_string because we'd then
585 escape by prepending a backslash. However, it's hard to
586 imagine any locale that would use digits or letters as
587 quotes, and set_custom_quoting is documented not to accept
588 them. Also, a digit or a special letter would cause
589 trouble if it appeared in quote_these_too, but that's also
590 documented as not accepting them. */
591 c_and_shell_quote_compat = true;
592 break;
594 default:
595 /* If we have a multibyte sequence, copy it until we reach
596 its end, find an error, or come back to the initial shift
597 state. For C-like styles, if the sequence has
598 unprintable characters, escape the whole sequence, since
599 we can't easily escape single characters within it. */
601 /* Length of multibyte sequence found so far. */
602 size_t m;
604 bool printable;
606 if (unibyte_locale)
608 m = 1;
609 printable = isprint (c) != 0;
611 else
613 mbstate_t mbstate;
614 memset (&mbstate, 0, sizeof mbstate);
616 m = 0;
617 printable = true;
618 if (argsize == SIZE_MAX)
619 argsize = strlen (arg);
623 wchar_t w;
624 size_t bytes = mbrtowc (&w, &arg[i + m],
625 argsize - (i + m), &mbstate);
626 if (bytes == 0)
627 break;
628 else if (bytes == (size_t) -1)
630 printable = false;
631 break;
633 else if (bytes == (size_t) -2)
635 printable = false;
636 while (i + m < argsize && arg[i + m])
637 m++;
638 break;
640 else
642 /* Work around a bug with older shells that "see" a '\'
643 that is really the 2nd byte of a multibyte character.
644 In practice the problem is limited to ASCII
645 chars >= '@' that are shell special chars. */
646 if ('[' == 0x5b && elide_outer_quotes
647 && quoting_style == shell_always_quoting_style)
649 size_t j;
650 for (j = 1; j < bytes; j++)
651 switch (arg[i + m + j])
653 case '[': case '\\': case '^':
654 case '`': case '|':
655 goto force_outer_quoting_style;
657 default:
658 break;
662 if (! iswprint (w))
663 printable = false;
664 m += bytes;
667 while (! mbsinit (&mbstate));
670 c_and_shell_quote_compat = printable;
672 if (1 < m || (backslash_escapes && ! printable))
674 /* Output a multibyte sequence, or an escaped
675 unprintable unibyte character. */
676 size_t ilim = i + m;
678 for (;;)
680 if (backslash_escapes && ! printable)
682 START_ESC ();
683 STORE ('0' + (c >> 6));
684 STORE ('0' + ((c >> 3) & 7));
685 c = '0' + (c & 7);
687 else if (is_right_quote)
689 STORE ('\\');
690 is_right_quote = false;
692 if (ilim <= i + 1)
693 break;
694 END_ESC ();
695 STORE (c);
696 c = arg[++i];
699 goto store_c;
704 if (! (((backslash_escapes && quoting_style != shell_always_quoting_style)
705 || elide_outer_quotes)
706 && quote_these_too
707 && quote_these_too[c / INT_BITS] >> (c % INT_BITS) & 1)
708 && !is_right_quote)
709 goto store_c;
711 store_escape:
712 START_ESC ();
714 store_c:
715 END_ESC ();
716 STORE (c);
718 if (! c_and_shell_quote_compat)
719 all_c_and_shell_quote_compat = false;
722 if (len == 0 && quoting_style == shell_always_quoting_style
723 && elide_outer_quotes)
724 goto force_outer_quoting_style;
726 /* Single shell quotes (') are commonly enough used as an apostrophe,
727 that we attempt to minimize the quoting in this case. Note itʼs
728 better to use the apostrophe modifier "\u02BC" if possible, as that
729 renders better and works with the word match regex \W+ etc. */
730 if (quoting_style == shell_always_quoting_style && ! elide_outer_quotes
731 && encountered_single_quote)
733 if (all_c_and_shell_quote_compat)
734 return quotearg_buffer_restyled (buffer, orig_buffersize, arg, argsize,
735 c_quoting_style,
736 flags, quote_these_too,
737 left_quote, right_quote);
738 else if (! buffersize && orig_buffersize)
740 /* Disable read-only scan, and reprocess to write quoted string. */
741 buffersize = orig_buffersize;
742 len = 0;
743 goto process_input;
747 if (quote_string && !elide_outer_quotes)
748 for (; *quote_string; quote_string++)
749 STORE (*quote_string);
751 if (len < buffersize)
752 buffer[len] = '\0';
753 return len;
755 force_outer_quoting_style:
756 /* Don't reuse quote_these_too, since the addition of outer quotes
757 sufficiently quotes the specified characters. */
758 if (quoting_style == shell_always_quoting_style && backslash_escapes)
759 quoting_style = shell_escape_always_quoting_style;
760 return quotearg_buffer_restyled (buffer, buffersize, arg, argsize,
761 quoting_style,
762 flags & ~QA_ELIDE_OUTER_QUOTES, NULL,
763 left_quote, right_quote);
766 /* Place into buffer BUFFER (of size BUFFERSIZE) a quoted version of
767 argument ARG (of size ARGSIZE), using O to control quoting.
768 If O is null, use the default.
769 Terminate the output with a null character, and return the written
770 size of the output, not counting the terminating null.
771 If BUFFERSIZE is too small to store the output string, return the
772 value that would have been returned had BUFFERSIZE been large enough.
773 If ARGSIZE is SIZE_MAX, use the string length of the argument for
774 ARGSIZE. */
775 size_t
776 quotearg_buffer (char *buffer, size_t buffersize,
777 char const *arg, size_t argsize,
778 struct quoting_options const *o)
780 struct quoting_options const *p = o ? o : &default_quoting_options;
781 int e = errno;
782 size_t r = quotearg_buffer_restyled (buffer, buffersize, arg, argsize,
783 p->style, p->flags, p->quote_these_too,
784 p->left_quote, p->right_quote);
785 errno = e;
786 return r;
789 /* Equivalent to quotearg_alloc (ARG, ARGSIZE, NULL, O). */
790 char *
791 quotearg_alloc (char const *arg, size_t argsize,
792 struct quoting_options const *o)
794 return quotearg_alloc_mem (arg, argsize, NULL, o);
797 /* Like quotearg_buffer (..., ARG, ARGSIZE, O), except return newly
798 allocated storage containing the quoted string, and store the
799 resulting size into *SIZE, if non-NULL. The result can contain
800 embedded null bytes only if ARGSIZE is not SIZE_MAX, SIZE is not
801 NULL, and set_quoting_flags has not set the null byte elision
802 flag. */
803 char *
804 quotearg_alloc_mem (char const *arg, size_t argsize, size_t *size,
805 struct quoting_options const *o)
807 struct quoting_options const *p = o ? o : &default_quoting_options;
808 int e = errno;
809 /* Elide embedded null bytes if we can't return a size. */
810 int flags = p->flags | (size ? 0 : QA_ELIDE_NULL_BYTES);
811 size_t bufsize = quotearg_buffer_restyled (0, 0, arg, argsize, p->style,
812 flags, p->quote_these_too,
813 p->left_quote,
814 p->right_quote) + 1;
815 char *buf = xcharalloc (bufsize);
816 quotearg_buffer_restyled (buf, bufsize, arg, argsize, p->style, flags,
817 p->quote_these_too,
818 p->left_quote, p->right_quote);
819 errno = e;
820 if (size)
821 *size = bufsize - 1;
822 return buf;
825 /* A storage slot with size and pointer to a value. */
826 struct slotvec
828 size_t size;
829 char *val;
832 /* Preallocate a slot 0 buffer, so that the caller can always quote
833 one small component of a "memory exhausted" message in slot 0. */
834 static char slot0[256];
835 static int nslots = 1;
836 static struct slotvec slotvec0 = {sizeof slot0, slot0};
837 static struct slotvec *slotvec = &slotvec0;
839 void
840 quotearg_free (void)
842 struct slotvec *sv = slotvec;
843 int i;
844 for (i = 1; i < nslots; i++)
845 free (sv[i].val);
846 if (sv[0].val != slot0)
848 free (sv[0].val);
849 slotvec0.size = sizeof slot0;
850 slotvec0.val = slot0;
852 if (sv != &slotvec0)
854 free (sv);
855 slotvec = &slotvec0;
857 nslots = 1;
860 /* Use storage slot N to return a quoted version of argument ARG.
861 ARG is of size ARGSIZE, but if that is SIZE_MAX, ARG is a
862 null-terminated string.
863 OPTIONS specifies the quoting options.
864 The returned value points to static storage that can be
865 reused by the next call to this function with the same value of N.
866 N must be nonnegative. N is deliberately declared with type "int"
867 to allow for future extensions (using negative values). */
868 static char *
869 quotearg_n_options (int n, char const *arg, size_t argsize,
870 struct quoting_options const *options)
872 int e = errno;
874 struct slotvec *sv = slotvec;
876 if (n < 0)
877 abort ();
879 if (nslots <= n)
881 bool preallocated = (sv == &slotvec0);
883 if (MIN (INT_MAX, MIN (PTRDIFF_MAX, SIZE_MAX) / sizeof *sv) <= n)
884 xalloc_die ();
886 slotvec = sv = xrealloc (preallocated ? NULL : sv, (n + 1) * sizeof *sv);
887 if (preallocated)
888 *sv = slotvec0;
889 memset (sv + nslots, 0, (n + 1 - nslots) * sizeof *sv);
890 nslots = n + 1;
894 size_t size = sv[n].size;
895 char *val = sv[n].val;
896 /* Elide embedded null bytes since we don't return a size. */
897 int flags = options->flags | QA_ELIDE_NULL_BYTES;
898 size_t qsize = quotearg_buffer_restyled (val, size, arg, argsize,
899 options->style, flags,
900 options->quote_these_too,
901 options->left_quote,
902 options->right_quote);
904 if (size <= qsize)
906 sv[n].size = size = qsize + 1;
907 if (val != slot0)
908 free (val);
909 sv[n].val = val = xcharalloc (size);
910 quotearg_buffer_restyled (val, size, arg, argsize, options->style,
911 flags, options->quote_these_too,
912 options->left_quote,
913 options->right_quote);
916 errno = e;
917 return val;
921 char *
922 quotearg_n (int n, char const *arg)
924 return quotearg_n_options (n, arg, SIZE_MAX, &default_quoting_options);
927 char *
928 quotearg_n_mem (int n, char const *arg, size_t argsize)
930 return quotearg_n_options (n, arg, argsize, &default_quoting_options);
933 char *
934 quotearg (char const *arg)
936 return quotearg_n (0, arg);
939 char *
940 quotearg_mem (char const *arg, size_t argsize)
942 return quotearg_n_mem (0, arg, argsize);
945 char *
946 quotearg_n_style (int n, enum quoting_style s, char const *arg)
948 struct quoting_options const o = quoting_options_from_style (s);
949 return quotearg_n_options (n, arg, SIZE_MAX, &o);
952 char *
953 quotearg_n_style_mem (int n, enum quoting_style s,
954 char const *arg, size_t argsize)
956 struct quoting_options const o = quoting_options_from_style (s);
957 return quotearg_n_options (n, arg, argsize, &o);
960 char *
961 quotearg_style (enum quoting_style s, char const *arg)
963 return quotearg_n_style (0, s, arg);
966 char *
967 quotearg_style_mem (enum quoting_style s, char const *arg, size_t argsize)
969 return quotearg_n_style_mem (0, s, arg, argsize);
972 char *
973 quotearg_char_mem (char const *arg, size_t argsize, char ch)
975 struct quoting_options options;
976 options = default_quoting_options;
977 set_char_quoting (&options, ch, 1);
978 return quotearg_n_options (0, arg, argsize, &options);
981 char *
982 quotearg_char (char const *arg, char ch)
984 return quotearg_char_mem (arg, SIZE_MAX, ch);
987 char *
988 quotearg_colon (char const *arg)
990 return quotearg_char (arg, ':');
993 char *
994 quotearg_colon_mem (char const *arg, size_t argsize)
996 return quotearg_char_mem (arg, argsize, ':');
999 char *
1000 quotearg_n_style_colon (int n, enum quoting_style s, char const *arg)
1002 struct quoting_options options;
1003 options = quoting_options_from_style (s);
1004 set_char_quoting (&options, ':', 1);
1005 return quotearg_n_options (n, arg, SIZE_MAX, &options);
1008 char *
1009 quotearg_n_custom (int n, char const *left_quote,
1010 char const *right_quote, char const *arg)
1012 return quotearg_n_custom_mem (n, left_quote, right_quote, arg,
1013 SIZE_MAX);
1016 char *
1017 quotearg_n_custom_mem (int n, char const *left_quote,
1018 char const *right_quote,
1019 char const *arg, size_t argsize)
1021 struct quoting_options o = default_quoting_options;
1022 set_custom_quoting (&o, left_quote, right_quote);
1023 return quotearg_n_options (n, arg, argsize, &o);
1026 char *
1027 quotearg_custom (char const *left_quote, char const *right_quote,
1028 char const *arg)
1030 return quotearg_n_custom (0, left_quote, right_quote, arg);
1033 char *
1034 quotearg_custom_mem (char const *left_quote, char const *right_quote,
1035 char const *arg, size_t argsize)
1037 return quotearg_n_custom_mem (0, left_quote, right_quote, arg,
1038 argsize);
1042 /* The quoting option used by the functions of quote.h. */
1043 struct quoting_options quote_quoting_options =
1045 locale_quoting_style,
1047 { 0 },
1048 NULL, NULL
1051 char const *
1052 quote_n_mem (int n, char const *arg, size_t argsize)
1054 return quotearg_n_options (n, arg, argsize, &quote_quoting_options);
1057 char const *
1058 quote_mem (char const *arg, size_t argsize)
1060 return quote_n_mem (0, arg, argsize);
1063 char const *
1064 quote_n (int n, char const *arg)
1066 return quote_n_mem (n, arg, SIZE_MAX);
1069 char const *
1070 quote (char const *arg)
1072 return quote_n (0, arg);