source: coreutils/trunk/lib/quotearg.c@ 1953

Last change on this file since 1953 was 1953, checked in by Silvan Scherrer, 8 years ago

coreutils: update trunk to version 8.26

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