Line data Source code
1 : #include <string.h>
2 : #include "serialize.h"
3 : #include "util/ascii.h"
4 : #include "util/numtostr.h"
5 :
6 779 : void string_append_escaped_arg_sv(String *s, StringView arg, bool escape_tilde)
7 : {
8 779 : static const char escmap[] = {
9 : [0x07] = 'a', [0x08] = 'b',
10 : [0x09] = 't', [0x0A] = 'n',
11 : [0x0B] = 'v', [0x0C] = 'f',
12 : [0x0D] = 'r', [0x1B] = 'e',
13 : ['"'] = '"', ['\\'] = '\\',
14 : };
15 :
16 779 : if (arg.length == 0) {
17 3 : string_append_literal(s, "''");
18 3 : return;
19 : }
20 :
21 776 : bool has_tilde_slash_prefix = strview_has_prefix(&arg, "~/");
22 776 : if (has_tilde_slash_prefix && !escape_tilde) {
23 : // Print "~/" and skip past it, so it doesn't get quoted
24 7 : string_append_literal(s, "~/");
25 7 : strview_remove_prefix(&arg, 2);
26 : }
27 :
28 776 : bool squote = false;
29 6854 : for (size_t i = 0, n = arg.length; i < n; i++) {
30 6088 : const unsigned char c = arg.data[i];
31 6088 : switch (c) {
32 371 : case ' ':
33 : case '"':
34 : case '$':
35 : case ';':
36 : case '\\':
37 371 : squote = true;
38 371 : continue;
39 4 : case '\'':
40 4 : goto dquote;
41 : }
42 5713 : if (ascii_iscntrl(c)) {
43 6 : goto dquote;
44 : }
45 : }
46 :
47 766 : if (squote) {
48 131 : string_append_byte(s, '\'');
49 131 : string_append_strview(s, &arg);
50 131 : string_append_byte(s, '\'');
51 : } else {
52 635 : if (has_tilde_slash_prefix && escape_tilde) {
53 2 : string_append_byte(s, '\\');
54 : }
55 635 : string_append_strview(s, &arg);
56 : }
57 : return;
58 :
59 10 : dquote:
60 10 : string_append_byte(s, '"');
61 133 : for (size_t i = 0, n = arg.length; i < n; i++) {
62 123 : unsigned char ch = arg.data[i];
63 123 : if (unlikely(ch < sizeof(escmap) && escmap[ch])) {
64 13 : string_append_byte(s, '\\');
65 13 : ch = escmap[ch];
66 110 : } else if (unlikely(ascii_iscntrl(ch))) {
67 2 : string_append_literal(s, "\\x");
68 2 : string_append_byte(s, hextab_upper[(ch >> 4) & 15]);
69 2 : ch = hextab_upper[ch & 15];
70 : }
71 123 : string_append_byte(s, ch);
72 : }
73 10 : string_append_byte(s, '"');
74 : }
|