Commit d2207485 d2207485610080f7f3c60b2a435c57fe5edb4ade by Sergey Poznyakoff

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.
1 parent c2dcdc0c
...@@ -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 /* Append the words found to the array resulting from a previous 49 /* Wordsplit flags. Only 3 bits of a 32-bit word remain unused.
50 It is getting crowded... */
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 },
......