summaryrefslogtreecommitdiff
path: root/Master
diff options
context:
space:
mode:
authorPiotr Strzelczyk <piotr@eps.gda.pl>2010-04-14 23:54:20 +0000
committerPiotr Strzelczyk <piotr@eps.gda.pl>2010-04-14 23:54:20 +0000
commit3899b58e34a03e8ad988f7436da0be1a14faa0ec (patch)
tree07b31a6a3fea70b815cfb04d02b7bd5448049aa1 /Master
parentbfda7f57f3a45f2390c6a5ad3df5a72fbdd81e4e (diff)
- encapsulated main chunk in a function to execute with
pcall for more robustness and better error catching - added texdoctk to scripts4tlperl table - added tlgs and tlperl to alias_table; callable as e.g.: runscript tlperl ... - doc tweaks git-svn-id: svn://tug.org/texlive/trunk@17871 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master')
-rw-r--r--Master/bin/win32/runscript.tlu570
1 files changed, 293 insertions, 277 deletions
diff --git a/Master/bin/win32/runscript.tlu b/Master/bin/win32/runscript.tlu
index 40e9577fc06..718fdb938c2 100644
--- a/Master/bin/win32/runscript.tlu
+++ b/Master/bin/win32/runscript.tlu
@@ -1,186 +1,197 @@
-
--- $Id$
-
-local svnrevision = string.match("$Revision$", "%d+") or "0"
-local svndate = string.match("$Date$", "[-%d]+") or "2009-12-04"
-local bannerstr = "runscript wrapper utility (rev. " ..
- svnrevision .. ", " .. svndate .. ")\n" ..
- "usage: runscript script-name [arguments]\n" ..
- "try -help [-v] for more information"
-
-local helpstr = [[
-
- Script wrappers in TeX Live on Windows
-
- Rationale
-
- Wrappers enable use of scripts on Windows as regular programs.
- They are also required for some binary programs to set up the
- right environment for them.
-
- Batch scripts can be used for wrapping but they are not as universal
- as binaries (there are some odd cases where they don't work) and
- it is hard to make them robust and secure. Compiled binary wrappers
- don't suffer from these problems but they are harder to write, debug
- and maintain in comparison to scripts. For these reasons a hybrid
- approach is taken that combines a binary stub with a launcher script.
-
- Adding wrappers for user scripts
-
- The script wrapping machinery is not limited to scripts shipped with
- TeX Live. You can also use it for script programs from manually
- installed packages, which should minimize the problems when using
- them with TeX Live.
-
- First, make sure that there is an interpreter program available on
- your system for the script you want to use. Interpreters for Perl
- and Lua are bundled with TeX Live, all others have to be installed
- independently. Lua scripts are the most efficient to run, so if you
- consider writing a new script, that would be the recommended choice.
-
- The following script types and their file extensions are currently
- supported and searched in that order:
-
- Lua (.tlu;.texlua;.lua) -- included
- Perl (.pl) -- included
- Ruby (.rb) -- requires installation
- Python (.py) -- requires installation
- Tcl (.tcl) -- requires installation
- Java (.jar) -- requires installation
- VBScript (.vbs) -- part of Windows
- Jscript (.js) -- part of Windows
- Batch (.bat;.cmd) -- part of Windows
-
- For Unix-style extensionless scripts the first line of the script is
- consulted for a she-bang (#!) specification of the interpreter
- program. This can be an arbitrary program but it must be present on
- the search path.
-
- Next, the script program needs to be installed somewhere below the
- 'scripts' directory under one of the TEXMF trees (consult the
- documentation or texmf/web2c/texmf.cnf file for a list). You may
- need to update the file search database afterwards with:
-
- mktexlsr [TEXMFDIR]
-
- Test if the script can be located with:
-
- kpsewhich --format=texmfscripts <script-name>.<ext>
-
- Once installed the script can be called immediately with:
-
- runscript <script-name> [script arguments]
-
- If you prefer to call the script program simply by its name, copy
- and rename bin/win32/runscript.exe to <script-name>.exe and put it
- in bin/win32/ directory of your TeX Live installation or, if you
- don't have the write permissions there, somewhere else on the search
- path.]]
-
-local docstr = [[
-
- Wrapper structure
-
- Wrappers consist of small binary stubs and a common texlua script.
- The binary stubs are all the same, just different names (but CLI
- and GUI stubs differ, see below, and GUI stubs are actually all
- different due to different embedded icons).
-
- The job of the binary stub is twofold: (a) call the texlua launcher
- script 'runscript.tlu' from the same directory (or more precisely
- from the directory containing 'runscript.dll') and (b) pass to it
- argv[0] and the unparsed argument string as the last two arguments
- (after adding a sentinel argument, which ends with a new line
- character). Arbitrary C strings can be passed, because the script
- is executed by linking with luatex.dll and calling the lua
- interpreter internally rather than by spawning a new process.
-
- There are two flavours of the binary stub: one for CLI programs
- and another one for GUI programs. The GUI variant does not open
- a console window nor does it block the command prompt if started
- from there. It also uses a dialog box to display an error message
- in addition to outputting to stderr.
-
- The stubs are further split into a common DLL and EXE proxies
- to it. This is for maintenance reasons - updates can be done by
- replacement of a single DLL rather than all binary stubs.
-
- The launcher script knows, which variant has been used to invoke it
- based on the sentinel argument. The lack of this argument means
- that it was invoked in a standard way, i.e. through texlua.exe.
-
- All the hard work of locating a script/program to execute happens
- in the launcher script. The located script/program is always
- executed directly by spawning its interpreter (or binary) in a new
- process. The system shell (cmd.exe) is never called (except for
- batch scripts, of course). If the located script happens to be
- a (tex)lua script, it is loaded and called internally from within
- this script, i.e. no new process is spawned.
-
- Source files
-
- runscript.tlu launcher script for locating and dispatching
- target scripts/programs
- runscript_dll.c common DLL part of the binary stubs; locates and
- calls the launcher script
- runscript_exe.c EXE proxy to the common DLL for CLI mode stubs
- wrunscript_exe.c EXE proxy to the common DLL for GUI mode stubs
-
- Compilation of binaries (requires luatex.dll in the same directory)
-
- with gcc (size optimized):
-
- gcc -Os -s -shared -o runscript.dll runscript_dll.c -L./ -lluatex
- gcc -Os -s -o runscript.exe runscript_exe.c -L./ -lrunscript
- gcc -mwindows -Os -s -o wrunscript.exe wrunscript_exe.c -L./ -lrunscript
-
- with tcc (extra small size):
-
- tiny_impdef luatex.dll
- tcc -shared -o runscript.dll runscript_dll.c luatex.def
- tcc -o runscript.exe runscript_exe.c runscript.def
- tcc -o wrunscript.exe wrunscript_exe.c runscript.def
-
- License
-
- Originally written in 2009 by Tomasz M. Trzeciak, Public Domain.
-
- Prior work:
- 'tl-w32-wrapper.texlua' by Reinhard Kotucha and Norbert Preining.
- 'tl-w32-wrapper.cmd' by Tomasz M. Trzeciak.
-
- Changelog
-
- 2009/12/04
- - initial version
- 2009/12/15
- - minor fixes for path & extension list parsing
- 2010/01/09
- - added support for GUI mode stubs
- 2010/02/28
- - enable GUI mode stubs for dviout, psv and texworks;
- - added generic handling of sys programs
- - added restricted repstopdf to alias_table
- 2010/03/13
- - added 'readme.txt' and changelog
- - added support and docs for calling user added scripts;
- (use path of 'runscript.dll' instead of .exe stub to
- locate 'runscript.tlu' script)
- - limit search for shell_escape_commands to system trees
- - added function for creating directory hierarchy
- - fixed directory creation for dviout & texworks aliases
- - fixed arg[0] of repstopdf & rpdfcrop
- 2010/03/28
- - restructured docs, added --help and --version options
- (available only when invoked under 'runscript' name)
- - use TEXMF_RESTRICTED_SCRIPTS kpse var for searching
- shell_escape_commands
- - changed command validation to handle a list of commands
- - prepend GUI mode command(s) to the command list
- - added support for .tcl scripts
- 2010/03/31
- - fixed fatal bug in extention_map definition for GUI mode
-]]
+
+-- $Id$
+
+local svnrevision = string.match("$Revision$", "%d+") or "0"
+local svndate = string.match("$Date$", "[-%d]+") or "2009-12-04"
+local bannerstr = "runscript wrapper utility (rev. " ..
+ svnrevision .. ", " .. svndate .. ")\n" ..
+ "usage: runscript script-name [arguments]\n" ..
+ "try -help [-v] for more information"
+
+local helpstr = [[
+
+ Script wrappers in TeX Live on Windows
+
+ Rationale
+
+ Wrappers enable use of scripts on Windows as regular programs.
+ They are also required for some binary programs to set up the
+ right environment for them.
+
+ Batch scripts can be used for wrapping but they are not as universal
+ as binaries (there are some odd cases where they don't work) and
+ it is hard to make them robust and secure. Compiled binary wrappers
+ don't suffer from these problems but they are harder to write, debug
+ and maintain in comparison to scripts. For these reasons a hybrid
+ approach is taken that combines a binary stub with a launcher script.
+
+ Adding wrappers for user scripts
+
+ The script wrapping machinery is not limited to scripts shipped with
+ TeX Live. You can also use it for script programs from manually
+ installed packages, which should minimize the problems when using
+ them with TeX Live.
+
+ First, make sure that there is an interpreter program available on
+ your system for the script you want to use. Interpreters for Perl
+ and Lua are bundled with TeX Live, all others have to be installed
+ independently. Lua scripts are the most efficient to run, so if you
+ consider writing a new script, that would be the recommended choice.
+
+ The following script types and their file extensions are currently
+ supported and searched in that order:
+
+ Lua (.tlu;.texlua;.lua) -- included
+ Perl (.pl) -- included
+ Ruby (.rb) -- requires installation
+ Python (.py) -- requires installation
+ Tcl (.tcl) -- requires installation
+ Java (.jar) -- requires installation
+ VBScript (.vbs) -- part of Windows
+ Jscript (.js) -- part of Windows
+ Batch (.bat;.cmd) -- part of Windows
+
+ For Unix-style extensionless scripts the first line of the script is
+ consulted for a she-bang (#!) specification of the interpreter
+ program. This can be an arbitrary program but it must be present on
+ the search path.
+
+ Next, the script program needs to be installed somewhere below the
+ 'scripts' directory under one of the TEXMF trees (consult the
+ documentation or texmf/web2c/texmf.cnf file for a list). You may
+ need to update the file search database afterwards with:
+
+ mktexlsr [TEXMFDIR]
+
+ It is also possible to use scripts that are outside of TEXMF hierarchy
+ by adjusting TEXMFSCRIPTS environment or kpathsea variable, see
+ kpathsea documentation for more information on setting its variables.
+
+ Test if the script can be located with:
+
+ kpsewhich --format=texmfscripts <script-name>.<ext>
+
+ Once installed the script can be called immediately with:
+
+ runscript <script-name> [script arguments]
+
+ If you prefer to call the script program simply by its name, copy
+ and rename bin/win32/runscript.exe to <script-name>.exe and put it
+ in bin/win32/ directory of your TeX Live installation or, if you
+ don't have the write permissions there, somewhere else on the search
+ path.]]
+
+local docstr = [[
+
+ Wrapper structure
+
+ Wrappers consist of small binary stubs and a common texlua script.
+ The binary stubs are all the same, just different names (but CLI
+ and GUI stubs differ, see below, and GUI stubs are actually all
+ different due to different embedded icons).
+
+ The job of the binary stub is twofold: (a) call the texlua launcher
+ script 'runscript.tlu' from the same directory (or more precisely
+ from the directory containing 'runscript.dll') and (b) pass to it
+ argv[0] and the unparsed argument string as the last two arguments
+ (after adding a sentinel argument, which ends with a new line
+ character). Arbitrary C strings can be passed, because the script
+ is executed by linking with luatex.dll and calling the lua
+ interpreter internally rather than by spawning a new process.
+
+ There are two flavours of the binary stub: one for CLI programs
+ and another one for GUI programs. The GUI variant does not open
+ a console window nor does it block the command prompt if started
+ from there. It also uses a dialog box to display an error message
+ in addition to outputting to stderr.
+
+ The stubs are further split into a common DLL and EXE proxies
+ to it. This is for maintenance reasons - updates can be done by
+ replacement of a single DLL rather than all binary stubs.
+
+ The launcher script knows, which variant has been used to invoke it
+ based on the sentinel argument. The lack of this argument means
+ that it was invoked in a standard way, i.e. through texlua.exe.
+
+ All the hard work of locating a script/program to execute happens
+ in the launcher script. The located script/program is always
+ executed directly by spawning its interpreter (or binary) in a new
+ process. The system shell (cmd.exe) is never called (except for
+ batch scripts, of course). If the located script happens to be
+ a (tex)lua script, it is loaded and called internally from within
+ this script, i.e. no new process is spawned.
+
+ Source files
+
+ runscript.tlu launcher script for locating and dispatching
+ target scripts/programs
+ runscript_dll.c common DLL part of the binary stubs; locates and
+ calls the launcher script
+ runscript_exe.c EXE proxy to the common DLL for CLI mode stubs
+ wrunscript_exe.c EXE proxy to the common DLL for GUI mode stubs
+
+ Compilation of binaries (requires luatex.dll in the same directory)
+
+ with gcc (size optimized):
+
+ gcc -Os -s -shared -o runscript.dll runscript_dll.c -L./ -lluatex
+ gcc -Os -s -o runscript.exe runscript_exe.c -L./ -lrunscript
+ gcc -mwindows -Os -s -o wrunscript.exe wrunscript_exe.c -L./ -lrunscript
+
+ with tcc (extra small size):
+
+ tiny_impdef luatex.dll
+ tcc -shared -o runscript.dll runscript_dll.c luatex.def
+ tcc -o runscript.exe runscript_exe.c runscript.def
+ tcc -o wrunscript.exe wrunscript_exe.c runscript.def
+
+ License
+
+ Originally written in 2009 by Tomasz M. Trzeciak, Public Domain.
+
+ Prior work:
+ 'tl-w32-wrapper.texlua' by Reinhard Kotucha and Norbert Preining.
+ 'tl-w32-wrapper.cmd' by Tomasz M. Trzeciak.
+
+ Changelog
+
+ 2009/12/04
+ - initial version
+ 2009/12/15
+ - minor fixes for path & extension list parsing
+ 2010/01/09
+ - added support for GUI mode stubs
+ 2010/02/28
+ - enable GUI mode stubs for dviout, psv and texworks;
+ - added generic handling of sys programs
+ - added restricted repstopdf to alias_table
+ 2010/03/13
+ - added 'readme.txt' and changelog
+ - added support and docs for calling user added scripts;
+ (use path of 'runscript.dll' instead of .exe stub to
+ locate 'runscript.tlu' script)
+ - limit search for shell_escape_commands to system trees
+ - added function for creating directory hierarchy
+ - fixed directory creation for dviout & texworks aliases
+ - fixed arg[0] of repstopdf & rpdfcrop
+ 2010/03/28
+ - restructured docs, added --help and --version options
+ (available only when invoked under 'runscript' name)
+ - use TEXMF_RESTRICTED_SCRIPTS kpse var for searching
+ shell_escape_commands
+ - changed command validation to handle a list of commands
+ - prepend GUI mode command(s) to the command list
+ - added support for .tcl scripts
+ 2010/03/31
+ - fixed fatal bug in extention_map definition for GUI mode
+ 2010/04/15
+ - encapsulated main chunk in a function to execute with
+ pcall for more robustness and better error catching
+ - added texdoctk to scripts4tlperl table
+ - added tlgs and tlperl to alias_table; callable as e.g.:
+ runscript tlperl ...
+ - doc tweaks
+]]
-- HELPER SUBROUTINES --
@@ -252,8 +263,8 @@ local function shebang_to_argv(progfullname)
end
-- checks if command exists on the path and returns its full path
-local function check_command(cmdlist, PATH)
- for cmd in string.gmatch(cmdlist, '%S+') do
+local function check_command(cmdlist, PATH)
+ for cmd in string.gmatch(cmdlist, '%S+') do
local cmdext = cmd..(string.find(cmd, '%.[^\\/.]*$') and '' or '.exe')
local fullcmd = is_abs_path(cmdext) and lfs.isfile(cmdext) and
cmdext or search_path(cmdext, PATH)
@@ -279,10 +290,10 @@ local function mkdir_plus(dir)
end
end
--- MAIN CHUNK --
+-- MAIN_CHUNK -- encapsulated in a function for more robust execution with pcall
+
+local function MAIN_CHUNK()
--- localize the assert function (it will be replaced in gui mode)
-local assert = assert
local guimode = false
local argline = ''
-- check for the sentinel argment coming from the .exe stub
@@ -293,73 +304,58 @@ if arg[#arg-2] and ( string.sub(arg[#arg-2], -1) == '\n' ) then
argline = table.remove(arg) -- pop unparsed arguments
arg[0] = table.remove(arg) -- pop C stub's argv[0]
guimode = (table.remove(arg) == 'GUI_MODE\n') -- pop sentinel argument
- if guimode then
- -- replace the assert function, if we are running w/o console window
- function assert(...)
- if select(1, ...) then return ... end
- local error_msg = select(2, ...)
- if type(error_msg) ~= 'string' then
- error_msg = "assertion failed!"
- end
- -- store the error message in an env var and throw an error
- -- it will be catched on the C side at exit and displayed
- -- in a message box
- os.setenv('RUNSCRIPT_ERROR_MESSAGE', error_msg)
- error(error_msg, 2)
- end
- end
else
-- we must be called as: texlua runscript.tlu progname ...
-- this is treated the same as: runscript[.exe] progname ...
-- we don't have the unparsed arument line in this case, so construct one
for k = 1, #arg do argline = argline..' '.._q(arg[k]) end
end
-
--- special behaviour when called under 'runscript' name
+
+-- special behaviour when called under 'runscript' name
-- ( lower arg[0] : get file name part : remove extension ) == 'runscript'
if (string.lower(arg[0]):match('[^\\/]+$'):gsub('%.[^.]*$', '') == 'runscript') then
- -- we are called as: runscript progname ...
- -- or as: runscript --help|-h|--version ...
- -- handle options first (only -help and -version)
- local opt = { h = false, help = false, v = false, version = false }
+ -- we are called as: runscript progname ...
+ -- or as: runscript --help|-h|--version ...
+ -- handle options first (only --help and --version)
+ local opt = { h = false, help = false, v = false, version = false }
local param, k
- while true do
+ while true do
-- remove the first argument from the arg table and from the argline string
- -- (this argument should have no embedded spaces!)
- param = table.remove(arg, 1)
- if not param then break end
+ -- (this argument should have no embedded spaces!)
+ param = table.remove(arg, 1)
+ if not param then break end
argline = string.gsub(argline, '^%S+%s*', '')
- param, k = string.lower(param):gsub('^%-%-?', '')
- -- if an option was given
- if (k > 0) then
- if opt[param] == nil then
- assert(nil, "unknown option: "..param.."\n"..bannerstr)
- end
- opt[param] = true
- else
- break
- end
- end
- if opt.help or opt.h then
- print(helpstr)
- if opt.v then print(docstr) end
- os.exit(0)
- elseif opt.version or opt.v then
- print(bannerstr)
- os.exit(0)
- end
- -- make sure we a new arg[0] is given and proceed
+ param, k = string.lower(param):gsub('^%-%-?', '')
+ -- if an option was given
+ if (k > 0) then
+ if opt[param] == nil then
+ error("unknown option: "..param.."\n"..bannerstr)
+ end
+ opt[param] = true
+ else
+ break
+ end
+ end
+ if opt.help or opt.h then
+ print(helpstr)
+ if opt.v then print(docstr) end
+ os.exit(0)
+ elseif opt.version or opt.v then
+ print(bannerstr)
+ os.exit(0)
+ end
+ -- make sure we a new arg[0] is given and proceed
arg[0] = assert(param, "not enough arguments!\n"..bannerstr)
end
-
--- kpse and environment set-up
+
+-- kpse and environment set-up
-- program name
local progname, k = string.lower(arg[0]):match('[^\\/]+$'):gsub('%.[^.]*$', ''):gsub('%-sys$', '')
local sysprog = (k > 0) -- sys type program/script (there was -sys suffix removed)
if (progname == 'runscript') then -- prevent recursive calls to this script
- assert(nil, "oops! wrapping the wrapper?")
+ error("oops! wrapping the wrapper?")
end
-- init kpathsea
local k = -1
@@ -372,8 +368,9 @@ local BINDIR = kpse.var_value('SELFAUTOLOC')
local PATH = os.getenv('PATH') or ''
-- perl stuff
local scripts4tlperl = {
- ['updmap-sys'] = true,
+ texdoctk = true,
updmap = true,
+ ['updmap-sys'] = true,
}
local PERLEXE = search_path('perl.exe', PATH)
if not PERLEXE or guimode or scripts4tlperl[progname] then
@@ -399,23 +396,18 @@ end
-- restricted programs
local shell_escape_commands = string.lower(kpse.var_value('shell_escape_commands'))
if string.find(','..shell_escape_commands..',', ','..progname..',', 1, true) then
- -- limit search path to the restricted (system) trees
- -- (not really necessary for entries in the alias_table,
- -- because they are not searched for with kpathsea)
+ -- limit search path to the restricted (system) trees
+ -- (not really necessary for entries in the alias_table,
+ -- because they are not searched for with kpathsea)
os.setenv('TEXMFSCRIPTS', kpse.var_value('TEXMF_RESTRICTED_SCRIPTS'))
end
--- alias table (programs with special needs)
+-- alias table (programs with special needs)
local alias_table = {--[[
['fmtutil-sys'] = {[0]=BINDIR..'/fmtutil.exe', 'fmtutil-sys', argline},
- ['updmap-sys'] =
- function ()
- os.setenv('TEXMFVAR', kpse.var_value('TEXMFSYSVAR'))
- os.setenv('TEXMFCONFIG', kpse.var_value('TEXMFSYSCONFIG'))
- return {[0]=PERLEXE, 'perl',
- _q(TEXDIR..'/texmf/scripts/tetex/updmap.pl'), argline}
- end,--]]
+ ['updmap-sys'] = {[0]=PERLEXE, 'perl',
+ _q(TEXDIR..'/texmf/scripts/tetex/updmap.pl'), argline},--]]
asy =
function ()
-- TODO: check if ASYMPTOTE_GS requires quoting of names with spaces
@@ -467,36 +459,38 @@ local alias_table = {--[[
end
return {[0]=TEXDIR..'/tlpkg/texworks/texworks.exe', 'texworks', argline}
end,
+ tlgs = {[0]=TEXDIR..'/tlpkg/tlgs/bin/gswin32c.exe', 'gswin32c', argline},
+ tlperl = {[0]=PERLEXE, 'perl', argline},
}
-
--- extension to interpeter mapping
-
--- the extension is mapped to argv table
--- the command to execute is given as the first element of the table
+
+-- extension to interpeter mapping
+
+-- the extension is mapped to argv table
+-- the command to execute is given as the first element of the table
-- (it can be a whitespace separated list of names to try)
local extension_map = {
['.bat'] = {'cmd', '/c', 'call'},
['.jar'] = {'java.exe', '-jar'},
- ['.pl' ] = {'perl.exe'},
- ['.py' ] = {'python.exe'},
- ['.rb' ] = {'ruby.exe'},
+ ['.pl' ] = {'perl.exe'},
+ ['.py' ] = {'python.exe'},
+ ['.rb' ] = {'ruby.exe'},
['.tcl'] = {'tclsh.exe tclsh85.exe tclsh84.exe'},
['.vbs'] = {'cscript.exe', '-nologo'},
-}
-if guimode then
- -- for GUI mode wrappers we try GUI mode interpeters where possible
- extension_map['.jar'][1] = 'javaw.exe ' .. extension_map['.jar'][1]
- extension_map['.pl' ][1] = 'wperl.exe ' .. extension_map['.pl' ][1]
- extension_map['.py' ][1] = 'pythonw.exe ' .. extension_map['.py' ][1]
- extension_map['.py' ][1] = 'rubyw.exe ' .. extension_map['.py' ][1]
- extension_map['.tcl'][1] = 'wish.exe wish85.exe wish84.exe ' .. extension_map['.tcl'][1]
- extension_map['.vbs'][1] = 'wscript.exe ' .. extension_map['.vbs'][1]
-end
-extension_map['.cmd'] = extension_map['.bat']
-extension_map['.js'] = extension_map['.vbs']
+}
+if guimode then
+ -- for GUI mode wrappers we try GUI mode interpeters where possible
+ extension_map['.jar'][1] = 'javaw.exe ' .. extension_map['.jar'][1]
+ extension_map['.pl' ][1] = 'wperl.exe ' .. extension_map['.pl' ][1]
+ extension_map['.py' ][1] = 'pythonw.exe ' .. extension_map['.py' ][1]
+ extension_map['.py' ][1] = 'rubyw.exe ' .. extension_map['.py' ][1]
+ extension_map['.tcl'][1] = 'wish.exe wish85.exe wish84.exe ' .. extension_map['.tcl'][1]
+ extension_map['.vbs'][1] = 'wscript.exe ' .. extension_map['.vbs'][1]
+end
+extension_map['.cmd'] = extension_map['.bat']
+extension_map['.js'] = extension_map['.vbs']
-- set up argv table
-
+
local program = alias_table[progname]
if program then -- special case (alias)
if (type(program) == 'function') then
@@ -515,20 +509,42 @@ else -- general case (no alias)
else
program = extension_map[ext] or assert(shebang_to_argv(progfullname))
table.insert(program, _q(progfullname))
- table.insert(program, argline)
- if not program[0] then
+ table.insert(program, argline)
+ if not program[0] then
program[0], program[1] = assert(check_command(program[1], PATH))
end
end
end
-
--- run the program/script
+
+-- run the program/script
if (type(program) == 'table') then
- os.exit(assert(os.spawn(program)))
+ local ret = assert(os.spawn(program))
+ if ret ~= 0 then
+ local dbginfo = debug.getinfo(1)
+ local errormsg = string.format("%s:%d: command failed with exit code %d:\n%s",
+ dbginfo.short_src, dbginfo.currentline - 2, ret, table.concat(program, ' ') )
+ os.setenv('RUNSCRIPT_ERROR_MESSAGE', errormsg)
+ io.stderr:write(errormsg, '\n')
+ end
+ os.exit(ret)
elseif (type(program) == 'string') then
- program = assert(loadfile(program))
- program()
+ dofile(program)
else
- assert(nil, "unexpected argument type: "..type(program))
+ error("unexpected argument type: " .. type(program))
+end
+
+end -- MAIN_CHUNK
+
+-- execute main_proc with pcall to catch any runtime errors
+
+local success, errormsg = pcall(MAIN_CHUNK)
+if not success then
+ os.setenv('RUNSCRIPT_ERROR_MESSAGE', errormsg)
+ error(errormsg)
end
+
+-- about RUNSCRIPT_ERROR_MESSAGE environment variable:
+-- it stores an error message that is catched and displayed
+-- in a message box on the C side at process exit
+-- (currently used only by gui mode stubs)