summaryrefslogtreecommitdiff
path: root/Master/bin/win32/runscript.tlu
diff options
context:
space:
mode:
authorAkira Kakuto <kakuto@fuk.kindai.ac.jp>2023-02-18 23:00:02 +0000
committerAkira Kakuto <kakuto@fuk.kindai.ac.jp>2023-02-18 23:00:02 +0000
commit047aa87fc09c5a339556abbd9f7efd9173c3a30f (patch)
treef9e5a7f9a1275937d5bb67ac1a22b54c794648d5 /Master/bin/win32/runscript.tlu
parentc161d2075c9aa004f188810883a543b5a0cfbec3 (diff)
windows binaries for TL2023
git-svn-id: svn://tug.org/texlive/trunk@65891 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/bin/win32/runscript.tlu')
-rwxr-xr-xMaster/bin/win32/runscript.tlu947
1 files changed, 0 insertions, 947 deletions
diff --git a/Master/bin/win32/runscript.tlu b/Master/bin/win32/runscript.tlu
deleted file mode 100755
index 5140e9af1af..00000000000
--- a/Master/bin/win32/runscript.tlu
+++ /dev/null
@@ -1,947 +0,0 @@
-
-
-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. This should minimize 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, Lua and Tcl/Tk (GUI scripts only) 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) -- included (GUI scripts only)
- Java (.jar) -- requires installation
- VBScript (.vbs) -- part of Windows
- JScript (.js) -- part of Windows
- Batch (.bat;.cmd) -- part of Windows
-
- Finally, Unix-style extensionless scripts are searched as last and
- the interpreter program is established based on the she-bang (#!)
- specification on the very first line of the script. 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>
-
- This should output the full path to the script if everything is
- properly installed and configured. If this test is successful,
- the script can be run 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 (or bin/win64/runscript.exe for
- 64-bit Windows) to <script-name>.exe and put it somewhere 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. Execution is done
- using a protected call, so any compile or runtime errors are caught.
-
- 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
- 2010/04/22
- - ensure only backslash is used in USERPROFILE variable
- (Adobe Reader crash case)
- - fixed argument processing for direct execution under texlua
- - more doc tweaks
- 2010/05/30
- - Windows XP or newer required to run TeXworks
- 2010/06/04
- - added support for Perl scripts starting with eval-exec-perl
- construct in place of she-bang (#!)
- 2010/06/25
- - run internal tlperl only with our Perl
- - added fontinst to alias_table
- - added support for all tex4ht commands from mk4ht.pl
- - removed some unsued aliases
- - some code refactoring and cleanup
- 2010/12/28
- - use of external Perl now requires kpathsea variable
- TEXLIVE_WINDOWS_TRY_EXTERNAL_PERL to be explicitly set to 1
- - alias_table replaced with if-elseif-end tests to streamline
- special cases and to avoid hardcoding of texmf* file paths
- - added a2ping to special cases (requires -x switch to Perl)
- - set ASYMPTOTE_GS (for asy) to full path to tlgs
- 2011/01/09
- - removed tex4ht commands starting with ht from mk4ht aliases;
- they have their own scripts and mk4ht calls them internally,
- so aliasing results in an infinite recursion
- - removed alias for fontinst (no fontinst.exe any more)
- - fixed GUI-mode interpreter for Ruby
- 2011/09/10
- - added -dDisableFAPI=true to psview argument list. Needed by
- gs-9.xx
- 2012/03/12
- - added '-i', '.' to psview argument list (author's request)
- - added environment clean up from Perl specific variables
- (when not using external Perl)
- 2012/08/05
- - added alias for fmtutil
- 2013/05/09
- - added alias mkluatexfontdb -> luaotfload-tool
- 2013/07/03
- - fix for psview and UNC paths in unix-style
- - remove not needed is_abs_path function
- 2013/08/07
- - handle updmap-sys via updmap --sys
- 2013/08/08
- - allow overriding gs/gs_dll/gs_lib with kpse variables
- TEXLIVE_WINDOWS_EXTERNAL_GS, ..._GS_LIB, ..._GS_DLL
- 2013/08/30
- - do not pass -NULL to dviout, to allow users changing and
- saving settings. Patch by Yusuke KUROKI
- 2013/09/22
- - add TEXMFDIST/fonts to the GS_LIB path. Patch by Yusuke KUROKI
- 2014/04/30
- - fix for argument duplication in fmtutil
- 2015/04/12
- - handle fmtutil-sys via fmtutil --sys
- 2015/09/10
- - more slash flipping for the sake of vbscript and unc paths
- 2015/12/11
- - fix spurious arguments for updmap and fmtutil
- 2016/04/22
- - Warning if external perl is requested but missing
- 2017/04/22 (exactly one year later ;-)
- - Cater for fmtutil-user and updmap-user => -user arg
- 2017/04/24
- - GS_LIB setting for tlgs.
- 2017/05/06
- - introduce sys_user_progs, make checks for updmap/fmtutil
- use sys_user_progs instead, add kanji-config-updmap
- 2018/03/12
- - introduce a new function gettexmfdist() for security.
- 2018/04/06
- - introduce a new function is_64bit_windows_os() to
- check Windows OS.
- 2018/06/20
- - support also scripts in trees other than TEXMFDIST:
- https://tug.org/pipermail/tex-live/2018-June/041922.html
- 2018/10/10
- - support cluttex scripts
- 2018/11/08
- - use included tcltk interpreter
-
-]]
-
--- HELPER SUBROUTINES --
-
-local TEXDIR
-local guimode
-
-local function show_error(msg)
- if guimode then
- local err_cmd
- os.setenv('RUNSCRIPT_ERROR_MESSAGE', msg)
- local errmess_path = TEXDIR .. '/texmf-dist/scripts/texlive/tl-errmess.vbs'
- local err_cmd = {"wscript", errmess_path:gsub('/','\\')}
- if lfs.isfile(errmess_path) then
- os.spawn(err_cmd)
- elseif lfs.isfile(TEXDIR..'/tlpkg/tltcl/tclkit.exe') and
- lfs.isfile(TEXDIR..'/tlpkg/tltcl/gui_err.tcl') then
- os.spawn{TEXDIR..'/tlpkg/tltcl/tclkit.exe',
- TEXDIR..'/tlpkg/tltcl/gui_err.tcl'}
- end
- else
- io.stderr:write(msg, '\n')
- end
-end
-
--- quotes string with spaces
-local function _q(str)
- str = string.gsub(str, '"', '') -- disallow embedded double quotes
- return string.find(str, "%s") and '"'..str..'"' or str
-end
-
--- prepends directories to path if they are not already there
-local function prepend_path(path, ...)
- local pathcmp = string.lower(string.gsub(path, '/', '\\'))..';'
- for k = 1, select('#', ...) do
- local dir = string.lower(string.gsub(select(k, ...), '/', '\\'))..';'
- if not string.find(pathcmp, dir, 1, true) then path = dir..path end
- end
- return path
-end
-
--- searches the PATH for a file
-local function search_path(fname, PATH, PATHEXT)
- if string.find(fname, '[/\\]') then
- return nil, "directory part not allowed for PATH search: "..fname
- end
- PATH = PATH or os.getenv('PATH')
- PATHEXT = PATHEXT or '\0' -- '\0' for no extension
- for dir in string.gmatch(PATH, '[^;]+') do
- local dirsep = (string.find(dir, '\\') and '\\' or '/')
- for ext in string.gmatch(PATHEXT, '[^;]+') do
- local f = dir..dirsep..fname..ext
- if lfs.isfile(f) then return f, ext end
- end
- end
- return nil, "file or program not on PATH: "..fname
-end
-
--- tests for tex4ht command (as given in mk4ht.pl)
--- except for commands starting with 'ht' (they have their own scripts)
-local function is_tex4ht_command(progname)
- local prefixes = 'xh uxh xhm mz oo es js jm tei teim db dbm w jh jh1'
- local formats = 'context latex tex texi xelatex xetex'
- for p in string.gmatch(prefixes, '%S+') do
- for q in string.gmatch(formats, '%S+') do
- if (progname == p..q) then
- -- we have a hit, but not all combinations are valid
- return (p ~= 'teim' and p ~= 'dbm') or (q ~= 'xelatex' and q~= 'xetex')
- end
- end
- end
- return false
-end
-
--- checks whether an item is in an array
-local function contains (tab, val)
- for index, value in ipairs(tab) do
- if value == val then
- return true
- end
- end
- return false
-end
-
--- locates texmfscript to execute
-local function find_texmfscript(progname, ext_list)
- ext_list = ext_list or '\0'
- for ext in string.gmatch(ext_list, '[^;]+') do
- local progfullname = kpse.find_file(progname..ext, 'texmfscripts')
- if progfullname then return progfullname, ext end
- end
- return nil, "no appropriate script or program found: "..progname
-end
-
--- converts the #! line to arg table
--- used for scripts w/o extension
--- only the two most common cases are considered:
--- #! /path/to/command [options]
--- #! /usr/bin/env command [options]
--- ([options] after the command are retained as well)
-local function shebang_to_argv(progfullname)
- local fid, errmsg = io.open(progfullname, 'r')
- if not fid then return nil, errmsg end
- local fstln = fid:read('*line')
- fid:close()
- if string.find(fstln, "eval.*exit.*exec.*perl") then
- -- special case of Perl's time-honoured "totally devious construct":
- -- eval '(exit $?0)' && eval 'exec perl -S $0 ${1+"$@"}' && eval 'exec perl -S $0 $argv:q'
- return {"perl"}
- elseif (string.sub(fstln, 1, 2) ~= '#!') then
- return nil, "don't know how to execute script: "..progfullname
- end
- local argv = string.explode( string.sub(fstln, 3) ) -- split on spaces
- argv[1] = string.match(argv[1], '[^/]+$')
- if (argv[1] == 'env') then table.remove(argv, 1) end
- return argv
-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 cmdext = cmd..(string.find(cmd, '%.[^\\/.]*$') and '' or '.exe')
- local fullcmd = search_path(cmdext, PATH)
- if fullcmd then
- return fullcmd, cmd
- end
- end
- return nil, 'program not found (not part of TeX Live): '..cmdlist
-end
-
--- creates directory or directory hierarchy
-local function mkdir_plus(dir)
- if lfs.mkdir(chgstrcp.syscptoutf8(dir)) then
- return true
- end
- -- try with system's mkdir in case we need to create intermediate dirs too
- local ret = os.spawn({[0]=search_path("cmd.exe"),
- string.format('cmd.exe /x /c mkdir "%s"', dir)})
- if ret == 0 then
- return true
- else
- return nil, string.format("cannot create directory (error code %d): %s", ret, dir)
- end
-end
-
---
--- return the TEXMFDIST directory in TeX Live
---
-local function gettexmfdist()
- local ffi = require("ffi")
- ffi.cdef[[
- typedef void* HANDLE;
- typedef char* LPCSTR;
- int GetModuleFileNameA(HANDLE h, LPCSTR l, int i);
- HANDLE GetModuleHandleA(const char *a);
- ]]
- local buffer = ffi.new("char[?]", 512)
- local runscripthandle = ffi.C.GetModuleHandleA("runscript.dll")
- if runscripthandle == nil then
- return nil
- end
- local err = ffi.C.GetModuleFileNameA(runscripthandle, buffer, 256)
- if err == 0 then
- return nil
- end
- local str = ffi.string(buffer)
- str = string.gsub(str, "\\","/")
- str = string.reverse(str)
- local a, b
--- remove '/runscript.dll'
- a, b = string.find(str, '/', 1, true)
- str = string.sub(str,a+1)
--- remove '/win32'
- a, b = string.find(str, '/', 1, true)
- str = string.sub(str,a+1)
--- remove '/bin'
- a, b = string.find(str, '/', 1, true)
- str = string.sub(str,a+1)
- str = string.reverse(str)
- str = str .. '/texmf-dist'
- return str
-end
-
---
--- Is the Windows OS 64bit?
---
-local function is_64bit_windows_os()
- local return_val = false
- -- 32 bit binaries always work, thus the default is false
- local architecture = os.getenv('PROCESSOR_ARCHITECTURE')
- if architecture ~= nil then
- if architecture == 'x86' then
- local is_wow64 = os.getenv('PROCESSOR_ARCHITEW6432')
- if is_wow64 == nil then
- return_val = false
- else
- return_val = true
- end
- else
- return_val = true
- end
- end
- return return_val
-end
-
--- MAIN_CHUNK -- encapsulated in a function for more robust execution with pcall
-
-local function MAIN_CHUNK()
-
---[[
-
-OVERVIEW OF MAIN_CHUNK
-
-We start out with a lot of housekeeping, especially with respect to
-perl and ghostscript: if we are going to use the built-in versions,
-then the search path and other environment variables must be set or
-unset to make these findable and working right.
-
-Next we compose an ARGV table for os.spawn, unless the script turns
-out to be a [tex]lua script; see further down this comment block.
-
-The parameter table ARGV can have the following elements (see the
-luatex manual on os.exec and os.spawn):
-
-- ARGV[0]: the full path to the interpreter
-- ARGV[1]: the filename part of the interpreter. The interpreter choice
- depends on the detected script extension and also on gui mode.
-- ARGV[2]: progfulname, the full path to the script
-- ARGV[3]: argline, i.e. the unparsed arguments for the script.
- This is normally the last argument passed to runscript.tlu.
- See the actual code for when this is not the case.
-
-ARGV[0] gets priority over ARGV[1] if it is present.
-
-After everything has been set up, a call os.spawn(ARGV) runs the
-right program with the right arguments.
-
-But in case the script to be run is a texlua script, we run the script
-in the current texlua process using the dofile function. The original arg
-argument table may have been modified before then.
-
-Some variables:
-
-- ARGV, see above
-- arg, the texlua argument table of runscript.tlu
-- progname, the name under which [w]runscript.exe was called
-- progfullname, the full path of the script to be run. This variable
- is introduced only after some special cases have been dealt with.
-- argline, unparsed arguments to the script; may get modified
-
---]]
-
--- set the system-default value for LC_CTYPE
--- http://tug.org/pipermail/tex-live/2018-May/041628.html
-os.setlocale("", "ctype")
-
--- preprocess arguments: arg[-1] => texlua.exe, arg[0] => scriptname
-
--- guimode already declared local
-guimode = false
-local argline = ''
--- check for the sentinel argment coming from the .exe stub
-if arg[#arg-2] and ( string.sub(arg[#arg-2], -1) == '\n' ) then
- -- argv[0] and unparsed argument line are passed
- -- from the .exe stub as the two last arguments
- -- pop them up from the arg table
- 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
-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 = #arg, 1, -1 do argline = _q(arg[k]) .. ' ' .. argline end
-end
-
--- program name
-
--- lower arg[0] : get file name part : remove extension
-local progname, substcount = string.lower(arg[0]):gsub('^.*[\\/]', ''):gsub('%.[^.]*$', '')
--- special behaviour when called under 'runscript' name
-if (progname == 'runscript') then
- -- we are called as: runscript progname ...
- -- or as: runscript --help|-h|--version ...
- -- handle options first (only --help and --version)
- local opt, param = {}, nil
- 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
- argline = string.gsub(argline, '^%S+%s*', '')
- local optname = string.lower(param):match('^%-%-?(.*)$')
- if not optname then
- break
- elseif (optname == 'h') or (optname == 'help') then
- opt.help = true
- elseif (optname == 'v') then
- opt.v = true
- elseif (optname == 'version') then
- opt.version = true
- else
- error("unknown option: "..param.."\n"..bannerstr)
- end
- end
- if opt.help 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 progname is valid
- arg[0] = assert(param, "not enough arguments!\n"..bannerstr)
- progname = string.lower(arg[0]):gsub('^.*[\\/]', ''):gsub('%.[^.]*$', '')
- assert(progname == string.lower(arg[0]), "bad command name: " .. arg[0])
-end
--- special case of sys programs
-progname, substcount = string.gsub(progname, '%-sys$', '')
-local sysprog = (substcount > 0) -- true if there was a -sys suffix removed
--- special case of user programs
--- we do not guard against programs foobar-user-sys ... we don't ship them
-progname, substcount = string.gsub(progname, '%-user$', '')
-local userprog = (substcount > 0) -- true if there was a -user suffix removed
--- prevent recursive calls to this script
-assert(progname ~= 'runscript', "oops! wrapping the wrapper?")
-
-
--- kpse and environment set-up
-
--- init kpathsea
-local k = -1
-while arg[k-1] do k = k - 1 end -- in case of a call: luatex --luaonly ...
-local lua_binary = arg[k]
-kpse.set_program_name(lua_binary, progname)
-
--- various dir-vars
--- TEXDIR already declared local
-TEXDIR = kpse.var_value('SELFAUTOPARENT')
--- local TEXMFDIST = kpse.var_value('TEXMFDIST')
--- use a new function to obtain TEXMFDIST
-local TEXMFDIST = gettexmfdist()
-if TEXMFDIST == nil then
- TEXMFDIST = kpse.var_value('TEXMFDIST')
-end
-local BINDIR = kpse.var_value('SELFAUTOLOC')
-local PATH = os.getenv('PATH') or ''
-
--- list of programs that have -sys and -user variants
-local sys_user_progs = { 'updmap', 'fmtutil', 'kanji-config-updmap' }
-
--- restricted programs
-local shell_escape_commands = string.lower(kpse.var_value('shell_escape_commands') or '')
-local is_restricted_progname = string.find( ','..shell_escape_commands..',',
- ','..progname..',', 1, true)
-if is_restricted_progname 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)
- os.setenv('TEXMFSCRIPTS', kpse.var_value('TEXMF_RESTRICTED_SCRIPTS'))
-end
--- perl stuff
-local scripts4tlperl = {
- tlperl = true,
- updmap = true,
- fmtutil = true,
- ['updmap-sys'] = true,
- ['fmtutil-sys'] = true,
-}
-local try_extern_perl = (kpse.var_value('TEXLIVE_WINDOWS_TRY_EXTERNAL_PERL') == '1') and
- not (is_restricted_progname or scripts4tlperl[progname])
-local PERLEXE = try_extern_perl and search_path('perl.exe', PATH)
-local extperl_warn
-if not PERLEXE then
- if try_extern_perl then extperl_warn = [[
-External Perl missing or outdated. Please install a recent Perl, or configure
-TeX Live to always use the builtin Perl:
- tlmgr conf texmf TEXLIVE_WINDOWS_TRY_EXTERNAL_PERL 0
-Meanwhile, continuing with built-in Perl...
-]]
- end -- if try_extern_perl
- PERLEXE = TEXDIR..'/tlpkg/tlperl/bin/perl.exe'
- os.setenv('PERL5LIB', TEXDIR..'/tlpkg/tlperl/lib')
- PATH = prepend_path(PATH, TEXDIR..'/tlpkg/tlperl/bin')
- local PERLENV = 'PERL5OPT;PERLIO;PERLIO_DEBUG;PERLLIB;PERL5DB;PERL5DB_THREADED;' ..
- 'PERL5SHELL;PERL_ALLOW_NON_IFS_LSP;PERL_DEBUG_MSTATS;' ..
- 'PERL_DESTRUCT_LEVEL;PERL_DL_NONLAZY;PERL_ENCODING;PERL_HASH_SEED;' ..
- 'PERL_HASH_SEED_DEBUG;PERL_ROOT;PERL_SIGNALS;PERL_UNICODE'
- for var in string.gmatch(PERLENV, '[^;]+') do os.setenv(var, nil) end
-end
--- gs stuff
-local override_gs
-if not is_restricted_progname then
- override_gs = kpse.var_value('TEXLIVE_WINDOWS_EXTERNAL_GS')
-end
--- the full path to the executable
-local GSEXE
--- the directory where the gs executable resides
-local GSDIR
--- the name of the gs executable
-local GSNAME
-if override_gs then
- -- first check whether we got an absolute path or only executable name
- if string.find(override_gs, '[/\\]') then
- GSEXE = override_gs
- else
- -- search in the path
- GSEXE = search_path(override_gs, PATH)
- end
-end
-if GSEXE then
- -- split the dir and progname part so that we can set the path
- -- work on a string with all forward slashes
- local foo = string.lower(string.gsub(GSEXE, '\\', '/'))
- GSNAME = string.gsub(foo, '^.*[\\/]', '')
- GSDIR = string.gsub(foo, '^(.*)[\\/].*$', '%1')
- -- search also for a GS_DLL setting
- -- we do not need to check for is_restricted_progname, since
- -- GSEXE is only defined when it is not set
- local GSDLL = kpse.var_value('TEXLIVE_WINDOWS_EXTERNAL_GS_DLL')
- if GSDLL then
- os.setenv('GS_DLL', GSDLL)
- end
- local GSLIB = kpse.var_value('TEXLIVE_WINDOWS_EXTERNAL_GS_LIB')
- if GSLIB then
- os.setenv('GS_LIB', GSLIB)
- end
-else
- -- use built in gs
- os.setenv('GS_LIB', TEXDIR..'/tlpkg/tlgs/lib;'
- ..TEXDIR..'/tlpkg/tlgs/fonts;'
- ..TEXDIR..'/tlpkg/tlgs/Resource/Init;'
- ..TEXDIR..'/tlpkg/tlgs/Resource;'
- ..TEXDIR..'/tlpkg/tlgs/kanji;'
- ..os.getenv('WINDIR')..'/Fonts;'..TEXMFDIST..'/fonts')
- if is_64bit_windows_os() then
- os.setenv('GS_DLL', TEXDIR..'/tlpkg/tlgs/bin/gsdll64.dll')
- GSEXE = TEXDIR..'/tlpkg/tlgs/bin/gswin64c.exe'
- GSNAME = 'gswin64c.exe'
- else
- os.setenv('GS_DLL', TEXDIR..'/tlpkg/tlgs/bin/gsdll32.dll')
- GSEXE = TEXDIR..'/tlpkg/tlgs/bin/gswin32c.exe'
- GSNAME = 'gswin32c.exe'
- end
-end
--- now setup the path so that the gs program will be found
-GSDIR = TEXDIR..'/tlpkg/tlgs/bin'
-PATH = prepend_path(PATH, GSDIR, BINDIR)
-os.setenv('PATH', PATH);
-
--- sys stuff
-if (sysprog and not contains(sys_user_progs, progname)) then
- os.setenv('TEXMFVAR', kpse.var_value('TEXMFSYSVAR'))
- os.setenv('TEXMFCONFIG', kpse.var_value('TEXMFSYSCONFIG'))
-end
--- Adobe Reader crash case: make sure USERPROFILE is not "slashed"
-os.setenv("USERPROFILE", os.getenv("USERPROFILE"):gsub('/', '\\'))
-
--- extension to interpreter mapping
-
--- the extension is mapped to an argument table.
--- the command to execute is given as the first element of the table,
--- which 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'},
- ['.tcl'] = {'tclsh.exe tclsh86.exe tclsh85.exe tclkitsh.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['.rb' ][1] = 'rubyw.exe ' .. extension_map['.rb' ][1]
- -- gui tcl shares no interpreters with non-gui tcl
- extension_map['.tcl'] = {'wish.exe wish86.exe wish85.exe tclkit.exe'}
- 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 ARGV = nil
-
--- special cases (aliases)
-
-if is_tex4ht_command(progname) then
- argline = progname .. ' ' .. argline
- progname = 'mk4ht'
-elseif progname == 'a2ping' then
- table.insert(extension_map['.pl'], '-x')
-elseif contains(sys_user_progs, progname) then
- if sysprog then
- argline = ' --sys ' .. argline
- elseif userprog then
- argline = ' --user ' .. argline
- end
- -- do not guess input encoding in format creation for ptex
- -- and friends since guessing is not complete
- os.setenv('GUESS_INPUT_KANJI_ENCODING', '0')
-elseif progname == 'asy' then
- os.setenv('ASYMPTOTE_GS', GSEXE)
- os.setenv('CYGWIN', 'nodosfilewarning')
- if is_64bit_windows_os() then
- ARGV = {[0]=TEXDIR..'/tlpkg/asymptote64/asy.exe', 'asy'}
- else
- ARGV = {[0]=TEXDIR..'/tlpkg/asymptote/asy.exe', 'asy'}
- end
-elseif progname == 'dviout' then
- local fontsdir = kpse.var_value('TEXMFVAR') .. '/fonts'
- if (lfs.attributes(chgstrcp.syscptoutf8(fontsdir), 'mode') ~= 'directory') then
- assert(mkdir_plus(fontsdir))
- end
- local tfmpath = kpse.show_path('tfm')
- tfmpath = string.gsub(tfmpath, '!!', '')
- tfmpath = string.gsub(tfmpath, '/', '\\')
- local texrt = {}
- for d in string.gmatch(tfmpath, '([^;]+\\fonts)\\tfm[^;]*') do
- if (lfs.attributes(chgstrcp.syscptoutf8(d), 'mode') == 'directory') then
- table.insert(texrt, d)
- end
- end
- local par = [["-gen=']] .. string.gsub(TEXDIR, '/', '\\') ..
- [[\tlpkg\dviout\gen_pk'" "-TEXROOT=']] ..
- table.concat(texrt, ';') .. [['" "-gsx=']] .. GSEXE .. [['"]];
- ARGV = {[0]=TEXDIR..'/tlpkg/dviout/dviout.exe', 'dviout', par}
-elseif progname == 'mkluatexfontdb' then
- progname = 'luaotfload-tool'
- table.insert(arg, '--alias=mkluatexfontdb')
-elseif progname == 'psv' then
- argline = '-sINPUT='..argline
- ARGV = {[0]=TEXDIR..'/tlpkg/tlpsv/gswxlua.exe', 'gswxlua',
- '-dDisableFAPI=true',
- '-l', (_q(TEXDIR..'/tlpkg/tlpsv/psv.wx.lua'):gsub('/','\\')),
- '-p', (_q(TEXDIR..'/tlpkg/tlpsv/psv_view.ps'):gsub('/','\\')),
- '-i', '.'}
-elseif progname == 'repstopdf' or progname == 'rpdfcrop' then
- argline = '--restricted ' .. argline
- progname = string.sub(progname, 2, -1)
-elseif progname == 'texworks' then
- local winver = tonumber(string.match(os.uname().version, '%D*(%d+%.?%d*)'))
- assert(winver >= 5.01, "Windows XP or newer required to run TeXworks")
- local TW_LIBPATH = kpse.var_value('TW_LIBPATH') or
- kpse.var_value('TEXMFCONFIG')..'/texworks'
- local TW_INIPATH = kpse.var_value('TW_INIPATH') or TW_LIBPATH
- os.setenv('TW_LIBPATH', TW_LIBPATH)
- os.setenv('TW_INIPATH', TW_INIPATH)
- if (TW_INIPATH and lfs.attributes(chgstrcp.syscptoutf8(TW_INIPATH), 'mode') ~= 'directory') then
- -- TeXworks needs directory holding its configuration to exist
- assert(mkdir_plus(TW_INIPATH))
- end
- ARGV = {[0]=TEXDIR..'/tlpkg/texworks/texworks.exe', 'texworks'}
-elseif progname == 'tlgs' then
- ARGV = {[0]=GSEXE, GSNAME}
-elseif progname == 'tlperl' then
- ARGV = {[0]=PERLEXE, 'perl'}
-elseif progname == 'latexdef' then
- progname = 'texdef'
- argline = ' --tex latex ' .. argline
-elseif progname == 'cllualatex' then
- progname = 'cluttex'
- argline = ' --engine=lualatex ' .. argline
-elseif progname == 'clxelatex' then
- progname = 'cluttex'
- argline = ' --engine=xelatex ' .. argline
-end
-
--- general case
-
-if not ARGV then
- os.setenv('TEXMF', TEXMFDIST)
- local extlist = '.lua;.tlu;.pl;.rb;.py;.tcl;.jar;.vbs;.js;.bat;.cmd;.texlua;\0'
- local progfullname = search_path(progname, BINDIR, '.lua;.tlu;.bat;.cmd') or
- find_texmfscript(progname, extlist)
- os.setenv('TEXMF', nil)
- if progfullname == nil then
- -- scripts in $TEXMFLOCAL etc. can't be found without the following
- -- line !!
- kpse.set_program_name('runscript')
- progfullname = assert(find_texmfscript(progname, extlist))
- end
- local ext = string.match(string.lower(progfullname), '%.[^\\/.]*$') or ''
- if (ext == '.lua') or (ext == '.tlu') or (ext == '.texlua') then -- lua script
- arg[0] = progfullname
- elseif (ext == '.tcl' and guimode) then -- tcl script; use built-in tcl/tk?
- local try_extern_tcl =
- (kpse.var_value('TEXLIVE_WINDOWS_TRY_EXTERNAL_TCL') == '1') and
- not is_restricted_progname
- local TCLEXENAME, TCLEXE
- if try_extern_tcl then
- TCLEXE, TCLEXENAME = check_command(extension_map['.tcl'][1], PATH)
- end
- if try_extern_tcl and not TCLEXE then
- local exttcl_warn = [[
-External Tcl missing or outdated. Please install a recent Tcl, or configure
-TeX Live to always use the builtin Tcl for gui scripts:
- tlmgr conf texmf TEXLIVE_WINDOWS_TRY_EXTERNAL_TCL 0
-Meanwhile, continuing with built-in Tcl...
-]]
- show_error(exttcl_warn)
- else -- did find something
- ARGV = {[0]=TCLEXE, TCLEXENAME}
- end
- if not TCLEXE then
- -- kit: tlpkg/tltcl/tclkit.exe
- -- regular wish: tlpkg/tltcl/bin/wish.exe
- -- we ignore the fact that a non-kit tcl/tk provides wish AND tclsh
- if lfs.isfile(TEXDIR..'/tlpkg/tltcl/tclkit.exe') then
- ARGV = {[0]=TEXDIR..'/tlpkg/tltcl/tclkit.exe', 'tclkit.exe'}
- PATH = prepend_path(PATH, TEXDIR:gsub('/','\\')..'\\tlpkg\\tltcl')
- elseif lfs.isfile(TEXDIR..'/tlpkg/tltcl/bin/wish.exe') then
- ARGV = {[0]=TEXDIR..'/tlpkg/tltcl/bin/wish.exe', 'wish.exe'}
- PATH = prepend_path(PATH, TEXDIR:gsub('/','\\')..'\\tlpkg\\tltcl\\bin')
- end
- end
- table.insert(ARGV, _q(progfullname:gsub('/','\\')))
- if (argline and argline ~= '') then argline = '-- '..argline end
- else -- not gui tcl or not tcl at all
- ARGV = extension_map[ext] or assert(shebang_to_argv(progfullname))
- -- [w|c]script, for one, mistakes a forward-slashed UNC script path
- -- for an option even when quoted
- table.insert(ARGV, _q(progfullname:gsub('/','\\')))
- if not ARGV[0] then
- ARGV[0], ARGV[1] = assert(check_command(ARGV[1], PATH))
- end
- end
-end
-
--- run the program/script
-
-if ARGV then
- table.insert(ARGV, argline) -- pass through original arguments
- if string.find (table.concat(ARGV, ' '), 'perl.exe') and extperl_warn then
-
- show_error(extperl_warn)
- end
- local ret = assert(os.spawn(ARGV))
- 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(ARGV, ' ') )
- show_error(errormsg)
- end
- os.exit(ret)
-else -- must be a lua script
- dofile(arg[0])
-end
-
-end -- MAIN_CHUNK
-
--- execute MAIN_CHUNK 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 caught and displayed
--- in a message box on the C side at process exit
--- (currently used only by gui mode stubs)