Page 1 of 1

able to run functions from another script?

Posted: 10 May 2020 04:21
by deusery
Can I run another batch script, and use functions from there? I'm trying to make a prototype of a text-based game, so I want to see if I can make the code for the main file smaller. :D

Re: able to run functions from another script?

Posted: 11 May 2020 00:38
by jeb
Hi deusery,

yes you can.

There are different solutions to build a batch library,
but no perfect one.

1) You can use a HACK/bug/feature of cmd.exe
If you call a label in the same file and then start a second batch file without CALL,
then the label will be jumped to also in the second batch file!

batch1.bat

Code: Select all

echo Start first func in batch2
call :externalFunc1
echo Start second func in batch2
call :externalFunc2
...
exit /b

:: Jump helper function, list all possible labels of batch2 here
:externalFunc1
:externalFunc2
:externalFunc3
batch2.bat
exit /b

But the drawback is the need to duplicate all labels in batch1.

2) You can use Batch-Macros
Pro: Fastest execution time
Contra: Hard to write, hard to debug

3) Trampoline jump

Add this to the beginning of each library

Code: Select all

@echo off
REM *** Trampoline jump for function calls of the form ex. "C:\:libraryFunction:\..\libThisLibraryName.bat"
FOR /F "tokens=3 delims=:" %%L in ("%~0") DO goto :%%L
And to use a function inside a library you call it like:

Code: Select all

call "c:\:myLibFunction:\..\path_to_lib\myLibrary.bat" arg1 arg2 ...
Pro: Very flexible
Contra: The call instruction looks strange and is a bit cumbersome

The CALL's can be simplyfied with the macro technic to something like

Code: Select all

%$MYLIBFUNC% arg1 arg2 ...

Personally, in my own library I'm using a mix of 2) and 3)


jeb

Re: able to run functions from another script?

Posted: 11 May 2020 07:41
by Aacini
You may also use the method fully described at this post:

Code: Select all

(
   rem Switch the context to the library file
   ren "%0" orig-main.bat
   ren Library.bat "%0"

   rem Call any function from the library. I.e.:
   call :anyFunction same parameters

   rem Switch the context back to the original file
   ren "%0" Library.bat
   ren orig-main.bat "%0"
)
The method just require to execute a couple ren commands at beginning and end of the code that uses the library functions, and enclose it in parentheses.

The advantage is that the function calls are exactly the same than when the functions were in the same file.

Re: able to run functions from another script?

Posted: 11 May 2020 09:17
by Eureka!
And yet another suggestion:

MAIN.cmd

Code: Select all

@echo off
setlocal


set RESULT=
call Maths :SUM 1 2
echo SUM RESULT = %RETURN%


set RESULT=
call Maths :MULTIPLY 1 2
echo MULTIPLY RESULT = %RETURN%

MATHS.cmd

Code: Select all

@echo off
setlocal

    set ALLPARMS=%*
    set ROUTINE=%1
    call set PassParms=%%ALLPARMS:%ROUTINE%=%%


    call %ROUTINE% %PassParms%


endlocal & set "RETURN=%RETURN%"
goto :EOF



::___________________________________________
::
                    :SUM (parm1 parm2)
::___________________________________________
::
    set /A RETURN=%1 + %2
goto :EOF 


::___________________________________________
::
                    :MULTIPLY  (parm1 parm2)
::___________________________________________
::
    set /A RETURN=%1 * %2
goto :EOF 

Output of MAIN.cmd: (Bit useless to add this, but here you go :))

Code: Select all

SUM RESULT = 3
MULTIPLY RESULT = 2
(Assuming that you will never use :<LABEL> as a parameter )

You can also call the MAths library llike this":
set Maths="c:\path to MathLibrary.cmd"
call %Maths% :SUM 1 2

Re: able to run functions from another script?

Posted: 11 May 2020 11:16
by T3RRY
Another approach still

Manipulate the Jobfile to equal the label to be called

Call the job label in the jobfile using %0 and pass on all other parameters used in the call.

JobCaller.bat

Code: Select all

@echo off
	CD "%~dp0"
	Setlocal DisableDelayedExpansion
::: - Allow Job file to call a label using it's own name
	Set "Switch.Job=REN Library_job!J#!.bat Library_job"
	Set "Job=Library_job"
::: - Track active Job#
	Set "J#=0"
	Set "End.Job=&& Set J#="
::: - Execute job with params via Call
	Set "EXC=&& Call"
	Setlocal EnableDelayedExpansion
	%Switch.Job%1.bat %EXC% %Job%1 one should equal %End.Job%1
	%Switch.Job%2.bat %EXC% %Job%2 two will equal %End.Job%2
	%Switch.Job%3.bat %EXC% %Job%3 three does equal %End.Job%3
::: - Reset Jobfile to Original name
	%Switch.Job%0.bat
Pause

Job_Library0.bat

Code: Select all

@Echo off
::: - call the target job  with arguments
	Call :%0 %*
	Exit /B
::: - Examples showing jobs called and parameters passed

:Library_job1
	Echo Library_job1 %* 1
Exit /B
:Library_job2
	Echo Library_job2 %* 2
Exit /B
:Library_job3
	Echo Library_job3 %* 3
Exit /B