What it is, why it`s important and how to write your own.
Description: The assumption is: A batch script snippet can be named a function when:
1.... it has a callable entrance point.
2.... on completion execution continues right after the command that initially called the function.
3.... it works the same no matter from where it`s being called, even when it calls itself recursively.
4.... the variables used within a function do not conflict with variables outside the function.
5.... it exchanges data with the calling code strictly through input and output variables or a return code.
The benefits behind functions are:
1.Keep the main script clean
2.Hide complexity in reusable functions
3.Test functions independently from the main script
4.Add more functionality to your batch script simply by adding more functions at the bottom
5.Don`t worry about the function implementation, just test it and use it
Create a Function What is a function?
Call a Function How to invoke a function?
Example - Calling a Function An Example showing how it works.
Passing Function Arguments How to pass arguments to the function?
Parsing Function Arguments How to retrieve function arguments within the function?
Example - Function with Arguments An Example showing how it works.
Returning Values the Classic Way The classic way of returning values and the limitations.
Returning Values via References Let the caller determine how to return the function result and avoid the need of dedicated variables.
Example - Returning Values using Variable Reference An Example showing how it works.
Local Variables in Functions How to avoid name conflicts and keep variable changes local to the function?
Returning Local Variables How to pass return values over the ENDLOCAL barrier?
Recursive Functions Tadaaah!!!
Summary Defining a standard format for a DOS batch function
DOS Batch - Function Tutorial What it is, why it`s important and how to write your own.
Create a Function - What is a function
Description: In DOS you write a function by surrounding a group of command by a label and a GOTO:EOF command. A single batch file can contain multiple functions defined like this. The label becomes the function name.
Script:
:myDosFunc - here starts my function identified by it`s label echo. here the myDosFunc function is executing a group of commands echo. it could do a lot of things GOTO:EOF
Call a Function - How to invoke a function
Description: A function can be called with the CALL command followed by the function label.
Script: 01.
call:myDosFunc
Example - Calling a Function - An Example showing how it works
Description: The use of batch functions will divide the script into two sections.
1.The main script: starting at line 1 ending with a GOTO:EOF command that terminates the script.
2.The function section: filling the second half of the batch file with one or more functions to be callable from the main script.
Script:
@echo off echo.going to execute myDosFunc call:myDosFunc echo.returned from myDosFuncecho.&pause&goto:eof
::-------------------------------------------------------- ::-- Function section starts below here ::--------------------------------------------------------
:myDosFunc - here starts my function identified by it`s label echo. here the myDosFunc function is executing a group of commands echo. it could do a lot of things goto:eof
call:myDosFunc 100 YeePEE call:myDosFunc 100 "for me" call:myDosFunc 100,"for me"
:myDosFunc - here starts myDosFunc identified by it`s label echo. echo. here the myDosFunc function is executing a group of commands echo. it could do %~1 of things %~2. goto:eof
Note: The last call to myDosFunc doesn`t use double quotes for the second argument. Subsequently "for" and "me" will be handled as two separate arguments, whereas the third argument "me" is not being used within the function.
Script:
@echo off echo.going to execute myDosFunc with different arguments call:myDosFunc 100 YeePEE call:myDosFunc 100 "for me" call:myDosFunc 100,"for me" call:myDosFunc 100,for me echo.&pause&goto:eof::-------------------------------------------------------- ::-- Function section starts below here ::--------------------------------------------------------
:myDosFunc - here starts my function identified by it's label echo. echo. here the myDosFunc function is executing a group of commands echo. it could do %~1 of things %~2. goto:eof
Returning Values the Classic Way - The classic way of returning values and the limitations
Description: The CALL command doesn`t support return values as known by other programming languages.
The classic walkaround is to have the function store the return value into a environment variable. The calling script can use this variable when the function returns. The :myGetFunc function below demonstrates how the variable var1 gets the "DosTips" string assigned which can then be used in the calling function.
Note: The var1 variable is reserved for this particular function. Any data stored in var1 by the calling function before calling :myGetVar will be overwritten.
Usage:
set "var1=some hopefully not important string" echo.var1 before: %var1% call:myGetFunc echo.var1 after : %var1%
:myGetFunc - get a value set "var1=DosTips" goto:eof
Note: The var1 variable is not reserved for this articular function. Any variable can be passed to the function the caller has full control.
Usage:
call:myGetFunc var1 echo.var1 after : %var1%
:myGetFunc - passing a variable by reference set "%~1=DosTips" goto:eof
@echo offset "var1=CmdTips" echo.var1 before: %var1% call:myGetFunc var1 echo.var1 after : %var1%
echo.&pause&goto:eof
::-------------------------------------------------------- ::-- Function section starts below here ::--------------------------------------------------------
:myGetFunc - passing a variable by reference set "%~1=DosTips" goto:eof
Local Variables in Functions - How to avoid name conflicts and keep variable changes local to the function
Description: The SETLOCAL causes the command processor to backup all environment variables. The variables can be restored by calling ENDLOCAL. Changes made im between are local to the current batch. ENDLOCAL is automatically being called when the end of the batch file is reached, i.e. by calling GOTO:EOF.
Localizing variables with SETLOCAL allows using variable names within a function freely without worrying about name conflicts with variables used outside the function.
Script:
@echo offset "aStr=Expect no changed, even if used in function" set "var1=No change for this one. Now what?" echo.aStr before: %aStr% echo.var1 before: %var1% call:myGetFunc var1 echo.aStr after : %aStr% echo.var1 after : %var1%
echo.&pause&goto:eof
::-------------------------------------------------------- ::-- Function section starts below here ::--------------------------------------------------------
:myGetFunc - passing a variable by reference SETLOCAL set "aStr=DosTips" set "%~1=%aStr%" ENDLOCAL goto:eof
@echo offset "aStr=Expect no changed, even if used in function" set "var1=Expect changed" echo.aStr before: %aStr% echo.var1 before: %var1% call:myGetFunc var1 echo.aStr after : %aStr% echo.var1 after : %var1%
echo.&pause&goto:eof
::-------------------------------------------------------- ::-- Function section starts below here ::--------------------------------------------------------
:myGetFunc - passing a variable by reference SETLOCAL set "aStr=DosTips" ( ENDLOCAL set "%~1=%aStr%" ) goto:eof
:myGetFunc2 - passing a variable by reference SETLOCAL set "aStr=DosTips" ENDLOCAL&set "%~1=%aStr%" &rem THIS ALSO WORKS FINE goto:eof
Recursive Functions - Tadaaah!!!
Description: Being able to completely encapsulate the body of a function by keeping variable changes local to the function and invisible to the caller we are now able to call a function recursively making sure each level of recursion works with its own set of variables even thought variable names are being reused.
Example: The next example below shows how to calculate a Fibonacci number recursively. The recursion ss when the Fibonacci algorism reaches a number greater or equal to a given input number.
The example starts with the numbers 0 and 1 the :myFibo function calls itself recursively to calculate the next Fibonacci number until it finds the Fibonacci number greater or equal 1000000000.
The first argument of the myFibo function is the name of the variable to store the output in. This variable must be initialized to the Fibonacci number to start with and will be used as current Fibonacci number when calling the function and will be set to the subsequent Fibonacci number when the function returns.
Script:
@echo offset "fst=0" set "fib=1" set "limit=1000000000" call:myFibo fib,%fst%,%limit% echo.The next Fibonacci number greater or equal %limit% is %fib%.
echo.&pause&goto:eof
::-------------------------------------------------------- ::-- Function section starts below here ::--------------------------------------------------------
:myFibo -- calculate recursively the next Fibonacci number greater or equal to a limit :: -- %~1: return variable reference and current Fibonacci number :: -- %~2: previous value :: -- %~3: limit SETLOCAL set /a "Number1=%~1" set /a "Number2=%~2" set /a "Limit=%~3" set /a "NumberN=Number1 + Number2" if /i %NumberN% LSS %Limit% call:myFibo NumberN,%Number1%,%Limit% (ENDLOCAL IF "%~1" NEQ "" SET "%~1=%NumberN%" ) goto:eof
:myFunctionName -- function description here :: -- %~1: argument description here SETLOCAL REM.--function body here set LocalVar1=... set LocalVar2=... (ENDLOCAL & REM -- RETURN VALUES IF "%~1" NEQ "" SET %~1=%LocalVar1% IF "%~2" NEQ "" SET %~2=%LocalVar2% ) GOTO:EOF