[PATCH 8/8] [cmd] Add for /f delims= support

Ann and Jason Edmeades jason at edmeades.me.uk
Tue Oct 23 16:48:32 CDT 2012


Support providing a set of delimiters when splitting apart a string
used in the for /f processing.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.winehq.org/pipermail/wine-patches/attachments/20121023/c03deb09/attachment.html>
-------------- next part --------------
From 91af0836ef9b92adba07b322367c1489be073c55 Mon Sep 17 00:00:00 2001
From: Jason Edmeades <jason at edmeades.me.uk>
Date: Tue, 23 Oct 2012 22:05:06 +0100
Subject: [PATCH 8/8] [cmd] Add for /f delims= support

Support providing a set of delimiters when splitting apart a string
used in the for /f processing.
---
 programs/cmd/batch.c                     |   29 ++++++++++++++++++++++-------
 programs/cmd/builtins.c                  |   13 +++++++------
 programs/cmd/tests/test_builtins.cmd.exp |   12 ++++++------
 programs/cmd/wcmd.h                      |    2 ++
 4 files changed, 37 insertions(+), 19 deletions(-)

diff --git a/programs/cmd/batch.c b/programs/cmd/batch.c
index 1c0bc24..7b037d7 100644
--- a/programs/cmd/batch.c
+++ b/programs/cmd/batch.c
@@ -121,9 +121,10 @@ void WCMD_batch (WCHAR *file, WCHAR *command, BOOL called, WCHAR *startLabel, HA
 }
 
 /*******************************************************************
- * WCMD_parameter
+ * WCMD_parameter_with_delims
  *
- * Extracts a delimited parameter from an input string
+ * Extracts a delimited parameter from an input string, providing
+ * the delimiters characters to use
  *
  * PARAMS
  *  s     [I] input string, non NULL
@@ -135,6 +136,7 @@ void WCMD_batch (WCHAR *file, WCHAR *command, BOOL called, WCHAR *startLabel, HA
  *  wholecmdline [I] True to indicate this routine is being used to parse the
  *                   command line, and special logic for arg0->1 transition
  *                   needs to be applied.
+ *  delims[I] The delimiter characters to use
  *
  * RETURNS
  *  Success: The nth delimited parameter found in s
@@ -150,10 +152,9 @@ void WCMD_batch (WCHAR *file, WCHAR *command, BOOL called, WCHAR *startLabel, HA
  *  other API calls, e.g. c:\"a b"\c is returned as c:\a b\c. However, some commands
  *  need to preserve the exact syntax (echo, for, etc) hence the raw option.
  */
