cmd: Call and goto finds the next matching label.

A call or a goto will find the next matching label not the first one in the
file. This means it could be later in the file or it could be earlier in the
file, so make goto (which 'call' also uses) first scan from current file
position to the end of the file, and subsequently from the start of the file
to the wrap point.

Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=42823
Signed-off-by: Jason Edmeades <us@edmeades.me.uk>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
oldstable
Jason Edmeades 2018-07-04 22:08:39 +01:00 committed by Alexandre Julliard
parent daee8b753c
commit 254dc78c2c
3 changed files with 113 additions and 18 deletions

View File

@ -2582,30 +2582,61 @@ void WCMD_goto (CMD_LIST **cmdList) {
if (labelend) *labelend = 0x00;
WINE_TRACE("goto label: '%s'\n", wine_dbgstr_w(paramStart));
SetFilePointer (context -> h, 0, NULL, FILE_BEGIN);
while (*paramStart &&
WCMD_fgets (string, sizeof(string)/sizeof(WCHAR), context -> h)) {
str = string;
/* Loop through potentially twice - once from current file position
through to the end, and second time from start to current file
position */
if (*paramStart) {
int loop;
LARGE_INTEGER startli;
for (loop=0; loop<2; loop++) {
if (loop==0) {
/* On first loop, save the file size */
startli.QuadPart = 0;
startli.u.LowPart = SetFilePointer(context -> h, startli.u.LowPart,
&startli.u.HighPart, FILE_CURRENT);
} else {
/* On second loop, start at the beginning of the file */
WINE_TRACE("Label not found, trying from beginning of file\n");
if (loop==1) SetFilePointer (context -> h, 0, NULL, FILE_BEGIN);
}
/* Ignore leading whitespace or no-echo character */
while (*str=='@' || isspaceW (*str)) str++;
while (WCMD_fgets (string, sizeof(string)/sizeof(WCHAR), context -> h)) {
str = string;
/* If the first real character is a : then this is a label */
if (*str == ':') {
str++;
/* Ignore leading whitespace or no-echo character */
while (*str=='@' || isspaceW (*str)) str++;
/* Skip spaces between : and label */
while (isspaceW (*str)) str++;
WINE_TRACE("str before brk %s\n", wine_dbgstr_w(str));
/* If the first real character is a : then this is a label */
if (*str == ':') {
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));
/* Skip spaces between : and label */
while (isspaceW (*str)) str++;
WINE_TRACE("str before brk %s\n", wine_dbgstr_w(str));
if (lstrcmpiW (str, paramStart) == 0) return;
}
/* 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;
}
/* See if we have gone beyond the end point if second time through */
if (loop==1) {
LARGE_INTEGER curli;
curli.QuadPart = 0;
curli.u.LowPart = SetFilePointer(context -> h, curli.u.LowPart,
&curli.u.HighPart, FILE_CURRENT);
if (curli.QuadPart > startli.QuadPart) {
WINE_TRACE("Reached wrap point, label not found\n");
break;
}
}
}
}
}
WCMD_output_stderr(WCMD_LoadMessage(WCMD_NOTARGET));
context -> skip_rest = TRUE;
}

View File

@ -3027,6 +3027,57 @@ echo FAILURE at dest 10
:dest10:this is also ignored
echo Correctly ignored trailing information
rem Testing which label is reached when there are many options
echo Begin:
set nextlabel=
call :sub
set nextlabel=middle
goto :sub
:sub
echo ..First sub
if not "%nextlabel%"=="" goto :%nextlabel%
goto :EOF
:sub
echo ..Second sub
if not "%nextlabel%"=="" goto :%nextlabel%
goto :EOF
:middle
echo Middle:
set nextlabel=
call :sub
set nextlabel=nearend
goto :sub
:sub
echo ..Third sub
if not "%nextlabel%"=="" goto :%nextlabel%
goto :EOF
:nearend
echo Near end:
set nextlabel=
call :sub
set nextlabel=end
goto :sub
:sub
echo ..Fourth sub
if not "%nextlabel%"=="" goto :%nextlabel%
goto :EOF
:end
echo At end:
set nextlabel=
call :sub
set nextlabel=done
goto :sub
:done
echo Finished
echo ------------ Testing PATH ------------
set WINE_backup_path=%path%
set path=original

View File

@ -1582,6 +1582,19 @@ goto with redirections worked
Ignoring double colons worked
label with mixed whitespace and no echo worked
Correctly ignored trailing information
Begin:
..First sub
..First sub
Middle:
..Third sub
..Third sub
Near end:
..Fourth sub
..Fourth sub
At end:
..First sub
..First sub
Finished
------------ Testing PATH ------------
PATH=original
PATH=try2