summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/mailutils/wordsplit.h6
-rw-r--r--libmailutils/string/wordsplit.c55
-rw-r--r--libmailutils/tests/wordsplit.at17
3 files changed, 66 insertions, 12 deletions
diff --git a/include/mailutils/wordsplit.h b/include/mailutils/wordsplit.h
index 3ddedb67a..0ce33a33e 100644
--- a/include/mailutils/wordsplit.h
+++ b/include/mailutils/wordsplit.h
@@ -28,6 +28,7 @@ struct mu_wordsplit
int ws_flags;
const char *ws_delim;
const char *ws_comment;
+ const char *ws_escape;
void (*ws_alloc_die) (struct mu_wordsplit *wsp);
void (*ws_error) (const char *, ...)
__attribute__ ((__format__ (__printf__, 1, 2)));
@@ -110,6 +111,9 @@ struct mu_wordsplit
stored in the element that follows its name. */
#define MU_WRDSF_ENV_KV 0x4000000
+/* ws_escape is set */
+#define MU_WRDSF_ESCAPE 0x8000000
+
#define MU_WRDSF_DEFFLAGS \
(MU_WRDSF_NOVAR | MU_WRDSF_NOCMD | \
MU_WRDSF_QUOTE | MU_WRDSF_SQUEEZE_DELIMS | MU_WRDSF_CESCAPES)
@@ -132,6 +136,8 @@ int mu_wordsplit_c_unquote_char (int c);
int mu_wordsplit_c_quote_char (int c);
size_t 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);
void mu_wordsplit_sh_unquote_copy (char *dst, const char *src, size_t n);
void mu_wordsplit_c_unquote_copy (char *dst, const char *src, size_t n);
void mu_wordsplit_c_quote_copy (char *dst, const char *src, int quote_hex);
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.