Please could you tell me if it's possible to call a subroutine which
exists in an external batch file?
Or do I have to extract the subroutine into its own batch file, and just
call that batch file instead?
Thanks for your help.
Regards,
Jonny
You could call the external batch file like so:
call c:\tools\ExternalBatchFile sub
then code that batch file as follows:
@echo off
if "%1"=="sub" goto sub
other lines of code
more code
goto :eof
:sub
subroutine code
goto :eof
Great idea. Thanks,
Regards,
Jonny
goto x%1
:x
echo default
goto:eof
:xsub
rem sub code
This is certainly a more dynamic approach, typically used in command /
scripting languages because of their ability to evaluate program entities
[e.g. label names] at runtime. There exists, however, the possibility of a
non-matching argument [i.e. %1 matches no part existing label names] being
passed, thus raising an interpreter error condition.
If this condition can be trapped then a default action may be taken, and
batch / script execution continue. However, AFAIK, this cannot be done in NT
/ W2K / XP batch language. The typical behaviour which is seen is, I
believe:
* Error message is issued [though it can be redirected
using '2>']:
"The system cannot find the batch label specified - ..."
* Batch execution is terminated, thus not even a default
action may be specified
I'd be interested to know whether there is any means of trapping interpreter
error conditions, thus allowing the suggested approach to be more reliably
used.
Cheers,
Anthony Borla
Nice one!
I prefer to keep subroutines within the same batch.
@echo off
lines of code
call :sub (arguments optional)
more code
goto :eof
:sub
subroutine code
goto :eof
--
Todd Vargo (double "L" to reply by email)
Place these two batches in the same folder and run Main.cmd ;-)
::Main.cmd:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
@echo off
echo We are in main.cmd
call :sub
echo leaving main.cmd
goto :eof
:sub
echo entered :sub in main.cmd
External.cmd
echo we never reach here
::Main.cmd::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
::External.cmd::::::::::::::::::::::::::::::::::::::::::::::::::::::
@echo off
echo external running
goto :eof
:sub
echo entered sub in external.cmd
echo there is no call or goto inside External.cmd to reach here.
::External.cmd::::::::::::::::::::::::::::::::::::::::::::::::::::::
HTH
--
Gruesse Greetings Saludos Saluti Salutations
Matthias
---------+---------+---------+---------+---------+---------+---------+
It is difficult to code an all-purpose error condition trapper. Better,
imho, to code for those specific conditions one can anticipate. In this
case, consider something like:
::: zzz.cmd: demo routine...
@echo off
set _me_zzz=%0
>nul find /i <%0 ":_%1 :"
if errorlevel 1 (
echo/Attempt to call Non-existing batch function "%~0:_%1"
echo/please advise application owner of this problem.
pause
goto:eof
)
shift
goto:_%0
:_ : default entry point
echo/this is in the default entry point
call %_me_zzz% sub
call %_me_zzz% badsub
pause
goto:eof
:_sub : this is the test subroutine
echo/this is in the test subroutine
goto:eof
False positives are prevented by prefixing the label name with ":_" and
suffixing with " :".
/Al
ERRATA: because of the shift, that last command should read:
goto x%0
/Al
> :_
> echo default
> goto:eof
>
> :_sub
> rem sub code
> goto:eof
>
> I also ALWAYS include a "goto:eof" at the end of the last subroutine (i.e.
> as part of the last subroutine). This is only redundant in those cases
where
> you will never add one more subroutine to the file.
>
> /Al
>
>
That's neat, Matthias. :)
I routinely use "_" instead of "x" in this context, and then use
"_"-prefixed labels ONLY when they need to be somehow referenced by a
calling batch script. In the example above, the existence of ANY label
starting with "X" would make that a potential target for other batch scripts
to use, even if this would be erroneous.
I also ALWAYS include the ":" label indicator (i.e.: goto:_%1), because if
you were to use CALL instead of GOTO, this avoids sending the command
processor on a wild goose chase looking for a separate batch script file.
Another issue here is that all parameter references in the called
subroutines would need to be offset by one. One way around that would be:
shift
goto x%1
Thanks, for some time I'm fiddling around with the idea to gather all
subs in a file BatchLib.cmd and include only stubs in the batches
which use the functions.
::LibDemo.cmd::::::::::::::::::::::::::::::::::::::::::::::::::::::::
@echo off&setlocal
Call :GetDate yy mm dd
echo %yy%-%mm%-%dd%
goto :eof
:DayNumber %Weekday% dow
:DaysToDate %days% yy mm dd
:FileDate %Filename% fy fm fd
:FileSizeComp %file% %operand% %size%
:GetDate yy mm dd
BatchLib.cmd %*
::LibDemo.cmd::::::::::::::::::::::::::::::::::::::::::::::::::::::::
::BatchLib.cmd:::::::::::::::::::::::::::::::::::::::::::::::::::::::
::contains all the functions from http://www.commandline.co.uk
::and my own ones.
::BatchLib.cmd:::::::::::::::::::::::::::::::::::::::::::::::::::::::
> foxidrive wrote:
>> On Sun, 27 Feb 2005 12:27:47 +0100, Matthias Tacke wrote:
>>
>> That's neat, Matthias. :)
>>
>
> Thanks, for some time I'm fiddling around with the idea to gather all
> subs in a file BatchLib.cmd and include only stubs in the batches
> which use the functions.
That'd keep you busy for a rainy day :)
The only drawback I can see is that you couldn't then rely on the behaviour
of a batch file once some subs in BatchLib.cmd have been changed. You'd
have to double check or beta test all the batches that relied on the
function that was updated.
Back in the dos days there was a similar program called PACO but which
housed all your .com files in a library. When disk clusters were precious
and com files were so small it was a great idea, but I didn't actually use
it because I would have had to edit all my batch files.
PACO collects COM files in library
Syntax: PACO f lib_file program
f=function code (see DOC):
L list, A add, U update, D delete, E extract
To run a program use lib name as prefix
Ver. 1.2 (c) 1995-97, Horst Schaeffer
LOL! That's *ALL* we need - another SystemGuard-type of guy! ;-)
/Al
Certainly a robust example, thank you.
Cheers,
Anthony Borla
I'm mortally offended.
Can't remember I ever tried to *sell* trivial ideas.
> Al Dunbar wrote:
>>
>> LOL! That's *ALL* we need - another SystemGuard-type of guy! ;-)
>>
>
> I'm mortally offended.
> Can't remember I ever tried to *sell* trivial ideas.
I would demand satisfaction from Al, Matthias...
Here, use this glove to slap him across the face. ;)
All your libraries are native commands!
LOL, I'll need a fugleman then (or is it second?) and a Doctor.
But I see, I forgot the smiley ;-)
No problem, the smiley was understood.
Perhaps you should test out that beta newreader addon I heard about. It
appends smileys to all incoming and outgoing posts in order to reduce the
overall level of ill-will on a world-wide basis!
/Al
Whoa, that is a long overdue feature. ;-) <-- Auto appended smiley
Hey, that's cool! :-)
Really, laughing is healthy - so much yellow spots in my thunderbird ;-)
Has 40tude macro capabilities to do that?
Dialog has a scripting language similar to Pascal so many things are
possible :-)
> On Sun, 27 Feb 2005 12:27:47 +0100, Matthias Tacke wrote:
>
> That's neat, Matthias. :)
Yes, that is "neat", but could you explain how it works? Why does it go to
the subroutine within the external.cmd without being called?
--
George Bernard Shaw was an idiot.
I gave some time ago the (wrong) tip to break a call chain by simply
running another batch as it was possible in dos/w9x/me.
When doing that from a called sub this didn't work. The shell
maintains a call stack and happens to erroneously inserting the last
active sub when switching to the other batch returning to the first
batch afterwards.
Since there is no hope that MS will fix this (and no guarantee new
versions behave the same) use of this "feature" is at your own
risk ;-)
--
Gruesse Greetings Saludos Saluti Salutations
Matthias :-)
---------+---------+---------+---------+---------+---------+---------+