Search code examples
batch-file

windows batch file early exit from for loop with function call


I have an issue with my batch script. The issue is that when I call the function in the for loop, loop body will be executed only once. For example, when my loop processes all files in the directory, when I call my function, it will only process one file instead of going through all files in the directory and I don't understand why. Here is my code snippet:

pushd ..\build\scenes\
del *.pdb > NUL 2> NUL
for %%f in ("..\..\src\game_scenes\*.cpp") do (
    set "FileName=%%f"
    set "BaseName=%%~nf"
    set "ExportName="
    
    for /F "tokens=1,* delims=_" %%a in ("!BaseName!") do (
        call :ProcessToken %%a
        set "RestOfName=%%b"
    )

    :NextToken
    if not "!RestOfName!"=="" (
        for /F "tokens=1,* delims=_" %%a in ("!RestOfName!") do (
            call :ProcessToken %%a
            set "RestOfName=%%b"
        )
        goto NextToken
    )
    
    set ExportName=!ExportName!Create
)
popd

goto :eof

:ProcessToken
    call :CapitalizeFirstLetter %1
    set "ExportName=!ExportName!!CapWord!"

    goto :eof

:CapitalizeFirstLetter
    set InputWord=%1
    set FirstChar=%InputWord:~0,1%
    set RemainingChars=%InputWord:~1%
    for %%i in (A B C D E F G H I J K L M N O P Q R S T U V W X Y Z) do (
        if /i "!FirstChar!"=="%%i" set FirstChar=%%i
    )
    set CapWord=!FirstChar!!RemainingChars!

    goto :eof

I've tried both goto :eof and exit /b in the end of the function bot neither helped me. So, I thought, maybe I just did something wrong. Thanks.


Solution

  • As said, goto to labels inside code blocks instantly exits the block.
    You could use a call to a function instead, there you can use goto without problems.

    And you could simplify your code

    pushd ..\build\scenes\
    del *.pdb > NUL 2> NUL
    for %%f in ("..\..\src\game_scenes\*.cpp") do (
        set "FileName=%%f"
        set "BaseName=%%~nf"
        set "ExportName="
        
        call :processName "!BaseName!"
        set ExportName=!ExportName!Create
    )
    
    goto :eof
    
    :processName
    set "RestOfName=%~1"
    :NextToken
    if not "!RestOfName!"=="" (
        for /F "tokens=1,* delims=_" %%a in ("!RestOfName!") do (
            call :ProcessToken %%a
            set "RestOfName=%%b"
        )
        goto NextToken
    )
    popd
    goto :eof
    ...