[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