Home > Software engineering >  Return a value from a called batch file label
Return a value from a called batch file label

Time:09-16

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

CodePudding user response:

@echo off  
SETLOCAL ENABLEDELAYEDEXPANSION  
  
:MAIN  
call :getReturnValue "1234 0815 4321 12815" "readBackVal"  
if %errorlevel% equ 0 (echo readback=%readBackVal%)  
pause  
endlocal  
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| >con 2>&1 findstr /r "^.*%%i$"  
    if !errorlevel! equ 0 (  
        set /a "%retval%=%%i"  
            exit /b 0  
        )  
    )  
)  
exit /b 1  
  
  
rem changes:  
rem endlocal moved to main.  
rem check for errorlevel moved to within the commandblock of the inner for-loop.  
rem 'exit /b 0' moved to within the if. This exit line stopped the for after the first item.  
rem redirection added to findstr command. Now the output shows the remaining problem.  
rem Invalid number.  Numeric constants are either decimal (17), hexadecimal (0x11), or octal (021).  
rem Findstr really does not like the value 0815, especially the starting zero.  
rem I am not sure how to change the regexp so findstr won't barf at the leading zero.  
rem Maybe someone else can solve this remaining problem.  

CodePudding user response:

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.
  • Related