diff options
author | Piotr Strzelczyk <piotr@eps.gda.pl> | 2009-12-15 01:06:54 +0000 |
---|---|---|
committer | Piotr Strzelczyk <piotr@eps.gda.pl> | 2009-12-15 01:06:54 +0000 |
commit | c783e443b4348e247772e1021f704bb27865425c (patch) | |
tree | 7469f7445d504743279535f69e7d163bf878d816 /Build/source/texk | |
parent | b71745579c90df84280f960748f50b72885f6a4f (diff) |
minor fixes for wrapper
git-svn-id: svn://tug.org/texlive/trunk@16410 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Build/source/texk')
-rw-r--r-- | Build/source/texk/texlive/w32_wrapper/runscript.tlu | 82 | ||||
-rw-r--r-- | Build/source/texk/texlive/w32_wrapper/runscript_dll.c | 29 | ||||
-rw-r--r-- | Build/source/texk/texlive/w32_wrapper/wrunscript.c | 45 |
3 files changed, 81 insertions, 75 deletions
diff --git a/Build/source/texk/texlive/w32_wrapper/runscript.tlu b/Build/source/texk/texlive/w32_wrapper/runscript.tlu index c330d224895..534c0babc7b 100644 --- a/Build/source/texk/texlive/w32_wrapper/runscript.tlu +++ b/Build/source/texk/texlive/w32_wrapper/runscript.tlu @@ -24,7 +24,7 @@ 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 compared to scritps. For these reasons a hybrid
+ and maintain in comparison to scripts. For these reasons a hybrid
approach was adopted that offers the best of both worlds - a binary
stub combined with a wrapper script.
@@ -43,11 +43,11 @@ is executed by linking with luatex.dll and calling its lua
interpreter directly rather than by spawning a new process.
- There are two variants of the binary stub: one for CLI programs
+ 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 promt if started
- from there. It also uses a dialog to display an error message in
- addition to stderr output.
+ 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
to it. This is for maintenance reasons - upgrades can be done by
@@ -62,58 +62,47 @@ 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, where it happens to be their interpreter. 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 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.
--]===================================================================]--
-- quotes string with spaces
local function _q(str)
- if str then
- str = string.gsub(str, '"', '') -- disallow embedded double quotes
- if string.find(str, "%s") then
- return '"'..str..'"'
- else
- return str
- end
- else
- return str
- end
+ str = string.gsub(str, '"', '') -- disallow embedded double quotes
+ return string.find(str, "%s") and '"'..str..'"' or str
end
-- checks if path is absolute (but not if it actually exists)
local function is_abs_path(fpath)
- if string.find(fpath, '^[/\\]') or string.find(fpath, '^[a-zA-Z]:[/\\]') then
- return true
- else
- return false
- end
+ return string.find(fpath, '^[a-zA-Z]:[/\\]') and true or false
end
-- prepends directories to path if they are not already there
local function prepend_path(path, ...)
- if (string.sub(path, -1) ~= ';') then path = path..';' end
+ local pathcmp = string.lower(string.gsub(path, '/', '\\'))..';'
for k = 1, select('#', ...) do
- local dir = string.gsub(select(k, ...), '/', '\\')..';'
- if not string.find(path, dir, 1, true) then path = dir..path end
+ 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 variable for a file
local function search_path(fname, PATH, PATHEXT)
- if is_abs_path(fname) then return fname end
+ if string.find(fname, '[/\\]') then
+ return nil, "not searching absolute or relative path: "..fname
+ end
PATH = PATH or os.getenv('PATH')
- PATHEXT = PATHEXT or '.'
+ PATHEXT = PATHEXT or '\0'
for dir in string.gmatch(PATH, '[^;]+') do
+ local dirsep = (string.find(dir, '\\') and '\\' or '/')
for ext in string.gmatch(PATHEXT, '[^;]+') do
- local dirsep = (string.find(dir, '\\') and '\\' or '/')
- local e = ((ext == '.') and '' or ext)
- local f = dir..dirsep..fname..e
- if lfs.isfile(f) then return f, e end
+ local f = dir..dirsep..fname..ext
+ if lfs.isfile(f) then return f, ext end
end
end
return nil, "file not found: "..fname
@@ -199,23 +188,21 @@ local progname = string.match(arg[0], '[^\\/]+$') progname = string.gsub(progname, '%.[^.]*$', '') -- remove extension
local progext = string.match(arg[0], '%.[^\\/.]*$') or ''
-- kpathsea
-local lua_binary = 'texlua'
-for k = -1, -1024*1024 do
- if not arg[k] then break end
- lua_binary = arg[k]
-end
+local k = -1
+while arg[k-1] do k = k - 1 end -- in case of call as: luatex --luaonly ...
+local lua_binary = arg[k]
kpse.set_program_name(lua_binary, progname)
-- vars
local TEXDIR = kpse.var_value('SELFAUTOPARENT')
local BINDIR = kpse.var_value('SELFAUTOLOC')
local PATH = os.getenv('PATH') or ''
-- perl stuff
-local script_for_tlperl = {
+local scripts4tlperl = {
['updmap-sys'] = true,
updmap = true,
}
local PERLEXE = search_path('perl.exe', PATH)
-if not PERLEXE or guimode or script_for_tlperl[progname] then
+if not PERLEXE or guimode or scripts4tlperl[progname] then
PERLEXE = TEXDIR..'/tlpkg/tlperl/bin/perl.exe'
os.setenv('PERL5LIB', TEXDIR..'/tlpkg/tlperl/lib')--[[
local PERL5SHELL = os.getenv('COMSPEC')
@@ -231,7 +218,10 @@ 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',--]]
--['fmtutil-sys'] = {[0]=BINDIR..'/fmtutil.exe', 'fmtutil-sys', argline},
['updmap-sys'] =
function ()
@@ -284,11 +274,11 @@ local alias_table = { local extension_map = { -- map script extension to command
['.bat'] = {'cmd', '/c', 'call'},
['.cmd'] = {'cmd', '/c', 'call'},
- ['.jar'] = {'java', '-jar'},
+ ['.jar'] = {guimode and 'javaw' or 'java', '-jar'},
['.js'] = {guimode and 'wscript' or 'cscript', '-nologo'},
['.pl'] = {guimode and 'wperl' or 'perl'},
- ['.py'] = {'python'},
- ['.rb'] = {'ruby'},
+ ['.py'] = {guimode and 'pythonw' or 'python'},
+ ['.rb'] = {guimode and 'rubyw' or 'ruby'},
['.vbs'] = {guimode and 'wscript' or 'cscript', '-nologo'},
}
@@ -298,10 +288,10 @@ if program then -- special case (alias) program = program()
end
else -- general case (no alias)
- local progfullname, ext = search_path(progname, PATH, ".tlu;.bat;.cmd")
+ 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;."))
+ ".tlu;.texlua;.lua;.pl;.rb;.py;.jar;.bat;.cmd;.vbs;.js;\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 d3f16a896ca..1b4818fe4b7 100644 --- a/Build/source/texk/texlive/w32_wrapper/runscript_dll.c +++ b/Build/source/texk/texlive/w32_wrapper/runscript_dll.c @@ -21,15 +21,12 @@ #include <stdio.h> #include <windows.h> #define IS_WHITESPACE(c) ((c == ' ') || (c == '\t')) -#define DIE(...) {\ - fprintf(stdout, header_fmt, module_name);\ - fprintf(stdout, __VA_ARGS__);\ - return 1;\ -} +#define MAX_MSG 512 +#define DIE(...) { _snprintf( msg_buf, MAX_MSG - 1, __VA_ARGS__ ); goto DIE; } const char module_name[] = "runscript.dll"; const char script_name[] = "runscript.tlu"; -const char header_fmt[] = "%s: "; +static char msg_buf[MAX_MSG]; __declspec(dllimport) int dllluatexmain( int argc, char *argv[] ); @@ -57,23 +54,29 @@ __declspec(dllexport) int dllrunscript( int argc, char *argv[] ) // get command line of this process argline = GetCommandLine(); // skip over argv[0] (it can contain embedded double quotes if launched from cmd.exe!) - quoted = 0; - for ( ; (*argline) && ( !IS_WHITESPACE(*argline) || quoted ); argline++ ) + 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] = "texlua"; // just a bare name, luatex strips the rest anyway + lua_argv[0] = strdup("texlua"); // 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] = "CLI_MODE\n"; // sentinel argument + lua_argv[lua_argc - 3] = strdup("CLI_MODE\n"); // sentinel argument lua_argv[lua_argc - 2] = argv[0]; // original argv[0] lua_argv[lua_argc - 1] = argline; // unparsed arguments lua_argv[lua_argc] = NULL; // call texlua interpreter - // NOTE: dllluatexmain never returns, it exits instead - return dllluatexmain( lua_argc, lua_argv ); -}
\ No newline at end of file + // dllluatexmain never returns, but we pretend that it does + k = dllluatexmain( lua_argc, lua_argv ); + if (lua_argv) free(lua_argv); + return k; + +DIE: + fprintf(stderr, "%s: ", module_name); + fprintf(stderr, msg_buf); + return 1; +} diff --git a/Build/source/texk/texlive/w32_wrapper/wrunscript.c b/Build/source/texk/texlive/w32_wrapper/wrunscript.c index d292dfd4abf..721b815451c 100644 --- a/Build/source/texk/texlive/w32_wrapper/wrunscript.c +++ b/Build/source/texk/texlive/w32_wrapper/wrunscript.c @@ -9,7 +9,7 @@ For more general info on wrapper structure see runscript.tlu. Compilation with gcc (size optimized): - gcc -Os -s -o wrunscript.exe wrunscript.c -L./ -lluatex + gcc -mwindows -Os -s -o wrunscript.exe wrunscript.c -L./ -lluatex Compilation with tcc (extra small size): tiny_impdef luatex.dll @@ -21,12 +21,7 @@ #include <windows.h> #define MAX_MSG 1024 #define IS_WHITESPACE(c) ((c == ' ') || (c == '\t')) -#define DIE(...) {\ - _snprintf( msg_buf, MAX_MSG - 1, __VA_ARGS__ );\ - fprintf( stderr, msg_buf );\ - MessageBox( NULL, msg_buf, own_path, MB_ICONERROR | MB_SETFOREGROUND );\ - return 1;\ -} +#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"; @@ -52,7 +47,11 @@ int APIENTRY WinMain( char argv0[MAX_PATH]; char fpath[MAX_PATH]; char *fname, *fext, **lua_argv; - int k, quoted, lua_argc; + int k, lua_argc; + int argc = 0; + char **argv, **env; + int new_mode = 0; + int expand_wildcards = 0; // clear error var in case it exists already SetEnvironmentVariable(err_env_var, NULL); @@ -73,18 +72,32 @@ int APIENTRY WinMain( if ( GetFileAttributes(fpath) == INVALID_FILE_ATTRIBUTES ) DIE("main lua script not found: %s\n", fpath); +#ifdef __MSVCRT__ + // WinMain doesn't provide argc & argv, use MSVCRT function directly + __getmainargs(&argc, &argv, &env, expand_wildcards, &new_mode); +#endif + // set up argument list for texlua script - lua_argc = 5; - lua_argv = (char **) malloc( ( lua_argc + 1 ) * sizeof( char * ) ); - lua_argv[0] = "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] = strdup("texlua"); // just a bare name, luatex strips the rest anyway lua_argv[1] = fpath; // script to execute - lua_argv[lua_argc - 3] = "GUI_MODE\n"; // sentinel argument - lua_argv[lua_argc - 2] = own_path; // our argv[0] + 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 - 2] = argc ? argv[0] : own_path; // original argv[0] lua_argv[lua_argc - 1] = argline; // unparsed arguments lua_argv[lua_argc] = NULL; - // dllluatexmain never returns, it exits instead - // register atexit handler to recover control + // register atexit handler to recover control before terminating atexit(finalize); - return dllluatexmain( lua_argc, lua_argv ); + // dllluatexmain never returns, but we pretend that it does + k = dllluatexmain( lua_argc, lua_argv ); + if (lua_argv) free(lua_argv); + return k; + +DIE: + fprintf(stderr, "%s: ", own_path); + fprintf(stderr, msg_buf); + MessageBox( NULL, msg_buf, own_path, MB_ICONERROR | MB_SETFOREGROUND ); + return 1; } |