for-loopbatch-filereturn-valueexitdelayedvariableexpansion

Return a value from a called batch file label


I have two labels in my batch file. The initial label MAIN shall stay in control, so it Calls the second label, which ends with exit /b.

My script's Main label Calls the other, passing it arguments, which will be used to search strings wothin a text file.

When returning to the Calling label, it slways receives an empty return string.

I think this has something to do with the variable expansion in a loop. Who knows?

Here is the Script:

@echo off
SETLOCAL ENABLEDELAYEDEXPANSION

:MAIN
call :getReturnValue "1234 0815 4321 12815" "readBackVal"
if !errorlevel! equ 0 (
    echo readback=!readBackVal!
    echo readback=%readBackVal%
)
pause
exit /b 0

REM Function, which checks if the give return value is in a specific textfile (line for line check)
:getReturnValue
set "myExpectedValueList=%~1"
set "retval=%~2"
set "file=textexample.txt"
for %%i in (%myExpectedValueList%) do (
    for /f "tokens=*" %%a in (%file%) do (
        echo %%a|findstr /r "^.*%%i$"
    )
    if !errorlevel! equ 0 (
        (endlocal
            set /a "%retval%=%%i")
        )
        exit /b 0
    )
)
exit /b 1

Here is the sample textfile textexample.txt:

Setup returns with errorcode=0815

Solution

  • Here is the answer i looked for:

    Hi, first i want to inform that i made some changes due to the Answer of @OJBakker. This changes are listed at the bottom of the script.

    The problem was to return a value from a called function/label to the calling function/label. The stich here is, that the magic is done in the (endlocal...) section of the called function/label -> means the return of the variable.

    Before the endlocal command is executed, the compiler replaces the variables in this section by their values and afterwards executes the command´s from left to right. Means following:

    First, the compiler sees following:

    (endlocal
        if "%retval%" neq "" (call set /a %retval%=%%i)
    )
    

    Second, the compiler replaces the variables by their values:

    (endlocal
        if "readBackVal" neq "" (set /a "readBackVal"=1815)
    )
    

    Third: This command is executed

    (endlocal
        if "readBackVal" neq "" (set /a "readBackVal"=1815)
    )
    

    Now here is my complete script (i also fixed some other problems with it which i commented at the bottom of the script

    @echo off
    SETLOCAL ENABLEDELAYEDEXPANSION
    
    :MAIN
    setlocal
    call :getReturnValue "1234 1815 4321 12815" "readBackVal"
    if "!errorlevel!" equ "0" (
        echo readback=!readBackVal!
    )
    pause
    exit /b 0
    
    REM Function, which checks if the give return value is in a specific textfile (line for line check)
    :getReturnValue
    setlocal
    set "myExpectedValueList=%~1"
    set "retval=%~2"
    set "file=textexample.txt"
    for %%i in (%myExpectedValueList%) do (
        for /f "tokens=*" %%a in (%file%) do (
            echo %%a|findstr /r "^.*%%i$" >NUL
        )
        if "!errorlevel!" equ "0" (
            (endlocal
                if "%retval%" neq "" (set /a %retval%=%%i)
            )
            exit /b 0
        )
    )
    exit /b 1
    
    REM Changes to initial posting:
    REM Added "setlocal" keyword to the function "getReturnValue"
    REM Corrected an invalid paranthesis in the (endlocal...) section
    REM Changed the file "textexample.txt" -> 0815 to 1815 to remove leading zero (findstr. Problem),
    REM Added check, if parameter "retval" has been passed to the called function e.g. is not empty
    REM FINAL -> applied double variable expansion (call set /a ...) to return the value proper
    REM to the :MAIN function.