4
@echo off  
:start1  
set /p input=action :   
for /f "tokens=1-2 delims= " %%a in ("%input%") do (  
goto :%%~a_%%~b >nul 2>&1 || goto start1
)    

if I put "| | echo your input is not recognized" it works, but the "goto start1" crashes the script

:explore_room   
@echo room explored  
goto start1  
pause  
:examine_door  
@echo door examined  
pause  
:examine_wall  
@echo wall examined  
pause  

3 Answers3

3
@echo off  
:start1  
set /p input=action :   
call :%input: =_% 2>nul
if errorlevel 1 echo your input is not recognized
goto start1


:explore_room   
@echo room explored  
pause  
exit /B 0

:examine_door  
echo door examined  
pause  
exit /B 0

:examine_wall  
echo wall examined  
pause 
exit /B 0

Example:

action :   examine door
door examined
Presione una tecla para continuar . . .
action :   explore hall
your input is not recognized
action :   explore room
room explored
Presione una tecla para continuar . . .
¿Desea terminar el trabajo por lotes (S/N)? s
Aacini
  • 65,180
  • 12
  • 72
  • 108
  • but why the `goto` does not work after the conditional execution and other commands work? – npocmaka Apr 27 '14 at 19:30
  • Because `call` and `goto` works differently in this case (when the label does not exists): `call` return errorlevel=1 _and continue execution_!. `goto` cancel execution... – Aacini Apr 27 '14 at 19:35
  • but why canceled only for `goto` ? – npocmaka Apr 27 '14 at 19:40
  • It's clear why the next line is not executed...In fact `call` also does not work.But these two seems to be the only commands.Looks like it just goes to the end of the file and labels cannot be read – npocmaka Apr 27 '14 at 19:43
  • Ok. I did more tests. It seems that the whole line that contain the `goto` is executed after the `goto` returns an errorlevel=1, but after the rest of commands in that line are executed, the Batch file is canceled... – Aacini Apr 27 '14 at 19:56
  • 4
    GOTO undefined label is a fatal error. It immediately terminates batch processing, but the currently executing block of code that has already been parsed continues to completion. However, the remainder of the code is executed using a command line context instead of a batch context. The following batch script `@goto undefinedLabel||call echo [%%undefinedVar%%]` will echo `[%undefinedVar%]` because of command line context. If it were batch context it would echo `[]`. – dbenham Apr 28 '14 at 04:57
3

This is a really strange and interessting bug!

The cause will be obvious when I used CALL instead of GOTO.

goto :notExist || call :someLabel

You get an error message like

Illegal to call a label outside of a batch file.

Obviously the parser switches to a cmd-line context here!

This is done when the first goto fails to find the label.
When you use first a call all works fine.

call :noLabel 2>nul || goto :thisWorks

This seems to be a general side effect of a failing goto.
When a goto fails, it normally stops immediatly the batch file.

But with the || operator the next command will be forced to execute.

But it seems that it works more like an exit /b, so you can use this effect to leave a function.

@echo off
setlocal DisableDelayedExpansion
set var=111
call :myFunc
set var
exit /b

:myFunc
setlocal EnableDelayedExpansion
set var=222
goto :noLabel 2>nul || set var=333!var!
echo This will be never reached
exit /b

The interessting output

var=333!var!

So the goto :noLabel acts like an exit /b and it also done the implicit ENDLOCAL before the part || set var=333!var! is executed.

The same issue (but without the || operator) was discussed at Dostips: Rules for label names vs GOTO and CALL

jeb
  • 78,592
  • 17
  • 171
  • 225
2

A way to do that using the technics desribed here : Check if label exists cmd by @MC ND and @dbenham :

@echo off  
:start1  
set /p input=action :   
for /f "tokens=1-2 delims= " %%a in ("%input%") do (  
findstr /ri /c:"^ *:%%~a_%%~b " /c:"^ *::%%~a_%%~b$" "%~f0" >nul 2>nul && goto :%%~a_%%~b)
goto:start1


:explore_room   
@echo room explored
goto:start1
Community
  • 1
  • 1
SachaDee
  • 9,245
  • 3
  • 23
  • 33
  • +1 , but why conditional execution works works with echo but not with second goto? `goto` as whole breaks the brackets and redirection/conditional execution context , but I don't think it is the whole answer... – npocmaka Apr 27 '14 at 19:24