Commit 254dc78c authored by Jason Edmeades's avatar Jason Edmeades Committed by Alexandre Julliard

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=42823Signed-off-by: 's avatarJason Edmeades <us@edmeades.me.uk> Signed-off-by: 's avatarAlexandre Julliard <julliard@winehq.org>
parent daee8b75
......@@ -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;
}
......
......@@ -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
......
......@@ -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
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment