diff options
author | Piotr Strzelczyk <piotr@eps.gda.pl> | 2010-01-09 01:27:39 +0000 |
---|---|---|
committer | Piotr Strzelczyk <piotr@eps.gda.pl> | 2010-01-09 01:27:39 +0000 |
commit | 5d8e7c1ee94a00e14af10d6099384079943da6e4 (patch) | |
tree | f0b4b688e9d7338fa9b9709e554698b920eb0ab9 /Build | |
parent | 7cd0f845c957c591ad6d4443831ba9fa29a686ca (diff) |
prepare wrapper for gui-mode stubs; enable wrapper consitency check for context, ps4pdf and tex4ht
git-svn-id: svn://tug.org/texlive/trunk@16645 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Build')
4 files changed, 86 insertions, 63 deletions
diff --git a/Build/source/texk/texlive/w32_wrapper/runscript.tlu b/Build/source/texk/texlive/w32_wrapper/runscript.tlu index 785e5e742aa..4b90e85706e 100644 --- a/Build/source/texk/texlive/w32_wrapper/runscript.tlu +++ b/Build/source/texk/texlive/w32_wrapper/runscript.tlu @@ -49,24 +49,21 @@ from there. It also uses a dialog box to display an error message
in addition to outputting to stderr.
- The CLI stub is further split into a common DLL and an EXE proxy
+ The stubs are further split into a common DLL and an EXE proxies
to it. This is for maintenance reasons - upgrades can be done by
- replacement of a single DLL rather than all binary stubs (the
- number of GUI stubs is much smaller, so this is much less of
- a problem).
+ replacement of a single DLL rather than all binary stubs.
The wrapper 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.
+ 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 this wrapper script. Once located, the script or 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, for increased performance it is converted to
- a function with Lua's loadfile and called without spawning a new
- process.
+ a (tex)lua script, it is loaded and called directly from within
+ this script, i.e. no new process is spawned.
--]===================================================================]--
@@ -91,13 +88,13 @@ local function prepend_path(path, ...) return path
end
--- searches the PATH variable for a file
+-- 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'
+ 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
@@ -145,7 +142,7 @@ local function check_command(cmd, PATH) if fullcmd then
return fullcmd
else
- return nil, 'program not found (not part of TeX Live): '..cmd
+ return nil, 'program not found (not part of TeX Live): '..cmdext
end
end
@@ -186,10 +183,12 @@ end -- program name
local progname = string.match(arg[0], '[^\\/]+$')
progname = string.gsub(progname, '%.[^.]*$', '') -- remove extension
-local progext = string.match(arg[0], '%.[^\\/.]*$') or ''
+if (progname == 'runscript') then -- prevent recursive calls to this script
+ assert(nil, "oops! wrapping the wrapper?")
+end
-- kpathsea
local k = -1
-while arg[k-1] do k = k - 1 end -- in case of call as: luatex --luaonly ...
+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)
-- vars
@@ -218,7 +217,7 @@ os.setenv('GS_DLL', TEXDIR..'/tlpkg/tlgs/bin/gsdll32.dll') PATH = prepend_path(PATH, TEXDIR..'/tlpkg/tlgs/bin', BINDIR)
os.setenv('PATH', PATH);
-local alias_table = {--[[
+local alias_table = {---[[
cmd = {'cmd'},
printargv = {'..\\print_argv.exe', argline},
scratch = 'scratch.lua',--]]
@@ -243,23 +242,19 @@ local alias_table = {--[[ function ()
return {[0]=assert(check_command('wscript', PATH)),
'wscript', _q(BINDIR..'/dviout.vbs'), argline}
- end
+ end,--]--]
psv = {[0]=TEXDIR..'/tlpkg/tlpsv/gswxlua.exe', 'gswxlua',
'-l', _q(TEXDIR..'/tlpkg/tlpsv/psv.wx.lua'),
'-p', _q(TEXDIR..'/tlpkg/tlpsv/psv_view.ps'), '-sINPUT='..argline},--]]
rpdfcrop = {PERLEXE, 'perl',
_q(TEXDIR..'/texmf-dist/scripts/pdfcrop/pdfcrop.pl'),
'--restricted', argline},
- runscript = -- prevent recursive calls to this script
- function ()
- assert(nil, "oops! wrapping the wrapper?")
- end,
sam2p = {[0]=TEXDIR..'/tlpkg/sam2p/sam2p.exe', 'sam2p', argline},--[[
texworks =
function ()
-- TODO: add to texmf/web2c/texmf.cnf
- -- TW_INIPATH = $TEXMFCONFIG/texworks
- -- TW_LIBPATH = $TW_INIPATH
+ -- TW_LIBPATH = $TEXMFCONFIG/texworks
+ -- TW_INIPATH = $TW_LIBPATH
local TW_INIPATH = kpse.var_value('TW_INIPATH') or
kpse.var_value('TEXMFCONFIG')..'/texworks'
os.setenv('TW_INIPATH', TW_INIPATH)
@@ -291,7 +286,7 @@ else -- general case (no alias) local progfullname, ext = search_path(progname, BINDIR, ".tlu;.bat;.cmd")
if not progfullname then
progfullname, ext = assert(find_texmfscript(progname,
- ".tlu;.texlua;.lua;.pl;.rb;.py;.jar;.bat;.cmd;.vbs;.js;\0"))
+ ".tlu;.texlua;.lua;.pl;.rb;.py;.jar;.vbs;.js;.bat;.cmd;\0"))
end
if (ext == '.lua') or (ext == '.tlu') or (ext == '.texlua') then
-- lua script
diff --git a/Build/source/texk/texlive/w32_wrapper/runscript_dll.c b/Build/source/texk/texlive/w32_wrapper/runscript_dll.c index 1b4818fe4b7..12b2840bb9c 100644 --- a/Build/source/texk/texlive/w32_wrapper/runscript_dll.c +++ b/Build/source/texk/texlive/w32_wrapper/runscript_dll.c @@ -10,38 +10,46 @@ Compilation 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 Compilation 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 ************************************************************************/ #include <stdio.h> +#include <stdlib.h> #include <windows.h> #define IS_WHITESPACE(c) ((c == ' ') || (c == '\t')) -#define MAX_MSG 512 +#define MAX_MSG 2*MAX_PATH #define DIE(...) { _snprintf( msg_buf, MAX_MSG - 1, __VA_ARGS__ ); goto DIE; } -const char module_name[] = "runscript.dll"; -const char script_name[] = "runscript.tlu"; -static char msg_buf[MAX_MSG]; +char module_name[] = "runscript.dll"; +char script_name[] = "runscript.tlu"; +char texlua_name[] = "texlua"; // just a bare name, luatex strips the rest anyway +char subsys_mode[] = "CUI_MODE\n"; +char err_env_var[] = "RUNSCRIPT_ERROR_MESSAGE"; +char msg_buf[MAX_MSG]; __declspec(dllimport) int dllluatexmain( int argc, char *argv[] ); __declspec(dllexport) int dllrunscript( int argc, char *argv[] ) { + static char own_path[MAX_PATH]; static char fpath[MAX_PATH]; char *fname, *argline, **lua_argv; int k, quoted, lua_argc; // file path of this executable - k = (int) GetModuleFileName(NULL, fpath, MAX_PATH); + k = (int) GetModuleFileName(NULL, own_path, MAX_PATH); if ( !k || (k == MAX_PATH) ) - DIE("cannot get own path (may be too long): %s\n", fpath); + DIE("cannot get own path (may be too long): %s\n", own_path); // script path + strcpy(fpath, own_path); fname = strrchr(fpath, '\\'); if ( fname == NULL ) DIE("no directory part in module path: %s\n", fpath); fname++; @@ -49,34 +57,73 @@ __declspec(dllexport) int dllrunscript( int argc, char *argv[] ) DIE("path too long: %s\n", fpath); strcpy(fname, script_name); if ( GetFileAttributes(fpath) == INVALID_FILE_ATTRIBUTES ) - DIE("lua script not found: %s\n", fpath); + DIE("main lua script not found: %s\n", fpath); // get command line of this process argline = GetCommandLine(); + if ( argline == NULL ) DIE("failed to retrieve command line string\n"); // skip over argv[0] (it can contain embedded double quotes if launched from cmd.exe!) for ( quoted = 0; (*argline) && ( !IS_WHITESPACE(*argline) || quoted ); argline++ ) if ( *argline == '"' ) quoted = !quoted; while ( IS_WHITESPACE(*argline) ) argline++; // remove leading whitespace if any // set up argument list for texlua script - lua_argc = argc + 4; - lua_argv = (char **) malloc( (lua_argc + 1) * sizeof(char *) ); - lua_argv[0] = strdup("texlua"); // just a bare name, luatex strips the rest anyway + lua_argc = argc ? argc + 4 : 5; + lua_argv = (char **)malloc( (lua_argc + 1) * sizeof(char *) ); + lua_argv[0] = texlua_name; lua_argv[1] = fpath; // script to execute - for ( k = 1; k < argc; k++ ) lua_argv[k+1] = argv[k]; - lua_argv[lua_argc - 3] = strdup("CLI_MODE\n"); // sentinel argument - lua_argv[lua_argc - 2] = argv[0]; // original argv[0] + for ( k = 1; k < argc; k++ ) lua_argv[k+1] = argv[k]; // copy argument list + lua_argv[lua_argc - 3] = subsys_mode; // sentinel argument + lua_argv[lua_argc - 2] = argc ? argv[0] : own_path; // original argv[0] lua_argv[lua_argc - 1] = argline; // unparsed arguments lua_argv[lua_argc] = NULL; // call texlua interpreter // dllluatexmain never returns, but we pretend that it does k = dllluatexmain( lua_argc, lua_argv ); - if (lua_argv) free(lua_argv); + free(lua_argv); return k; DIE: fprintf(stderr, "%s: ", module_name); fprintf(stderr, msg_buf); + if (*subsys_mode == 'G') + MessageBox( NULL, msg_buf, module_name, MB_ICONERROR | MB_SETFOREGROUND ); return 1; } + +void finalize( void ) +{ + // check for and display error message if any + char *err_msg; + if ( err_msg = (char *) getenv(err_env_var) ) + MessageBox( NULL, err_msg, module_name, MB_ICONERROR | MB_SETFOREGROUND ); +} + +__declspec(dllexport) int dllwrunscript( + HINSTANCE hInstance, + HINSTANCE hPrevInstance, + char *argline, + int winshow +) { + // set sentinel argument + *subsys_mode = 'G'; + // clear error var in case it exists already + SetEnvironmentVariable(err_env_var, NULL); + // register atexit handler to recover control before terminating + atexit( finalize ); + // call the console entry point routine +#ifdef __MSVCRT__ + // WinMain doesn't provide argc & argv, call MSVCRT proc to get them + int argc = 0; + char **argv, **env; + int expand_wildcards = 0; + int new_mode; + __getmainargs(&argc, &argv, &env, expand_wildcards, &new_mode); + return dllrunscript( argc, argv ); +#else + return dllrunscript( 0, NULL ); +#endif +} + + diff --git a/Build/source/texk/texlive/w32_wrapper/runscript_exe.c b/Build/source/texk/texlive/w32_wrapper/runscript_exe.c index 078bdccc4cf..22bfadae886 100644 --- a/Build/source/texk/texlive/w32_wrapper/runscript_exe.c +++ b/Build/source/texk/texlive/w32_wrapper/runscript_exe.c @@ -1,23 +1,3 @@ -/************************************************************************ - - Generic script wrapper - - Public Domain - Originally written 2009 by T.M.Trzeciak - - For rationale and structure details see runscript.tlu script. - - Compilation 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 - - Compilation 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 - -************************************************************************/ - #include <windows.h> __declspec(dllimport) int dllrunscript( int argc, char *argv[] ); diff --git a/Build/source/texk/texlive/w32_wrapper/wrunscript.c b/Build/source/texk/texlive/w32_wrapper/wrunscript.c index 721b815451c..12cdb6f6d63 100644 --- a/Build/source/texk/texlive/w32_wrapper/wrunscript.c +++ b/Build/source/texk/texlive/w32_wrapper/wrunscript.c @@ -19,13 +19,15 @@ #include <stdio.h> #include <windows.h> -#define MAX_MSG 1024 +#define MAX_MSG 512 #define IS_WHITESPACE(c) ((c == ' ') || (c == '\t')) #define DIE(...) { _snprintf( msg_buf, MAX_MSG - 1, __VA_ARGS__ ); goto DIE; } -const char err_env_var[] = "RUNSCRIPT_ERROR_MESSAGE"; -const char script_name[] = "runscript.tlu"; -static char own_path[MAX_PATH] = "(NULL)"; +char err_env_var[] = "RUNSCRIPT_ERROR_MESSAGE"; +char script_name[] = "runscript.tlu"; +char texlua_name[] = "texlua"; +char sentinel_arg[] = "GUI_MODE\n"; +static char own_path[MAX_PATH] = "runscript"; static char msg_buf[MAX_MSG]; void finalize( void ) @@ -44,7 +46,6 @@ int APIENTRY WinMain( char *argline, int winshow ){ - char argv0[MAX_PATH]; char fpath[MAX_PATH]; char *fname, *fext, **lua_argv; int k, lua_argc; @@ -80,10 +81,10 @@ int APIENTRY WinMain( // set up argument list for texlua script lua_argc = argc ? argc + 4 : 5; lua_argv = (char **) malloc( (lua_argc + 1) * sizeof(char *) ); - lua_argv[0] = strdup("texlua"); // just a bare name, luatex strips the rest anyway + lua_argv[0] = texlua_name; // just a bare name, luatex strips the rest anyway lua_argv[1] = fpath; // script to execute for ( k = 1; k < argc; k++ ) lua_argv[k+1] = argv[k]; - lua_argv[lua_argc - 3] = strdup("GUI_MODE\n"); // sentinel argument + lua_argv[lua_argc - 3] = sentinel_arg; // sentinel argument lua_argv[lua_argc - 2] = argc ? argv[0] : own_path; // original argv[0] lua_argv[lua_argc - 1] = argline; // unparsed arguments lua_argv[lua_argc] = NULL; |