Welcome!

By registering with us, you'll be able to discuss, share and private message with other members of our community.

SignUp Now!

defering a chain operation

Apr
318
7
If I DEFER a chain (without the CALL statement) to another batch (so I can cleanup a bit before QUITing) TCC disbehaves. Starting batches from the commandline doesn't work anymore and starting an external program does not display the prompt (I.e. wait ).

Cheers, DJ
 
My very first attempt to figure out what DJ meant proved interesting. Below (1) the deferred command was apparently not executed, and (2) later, the prompt did not appear after issuing the "notepad" command (I do not "Wait for external apps").
Code:
v:\> type deferbat.btm
defer v:\echofoo.btm

v:\> type v:\echofoo.btm
echo foo

v:\> deferbat.btm

v:\> notepad deferbat.btm
< no prompt until notepad was closed >
 
And, as DJ said, after that experiment, TCC would not run BTMs at all.
 
Also, with "Wait for external apps" unchecked, an external specified with DEFER (e.g., "defer notepad") runs in the batch file context; that is with TCC waiting for it to finish. The help's "Purpose: Execute a command after the batch file exits" suggests (at least to me) that that shouldn't be the case.
 
DEFER was never intended for executing batch files, and would in fact require rewriting the parser to support that.

But since I can't think of any reason why you would need to DEFER a batch file, I don't think it's a significant limitation (and nobody has found any reason to do it for 20 years!).
 
DEFER was never intended for executing batch files, and would in fact require rewriting the parser to support that.

But since I can't think of any reason why you would need to DEFER a batch file, I don't think it's a significant limitation (and nobody has found any reason to do it for 20 years!).
I think DEFER only goes back seven or eight years. I can't think of a reason one would *NEED* to DEFER anything (and if there is, I don't see why batch file should be special). DEFER seems to be just a convenience.
Anyway, if the help spelled things out more, this question might not have been raised. Experimentation leads me to believe that when DEFER'd commands are executed ...
1. you're still in the batch interpreter (and _batch = 1 and external apps are waited for)
2. an automatic, end-of-batch ENDLOCAL has taken place
3. ON handlers have been cancelled
4. batch arguments no longer exist and trying to refer to them causes trouble ... for example, if you run this one (below) once, you won't see the arg0 line and thereafter TCC won't run any batch files.
Code:
v:\> type deferbat.btm
echo I am %0
defer echo arg0 = %%0
quit

As for DEFERing batch files, "DEFER CALL batchfile" seems to work OK and may satisfy DJ's original purposes.
 
Last edited:
I use this line in temporary batch files that only need to be run once:
Code:
defer del %0

(That works because the %0 is expanded at the time of the DEFER command.)
 
I'm not sure I understand the problem -- can you provide an example?

Well, I can show you the code. Don't know if it will be helpfull, but here it is:

Code:
:: ----------------------
:: %1=version, %2=appspec
:: ----------------------
set LibVersion=0.8
set AppVersion=%@REGEXSUB[1,"(\d+\.\d+(\.\d+)*|auto)","%1"]
switch "%AppVersion"
    case "auto"
        set MappedVersion=%LibVersion
    case "0.1"
        set MappedVersion=0.4
    case "0.2"
        set MappedVersion=0.4
    default
        iff "%AppVersion" eq "" then
            echoerr %@upper[%@name[%0]]: version not recognized.
        else
            echoerr %@upper[%@name[%0]]: version %AppVersion is not supported.
            echoerr Depreciated versions should adapt to the next higher supported version.
        endiff
        quit 1
endswitch

:: By slightly defering the chain,
defer %jpHome\Projects\TCApp\v%MappedVersion\TCApp.BTM %2$

:: you can cleanup _all_ envars.
:: In the case of MappedVersion important for reentrancy of the framework
unset AppVersion LibVersion MappedVersion

quit 0

What you're looking at is a dispatcher of jobs that selects the right version of a framework for the job to run within. (that probably didn't tell you much, but this particular source file just is not any longer)

I added some comment at the end to clarify what I am trying to do - and I do want to point out that the manual explicitely talks about cmdline expansion being done immediately or delayed, suggesting to me a way of cleaning up in cases like this.

And yes, I can think of several workarounds. I am not blocked in my work.

DJ
 
Last edited:
I use this line in temporary batch files that only need to be run once:
Code:
defer del %0

(That works because the %0 is expanded at the time of the DEFER command.)

Exactly. I've written a little sub that makes "auto-delete" temporary files. I find it very convenient.

Code:
:: ------
:__TmpBtm [ in_basepath _autodel ]
:: ------
    set tmpFile=%@QUOTE[%@UNIQUE[%@IF["%in_basepath" eq "",%temp,%in_basepath]]]
    set _TmpBtm=%%@RTRIM[.txt,%tmpFile].BTM
    ren /q %tmpFile %_TmpBtm
    if %_autodel==1 defer del /q %_TmpBtm
    unset tmpFile
return

Not every implementation detail is clear in this example (there's a big piece of context missing) but I think it is sufficient to underline the point that DEFER can be very useful.

DJ
 
I don't understand. There's no "DEFER" in there. And simply running TCApp.btm will cause the current BTM to exit and it will never reach the UNSET command before the QUIT.
 
DEFER was never intended for executing batch files, and would in fact require rewriting the parser to support that.

But since I can't think of any reason why you would need to DEFER a batch file, I don't think it's a significant limitation (and nobody has found any reason to do it for 20 years!).

Really Rex, "blaming the customer" ?

You can not blame the customer for not knowing the intended use if it's not mentioned in the manual. Also, I wonder what you base your judgement on that it is "not a significant limitation" if you haven't bothered to look at the use-case.

I merely posted, because I stumbled on a way to compromise the normal functioning of your product. Normally I would expect somebody to take note, say thanks, plug the hole and fix the documentation.

Personally, I do feel that the DEFER command has interesting and useful applications (I've presented two) and that to exclude batches from being deferred would significantly limit its usefulness.

Cheers,

DJ
 
Last edited:
I use this line in temporary batch files that only need to be run once:
Code:
defer del %0

(That works because the %0 is expanded at the time of the DEFER command.)

If it's a .BTM file, or if you do a LOADBTM ON first, you can DEL %0 at any point within the batch file....
 
Really Rex, "blaming the customer" ?

You can not blame the customer for not knowing the intended use if it's not mentioned in the manual.

The documentation for DEFER says "Execute a command after the batch file exits". It does not say anything about supporting batch files -- a "command" in the context of the help file refers only to internal or external commands, not batch files. If batch files were also supported they would be explicitly mentioned.

If you want to request support for batch files in DEFER, please post it in the feedback forum. (Since it will require a substantial parser rewrite, it will need a significant amount of support from other users.)
 
a "command" in the context of the help file refers only to internal or external commands, not batch files. If batch files were also supported they would be explicitly mentioned.

I think we're pretty used to "command" including batch files, aliases, URLs, ... anything with an association. START and DO /P, for example, handle batch files without the help explicitly saying so.

Anyway, what about
Code:
defer call batch_file
That seems to work just fine, even if deferred BTMs themselves use "defer call batch_file".
 
DJ, please excuse the extremely tangential and off-topic nature of this post but the linguistic stickler in me noted something that I felt compelled to mention.

"Depreciated versions should adapt to the next higher supported version."

I'm virtually certain that the appropriate word in that sentence should be "deprecated" instead of "depreciated."
 
Just in case someone might be curious; the original problem I had to solve was how to clean up envars if you're not calling but chaining away to a secondary batch. The simple solution is, of course, defering the clean-up instead of the chain.
 
Back
Top