Reached the maximum set recursion level - setlocal

Read a few bits, but try your best to figure it out. Basically, you need to use Setlocal with deferred expansion on and off to use and manage variables with exclamation marks. An example of this code is below. A section of code can loop through a session, and at some point (I believe 32?) I get a "Maximum level of recursion localization" error.

I did a little familiarity with Endlocal but can't figure out how to use it. My concern is that some parts of the code are extracting from the surrounding code (e.g.% _emuExts%) the environment vars, while there are some vars in the extract that I want to use outside the extract (e.g.% startfile% and% lauchfile2% ). Hope this makes some sense!

My question is really about where to put any EndLocal to ensure that it can use variables from "around" the code, and also set variables that can be used outside of the "local" bit. To be honest, we are trying to conceptualize ideas around "local" and "levels of recursion".

Code:

:: Example of var contents:
set _emuExts=cue bin iso
:: Problem code:
Setlocal DisableDelayedExpansion
for %%e in (%_emuExts%) do (
        echo Extention: %%e 
        for /F "delims=" %%a in ('dir /b *.%%e') do (               
                set launchfile=%%~na.%%e            
                echo Launchfile this iteration: [%%~na.%%e]%_log1%
            )
        echo Next iteration......
    )
echo Final Launchfile: "%launchfile%" %_log1%
set launchfile2=%launchfile:!={-exc-}%
echo Launchfile with replace: %launchfile2%%_log1%
setlocal enabledelayedexpansion
:: .....more code   
Setlocal DisableDelayedExpansion
set "_FinalemuCmd=%_FinalemuCmd:{-exc-}=!%"
start /wait "" "%_emuExe%" %_FinalemuCmd%
setlocal enabledelayedexpansion
:: ...continues....

      

Functionally, this loops through the current directory, through the values ​​specified in% _emuExts%, and sets% launchfile% to the extension of the "priority" extension (rightmost extension). Some filenames have exclamation marks - hence the delayed switch. Then it shuts down "!" for "{-exc -}"

Apologies - may be obvious to you guys - but hard to get a head on. Thanks to

+3


source to share


3 answers


Rather than complicating the code with all SETLOCALs, is it possible to change the code so you don't have to defer expansion? I don't see any code above that requires it. Of course the code is missing. Maybe we should look at this. If you must set SETLOCAL multiple times, there is a technique called "tunneling" that allows you to pass variables that are local in one section of code to another section of code. For this you can do something like this endlocal & set MyVar=%MyVar%

. This works because at load time the entire string is parsed and% MyVar% is expanded. The runtime behavior is to then set this value to a new variable (of the same or a different name, of your choice) outside the localized code.



+1


source


Thanks guys! I'm an amateur, so my solution is probably not the most eloquent, but it worked! Most of my scripts work with setlocalexpantion enabled. Several things helped solve this problem:

  • Treating setlocal + endlocal as parentheses - closing any setlocal with matching endlocal
  • If you need to "pass" the set variable "inside" these pareheses to the rest of the script using endlocal with a tunneling method
  • Detecting that if you are endlocal the script reverts to its previous "setlocal" state (i.e. no need to re-enable delayed expansion via set after "closed" disable)


So the final, working code:

:: Example of var contents:
set _emuExts=cue bin iso
:: Problem code:
Setlocal DisableDelayedExpansion
for %%e in (%_emuExts%) do (
        echo Extention: %%e 
        for /F "delims=" %%a in ('dir /b *.%%e') do (               
                set launchfile=%%~na.%%e
                echo Launchfile this iteration: [%%~na.%%e]%_log1%
            )
        echo Next iteration......
    )
echo Final Launchfile: "%launchfile%" %_log1%
set launchfile2=%launchfile:!={-exc-}%
echo Launchfile with replace: %launchfile2%%_log1%
endlocal & (
        set "launchfile=%launchfile%"
        set "launchfile2=%launchfile2%"
    )
:: .....more code  
Setlocal DisableDelayedExpansion
set "_FinalemuCmd=%_FinalemuCmd:{-exc-}=!%"
echo after replace and no delayed: %_FinalemuCmd%%_log1%
pause
echo 
start /wait "" "%_emuExe%" %_FinalemuCmd%
::ping -n 3 localhost  > nul
endlocal
:: ...continues....

      

+1


source


To manipulate exclamation marks in file names, use a procedure call as in the following example. Note setlocal

and endlocal

are like parentheses, so they should always be chained together. By doing this, you never reach the maximum level of setlocal recursion ...

@echo off
@SETLOCAL enableextensions enabledelayedexpansion
  set "launchfile="
  for /f %%G in ('dir /b *.enu') do (
    SETLOCAL disabledelayedexpansion
      Call :exclamsub "%%~dpnxG"
    ENDLOCAL
  )
@ENDLOCAL
goto :eof

:exclamsub
@echo off
  set "launchfile=%~1"
  @echo %1 ^[%launchfile%^]
goto :eof

      

0


source







All Articles