wordsplit: implement separate single- and double-quote parsing.
* include/mailutils/wordsplit.h (MU_WRDSF_SQUOTE,MU_WRDSF_DQUOTE): New flags. (MU_WRDSF_QUOTE): Redefine as an OR of the above two. * libmailutils/string/wordsplit.c (scan_word): Treat '\'' and '"' separately, depending on the flags. * libmailutils/tests/wsp.c: Add squote and dquote options. * libmailutils/tests/wordsplit.at: Test separate quoting support.
Showing
4 changed files
with
56 additions
and
29 deletions
... | @@ -46,73 +46,79 @@ struct mu_wordsplit | ... | @@ -46,73 +46,79 @@ struct mu_wordsplit |
46 | struct mu_wordsplit_node *ws_head, *ws_tail; | 46 | struct mu_wordsplit_node *ws_head, *ws_tail; |
47 | }; | 47 | }; |
48 | 48 | ||
49 | /* Wordsplit flags. Only 3 bits of a 32-bit word remain unused. | ||
50 | It is getting crowded... */ | ||
49 | /* Append the words found to the array resulting from a previous | 51 | /* Append the words found to the array resulting from a previous |
50 | call. */ | 52 | call. */ |
51 | #define MU_WRDSF_APPEND 0x0000001 | 53 | #define MU_WRDSF_APPEND 0x00000001 |
52 | /* Insert we_offs initial NULLs in the array ws_wordv. | 54 | /* Insert we_offs initial NULLs in the array ws_wordv. |
53 | (These are not counted in the returned ws_wordc.) */ | 55 | (These are not counted in the returned ws_wordc.) */ |
54 | #define MU_WRDSF_DOOFFS 0x0000002 | 56 | #define MU_WRDSF_DOOFFS 0x00000002 |
55 | /* Don't do command substitution. Reserved for future use. */ | 57 | /* Don't do command substitution. Reserved for future use. */ |
56 | #define MU_WRDSF_NOCMD 0x0000004 | 58 | #define MU_WRDSF_NOCMD 0x00000004 |
57 | /* The parameter p resulted from a previous call to | 59 | /* The parameter p resulted from a previous call to |
58 | mu_wordsplit(), and mu_wordsplit_free() was not called. Reuse the | 60 | mu_wordsplit(), and mu_wordsplit_free() was not called. Reuse the |
59 | allocated storage. */ | 61 | allocated storage. */ |
60 | #define MU_WRDSF_REUSE 0x0000008 | 62 | #define MU_WRDSF_REUSE 0x00000008 |
61 | /* Print errors */ | 63 | /* Print errors */ |
62 | #define MU_WRDSF_SHOWERR 0x0000010 | 64 | #define MU_WRDSF_SHOWERR 0x00000010 |
63 | /* Consider it an error if an undefined shell variable | 65 | /* Consider it an error if an undefined shell variable |
64 | is expanded. */ | 66 | is expanded. */ |
65 | #define MU_WRDSF_UNDEF 0x0000020 | 67 | #define MU_WRDSF_UNDEF 0x00000020 |
66 | 68 | ||
67 | /* Don't do variable expansion. */ | 69 | /* Don't do variable expansion. */ |
68 | #define MU_WRDSF_NOVAR 0x0000040 | 70 | #define MU_WRDSF_NOVAR 0x00000040 |
69 | /* Abort on ENOMEM error */ | 71 | /* Abort on ENOMEM error */ |
70 | #define MU_WRDSF_ENOMEMABRT 0x0000080 | 72 | #define MU_WRDSF_ENOMEMABRT 0x00000080 |
71 | /* Trim off any leading and trailind whitespace */ | 73 | /* Trim off any leading and trailind whitespace */ |
72 | #define MU_WRDSF_WS 0x0000100 | 74 | #define MU_WRDSF_WS 0x00000100 |
75 | /* Handle single quotes */ | ||
76 | #define MU_WRDSF_SQUOTE 0x00000200 | ||
77 | /* Handle double quotes */ | ||
78 | #define MU_WRDSF_DQUOTE 0x00000400 | ||
73 | /* Handle quotes and escape directives */ | 79 | /* Handle quotes and escape directives */ |
74 | #define MU_WRDSF_QUOTE 0x0000200 | 80 | #define MU_WRDSF_QUOTE (MU_WRDSF_SQUOTE|MU_WRDSF_DQUOTE) |
75 | /* Replace each input sequence of repeated delimiters with a single | 81 | /* Replace each input sequence of repeated delimiters with a single |
76 | delimiter */ | 82 | delimiter */ |
77 | #define MU_WRDSF_SQUEEZE_DELIMS 0x0000400 | 83 | #define MU_WRDSF_SQUEEZE_DELIMS 0x00000800 |
78 | /* Return delimiters */ | 84 | /* Return delimiters */ |
79 | #define MU_WRDSF_RETURN_DELIMS 0x0000800 | 85 | #define MU_WRDSF_RETURN_DELIMS 0x00001000 |
80 | /* Treat sed expressions as words */ | 86 | /* Treat sed expressions as words */ |
81 | #define MU_WRDSF_SED_EXPR 0x0001000 | 87 | #define MU_WRDSF_SED_EXPR 0x00002000 |
82 | /* ws_delim field is initialized */ | 88 | /* ws_delim field is initialized */ |
83 | #define MU_WRDSF_DELIM 0x0002000 | 89 | #define MU_WRDSF_DELIM 0x00004000 |
84 | /* ws_comment field is initialized */ | 90 | /* ws_comment field is initialized */ |
85 | #define MU_WRDSF_COMMENT 0x0004000 | 91 | #define MU_WRDSF_COMMENT 0x00008000 |
86 | /* ws_alloc_die field is initialized */ | 92 | /* ws_alloc_die field is initialized */ |
87 | #define MU_WRDSF_ALLOC_DIE 0x0008000 | 93 | #define MU_WRDSF_ALLOC_DIE 0x00010000 |
88 | /* ws_error field is initialized */ | 94 | /* ws_error field is initialized */ |
89 | #define MU_WRDSF_ERROR 0x0010000 | 95 | #define MU_WRDSF_ERROR 0x00020000 |
90 | /* ws_debug field is initialized */ | 96 | /* ws_debug field is initialized */ |
91 | #define MU_WRDSF_DEBUG 0x0020000 | 97 | #define MU_WRDSF_DEBUG 0x00040000 |
92 | /* ws_env field is initialized */ | 98 | /* ws_env field is initialized */ |
93 | #define MU_WRDSF_ENV 0x0040000 | 99 | #define MU_WRDSF_ENV 0x00080000 |
94 | /* ws_getvar field is initialized */ | 100 | /* ws_getvar field is initialized */ |
95 | #define MU_WRDSF_GETVAR 0x0080000 | 101 | #define MU_WRDSF_GETVAR 0x00100000 |
96 | /* enable debugging */ | 102 | /* enable debugging */ |
97 | #define MU_WRDSF_SHOWDBG 0x0100000 | 103 | #define MU_WRDSF_SHOWDBG 0x00200000 |
98 | /* Don't split input into words. Useful for side effects. */ | 104 | /* Don't split input into words. Useful for side effects. */ |
99 | #define MU_WRDSF_NOSPLIT 0x0200000 | 105 | #define MU_WRDSF_NOSPLIT 0x00400000 |
100 | /* Keep undefined variables in place, instead of expanding them to | 106 | /* Keep undefined variables in place, instead of expanding them to |
101 | empty string */ | 107 | empty string */ |
102 | #define MU_WRDSF_KEEPUNDEF 0x0400000 | 108 | #define MU_WRDSF_KEEPUNDEF 0x00800000 |
103 | /* Warn about undefined variables */ | 109 | /* Warn about undefined variables */ |
104 | #define MU_WRDSF_WARNUNDEF 0x0800000 | 110 | #define MU_WRDSF_WARNUNDEF 0x01000000 |
105 | /* Handle C escapes */ | 111 | /* Handle C escapes */ |
106 | #define MU_WRDSF_CESCAPES 0x1000000 | 112 | #define MU_WRDSF_CESCAPES 0x02000000 |
107 | 113 | ||
108 | /* ws_closure is set */ | 114 | /* ws_closure is set */ |
109 | #define MU_WRDSF_CLOSURE 0x2000000 | 115 | #define MU_WRDSF_CLOSURE 0x04000000 |
110 | /* ws_env is a Key/Value environment, i.e. the value of a variable is | 116 | /* ws_env is a Key/Value environment, i.e. the value of a variable is |
111 | stored in the element that follows its name. */ | 117 | stored in the element that follows its name. */ |
112 | #define MU_WRDSF_ENV_KV 0x4000000 | 118 | #define MU_WRDSF_ENV_KV 0x08000000 |
113 | 119 | ||
114 | /* ws_escape is set */ | 120 | /* ws_escape is set */ |
115 | #define MU_WRDSF_ESCAPE 0x8000000 | 121 | #define MU_WRDSF_ESCAPE 0x10000000 |
116 | 122 | ||
117 | #define MU_WRDSF_DEFFLAGS \ | 123 | #define MU_WRDSF_DEFFLAGS \ |
118 | (MU_WRDSF_NOVAR | MU_WRDSF_NOCMD | \ | 124 | (MU_WRDSF_NOVAR | MU_WRDSF_NOCMD | \ | ... | ... |
... | @@ -1115,7 +1115,8 @@ scan_word (struct mu_wordsplit *wsp, size_t start) | ... | @@ -1115,7 +1115,8 @@ scan_word (struct mu_wordsplit *wsp, size_t start) |
1115 | continue; | 1115 | continue; |
1116 | } | 1116 | } |
1117 | 1117 | ||
1118 | if (command[i] == '\'' || command[i] == '"') | 1118 | if (((wsp->ws_flags & MU_WRDSF_SQUOTE) && command[i] == '\'') || |
1119 | ((wsp->ws_flags & MU_WRDSF_DQUOTE) && command[i] == '"')) | ||
1119 | { | 1120 | { |
1120 | if (join && wsp->ws_tail) | 1121 | if (join && wsp->ws_tail) |
1121 | wsp->ws_tail->flags |= _WSNF_JOIN; | 1122 | wsp->ws_tail->flags |= _WSNF_JOIN; | ... | ... |
... | @@ -355,4 +355,22 @@ TESTWSP([unescape],[],[-default novar nocmd quote escape '\"'], | ... | @@ -355,4 +355,22 @@ TESTWSP([unescape],[],[-default novar nocmd quote escape '\"'], |
355 | 2: "bs \\" | 355 | 2: "bs \\" |
356 | ]) | 356 | ]) |
357 | 357 | ||
358 | TESTWSP([dquote],[],[-default novar nocmd dquote], | ||
359 | [a "quoted example" isn't it], | ||
360 | [NF: 4 | ||
361 | 0: a | ||
362 | 1: "quoted example" | ||
363 | 2: isn't | ||
364 | 3: it | ||
365 | ]) | ||
366 | |||
367 | TESTWSP([squote],[],[-default novar nocmd squote], | ||
368 | [a 'quoted example' isn"t it], | ||
369 | [NF: 4 | ||
370 | 0: a | ||
371 | 1: "quoted example" | ||
372 | 2: "isn\"t" | ||
373 | 3: it | ||
374 | ]) | ||
375 | |||
358 | m4_popdef([TESTWSP]) | 376 | m4_popdef([TESTWSP]) | ... | ... |
... | @@ -37,6 +37,8 @@ struct mu_kwd bool_keytab[] = { | ... | @@ -37,6 +37,8 @@ struct mu_kwd bool_keytab[] = { |
37 | { "nocmd", MU_WRDSF_NOCMD }, | 37 | { "nocmd", MU_WRDSF_NOCMD }, |
38 | { "ws", MU_WRDSF_WS }, | 38 | { "ws", MU_WRDSF_WS }, |
39 | { "quote", MU_WRDSF_QUOTE }, | 39 | { "quote", MU_WRDSF_QUOTE }, |
40 | { "squote", MU_WRDSF_SQUOTE }, | ||
41 | { "dquote", MU_WRDSF_DQUOTE }, | ||
40 | { "squeeze_delims", MU_WRDSF_SQUEEZE_DELIMS }, | 42 | { "squeeze_delims", MU_WRDSF_SQUEEZE_DELIMS }, |
41 | { "return_delims", MU_WRDSF_RETURN_DELIMS }, | 43 | { "return_delims", MU_WRDSF_RETURN_DELIMS }, |
42 | { "sed", MU_WRDSF_SED_EXPR }, | 44 | { "sed", MU_WRDSF_SED_EXPR }, | ... | ... |
-
Please register or sign in to post a comment