summaryrefslogtreecommitdiff
path: root/libmailutils
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org.ua>2011-11-17 18:19:15 +0200
committerSergey Poznyakoff <gray@gnu.org.ua>2011-11-17 18:19:15 +0200
commit2ec525acff5a090dcba8a0c7c166bbe745340902 (patch)
tree93d925f1401cde4d6703f5a8feb73d87ef40db9e /libmailutils
parentb26b2120ce815173819cf5bea197d4f5264aecdb (diff)
downloadmailutils-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.c55
-rw-r--r--libmailutils/tests/wordsplit.at17
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])

Return to:

Send suggestions and report system problems to the System administrator.