cmd: Fix FOR tab handling.
This commit is contained in:
parent
6572de3cfa
commit
20fa3fe802
|
@ -902,8 +902,10 @@ void WCMD_for (WCHAR *p, CMD_LIST **cmdList) {
|
||||||
WIN32_FIND_DATAW fd;
|
WIN32_FIND_DATAW fd;
|
||||||
HANDLE hff;
|
HANDLE hff;
|
||||||
int i;
|
int i;
|
||||||
const WCHAR inW[] = {'i', 'n', ' ', '\0'};
|
const WCHAR inW[] = {'i', 'n', ' ', '\0'};
|
||||||
const WCHAR doW[] = {'d', 'o', ' ', '\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;
|
CMD_LIST *setStart, *thisSet, *cmdStart, *cmdEnd;
|
||||||
WCHAR variable[4];
|
WCHAR variable[4];
|
||||||
WCHAR *firstCmd;
|
WCHAR *firstCmd;
|
||||||
|
@ -938,7 +940,7 @@ void WCMD_for (WCHAR *p, CMD_LIST **cmdList) {
|
||||||
|
|
||||||
/* Skip whitespace */
|
/* Skip whitespace */
|
||||||
curPos++;
|
curPos++;
|
||||||
while (*curPos && *curPos==' ') curPos++;
|
while (*curPos && (*curPos==' ' || *curPos=='\t')) curPos++;
|
||||||
|
|
||||||
/* Next parm is either qualifier, path/options or variable -
|
/* Next parm is either qualifier, path/options or variable -
|
||||||
only care about it if it is the path/options */
|
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 */
|
/* Skip whitespace between qualifiers */
|
||||||
while (*curPos && *curPos==' ') curPos++;
|
while (*curPos && (*curPos==' ' || *curPos=='\t')) curPos++;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Skip whitespace before variable */
|
/* Skip whitespace before variable */
|
||||||
while (*curPos && *curPos==' ') curPos++;
|
while (*curPos && (*curPos==' ' || *curPos=='\t')) curPos++;
|
||||||
|
|
||||||
/* Ensure line continues with variable */
|
/* Ensure line continues with variable */
|
||||||
if (!*curPos || *curPos != '%') {
|
if (!*curPos || *curPos != '%') {
|
||||||
|
@ -968,19 +970,21 @@ void WCMD_for (WCHAR *p, CMD_LIST **cmdList) {
|
||||||
|
|
||||||
/* Variable should follow */
|
/* Variable should follow */
|
||||||
i = 0;
|
i = 0;
|
||||||
while (curPos[i] && curPos[i]!=' ') i++;
|
while (curPos[i] && curPos[i]!=' ' && curPos[i]!='\t') i++;
|
||||||
memcpy(&variable[0], curPos, i*sizeof(WCHAR));
|
memcpy(&variable[0], curPos, i*sizeof(WCHAR));
|
||||||
variable[i] = 0x00;
|
variable[i] = 0x00;
|
||||||
WINE_TRACE("Variable identified as %s\n", wine_dbgstr_w(variable));
|
WINE_TRACE("Variable identified as %s\n", wine_dbgstr_w(variable));
|
||||||
curPos = &curPos[i];
|
curPos = &curPos[i];
|
||||||
|
|
||||||
/* Skip whitespace before IN */
|
/* Skip whitespace before IN */
|
||||||
while (*curPos && *curPos==' ') curPos++;
|
while (*curPos && (*curPos==' ' || *curPos=='\t')) curPos++;
|
||||||
|
|
||||||
/* Ensure line continues with IN */
|
/* Ensure line continues with IN */
|
||||||
if (!*curPos
|
if (!*curPos
|
||||||
|| CompareStringW(LOCALE_USER_DEFAULT, NORM_IGNORECASE | SORT_STRINGSORT,
|
|| (CompareStringW(LOCALE_USER_DEFAULT, NORM_IGNORECASE | SORT_STRINGSORT,
|
||||||
curPos, 3, inW, -1) != CSTR_EQUAL) {
|
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));
|
WCMD_output (WCMD_LoadMessage(WCMD_SYNTAXERR));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1005,9 +1009,11 @@ void WCMD_for (WCHAR *p, CMD_LIST **cmdList) {
|
||||||
/* Syntax error if missing close bracket, or nothing following it
|
/* Syntax error if missing close bracket, or nothing following it
|
||||||
and once we have the complete set, we expect a DO */
|
and once we have the complete set, we expect a DO */
|
||||||
WINE_TRACE("Looking for 'do' in %p\n", *cmdList);
|
WINE_TRACE("Looking for 'do' in %p\n", *cmdList);
|
||||||
if ((*cmdList == NULL) ||
|
if ((*cmdList == NULL)
|
||||||
(CompareStringW(LOCALE_USER_DEFAULT, NORM_IGNORECASE | SORT_STRINGSORT,
|
|| (CompareStringW(LOCALE_USER_DEFAULT, NORM_IGNORECASE | SORT_STRINGSORT,
|
||||||
(*cmdList)->command, 3, doW, -1) != CSTR_EQUAL)) {
|
(*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));
|
WCMD_output (WCMD_LoadMessage(WCMD_SYNTAXERR));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -386,6 +386,7 @@ for %%i in@tab@(X3) do echo %%i
|
||||||
for %%i in (@tab@ foo@tab@) do echo %%i
|
for %%i in (@tab@ foo@tab@) do echo %%i
|
||||||
for@tab@ %%i in@tab@(@tab@M) do echo %%i
|
for@tab@ %%i in@tab@(@tab@M) do echo %%i
|
||||||
for %%i@tab@in (X)@tab@do@tab@echo %%i
|
for %%i@tab@in (X)@tab@do@tab@echo %%i
|
||||||
|
for@tab@ %%j in@tab@(@tab@M, N, O@tab@) do echo %%j
|
||||||
goto :endForTestFun1
|
goto :endForTestFun1
|
||||||
:forTestFun1
|
:forTestFun1
|
||||||
echo %1
|
echo %1
|
||||||
|
|
|
@ -275,11 +275,14 @@ A
|
||||||
B
|
B
|
||||||
C
|
C
|
||||||
X
|
X
|
||||||
@todo_wine@X2
|
X2
|
||||||
@todo_wine@X3
|
X3
|
||||||
foo
|
foo
|
||||||
@todo_wine@M
|
M
|
||||||
@todo_wine@X
|
X
|
||||||
|
M
|
||||||
|
N
|
||||||
|
O
|
||||||
...imbricated FORs
|
...imbricated FORs
|
||||||
@todo_wine@X Y
|
@todo_wine@X Y
|
||||||
@todo_wine@X Y
|
@todo_wine@X Y
|
||||||
|
|
|
@ -1742,7 +1742,8 @@ WCHAR *WCMD_ReadAndParseLine(const WCHAR *optionalcmd, CMD_LIST **output, HANDLE
|
||||||
CMD_DELIMITERS prevDelim = CMD_NONE;
|
CMD_DELIMITERS prevDelim = CMD_NONE;
|
||||||
static WCHAR *extraSpace = NULL; /* Deliberately never freed */
|
static WCHAR *extraSpace = NULL; /* Deliberately never freed */
|
||||||
const WCHAR remCmd[] = {'r','e','m',' ','\0'};
|
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 ifCmd[] = {'i','f',' ','\0'};
|
||||||
const WCHAR ifElse[] = {'e','l','s','e',' ','\0'};
|
const WCHAR ifElse[] = {'e','l','s','e',' ','\0'};
|
||||||
BOOL inRem = FALSE;
|
BOOL inRem = FALSE;
|
||||||
|
@ -1826,7 +1827,8 @@ WCHAR *WCMD_ReadAndParseLine(const WCHAR *optionalcmd, CMD_LIST **output, HANDLE
|
||||||
|
|
||||||
/* Certain commands need special handling */
|
/* Certain commands need special handling */
|
||||||
if (curStringLen == 0 && curCopyTo == curString) {
|
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 command starts with 'rem', ignore any &&, ( etc */
|
||||||
if (CompareStringW(LOCALE_USER_DEFAULT, NORM_IGNORECASE | SORT_STRINGSORT,
|
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 */
|
/* If command starts with 'for', handle ('s mid line after IN or DO */
|
||||||
} else if (CompareStringW(LOCALE_USER_DEFAULT, NORM_IGNORECASE | SORT_STRINGSORT,
|
} 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;
|
inFor = TRUE;
|
||||||
|
|
||||||
/* If command starts with 'if' or 'else', handle ('s mid line. We should ensure this
|
/* 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 */
|
is then 0, and all whitespace is skipped */
|
||||||
} else if (inFor &&
|
} else if (inFor &&
|
||||||
(CompareStringW(LOCALE_USER_DEFAULT, NORM_IGNORECASE | SORT_STRINGSORT,
|
(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");
|
WINE_TRACE("Found DO\n");
|
||||||
lastWasDo = TRUE;
|
lastWasDo = TRUE;
|
||||||
onlyWhiteSpace = TRUE;
|
onlyWhiteSpace = TRUE;
|
||||||
|
@ -1876,12 +1882,15 @@ WCHAR *WCMD_ReadAndParseLine(const WCHAR *optionalcmd, CMD_LIST **output, HANDLE
|
||||||
|
|
||||||
/* Special handling for the 'FOR' command */
|
/* Special handling for the 'FOR' command */
|
||||||
if (inFor && lastWasWhiteSpace) {
|
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));
|
WINE_TRACE("Found 'FOR', comparing next parm: '%s'\n", wine_dbgstr_w(curPos));
|
||||||
|
|
||||||
if (CompareStringW(LOCALE_USER_DEFAULT, NORM_IGNORECASE | SORT_STRINGSORT,
|
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");
|
WINE_TRACE("Found IN\n");
|
||||||
lastWasIn = TRUE;
|
lastWasIn = TRUE;
|
||||||
onlyWhiteSpace = 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,
|
/* 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
|
so reset this variable and then it will remain true until a non
|
||||||
whitespace is found */
|
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 */
|
/* Flag end of interest in FOR DO and IN parms once something has been processed */
|
||||||
if (!lastWasWhiteSpace) {
|
if (!lastWasWhiteSpace) {
|
||||||
|
|
Loading…
Reference in New Issue