[2/8] cmd: Fix FOR tab handling
Frédéric Delanoy
frederic.delanoy at gmail.com
Tue Aug 23 15:54:50 CDT 2011
---
programs/cmd/builtins.c | 30 ++++++++++++++++++------------
programs/cmd/tests/test_builtins.cmd | 1 +
programs/cmd/tests/test_builtins.cmd.exp | 11 +++++++----
programs/cmd/wcmdmain.c | 24 +++++++++++++++++-------
4 files changed, 43 insertions(+), 23 deletions(-)
diff --git a/programs/cmd/builtins.c b/programs/cmd/builtins.c
index c4ad231..7aaa900 100644
--- a/programs/cmd/builtins.c
+++ b/programs/cmd/builtins.c
@@ -902,8 +902,10 @@ void WCMD_for (WCHAR *p, CMD_LIST **cmdList) {
WIN32_FIND_DATAW fd;
HANDLE hff;
int i;
- const WCHAR inW[] = {'i', 'n', ' ', '\0'};
- const WCHAR doW[] = {'d', 'o', ' ', '\0'};
+ const WCHAR inW[] = {'i', 'n', ' ', '\0'};
+ const WCHAR inTabW[] = {'i', 'n', '\t', '\0'};
+ const WCHAR doW[] = {'d', 'o', ' ', '\0'};
+ const WCHAR doTabW[] = {'d', 'o', '\t', '\0'};
CMD_LIST *setStart, *thisSet, *cmdStart, *cmdEnd;
WCHAR variable[4];
WCHAR *firstCmd;
@@ -938,7 +940,7 @@ void WCMD_for (WCHAR *p, CMD_LIST **cmdList) {
/* Skip whitespace */
curPos++;
- while (*curPos && *curPos==' ') curPos++;
+ while (*curPos && (*curPos==' ' || *curPos=='\t')) curPos++;
/* Next parm is either qualifier, path/options or variable -
only care about it if it is the path/options */
@@ -954,11 +956,11 @@ void WCMD_for (WCHAR *p, CMD_LIST **cmdList) {
}
/* Skip whitespace between qualifiers */
- while (*curPos && *curPos==' ') curPos++;
+ while (*curPos && (*curPos==' ' || *curPos=='\t')) curPos++;
}
/* Skip whitespace before variable */
- while (*curPos && *curPos==' ') curPos++;
+ while (*curPos && (*curPos==' ' || *curPos=='\t')) curPos++;
/* Ensure line continues with variable */
if (!*curPos || *curPos != '%') {
@@ -968,19 +970,21 @@ void WCMD_for (WCHAR *p, CMD_LIST **cmdList) {
/* Variable should follow */
i = 0;
- while (curPos[i] && curPos[i]!=' ') i++;
+ while (curPos[i] && curPos[i]!=' ' && curPos[i]!='\t') i++;
memcpy(&variable[0], curPos, i*sizeof(WCHAR));
variable[i] = 0x00;
WINE_TRACE("Variable identified as %s\n", wine_dbgstr_w(variable));
curPos = &curPos[i];
/* Skip whitespace before IN */
- while (*curPos && *curPos==' ') curPos++;
+ while (*curPos && (*curPos==' ' || *curPos=='\t')) curPos++;
/* Ensure line continues with IN */
if (!*curPos
- || CompareStringW(LOCALE_USER_DEFAULT, NORM_IGNORECASE | SORT_STRINGSORT,
- curPos, 3, inW, -1) != CSTR_EQUAL) {
+ || (CompareStringW(LOCALE_USER_DEFAULT, NORM_IGNORECASE | SORT_STRINGSORT,
+ curPos, 3, inW, -1) != CSTR_EQUAL
+ && CompareStringW(LOCALE_USER_DEFAULT, NORM_IGNORECASE | SORT_STRINGSORT,
+ curPos, 3, inTabW, -1) != CSTR_EQUAL)) {
WCMD_output (WCMD_LoadMessage(WCMD_SYNTAXERR));
return;
}
@@ -1005,9 +1009,11 @@ void WCMD_for (WCHAR *p, CMD_LIST **cmdList) {
/* Syntax error if missing close bracket, or nothing following it
and once we have the complete set, we expect a DO */
WINE_TRACE("Looking for 'do' in %p\n", *cmdList);
- if ((*cmdList == NULL) ||
- (CompareStringW(LOCALE_USER_DEFAULT, NORM_IGNORECASE | SORT_STRINGSORT,
- (*cmdList)->command, 3, doW, -1) != CSTR_EQUAL)) {
+ if ((*cmdList == NULL)
+ || (CompareStringW(LOCALE_USER_DEFAULT, NORM_IGNORECASE | SORT_STRINGSORT,
+ (*cmdList)->command, 3, doW, -1) != CSTR_EQUAL
+ && CompareStringW(LOCALE_USER_DEFAULT, NORM_IGNORECASE | SORT_STRINGSORT,
+ (*cmdList)->command, 3, doTabW, -1) != CSTR_EQUAL)) {
WCMD_output (WCMD_LoadMessage(WCMD_SYNTAXERR));
return;
}
diff --git a/programs/cmd/tests/test_builtins.cmd b/programs/cmd/tests/test_builtins.cmd
index b815e77..0d2f983 100644
--- a/programs/cmd/tests/test_builtins.cmd
+++ b/programs/cmd/tests/test_builtins.cmd
@@ -386,6 +386,7 @@ for %%i in at tab@(X3) do echo %%i
for %%i in (@tab@ foo at tab@) do echo %%i
for at tab@ %%i in at tab@(@tab at M) do echo %%i
for %%i at tab@in (X)@tab at do@tab at echo %%i
+for at tab@ %%j in at tab@(@tab at M, N, O at tab@) do echo %%j
goto :endForTestFun1
:forTestFun1
echo %1
diff --git a/programs/cmd/tests/test_builtins.cmd.exp b/programs/cmd/tests/test_builtins.cmd.exp
index b86c012..1138485 100644
--- a/programs/cmd/tests/test_builtins.cmd.exp
+++ b/programs/cmd/tests/test_builtins.cmd.exp
@@ -275,11 +275,14 @@ A
B
C
X
- at todo_wine@X2
- at todo_wine@X3
+X2
+X3
foo
- at todo_wine@M
- at todo_wine@X
+M
+X
+M
+N
+O
...imbricated FORs
@todo_wine at X Y
@todo_wine at X Y
diff --git a/programs/cmd/wcmdmain.c b/programs/cmd/wcmdmain.c
index d758857..67b6ef4 100644
--- a/programs/cmd/wcmdmain.c
+++ b/programs/cmd/wcmdmain.c
@@ -1742,7 +1742,8 @@ WCHAR *WCMD_ReadAndParseLine(const WCHAR *optionalcmd, CMD_LIST **output, HANDLE
CMD_DELIMITERS prevDelim = CMD_NONE;
static WCHAR *extraSpace = NULL; /* Deliberately never freed */
const WCHAR remCmd[] = {'r','e','m',' ','\0'};
- const WCHAR forCmd[] = {'f','o','r',' ','\0'};
+ const WCHAR forCmd[] = {'f','o','r',' ' ,'\0'};
+ const WCHAR forTabCmd[] = {'f','o','r','\t','\0'};
const WCHAR ifCmd[] = {'i','f',' ','\0'};
const WCHAR ifElse[] = {'e','l','s','e',' ','\0'};
BOOL inRem = FALSE;
@@ -1826,7 +1827,8 @@ WCHAR *WCMD_ReadAndParseLine(const WCHAR *optionalcmd, CMD_LIST **output, HANDLE
/* Certain commands need special handling */
if (curStringLen == 0 && curCopyTo == curString) {
- const WCHAR forDO[] = {'d','o',' ','\0'};
+ const WCHAR forDO[] = {'d','o',' ' ,'\0'};
+ const WCHAR forDOTab[] = {'d','o','\t','\0'};
/* If command starts with 'rem', ignore any &&, ( etc */
if (CompareStringW(LOCALE_USER_DEFAULT, NORM_IGNORECASE | SORT_STRINGSORT,
@@ -1835,7 +1837,9 @@ WCHAR *WCMD_ReadAndParseLine(const WCHAR *optionalcmd, CMD_LIST **output, HANDLE
/* If command starts with 'for', handle ('s mid line after IN or DO */
} else if (CompareStringW(LOCALE_USER_DEFAULT, NORM_IGNORECASE | SORT_STRINGSORT,
- curPos, 4, forCmd, -1) == CSTR_EQUAL) {
+ curPos, 4, forCmd, -1) == CSTR_EQUAL
+ || CompareStringW(LOCALE_USER_DEFAULT, NORM_IGNORECASE | SORT_STRINGSORT,
+ curPos, 4, forTabCmd, -1) == CSTR_EQUAL) {
inFor = TRUE;
/* If command starts with 'if' or 'else', handle ('s mid line. We should ensure this
@@ -1863,7 +1867,9 @@ WCHAR *WCMD_ReadAndParseLine(const WCHAR *optionalcmd, CMD_LIST **output, HANDLE
is then 0, and all whitespace is skipped */
} else if (inFor &&
(CompareStringW(LOCALE_USER_DEFAULT, NORM_IGNORECASE | SORT_STRINGSORT,
- curPos, 3, forDO, -1) == CSTR_EQUAL)) {
+ curPos, 3, forDO, -1) == CSTR_EQUAL
+ || CompareStringW(LOCALE_USER_DEFAULT, NORM_IGNORECASE | SORT_STRINGSORT,
+ curPos, 3, forDOTab, -1) == CSTR_EQUAL)) {
WINE_TRACE("Found DO\n");
lastWasDo = TRUE;
onlyWhiteSpace = TRUE;
@@ -1876,12 +1882,15 @@ WCHAR *WCMD_ReadAndParseLine(const WCHAR *optionalcmd, CMD_LIST **output, HANDLE
/* Special handling for the 'FOR' command */
if (inFor && lastWasWhiteSpace) {
- const WCHAR forIN[] = {'i','n',' ','\0'};
+ const WCHAR forIN[] = {'i','n',' ' ,'\0'};
+ const WCHAR forINTab[] = {'i','n','\t','\0'};
WINE_TRACE("Found 'FOR', comparing next parm: '%s'\n", wine_dbgstr_w(curPos));
if (CompareStringW(LOCALE_USER_DEFAULT, NORM_IGNORECASE | SORT_STRINGSORT,
- curPos, 3, forIN, -1) == CSTR_EQUAL) {
+ curPos, 3, forIN, -1) == CSTR_EQUAL
+ || CompareStringW(LOCALE_USER_DEFAULT, NORM_IGNORECASE | SORT_STRINGSORT,
+ curPos, 3, forINTab, -1) == CSTR_EQUAL) {
WINE_TRACE("Found IN\n");
lastWasIn = TRUE;
onlyWhiteSpace = TRUE;
@@ -2106,7 +2115,8 @@ WCHAR *WCMD_ReadAndParseLine(const WCHAR *optionalcmd, CMD_LIST **output, HANDLE
/* At various times we need to know if we have only skipped whitespace,
so reset this variable and then it will remain true until a non
whitespace is found */
- if ((thisChar != ' ') && (thisChar != '\n')) onlyWhiteSpace = FALSE;
+ if ((thisChar != ' ') && (thisChar != '\t') && (thisChar != '\n'))
+ onlyWhiteSpace = FALSE;
/* Flag end of interest in FOR DO and IN parms once something has been processed */
if (!lastWasWhiteSpace) {
--
1.7.6
More information about the wine-patches
mailing list