The solution would seem hard to find, but it is actually simpler than it would seem. Basically, this implementation would cause a batch file to recursively call itself, which will make more sense later. First, you will need a way to differentiate a function call from a normal command line argument. In my example, I will (for simplicity's sake) use the colon :
to denote that the argument is a function. This will result in the following code (only part of the command):
set fn=%1
if "%fn:0,1%"==":" ...
This code would first set a variable to take the first argument and accept that as the function name. Next, we need to go to that function in the recursive call, which is as simple as this.
goto %fn%
Now, we need a way to account for incorrect function calls and kill the execution of the batch file if it is wrong (like any language with proper function calls would). This modification would allow this error to be caught and will promptly kill the batch file. In case you're wondering, I separated the statement into a set a variable if the function doesn't exist. I added that echo
statement to make it easier to debug.
goto %fn% || set err=t
if defined %err% (
echo Undefined function: %fn%!
goto :eof
)
So, after that, you can make the functions like you would otherwise normally, because the goto :eof
call would act the same as it would with or without extensions. Here's the entire batch file implementation of this (I didn't mention the needed shift, which is here):
@echo off
:: You will not need to enable extensions
:: here.
setlocal
set fn=%1
shift
if "%fn:0,1%"==":" (
goto %fn% || set err=t
if defined %err% (
echo Undefined function: %fn%!
goto :eof
)
)
:: Normal commands go here. You can also
:: include your functions normally as well.
One little difference between the function calling mechanism with extensions and this implementation that must be noted is this: you have to call your function like this call %0 :function args
instead of call :function args
, like how you would with extensions enabled. If you don't, you will most assuredly find bugs that are insanely hard to find (the error won't start you in the right direction).
If you want a little sugar for this, you could always set call=call %%0
and use %call% :function
args
EDIT: I forgot a small nuance in how to actually call the function. I fixed it in the main body.