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

Martin Wilck mwilck at arcor.de
Thu Sep 29 15:10:52 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                     |   83 ++++++++++++++++++++----------
 programs/cmd/tests/test_builtins.cmd.exp |    8 ++--
 programs/cmd/tests/test_cmdline.cmd.exp  |   18 +++---
 3 files changed, 68 insertions(+), 41 deletions(-)

diff --git a/programs/cmd/batch.c b/programs/cmd/batch.c
index 447eccd..1ecdecf 100644
--- a/programs/cmd/batch.c
+++ b/programs/cmd/batch.c
@@ -111,6 +111,29 @@ void WCMD_batch (WCHAR *file, WCHAR *command, int called, WCHAR *startLabel, HAN
   context = prev_context;
 }
 
+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;
+}
+
 /*******************************************************************
  * WCMD_parameter
  *
@@ -137,39 +160,43 @@ void WCMD_batch (WCHAR *file, WCHAR *command, int called, WCHAR *startLabel, HAN
  *  after each call.
  *  Doesn't include any potentially delimiting double quotes
  */
+
 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')))
+    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') 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;
+        if (*p == '\0') {
+            param[0] = '\0';
             return param;
         }
-        if (quotesDelimited && *p == '"') p++;
-        curParamNb++;
+        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 275c701..695493b 100644
--- 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