summaryrefslogtreecommitdiff
path: root/Build/source
diff options
context:
space:
mode:
authorPiotr Strzelczyk <piotr@eps.gda.pl>2010-01-09 01:27:39 +0000
committerPiotr Strzelczyk <piotr@eps.gda.pl>2010-01-09 01:27:39 +0000
commit5d8e7c1ee94a00e14af10d6099384079943da6e4 (patch)
treef0b4b688e9d7338fa9b9709e554698b920eb0ab9 /Build/source
parent7cd0f845c957c591ad6d4443831ba9fa29a686ca (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/source')
-rw-r--r--Build/source/texk/texlive/w32_wrapper/runscript.tlu39
-rw-r--r--Build/source/texk/texlive/w32_wrapper/runscript_dll.c75
-rw-r--r--Build/source/texk/texlive/w32_wrapper/runscript_exe.c20
-rw-r--r--Build/source/texk/texlive/w32_wrapper/wrunscript.c15
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;