diff options
author | Sergey Poznyakoff <gray@gnu.org.ua> | 2011-11-17 18:19:15 +0200 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org.ua> | 2011-11-17 18:19:15 +0200 |
commit | 2ec525acff5a090dcba8a0c7c166bbe745340902 (patch) | |
tree | 93d925f1401cde4d6703f5a8feb73d87ef40db9e /libmailutils | |
parent | b26b2120ce815173819cf5bea197d4f5264aecdb (diff) | |
download | mailutils-2ec525acff5a090dcba8a0c7c166bbe745340902.tar.gz mailutils-2ec525acff5a090dcba8a0c7c166bbe745340902.tar.bz2 |
Improve wordsplit.
* include/mailutils/wordsplit.h (mu_wordsplit) <ws_escape>: New member.
(MU_WRDSF_ESCAPE): New flag.
(mu_wordsplit_general_unquote_copy): New function.
* libmailutils/string/wordsplit.c: Remove empty nodes after whitespace
trimming. If MU_WRDSF_ESCAPE is set, remove only backslashes appearing
in front of a character in ws_escape.
* libmailutils/tests/wordsplit.at: Test new features.
Diffstat (limited to 'libmailutils')
-rw-r--r-- | libmailutils/string/wordsplit.c | 55 | ||||
-rw-r--r-- | libmailutils/tests/wordsplit.at | 17 |
2 files changed, 60 insertions, 12 deletions
diff --git a/libmailutils/string/wordsplit.c b/libmailutils/string/wordsplit.c index 26342dc3c..4536cc214 100644 --- a/libmailutils/string/wordsplit.c +++ b/libmailutils/string/wordsplit.c @@ -500,7 +500,12 @@ wsnode_quoteremoval (struct mu_wordsplit *wsp) p->v.word = newstr; p->flags |= _WSNF_WORD; } - uqfn (p->v.word, str, slen); + + if (wsp->ws_flags & MU_WRDSF_ESCAPE) + mu_wordsplit_general_unquote_copy (p->v.word, str, slen, + wsp->ws_escape); + else + uqfn (p->v.word, str, slen); } } return 0; @@ -906,32 +911,39 @@ node_expand_vars (struct mu_wordsplit *wsp, struct mu_wordsplit_node *node) return 0; } -static int -mu_wordsplit_varexp (struct mu_wordsplit *wsp) +/* Remove NULL lists */ +static void +wsnode_nullelim (struct mu_wordsplit *wsp) { struct mu_wordsplit_node *p; for (p = wsp->ws_head; p;) { struct mu_wordsplit_node *next = p->next; - if (!(p->flags & _WSNF_NOEXPAND)) - if (node_expand_vars (wsp, p)) - return 1; + if (p->flags & _WSNF_NULL) + { + wsnode_remove (wsp, p); + wsnode_free (p); + } p = next; } +} + +static int +mu_wordsplit_varexp (struct mu_wordsplit *wsp) +{ + struct mu_wordsplit_node *p; - /* Remove NULL lists */ for (p = wsp->ws_head; p;) { struct mu_wordsplit_node *next = p->next; - if (p->flags & _WSNF_NULL) - { - wsnode_remove (wsp, p); - wsnode_free (p); - } + if (!(p->flags & _WSNF_NOEXPAND)) + if (node_expand_vars (wsp, p)) + return 1; p = next; } + wsnode_nullelim (wsp); return 0; } @@ -959,7 +971,11 @@ mu_wordsplit_trimws (struct mu_wordsplit *wsp) for (n = p->v.segm.end; n > p->v.segm.beg && ISWS (wsp->ws_input[n-1]); n--); p->v.segm.end = n; + if (p->v.segm.beg == p->v.segm.end) + p->flags |= _WSNF_NULL; } + + wsnode_nullelim (wsp); } static int @@ -1217,6 +1233,21 @@ mu_wordsplit_c_quoted_length (const char *str, int quote_hex, int *quote) } void +mu_wordsplit_general_unquote_copy (char *dst, const char *src, size_t n, + const char *escapable) +{ + int i; + + for (i = 0; i < n;) + { + if (src[i] == '\\' && i < n && strchr (escapable, src[i+1])) + i++; + *dst++ = src[i++]; + } + *dst = 0; +} + +void mu_wordsplit_sh_unquote_copy (char *dst, const char *src, size_t n) { int i; diff --git a/libmailutils/tests/wordsplit.at b/libmailutils/tests/wordsplit.at index 8625f9538..99b0dcb72 100644 --- a/libmailutils/tests/wordsplit.at +++ b/libmailutils/tests/wordsplit.at @@ -313,6 +313,15 @@ TESTWSP([C escapes off],[],[-cescapes], 3: newnline ]) +TESTWSP([ws elimination],[],[delim ' ()' ws return_delims], +[( list items )], +[NF: 4 +0: ( +1: list +2: items +3: ) +]) + TESTWSP([empty quotes],[],[delim : ws return_delims], [t=""], [NF: 1 @@ -338,4 +347,12 @@ TESTWSP([suppress ws trimming within quotes],[], 4: "formatfield=In message %{text}, " ]) +TESTWSP([unescape],[],[-default novar nocmd quote escape '\"'], +[\Seen "quote \"" "bs \\"], +[NF: 3 +0: \\Seen +1: "quote \"" +2: "bs \\" +]) + m4_popdef([TESTWSP]) |