Jason Edmeades : cmd: Call and goto finds the next matching label.
Alexandre Julliard
julliard at winehq.org
Thu Jul 5 15:25:53 CDT 2018
Module: wine
Branch: master
Commit: 254dc78c2cc5aec26b8af6956c3525c1880bf570
URL: https://source.winehq.org/git/wine.git/?a=commit;h=254dc78c2cc5aec26b8af6956c3525c1880bf570
Author: Jason Edmeades <us at edmeades.me.uk>
Date: Wed Jul 4 22:08:39 2018 +0100
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 at edmeades.me.uk>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
programs/cmd/builtins.c | 67 +++++++++++++++++++++++---------
programs/cmd/tests/test_builtins.cmd | 51 ++++++++++++++++++++++++
programs/cmd/tests/test_builtins.cmd.exp | 13 +++++++
3 files changed, 113 insertions(+), 18 deletions(-)
diff --git a/programs/cmd/builtins.c b/programs/cmd/builtins.c
index 35b68bd..3a0981d 100644
--- a/programs/cmd/builtins.c
+++ b/programs/cmd/builtins.c
@@ -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;
}
diff --git a/programs/cmd/tests/test_builtins.cmd b/programs/cmd/tests/test_builtins.cmd
index 49c2d9e..0a8122c 100644
--- a/programs/cmd/tests/test_builtins.cmd
+++ b/programs/cmd/tests/test_builtins.cmd
@@ -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
diff --git a/programs/cmd/tests/test_builtins.cmd.exp b/programs/cmd/tests/test_builtins.cmd.exp
index cfde83b..7f4f724 100644
--- a/programs/cmd/tests/test_builtins.cmd.exp
+++ b/programs/cmd/tests/test_builtins.cmd.exp
@@ -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
More information about the wine-cvs
mailing list