[4/5] cmd: Add an output parameter to WCMD_parameter to point to the end of the extracted param, if requested

Frédéric Delanoy frederic.delanoy at gmail.com
Tue Sep 6 12:19:43 CDT 2011


Necessary mainly for double quoted string parameters, as they are stripped in
the return value.
Such params need to be preserved for certain commands, notably when comparing
strings with IF '==' operator.
---
 programs/cmd/batch.c     |   18 ++++++++++++------
 programs/cmd/builtins.c  |   34 +++++++++++++++++-----------------
 programs/cmd/directory.c |    2 +-
 programs/cmd/wcmd.h      |    2 +-
 programs/cmd/wcmdmain.c  |   10 +++++-----
 5 files changed, 36 insertions(+), 30 deletions(-)

diff --git a/programs/cmd/batch.c b/programs/cmd/batch.c
index 53330ff..9b29bb3 100644
--- a/programs/cmd/batch.c
+++ b/programs/cmd/batch.c
@@ -123,6 +123,8 @@ void WCMD_batch (WCHAR *file, WCHAR *command, int called, WCHAR *startLabel, HAN
  *            Starts at 0
  *  where [O] if non NULL, pointer to the start of the nth parameter in s,
  *            potentially a " character
+ *  end   [O] if non NULL, and 'where' non NULL, pointer to the last char of
+ *            the nth parameter in s, potentially a " character
  *
  * RETURNS
  *  Success: Returns the nth delimited parameter found in s.
@@ -136,14 +138,16 @@ 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 *WCMD_parameter (WCHAR *s, int n, WCHAR **where, WCHAR **end) {
     int curParamNb = 0;
     static WCHAR param[MAX_PATH];
     WCHAR *p = s, *q;
     BOOL quotesDelimited;
+    BOOL setWhere = (where != NULL);
+    BOOL setEnd   = setWhere && (end != NULL);
 
-    if (where != NULL) *where = NULL;
+    if (setWhere) *where = NULL;
+    if (setEnd)   *end   = NULL;
     param[0] = '\0';
     while (TRUE) {
         while (*p && ((*p == ' ') || (*p == ',') || (*p == '=') || (*p == '\t')))
@@ -151,7 +155,7 @@ WCHAR *WCMD_parameter (WCHAR *s, int n, WCHAR **where) {
         if (*p == '\0') return param;
 
         quotesDelimited = (*p == '"');
-        if (where != NULL && curParamNb == n) *where = p;
+        if (setWhere && curParamNb == n) *where = p;
 
         if (quotesDelimited) {
             q = ++p;
@@ -164,6 +168,7 @@ WCHAR *WCMD_parameter (WCHAR *s, int n, WCHAR **where) {
         if (curParamNb == n) {
             memcpy(param, q, (p - q) * sizeof(WCHAR));
             param[p-q] = '\0';
+            if (setEnd) *end = p - 1 + quotesDelimited;
             return param;
         }
         if (quotesDelimited && *p == '"') p++;
@@ -360,8 +365,9 @@ void WCMD_HandleTildaModifiers(WCHAR **start, const WCHAR *forVariable,
   if (*lastModifier == '0') {
     strcpyW(outputparam, context->batchfileW);
   } else if ((*lastModifier >= '1' && *lastModifier <= '9')) {
-    strcpyW(outputparam, WCMD_parameter (context -> command,
-                 *lastModifier-'0' + context -> shift_count[*lastModifier-'0'], NULL));
+    strcpyW(outputparam,
+            WCMD_parameter (context -> command, *lastModifier-'0' + context -> shift_count[*lastModifier-'0'],
+                            NULL, NULL));
   } else {
     strcpyW(outputparam, forValue);
   }
diff --git a/programs/cmd/builtins.c b/programs/cmd/builtins.c
index 25503bd..c7814f9 100644
--- a/programs/cmd/builtins.c
+++ b/programs/cmd/builtins.c
@@ -526,7 +526,7 @@ void WCMD_create_dir (WCHAR *command) {
     }
     /* Loop through all args */
     while (TRUE) {
-        WCHAR *thisArg = WCMD_parameter(command, argno++, &argN);
+        WCHAR *thisArg = WCMD_parameter(command, argno++, &argN, NULL);
         if (!argN) break;
         if (!create_full_path(thisArg)) {
             WCMD_print_error ();
@@ -830,7 +830,7 @@ BOOL WCMD_delete (WCHAR *command) {
         WCHAR *thisArg;
 
         argN = NULL;
-        thisArg = WCMD_parameter (command, argno, &argN);
+        thisArg = WCMD_parameter (command, argno, &argN, NULL);
         if (!argN)
             break;       /* no more parameters */
         if (argN[0] == '/')
@@ -1037,7 +1037,7 @@ void WCMD_for (WCHAR *p, CMD_LIST **cmdList) {
 
     WINE_TRACE("Processing for set %p\n", thisSet);
     i = 0;
-    while (*(item = WCMD_parameter (thisSet->command, i, &itemStart))) {
+    while (*(item = WCMD_parameter (thisSet->command, i, &itemStart, NULL))) {
 
       /*
        * If the parameter within the set has a wildcard then search for matching files
@@ -1134,7 +1134,7 @@ void WCMD_for (WCHAR *p, CMD_LIST **cmdList) {
             while (WCMD_fgets (buffer, sizeof(buffer)/sizeof(WCHAR), input)) {
 
               /* Skip blank lines*/
-              parm = WCMD_parameter (buffer, 0, &where);
+              parm = WCMD_parameter (buffer, 0, &where, NULL);
               WINE_TRACE("Parsed parameter: %s from %s\n", wine_dbgstr_w(parm),
                          wine_dbgstr_w(buffer));
 
@@ -1164,7 +1164,7 @@ void WCMD_for (WCHAR *p, CMD_LIST **cmdList) {
 
           /* Skip blank lines, and re-extract parameter now string has quotes removed */
           strcpyW(buffer, item);
-          parm = WCMD_parameter (buffer, 0, &where);
+          parm = WCMD_parameter (buffer, 0, &where, NULL);
           WINE_TRACE("Parsed parameter: %s from %s\n", wine_dbgstr_w(parm),
                        wine_dbgstr_w(buffer));
 
@@ -1496,22 +1496,22 @@ void WCMD_if (WCHAR *p, CMD_LIST **cmdList) {
   WINE_TRACE("Condition: %s\n", wine_dbgstr_w(condition));
 
   if (!lstrcmpiW (condition, errlvlW)) {
-    test = (errorlevel >= atoiW(WCMD_parameter(p, 1+negate, NULL)));
-    WCMD_parameter (p, 2+negate, &command);
+    test = (errorlevel >= atoiW(WCMD_parameter(p, 1+negate, NULL, NULL)));
+    WCMD_parameter(p, 2+negate, &command, NULL);
   }
   else if (!lstrcmpiW (condition, existW)) {
-    test = (GetFileAttributesW(WCMD_parameter(p, 1+negate, NULL)) != INVALID_FILE_ATTRIBUTES);
-    WCMD_parameter (p, 2+negate, &command);
+    test = (GetFileAttributesW(WCMD_parameter(p, 1+negate, NULL, NULL)) != INVALID_FILE_ATTRIBUTES);
+    WCMD_parameter(p, 2+negate, &command, NULL);
   }
   else if (!lstrcmpiW (condition, defdW)) {
-    test = (GetEnvironmentVariableW(WCMD_parameter(p, 1+negate, NULL), NULL, 0) > 0);
-    WCMD_parameter (p, 2+negate, &command);
+    test = (GetEnvironmentVariableW(WCMD_parameter(p, 1+negate, NULL, NULL), NULL, 0) > 0);
+    WCMD_parameter(p, 2+negate, &command, NULL);
   }
   else if ((s = strstrW (p, eqeqW))) {
     s += 2;
-    test = caseInsensitive ? (!lstrcmpiW(condition, WCMD_parameter(s, 0, NULL)))
-                           : (!lstrcmpW (condition, WCMD_parameter(s, 0, NULL)));
-    WCMD_parameter (s, 1, &command);
+    test = caseInsensitive ? (!lstrcmpiW(condition, WCMD_parameter(s, 0, NULL, NULL)))
+                           : (!lstrcmpW (condition, WCMD_parameter(s, 0, NULL, NULL)));
+    WCMD_parameter(s, 1, &command, NULL);
   }
   else {
     WCMD_output (WCMD_LoadMessage(WCMD_SYNTAXERR));
@@ -1691,7 +1691,7 @@ void WCMD_remove_dir (WCHAR *command) {
 
   /* Loop through all args */
   while (argN) {
-    WCHAR *thisArg = WCMD_parameter (command, argno++, &argN);
+    WCHAR *thisArg = WCMD_parameter (command, argno++, &argN, NULL);
     if (argN && argN[0] != '/') {
       WINE_TRACE("rd: Processing arg %s (quals:%s)\n", wine_dbgstr_w(thisArg),
                  wine_dbgstr_w(quals));
@@ -2428,7 +2428,7 @@ void WCMD_type (WCHAR *command) {
   /* Loop through all args */
   errorlevel = 0;
   while (argN) {
-    WCHAR *thisArg = WCMD_parameter (command, argno++, &argN);
+    WCHAR *thisArg = WCMD_parameter (command, argno++, &argN, NULL);
 
     HANDLE h;
     WCHAR buffer[512];
@@ -2522,7 +2522,7 @@ void WCMD_more (WCHAR *command) {
     WCMD_enter_paged_mode(moreStrPage);
 
     while (argN) {
-      WCHAR *thisArg = WCMD_parameter (command, argno++, &argN);
+      WCHAR *thisArg = WCMD_parameter (command, argno++, &argN, NULL);
       HANDLE h;
 
       if (!argN) break;
diff --git a/programs/cmd/directory.c b/programs/cmd/directory.c
index 217f31c..1863690 100644
--- a/programs/cmd/directory.c
+++ b/programs/cmd/directory.c
@@ -839,7 +839,7 @@ void WCMD_directory (WCHAR *cmd) {
   prevEntry = NULL;
   while (argN) {
     WCHAR fullname[MAXSTRING];
-    WCHAR *thisArg = WCMD_parameter (cmd, argno++, &argN);
+    WCHAR *thisArg = WCMD_parameter(cmd, argno++, &argN, NULL);
     if (argN && argN[0] != '/') {
 
       WINE_TRACE("Found parm '%s'\n", wine_dbgstr_w(thisArg));
diff --git a/programs/cmd/wcmd.h b/programs/cmd/wcmd.h
index c4ece13..4b48420 100644
--- a/programs/cmd/wcmd.h
+++ b/programs/cmd/wcmd.h
@@ -97,7 +97,7 @@ void WCMD_version (void);
 int  WCMD_volume (int mode, const WCHAR *command);
 
 WCHAR *WCMD_fgets (WCHAR *s, int n, HANDLE stream);
-WCHAR *WCMD_parameter (WCHAR *s, int n, WCHAR **where);
+WCHAR *WCMD_parameter (WCHAR *s, int n, WCHAR **where, WCHAR **end);
 WCHAR *WCMD_skip_leading_spaces (WCHAR *string);
 BOOL WCMD_keyword_ws_found(const WCHAR *keyword, int len, const WCHAR *ptr);
 void WCMD_HandleTildaModifiers(WCHAR **start, const WCHAR *forVariable, const WCHAR *forValue, BOOL justFors);
diff --git a/programs/cmd/wcmdmain.c b/programs/cmd/wcmdmain.c
index 4f1a2f3..4fbbbf6 100644
--- a/programs/cmd/wcmdmain.c
+++ b/programs/cmd/wcmdmain.c
@@ -833,13 +833,13 @@ static void handleExpansion(WCHAR *cmd, BOOL justFors,
 
     /* Replace use of %0...%9 if in batch program*/
     } else if (!justFors && context && (i >= 0) && (i <= 9)) {
-      t = WCMD_parameter (context -> command, i + context -> shift_count[i], NULL);
+      t = WCMD_parameter(context -> command, i + context -> shift_count[i], NULL, NULL);
       WCMD_strsubstW(p, p+2, t, -1);
 
     /* Replace use of %* if in batch program*/
     } else if (!justFors && context && *(p+1)=='*') {
       WCHAR *startOfParms = NULL;
-      t = WCMD_parameter (context -> command, 1, &startOfParms);
+      t = WCMD_parameter(context -> command, 1, &startOfParms, NULL);
       if (startOfParms != NULL)
         WCMD_strsubstW(p, p+2, startOfParms, -1);
       else
@@ -1357,8 +1357,8 @@ void WCMD_execute (const WCHAR *command, const WCHAR *redirects,
 
     /* Otherwise STDIN could come from a '<' redirect */
     } else if ((p = strchrW(new_redir,'<')) != NULL) {
-      h = CreateFileW(WCMD_parameter (++p, 0, NULL), GENERIC_READ, FILE_SHARE_READ, &sa, OPEN_EXISTING,
-		FILE_ATTRIBUTE_NORMAL, NULL);
+      h = CreateFileW(WCMD_parameter(++p, 0, NULL, NULL), GENERIC_READ, FILE_SHARE_READ,
+                      &sa, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
       if (h == INVALID_HANDLE_VALUE) {
 	WCMD_print_error ();
         HeapFree( GetProcessHeap(), 0, cmd );
@@ -1402,7 +1402,7 @@ void WCMD_execute (const WCHAR *command, const WCHAR *redirects,
         WINE_TRACE("Redirect %d (%p) to %d (%p)\n", handle, GetStdHandle(idx_stdhandles[idx]), idx, h);
 
       } else {
-        WCHAR *param = WCMD_parameter (p, 0, NULL);
+        WCHAR *param = WCMD_parameter(p, 0, NULL, NULL);
         h = CreateFileW(param, GENERIC_WRITE, 0, &sa, creationDisposition,
                         FILE_ATTRIBUTE_NORMAL, NULL);
         if (h == INVALID_HANDLE_VALUE) {
-- 
1.7.6




More information about the wine-patches mailing list