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
struct mu_wordsplit_node *ws_head, *ws_tail;
};
/* Wordsplit flags. Only 3 bits of a 32-bit word remain unused.
It is getting crowded... */
/* Append the words found to the array resulting from a previous
call. */
#define MU_WRDSF_APPEND 0x0000001
#define MU_WRDSF_APPEND 0x00000001
/* Insert we_offs initial NULLs in the array ws_wordv.
(These are not counted in the returned ws_wordc.) */
#define MU_WRDSF_DOOFFS 0x0000002
#define MU_WRDSF_DOOFFS 0x00000002
/* Don't do command substitution. Reserved for future use. */
#define MU_WRDSF_NOCMD 0x0000004
#define MU_WRDSF_NOCMD 0x00000004
/* The parameter p resulted from a previous call to
mu_wordsplit(), and mu_wordsplit_free() was not called. Reuse the
allocated storage. */
#define MU_WRDSF_REUSE 0x0000008
#define MU_WRDSF_REUSE 0x00000008
/* Print errors */
#define MU_WRDSF_SHOWERR 0x0000010
#define MU_WRDSF_SHOWERR 0x00000010
/* Consider it an error if an undefined shell variable
is expanded. */
#define MU_WRDSF_UNDEF 0x0000020
#define MU_WRDSF_UNDEF 0x00000020
/* Don't do variable expansion. */
#define MU_WRDSF_NOVAR 0x0000040
#define MU_WRDSF_NOVAR 0x00000040
/* Abort on ENOMEM error */
#define MU_WRDSF_ENOMEMABRT 0x0000080
#define MU_WRDSF_ENOMEMABRT 0x00000080
/* Trim off any leading and trailind whitespace */
#define MU_WRDSF_WS 0x0000100
#define MU_WRDSF_WS 0x00000100
/* Handle single quotes */
#define MU_WRDSF_SQUOTE 0x00000200
/* Handle double quotes */
#define MU_WRDSF_DQUOTE 0x00000400
/* Handle quotes and escape directives */
#define MU_WRDSF_QUOTE 0x0000200
#define MU_WRDSF_QUOTE (MU_WRDSF_SQUOTE|MU_WRDSF_DQUOTE)
/* Replace each input sequence of repeated delimiters with a single
delimiter */
#define MU_WRDSF_SQUEEZE_DELIMS 0x0000400
#define MU_WRDSF_SQUEEZE_DELIMS 0x00000800
/* Return delimiters */
#define MU_WRDSF_RETURN_DELIMS 0x0000800
#define MU_WRDSF_RETURN_DELIMS 0x00001000
/* Treat sed expressions as words */
#define MU_WRDSF_SED_EXPR 0x0001000
#define MU_WRDSF_SED_EXPR 0x00002000
/* ws_delim field is initialized */
#define MU_WRDSF_DELIM 0x0002000
#define MU_WRDSF_DELIM 0x00004000
/* ws_comment field is initialized */
#define MU_WRDSF_COMMENT 0x0004000
#define MU_WRDSF_COMMENT 0x00008000
/* ws_alloc_die field is initialized */
#define MU_WRDSF_ALLOC_DIE 0x0008000
#define MU_WRDSF_ALLOC_DIE 0x00010000
/* ws_error field is initialized */
#define MU_WRDSF_ERROR 0x0010000
#define MU_WRDSF_ERROR 0x00020000
/* ws_debug field is initialized */
#define MU_WRDSF_DEBUG 0x0020000
#define MU_WRDSF_DEBUG 0x00040000
/* ws_env field is initialized */
#define MU_WRDSF_ENV 0x0040000
#define MU_WRDSF_ENV 0x00080000
/* ws_getvar field is initialized */
#define MU_WRDSF_GETVAR 0x0080000
#define MU_WRDSF_GETVAR 0x00100000
/* enable debugging */
#define MU_WRDSF_SHOWDBG 0x0100000
#define MU_WRDSF_SHOWDBG 0x00200000
/* Don't split input into words. Useful for side effects. */
#define MU_WRDSF_NOSPLIT 0x0200000
#define MU_WRDSF_NOSPLIT 0x00400000
/* Keep undefined variables in place, instead of expanding them to
empty string */
#define MU_WRDSF_KEEPUNDEF 0x0400000
#define MU_WRDSF_KEEPUNDEF 0x00800000
/* Warn about undefined variables */
#define MU_WRDSF_WARNUNDEF 0x0800000
#define MU_WRDSF_WARNUNDEF 0x01000000
/* Handle C escapes */
#define MU_WRDSF_CESCAPES 0x1000000
#define MU_WRDSF_CESCAPES 0x02000000
/* ws_closure is set */
#define MU_WRDSF_CLOSURE 0x2000000
#define MU_WRDSF_CLOSURE 0x04000000
/* ws_env is a Key/Value environment, i.e. the value of a variable is
stored in the element that follows its name. */
#define MU_WRDSF_ENV_KV 0x4000000
#define MU_WRDSF_ENV_KV 0x08000000
/* ws_escape is set */
#define MU_WRDSF_ESCAPE 0x8000000
#define MU_WRDSF_ESCAPE 0x10000000
#define MU_WRDSF_DEFFLAGS \
(MU_WRDSF_NOVAR | MU_WRDSF_NOCMD | \
......
......@@ -1115,7 +1115,8 @@ scan_word (struct mu_wordsplit *wsp, size_t start)
continue;
}
if (command[i] == '\'' || command[i] == '"')
if (((wsp->ws_flags & MU_WRDSF_SQUOTE) && command[i] == '\'') ||
((wsp->ws_flags & MU_WRDSF_DQUOTE) && command[i] == '"'))
{
if (join && wsp->ws_tail)
wsp->ws_tail->flags |= _WSNF_JOIN;
......
......@@ -355,4 +355,22 @@ TESTWSP([unescape],[],[-default novar nocmd quote escape '\"'],
2: "bs \\"
])
TESTWSP([dquote],[],[-default novar nocmd dquote],
[a "quoted example" isn't it],
[NF: 4
0: a
1: "quoted example"
2: isn't
3: it
])
TESTWSP([squote],[],[-default novar nocmd squote],
[a 'quoted example' isn"t it],
[NF: 4
0: a
1: "quoted example"
2: "isn\"t"
3: it
])
m4_popdef([TESTWSP])
......
......@@ -37,6 +37,8 @@ struct mu_kwd bool_keytab[] = {
{ "nocmd", MU_WRDSF_NOCMD },
{ "ws", MU_WRDSF_WS },
{ "quote", MU_WRDSF_QUOTE },
{ "squote", MU_WRDSF_SQUOTE },
{ "dquote", MU_WRDSF_DQUOTE },
{ "squeeze_delims", MU_WRDSF_SQUEEZE_DELIMS },
{ "return_delims", MU_WRDSF_RETURN_DELIMS },
{ "sed", MU_WRDSF_SED_EXPR },
......