-WCHAR *WCMD_parameter (WCHAR *s, int n, WCHAR **start, WCHAR **end, BOOL raw,
-                       BOOL wholecmdline)
+WCHAR *WCMD_parameter_with_delims (WCHAR *s, int n, WCHAR **start, WCHAR **end,
+                                   BOOL raw, BOOL wholecmdline, const WCHAR *delims)
 {
-    static const WCHAR defaultDelims[] = { ' ', '\t', ',', '=', ';', '\0' };
     int curParamNb = 0;
     static WCHAR param[MAX_PATH];
     WCHAR *p = s, *begin;
@@ -165,7 +166,7 @@ WCHAR *WCMD_parameter (WCHAR *s, int n, WCHAR **start, WCHAR **end, BOOL raw,
     while (TRUE) {
 
         /* Absorb repeated word delimiters until we get to the next token (or the end!) */
-        while (*p && (strchrW(defaultDelims, *p) != NULL))
+        while (*p && (strchrW(delims, *p) != NULL))
             p++;
         if (*p == '\0') return param;
 
@@ -179,7 +180,7 @@ WCHAR *WCMD_parameter (WCHAR *s, int n, WCHAR **start, WCHAR **end, BOOL raw,
         /* Loop character by character, but just need to special case quotes */
         while (*p) {
             /* Once we have found a delimiter, break */
-            if (strchrW(defaultDelims, *p) != NULL) break;
+            if (strchrW(delims, *p) != NULL) break;
 
             /* Very odd special case - Seems as if a ( acts as a delimiter which is
                not swallowed but is effective only when it comes between the program
@@ -218,6 +219,20 @@ WCHAR *WCMD_parameter (WCHAR *s, int n, WCHAR **start, WCHAR **end, BOOL raw,
     }
 }
 
+/*******************************************************************
+ * WCMD_parameter
+ *
+ * Extracts a delimited parameter from an input string, using a
+ * default set of delimiter characters. For parameters, see the main
+ * function above.
+ */
+WCHAR *WCMD_parameter (WCHAR *s, int n, WCHAR **start, WCHAR **end, BOOL raw,
+                       BOOL wholecmdline)
+{
+  static const WCHAR defaultDelims[] = { ' ', '\t', ',', '=', ';', '\0' };
+  return WCMD_parameter_with_delims (s, n, start, end, raw, wholecmdline, defaultDelims);
+}
+
 /****************************************************************************
  * WCMD_fgets
  *
diff --git a/programs/cmd/builtins.c b/programs/cmd/builtins.c
index 4bb4702..8eaa9e7 100644
--- a/programs/cmd/builtins.c
+++ b/programs/cmd/builtins.c
@@ -1600,7 +1600,7 @@ static BOOL WCMD_parse_forf_options(WCHAR *options, WCHAR *eol, int *skip,
       }
       if (*pos==' ' && *(pos+1)==0) delims[i++] = *pos;
       delims[i++] = 0; /* Null terminate the delims */
-      WINE_FIXME("Found delims as '%s'\n", wine_dbgstr_w(delims));
+      WINE_TRACE("Found delims as '%s'\n", wine_dbgstr_w(delims));
 
     /* Save the tokens being requested */
     } else if (CompareStringW(LOCALE_USER_DEFAULT, NORM_IGNORECASE | SORT_STRINGSORT,
@@ -1694,6 +1694,7 @@ static void WCMD_add_dirstowalk(DIRECTORY_STACK *dirsToWalk) {
  *  doExecuted   [O]    - Set to TRUE if the DO is ever executed once
  *  forf_skip    [I/O]  - How many lines to skip first
  *  forf_eol     [I]    - The 'end of line' (comment) character
+ *  forf_delims  [I]    - The delimiters to use when breaking the string apart
  */
 static void WCMD_parse_line(CMD_LIST    *cmdStart,
                             const WCHAR *firstCmd,
@@ -1702,7 +1703,8 @@ static void WCMD_parse_line(CMD_LIST    *cmdStart,
                             WCHAR       *buffer,
                             BOOL        *doExecuted,
                             int         *forf_skip,
-                            WCHAR        forf_eol) {
+                            WCHAR        forf_eol,
+                            WCHAR       *forf_delims) {
 
   WCHAR *parm, *where;
 
@@ -1713,7 +1715,7 @@ static void WCMD_parse_line(CMD_LIST    *cmdStart,
   }
 
   /* Extract the parameter */
-  parm = WCMD_parameter (buffer, 0, &where, NULL, FALSE, FALSE);
+  parm = WCMD_parameter_with_delims(buffer, 0, &where, NULL, FALSE, FALSE, forf_delims);
   WINE_TRACE("Parsed parameter: %s from %s\n", wine_dbgstr_w(parm),
              wine_dbgstr_w(buffer));
 
@@ -2070,7 +2072,7 @@ void WCMD_for (WCHAR *p, CMD_LIST **cmdList) {
               /* Read line by line until end of file */
               while (WCMD_fgets(buffer, sizeof(buffer)/sizeof(WCHAR), input)) {
                 WCMD_parse_line(cmdStart, firstCmd, &cmdEnd, variable, buffer, &doExecuted,
-                                &forf_skip, forf_eol);
+                                &forf_skip, forf_eol, forf_delims);
                 buffer[0] = 0;
               }
               CloseHandle (input);
@@ -2090,7 +2092,6 @@ void WCMD_for (WCHAR *p, CMD_LIST **cmdList) {
              Note that the last quote is removed from the set and the string terminates
              there to mimic windows                                                        */
           WCHAR *strend = strrchrW(itemStart, forf_usebackq?'\'':'"');
-
           if (strend) {
             *strend = 0x00;
             itemStart++;
@@ -2099,7 +2100,7 @@ void WCMD_for (WCHAR *p, CMD_LIST **cmdList) {
           /* Copy the item away from the global buffer used by WCMD_parameter */
           strcpyW(buffer, itemStart);
           WCMD_parse_line(cmdStart, firstCmd, &cmdEnd, variable, buffer, &doExecuted,
-                            &forf_skip, forf_eol);
+                            &forf_skip, forf_eol, forf_delims);
 
           /* Only one string can be supplied in the whole set, abort future set processing */
           thisSet = NULL;
diff --git a/programs/cmd/tests/test_builtins.cmd.exp b/programs/cmd/tests/test_builtins.cmd.exp
index c15a58d..9b5eb3b 100644
--- a/programs/cmd/tests/test_builtins.cmd.exp
+++ b/programs/cmd/tests/test_builtins.cmd.exp
@@ -826,14 +826,14 @@ ad
 z at y
 a|d
 no output
- at todo_wine@no output
+no output
 ------ delims option
- at todo_wine@a
- at todo_wine@a at space@
- at todo_wine@a d
 a
- at todo_wine@C r
- at todo_wine@foo bar baz
+a at space@
+a d
+a
+C r
+foo bar baz
 @todo_wine at c:\
 ------ skip option
 c
diff --git a/programs/cmd/wcmd.h b/programs/cmd/wcmd.h
index d4d148f..26b89c6 100644
--- a/programs/cmd/wcmd.h
+++ b/programs/cmd/wcmd.h
@@ -108,6 +108,8 @@ static inline BOOL WCMD_is_console_handle(HANDLE h)
 }
 WCHAR *WCMD_fgets (WCHAR *buf, DWORD n, HANDLE stream);
 WCHAR *WCMD_parameter (WCHAR *s, int n, WCHAR **start, WCHAR **end, BOOL raw, BOOL wholecmdline);
+WCHAR *WCMD_parameter_with_delims (WCHAR *s, int n, WCHAR **start, WCHAR **end, BOOL raw,
+                                   BOOL wholecmdline, const WCHAR *delims);
 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);
-- 
1.7.9.5


More information about the wine-patches mailing list