I have to agree that that isn't the most efficient method for keeping
track of the "errorlevel_changed". I will be resubmitting the patch
with a better implementation, using the process stack as you
suggested.

However, I would like to say that it really wouldn't be possible to only
use the success/failure value from the functions that don't change the
"errorlevel". This is because there is a subtle difference that sadly
Windows thought was a great idea (I think it should work like you say).
Windows checks if the "errorlevel" has changed in any of the commands
inside of a call and if it has then it checks the errorlevel, if it hasn't
changed it assumes a success. This means that even if the last
command "succeeds" without changing the errorlevel it doesn't matter
(e.g. "echo test") if any of the previous commands inside of a call
updated the errorlevel. Working examples can be seen on line 291-312
of programs/cmd/tests/test-builtins.cmd or a small snippet of them
below:

-snip
> :cfail
> echo %1
> call :setError 1
> goto :eof
-snip-
> call :cfail c1||call :cfail c2
-snip-
> :setError
> exit /B %1
-snip-

The code above will return (and would do so even if one inserted
a "echo foobar" after the "call :setError 1"):
c1
c2


On Tue, Sep 19, 2017 at 5:27 AM, Alexandre Julliard <julliard@winehq.org> wrote:
Alexander Coffin <alexcoffin1999@gmail.com> writes:

> @@ -1478,7 +1557,9 @@ void WCMD_execute (const WCHAR *command, const WCHAR *redirects,
>      switch (i) {
>
>        case WCMD_CALL:
> +        push_errorlevel_changed();
>          WCMD_call (p);
> +        pop_errorlevel_changed();

This seems to be the only place that does this, so I don't see why you
need to manage your own stack instead of saving/restoring things on the
process stack.

Also returning a success/failure value from the various functions that
implement commands would probably be cleaner than adding a global
'changed' flag.

--
Alexandre Julliard
julliard@winehq.org