Version 9 of DOS BAT magic

Updated 2002-11-22 20:35:17

::set - {

 @goto start

Richard Suchenwirth - In exec magic, it was explained how a script can be understood both by a Unix shell (which starts tclsh with itself) and Tcl. Here's my version of how to achieve the same with MS-DOS batch files.

The first line (up above) is the first trick - to DOS it's an acceptable label because of the leading colon (:), so it proceeds to the :start label (you can omit that section, it's only to document it in Wiki style ;-) The commands after that turn off the echoing of command input and possibly complete the filename with the .bat extension. But you still have to call this script with relative path name - BAT files are searched on PATH but don't tell you where they were found. Then tclsh is called with the name of the script and up to 9 arguments, which you may group in DOS with double quotes if they contain whitespace or are empty strings, and after that control is transfered to the again fancily named label "end of BAT file", where the script ends without terminating its caller (which DOS's exit would do).

To Tcl, the global set command assigns the content of the braces to the variable "-" which is unset immediately after. From that line, your "payload" code may begin. In it, you may refer to environment variables that were set in the DOS part of the script - e.g ::env(script) or ::env(SCRIPT) (case doesn't matter that much for DOS) also contains the script's file name.

Finally, the label "end of BAT file" is hidden to Tcl by prolonging the preceding comment by the trailing backslash (which must not be omitted, like in exec magic).

For a linguist, twisting a single source file so that three very diverse languages (DOS-BAT, Tcl, and WikiML) understand it each in their own way, makes a small but entertaining weekend fun project...enjoy!


 :start
 @echo off
 set script=%0
 if exist %script%.bat set script=%script%.bat
 tclsh %script% %1 %2 %3 %4 %5 %6 %7 %8 %9
 goto end of BAT file
 };unset - ;#-------------------------------begin "payload" Tcl
 puts "Hello, DOS, time now is"
 puts [clock format [clock seconds]] 

rem echo "co to znaczy?"

 gets stdin line ;# just to test 
 puts [string toupper $line]
 puts [list argc: $argc argv: $argv]
 #------------------------------------------end Tcl\
 :end of BAT file

My god, Richard. You have brought back long supressed memories of multi-hundred line DOS batch files... -PSE