[PATCH 5/5] cmd: fix parameter parsing of quotes and special chars

Martin Wilck mwilck at arcor.de
Sun Sep 25 08:19:44 CDT 2011


This patch applies the same logic of changes to WCMD_parameter()
that the previous two patches made to WCMD_parse().
Simplfied WCMD_parameter wrt previous submission.
---
 programs/cmd/batch.c                     |   88 +++++++++++++++++++-----------
 programs/cmd/tests/test_builtins.cmd.exp |    8 ++--
 programs/cmd/tests/test_cmdline.cmd.exp  |   18 +++---
 3 files changed, 70 insertions(+), 44 deletions(-)

diff --git a/programs/cmd/batch.c b/programs/cmd/batch.c
index f988d95..66e1fff 100644
--- a/programs/cmd/batch.c
+++ b/programs/cmd/batch.c
@@ -137,39 +137,65 @@ void WCMD_batch (WCHAR *file, WCHAR *command, int called, WCHAR *startLabel, HAN
  *  after each call.
  *  Doesn't include any potentially delimiting double quotes
  */
+static BOOL is_param_delimiter(WCHAR c, int n)
+{
+    return ((c == ' ') || (c == ',') || (c == '=') || (c == '\t')
+	    || (c == ';') || (c == '(' && n == 0));
+}
+
+static int memcpy_without_quotes(WCHAR *to, const WCHAR *from, int len)
+{
+    WCHAR *t = to, *quot;
+    int n;
+    while (len > 0 && (quot = memchrW(from, '"', len)) != NULL) {
+	n = quot - from;
+	if (n > 0)
+	    memcpy(t, from, n * sizeof(WCHAR));
+	t += n;
+	from += ++n;
+	len -= n;
+    }
+    if (len > 0)
+	memcpy(t, from, len * sizeof(WCHAR));
+    return (t - to) + len;
+}
+
 WCHAR *WCMD_parameter (WCHAR *s, int n, WCHAR **where, WCHAR **end) {
-    int curParamNb = 0;
+    int par = 0;
     static WCHAR param[MAX_PATH];
-    WCHAR *p = s, *q;
-    BOOL quotesDelimited;
-
-    if (where != NULL) *where = NULL;
-    if (end != NULL) *end = NULL;
-    param[0] = '\0';
-    while (TRUE) {
-        while (*p && ((*p == ' ') || (*p == ',') || (*p == '=') || (*p == '\t')))
-            p++;
-        if (*p == '\0') return param;
-
-        quotesDelimited = (*p == '"');
-        if (where != NULL && curParamNb == n) *where = p;
-
-        if (quotesDelimited) {
-            q = ++p;
-            while (*p && *p != '"') p++;
-        } else {
-            q = p;
-            while (*p && (*p != ' ') && (*p != ',') && (*p != '=') && (*p != '\t'))
-                p++;
-        }
-        if (curParamNb == n) {
-            memcpy(param, q, (p - q) * sizeof(WCHAR));
-            param[p-q] = '\0';
-            if (end) *end = p - 1 + quotesDelimited;
-            return param;
-        }
-        if (quotesDelimited && *p == '"') p++;
-        curParamNb++;
+    WCHAR *p = s, *_whr, *_end;
+    WCHAR **_pwhr = (where ? : &_whr), **_pend = (end ? : &_end);
+
+    *_pwhr = *_pend = NULL;
+    for (par = 0; ; par++) {
+	while (is_param_delimiter(*p, par))
+	    p++;
+	if (*p == '\0') {
+	    param[0] = '\0';
+	    return param;
+	}
+	if (par == n) *_pwhr = p;
+	while (TRUE) { /* inner loop for parsing a single token */
+	    if (*p == '"') {
+		do p++; while (*p != '\0' && *p != '"');
+		if (*p != '\0') p++;
+	    } else
+		while (*p != '\0' && *p != '"' && !is_param_delimiter(*p, par))
+		    p++;
+	    if (*p == '\0' || is_param_delimiter(*p, par)) {
+		if (par == n) {
+		    int len = p - *_pwhr;
+		    *_pend = p - 1;
+		    if (n == 0)
+			len = memcpy_without_quotes(param, *_pwhr, len);
+		    else
+			memcpy(param, *_pwhr, len * sizeof(WCHAR));
+		    param[len] = '\0';
+		    return param;
+		} else
+		    break;
+	    }
+	}
     }
 }
 
diff --git a/programs/cmd/tests/test_builtins.cmd.exp b/programs/cmd/tests/test_builtins.cmd.exp
index 31b1780..cb0a5c2 100644
--- a/programs/cmd/tests/test_builtins.cmd.exp
+++ b/programs/cmd/tests/test_builtins.cmd.exp
@@ -718,16 +718,16 @@ foo at space@
 foo 8
 foo at space@@space@
 foo bar at space@
- at todo_wine@foo ""@space@
- at todo_wine@"" bar at space@
+foo ""@space@
+"" bar at space@
 foo ''@space@
 '' bar at space@
 ... internal routines ...
 bar :testRoutine
 foo at space@
 foo bar
- at todo_wine@foo ""
- at todo_wine@"" bar
+foo ""
+"" bar
 foo ''
 '' bar
 ... with builtins ...
diff --git a/programs/cmd/tests/test_cmdline.cmd.exp b/programs/cmd/tests/test_cmdline.cmd.exp
index bb74504..7c55930 100755
--- a/programs/cmd/tests/test_cmdline.cmd.exp
+++ b/programs/cmd/tests/test_cmdline.cmd.exp
@@ -66,12 +66,12 @@
 1:1,2:@space@
 1:(1),2:@space@
 1:1(2),2:@space@
- at todo_wine@1:(1),2:@space@
- at todo_wine@1:((1)),2:@space@
- at todo_wine@1:(1)(2),2:@space@
- at todo_wine@1:(1),2:(2)@space@
- at todo_wine@1:1,2:2 at space@
- at todo_wine@1:1,2:2 at space@
- at todo_wine@1:1,2:2 at space@
- at todo_wine@1:"p at space@"1,2:p"@space@"2 at space@
- at todo_wine@1:p"1 at space@p",2:2 at space@
+1:(1),2:@space@
+1:((1)),2:@space@
+1:(1)(2),2:@space@
+1:(1),2:(2)@space@
+1:1,2:2 at space@
+1:1,2:2 at space@
+1:1,2:2 at space@
+1:"p at space@"1,2:p"@space@"2 at space@
+1:p"1 at space@p",2:2 at space@
-- 
1.7.3.4



More information about the wine-patches mailing list