mirror of
git://source.winehq.org/git/wine.git
synced 2024-10-31 10:41:12 +00:00
cmd: Fix handling of redundant information on goto/labels.
This commit is contained in:
parent
f3eb64ec73
commit
dc4dd0cb97
4 changed files with 99 additions and 22 deletions
|
@ -2501,7 +2501,8 @@ void WCMD_give_help (const WCHAR *args)
|
||||||
void WCMD_goto (CMD_LIST **cmdList) {
|
void WCMD_goto (CMD_LIST **cmdList) {
|
||||||
|
|
||||||
WCHAR string[MAX_PATH];
|
WCHAR string[MAX_PATH];
|
||||||
WCHAR current[MAX_PATH];
|
WCHAR *labelend = NULL;
|
||||||
|
const WCHAR labelEndsW[] = {'>','<','|','&',' ',':','\t','\0'};
|
||||||
|
|
||||||
/* Do not process any more parts of a processed multipart or multilines command */
|
/* Do not process any more parts of a processed multipart or multilines command */
|
||||||
if (cmdList) *cmdList = NULL;
|
if (cmdList) *cmdList = NULL;
|
||||||
|
@ -2521,25 +2522,38 @@ void WCMD_goto (CMD_LIST **cmdList) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Support goto :label as well as goto label */
|
/* Support goto :label as well as goto label plus remove trailing chars */
|
||||||
if (*paramStart == ':') paramStart++;
|
if (*paramStart == ':') paramStart++;
|
||||||
|
labelend = strpbrkW(paramStart, labelEndsW);
|
||||||
|
if (labelend) *labelend = 0x00;
|
||||||
|
WINE_TRACE("goto label: '%s'\n", wine_dbgstr_w(paramStart));
|
||||||
|
|
||||||
SetFilePointer (context -> h, 0, NULL, FILE_BEGIN);
|
SetFilePointer (context -> h, 0, NULL, FILE_BEGIN);
|
||||||
while (WCMD_fgets (string, sizeof(string)/sizeof(WCHAR), context -> h)) {
|
while (*paramStart &&
|
||||||
|
WCMD_fgets (string, sizeof(string)/sizeof(WCHAR), context -> h)) {
|
||||||
str = string;
|
str = string;
|
||||||
while (isspaceW (*str)) str++;
|
|
||||||
if (*str == ':') {
|
|
||||||
DWORD index = 0;
|
|
||||||
str++;
|
|
||||||
while (((current[index] = str[index])) && (!isspaceW (current[index])))
|
|
||||||
index++;
|
|
||||||
|
|
||||||
/* ignore space at the end */
|
/* Ignore leading whitespace or no-echo character */
|
||||||
current[index] = 0;
|
while (*str=='@' || isspaceW (*str)) str++;
|
||||||
if (lstrcmpiW (current, paramStart) == 0) return;
|
|
||||||
|
/* If the first real character is a : then this is a label */
|
||||||
|
if (*str == ':') {
|
||||||
|
str++;
|
||||||
|
|
||||||
|
/* Skip spaces between : and label */
|
||||||
|
while (isspaceW (*str)) str++;
|
||||||
|
WINE_TRACE("str before brk %s\n", wine_dbgstr_w(str));
|
||||||
|
|
||||||
|
/* Label ends at whitespace or redirection characters */
|
||||||
|
labelend = strpbrkW(str, labelEndsW);
|
||||||
|
if (labelend) *labelend = 0x00;
|
||||||
|
WINE_TRACE("comparing found label %s\n", wine_dbgstr_w(str));
|
||||||
|
|
||||||
|
if (lstrcmpiW (str, paramStart) == 0) return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
WCMD_output_stderr(WCMD_LoadMessage(WCMD_NOTARGET));
|
WCMD_output_stderr(WCMD_LoadMessage(WCMD_NOTARGET));
|
||||||
|
context -> skip_rest = TRUE;
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2538,17 +2538,72 @@ echo %ErrorLevel% should still be 7
|
||||||
|
|
||||||
echo ------------ Testing GOTO ------------
|
echo ------------ Testing GOTO ------------
|
||||||
if a==a goto dest1
|
if a==a goto dest1
|
||||||
|
echo FAILURE at dest 1
|
||||||
:dest1
|
:dest1
|
||||||
echo goto with no leading space worked
|
echo goto with no leading space worked
|
||||||
|
if a==a goto :dest1b
|
||||||
|
echo FAILURE at dest 1b
|
||||||
|
:dest1b
|
||||||
|
echo goto with colon and no leading space worked
|
||||||
if b==b goto dest2
|
if b==b goto dest2
|
||||||
|
echo FAILURE at dest 2
|
||||||
:dest2
|
:dest2
|
||||||
echo goto with a leading space worked
|
echo goto with a leading space worked
|
||||||
if c==c goto dest3
|
if c==c goto dest3
|
||||||
|
echo FAILURE at dest 3
|
||||||
:dest3
|
:dest3
|
||||||
echo goto with a leading tab worked
|
echo goto with a leading tab worked
|
||||||
if d==d goto dest4
|
if d==d goto dest4
|
||||||
|
echo FAILURE at dest 4
|
||||||
:dest4@space@
|
:dest4@space@
|
||||||
echo goto with a following space worked
|
echo goto with a following space worked
|
||||||
|
if e==e goto dest5
|
||||||
|
echo FAILURE at dest 5
|
||||||
|
:dest5&& echo FAILURE
|
||||||
|
echo goto with following amphersands worked
|
||||||
|
|
||||||
|
del failure.txt >nul 2>&1
|
||||||
|
if f==f goto dest6
|
||||||
|
echo FAILURE at dest 6
|
||||||
|
:dest6>FAILURE.TXT
|
||||||
|
if exist FAILURE.TXT echo FAILURE at dest 6 as file exists
|
||||||
|
echo goto with redirections worked
|
||||||
|
del FAILURE.TXT >nul 2>&1
|
||||||
|
|
||||||
|
:: some text that is ignored | dir >cmd_output | another test
|
||||||
|
if exist cmd_output echo FAILURE at dest 6 as file exists
|
||||||
|
echo Ignoring double colons worked
|
||||||
|
del cmd_output >nul 2>&1
|
||||||
|
|
||||||
|
rem goto a label which does not exist issues an error message and
|
||||||
|
rem acts the same as goto :EOF, and ensure ::label is never matched
|
||||||
|
del testgoto.bat >nul 2>&1
|
||||||
|
echo goto :dest7 ^>nul 2^>^&1 >> testgoto.bat
|
||||||
|
echo echo FAILURE at dest 7 - Should have not found label and issued an error plus ended the batch>> testgoto.bat
|
||||||
|
echo ::dest7>> testgoto.bat
|
||||||
|
echo echo FAILURE at dest 7 - Incorrectly went to label >> testgoto.bat
|
||||||
|
call testgoto.bat
|
||||||
|
del testgoto.bat >nul 2>&1
|
||||||
|
|
||||||
|
del testgoto.bat >nul 2>&1
|
||||||
|
echo goto ::dest8 ^>nul 2^>^&1 >> testgoto.bat
|
||||||
|
echo echo FAILURE at dest 8 - Should have not found label and issued an error plus ended the batch>> testgoto.bat
|
||||||
|
echo ::dest8>> testgoto.bat
|
||||||
|
echo echo FAILURE at dest 8 - Incorrectly went to label >> testgoto.bat
|
||||||
|
call testgoto.bat
|
||||||
|
del testgoto.bat >nul 2>&1
|
||||||
|
|
||||||
|
if g==g goto dest9
|
||||||
|
echo FAILURE at dest 9
|
||||||
|
:dest91
|
||||||
|
echo FAILURE at dest 91
|
||||||
|
@ : dest9>rubbish
|
||||||
|
echo label with mixed whitespace and no echo worked
|
||||||
|
|
||||||
|
if h==h goto :dest10:this is ignored
|
||||||
|
echo FAILURE at dest 10
|
||||||
|
:dest10:this is also ignored
|
||||||
|
echo Correctly ignored trailing information
|
||||||
|
|
||||||
echo ------------ Testing PATH ------------
|
echo ------------ Testing PATH ------------
|
||||||
set WINE_backup_path=%path%
|
set WINE_backup_path=%path%
|
||||||
|
|
|
@ -1294,9 +1294,15 @@ errorlevel zero, good@or_broken@errorlevel nonzero, bad
|
||||||
7 should still be 7
|
7 should still be 7
|
||||||
------------ Testing GOTO ------------
|
------------ Testing GOTO ------------
|
||||||
goto with no leading space worked
|
goto with no leading space worked
|
||||||
|
goto with colon and no leading space worked
|
||||||
goto with a leading space worked
|
goto with a leading space worked
|
||||||
goto with a leading tab worked
|
goto with a leading tab worked
|
||||||
goto with a following space worked
|
goto with a following space worked
|
||||||
|
goto with following amphersands worked
|
||||||
|
goto with redirections worked
|
||||||
|
Ignoring double colons worked
|
||||||
|
label with mixed whitespace and no echo worked
|
||||||
|
Correctly ignored trailing information
|
||||||
------------ Testing PATH ------------
|
------------ Testing PATH ------------
|
||||||
PATH=original
|
PATH=original
|
||||||
PATH=try2
|
PATH=try2
|
||||||
|
|
|
@ -1813,7 +1813,7 @@ WCHAR *WCMD_ReadAndParseLine(const WCHAR *optionalcmd, CMD_LIST **output, HANDLE
|
||||||
static const WCHAR forCmd[] = {'f','o','r'};
|
static const WCHAR forCmd[] = {'f','o','r'};
|
||||||
static const WCHAR ifCmd[] = {'i','f'};
|
static const WCHAR ifCmd[] = {'i','f'};
|
||||||
static const WCHAR ifElse[] = {'e','l','s','e'};
|
static const WCHAR ifElse[] = {'e','l','s','e'};
|
||||||
BOOL inRem = FALSE;
|
BOOL inOneLine = FALSE;
|
||||||
BOOL inFor = FALSE;
|
BOOL inFor = FALSE;
|
||||||
BOOL inIn = FALSE;
|
BOOL inIn = FALSE;
|
||||||
BOOL inIf = FALSE;
|
BOOL inIf = FALSE;
|
||||||
|
@ -1910,9 +1910,10 @@ WCHAR *WCMD_ReadAndParseLine(const WCHAR *optionalcmd, CMD_LIST **output, HANDLE
|
||||||
if (curStringLen == 0 && curCopyTo == curString) {
|
if (curStringLen == 0 && curCopyTo == curString) {
|
||||||
static const WCHAR forDO[] = {'d','o'};
|
static const WCHAR forDO[] = {'d','o'};
|
||||||
|
|
||||||
/* If command starts with 'rem ', ignore any &&, ( etc. */
|
/* If command starts with 'rem ' or identifies a label, ignore any &&, ( etc. */
|
||||||
if (WCMD_keyword_ws_found(remCmd, sizeof(remCmd)/sizeof(remCmd[0]), curPos)) {
|
if (WCMD_keyword_ws_found(remCmd, sizeof(remCmd)/sizeof(remCmd[0]), curPos) ||
|
||||||
inRem = TRUE;
|
*curPos == ':') {
|
||||||
|
inOneLine = TRUE;
|
||||||
|
|
||||||
} else if (WCMD_keyword_ws_found(forCmd, sizeof(forCmd)/sizeof(forCmd[0]), curPos)) {
|
} else if (WCMD_keyword_ws_found(forCmd, sizeof(forCmd)/sizeof(forCmd[0]), curPos)) {
|
||||||
inFor = TRUE;
|
inFor = TRUE;
|
||||||
|
@ -1971,11 +1972,12 @@ WCHAR *WCMD_ReadAndParseLine(const WCHAR *optionalcmd, CMD_LIST **output, HANDLE
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Nothing 'ends' a REM statement and &&, quotes etc are ineffective,
|
/* Nothing 'ends' a one line statement (e.g. REM or :labels mean
|
||||||
so just use the default processing ie skip character specific
|
the &&, quotes and redirection etc are ineffective, so just force
|
||||||
matching below */
|
the use of the default processing by skipping character specific
|
||||||
if (!inRem) thisChar = *curPos;
|
matching below) */
|
||||||
else thisChar = 'X'; /* Character with no special processing */
|
if (!inOneLine) thisChar = *curPos;
|
||||||
|
else thisChar = 'X'; /* Character with no special processing */
|
||||||
|
|
||||||
lastWasWhiteSpace = FALSE; /* Will be reset below */
|
lastWasWhiteSpace = FALSE; /* Will be reset below */
|
||||||
lastWasCaret = FALSE;
|
lastWasCaret = FALSE;
|
||||||
|
@ -2225,7 +2227,7 @@ WCHAR *WCMD_ReadAndParseLine(const WCHAR *optionalcmd, CMD_LIST **output, HANDLE
|
||||||
WCHAR *extraData;
|
WCHAR *extraData;
|
||||||
|
|
||||||
WINE_TRACE("Need to read more data as outstanding brackets or carets\n");
|
WINE_TRACE("Need to read more data as outstanding brackets or carets\n");
|
||||||
inRem = FALSE;
|
inOneLine = FALSE;
|
||||||
prevDelim = CMD_NONE;
|
prevDelim = CMD_NONE;
|
||||||
inQuotes = 0;
|
inQuotes = 0;
|
||||||
memset(extraSpace, 0x00, (MAXSTRING+1) * sizeof(WCHAR));
|
memset(extraSpace, 0x00, (MAXSTRING+1) * sizeof(WCHAR));
|
||||||
|
|
Loading…
Reference in a new issue