From 7aac571572f07680323bd41a3f79f20cf72c0cfb Mon Sep 17 00:00:00 2001 From: Luigi Scarso Date: Wed, 20 Feb 2019 01:04:18 +0000 Subject: aux files for cross-compilation of Mingw win64; fixed spaces on luatex.am git-svn-id: svn://tug.org/texlive/trunk@50068 c570f23f-e606-0410-a88d-b1316a301751 --- Build/source/texk/texlive/w64_mingw_wrapper/README | 8 + .../texk/texlive/w64_mingw_wrapper/bitmap2eps.ico | Bin 0 -> 3262 bytes .../texk/texlive/w64_mingw_wrapper/bitmap2eps.svg | 525 ++++++++++++ .../texk/texlive/w64_mingw_wrapper/calldll.c | 13 + .../texk/texlive/w64_mingw_wrapper/callexe.c | 43 + .../texlive/w64_mingw_wrapper/context/mtxrun.dll | Bin 0 -> 7680 bytes .../texlive/w64_mingw_wrapper/context/mtxrun.exe | Bin 0 -> 4608 bytes .../texlive/w64_mingw_wrapper/context/mtxrun_dll.c | 306 +++++++ .../texlive/w64_mingw_wrapper/context/mtxrun_exe.c | 8 + .../texlive/w64_mingw_wrapper/context/readme.txt | 40 + .../texlive/w64_mingw_wrapper/libkpathsea-6.dll | Bin 0 -> 112742 bytes .../texk/texlive/w64_mingw_wrapper/readme.txt | 229 +++++ .../texk/texlive/w64_mingw_wrapper/runscript.dll | Bin 0 -> 17920 bytes .../texk/texlive/w64_mingw_wrapper/runscript.exe | Bin 0 -> 16384 bytes .../texk/texlive/w64_mingw_wrapper/runscript.tlu | 928 +++++++++++++++++++++ .../texk/texlive/w64_mingw_wrapper/runscript_dll.c | 127 +++ .../texk/texlive/w64_mingw_wrapper/runscript_exe.c | 15 + .../texk/texlive/w64_mingw_wrapper/texlua.dll | Bin 0 -> 255860 bytes .../texk/texlive/w64_mingw_wrapper/texlua.exe | Bin 0 -> 6250496 bytes .../texk/texlive/w64_mingw_wrapper/tl-tray-menu.c | 310 +++++++ .../texk/texlive/w64_mingw_wrapper/tlmgr-gui.txt | 77 ++ .../texk/texlive/w64_mingw_wrapper/tlmgr.ico | Bin 0 -> 4286 bytes .../texk/texlive/w64_mingw_wrapper/tlmgr.svg | 245 ++++++ .../texlive/w64_mingw_wrapper/wrunscript_exe.c | 27 + Build/source/texk/web2c/luatexdir/am/luatex.am | 16 +- 25 files changed, 2909 insertions(+), 8 deletions(-) create mode 100644 Build/source/texk/texlive/w64_mingw_wrapper/README create mode 100644 Build/source/texk/texlive/w64_mingw_wrapper/bitmap2eps.ico create mode 100644 Build/source/texk/texlive/w64_mingw_wrapper/bitmap2eps.svg create mode 100644 Build/source/texk/texlive/w64_mingw_wrapper/calldll.c create mode 100644 Build/source/texk/texlive/w64_mingw_wrapper/callexe.c create mode 100755 Build/source/texk/texlive/w64_mingw_wrapper/context/mtxrun.dll create mode 100755 Build/source/texk/texlive/w64_mingw_wrapper/context/mtxrun.exe create mode 100644 Build/source/texk/texlive/w64_mingw_wrapper/context/mtxrun_dll.c create mode 100644 Build/source/texk/texlive/w64_mingw_wrapper/context/mtxrun_exe.c create mode 100644 Build/source/texk/texlive/w64_mingw_wrapper/context/readme.txt create mode 100755 Build/source/texk/texlive/w64_mingw_wrapper/libkpathsea-6.dll create mode 100644 Build/source/texk/texlive/w64_mingw_wrapper/readme.txt create mode 100755 Build/source/texk/texlive/w64_mingw_wrapper/runscript.dll create mode 100755 Build/source/texk/texlive/w64_mingw_wrapper/runscript.exe create mode 100755 Build/source/texk/texlive/w64_mingw_wrapper/runscript.tlu create mode 100644 Build/source/texk/texlive/w64_mingw_wrapper/runscript_dll.c create mode 100644 Build/source/texk/texlive/w64_mingw_wrapper/runscript_exe.c create mode 100755 Build/source/texk/texlive/w64_mingw_wrapper/texlua.dll create mode 100755 Build/source/texk/texlive/w64_mingw_wrapper/texlua.exe create mode 100644 Build/source/texk/texlive/w64_mingw_wrapper/tl-tray-menu.c create mode 100644 Build/source/texk/texlive/w64_mingw_wrapper/tlmgr-gui.txt create mode 100644 Build/source/texk/texlive/w64_mingw_wrapper/tlmgr.ico create mode 100644 Build/source/texk/texlive/w64_mingw_wrapper/tlmgr.svg create mode 100644 Build/source/texk/texlive/w64_mingw_wrapper/wrunscript_exe.c diff --git a/Build/source/texk/texlive/w64_mingw_wrapper/README b/Build/source/texk/texlive/w64_mingw_wrapper/README new file mode 100644 index 00000000000..33eb4ae5181 --- /dev/null +++ b/Build/source/texk/texlive/w64_mingw_wrapper/README @@ -0,0 +1,8 @@ +This file and the graphics are public domain. + +This directory is for the generic TeX Live wrapper on Windows that is +used for most scripts. The main file is runscript.tlu. + +*.svg are the sources for *.ico, +and the *.ico are used in wrappers. +Hence their locaton here. diff --git a/Build/source/texk/texlive/w64_mingw_wrapper/bitmap2eps.ico b/Build/source/texk/texlive/w64_mingw_wrapper/bitmap2eps.ico new file mode 100644 index 00000000000..be4be44b3d1 Binary files /dev/null and b/Build/source/texk/texlive/w64_mingw_wrapper/bitmap2eps.ico differ diff --git a/Build/source/texk/texlive/w64_mingw_wrapper/bitmap2eps.svg b/Build/source/texk/texlive/w64_mingw_wrapper/bitmap2eps.svg new file mode 100644 index 00000000000..aac123a3914 --- /dev/null +++ b/Build/source/texk/texlive/w64_mingw_wrapper/bitmap2eps.svg @@ -0,0 +1,525 @@ + + + +image/svg+xml \ No newline at end of file diff --git a/Build/source/texk/texlive/w64_mingw_wrapper/calldll.c b/Build/source/texk/texlive/w64_mingw_wrapper/calldll.c new file mode 100644 index 00000000000..ddb17f31055 --- /dev/null +++ b/Build/source/texk/texlive/w64_mingw_wrapper/calldll.c @@ -0,0 +1,13 @@ +/* Public domain. + * Originally written by Akira Kakuto + * + * DLL calling main program for TeX & Co + * DLLPROC must be defined in the Makefile as, + * e.g., -DDLLPROC=dlltexmain. + */ + +__declspec(dllimport) DLLPROC(int ac, char **av); +int main(int ac, char **av) +{ + return (DLLPROC(ac, av)); +} diff --git a/Build/source/texk/texlive/w64_mingw_wrapper/callexe.c b/Build/source/texk/texlive/w64_mingw_wrapper/callexe.c new file mode 100644 index 00000000000..2aa041ea0da --- /dev/null +++ b/Build/source/texk/texlive/w64_mingw_wrapper/callexe.c @@ -0,0 +1,43 @@ +/* Public domain. + * Originally written by Akira Kakuto + * + * WIN32 wrapper program replacing Unix symlinks such as, + * e.g., ofm2opl -> omfonts. + * + * EXEPROG must be defined in the Makefile as, + * e.g., -DEXEPROG=\"omfonts.exe\". + */ +#include +#include +#include +#include +#include + +static int is_include_space(char *s) +{ + char *p; + p = strchr(s, ' '); + if(p) return 1; + p = strchr(s, '\t'); + if(p) return 1; + return 0; +} + +int main(int argc, char *argv[]) +{ + int i; + char *p; + + for(i = 0; i < argc; i++) { + if(is_include_space(argv[i])) { + p = (char *)malloc(strlen(argv[i])+3); + strcpy(p, "\""); + strcat(p, argv[i]); + strcat(p, "\""); + free(argv[i]); + argv[i] = p; + } + } + argv[argc] = NULL; + return _spawnvp(_P_WAIT, EXEPROG, (const char * const *)argv); +} diff --git a/Build/source/texk/texlive/w64_mingw_wrapper/context/mtxrun.dll b/Build/source/texk/texlive/w64_mingw_wrapper/context/mtxrun.dll new file mode 100755 index 00000000000..3c4481c319d Binary files /dev/null and b/Build/source/texk/texlive/w64_mingw_wrapper/context/mtxrun.dll differ diff --git a/Build/source/texk/texlive/w64_mingw_wrapper/context/mtxrun.exe b/Build/source/texk/texlive/w64_mingw_wrapper/context/mtxrun.exe new file mode 100755 index 00000000000..0e7882cf926 Binary files /dev/null and b/Build/source/texk/texlive/w64_mingw_wrapper/context/mtxrun.exe differ diff --git a/Build/source/texk/texlive/w64_mingw_wrapper/context/mtxrun_dll.c b/Build/source/texk/texlive/w64_mingw_wrapper/context/mtxrun_dll.c new file mode 100644 index 00000000000..fc2e260f5a2 --- /dev/null +++ b/Build/source/texk/texlive/w64_mingw_wrapper/context/mtxrun_dll.c @@ -0,0 +1,306 @@ +/************************************************************************ + + Copyright: + + Public Domain + Originally written in 2010 by Tomasz M. Trzeciak and Hans Hagen + + This program is derived from the 'runscript' program originally + written in 2009 by T.M. Trzeciak. It has been adapted for use in + ConTeXt MkIV. + + Comment: + + In ConTeXt MkIV we have two core scripts: luatools.lua and + mtxrun.lua where the second one is used to launch other scripts. + Normally a user will use a call like: + + mtxrun --script font --reload + + Here mtxrun is a lua script. In order to avoid the usage of a cmd + file on windows this runner will start texlua directly. If the + shared library luatex.dll is available, texlua will be started in + the same process avoiding thus any additional overhead. Otherwise + it will be spawned in a new proces. + + We also don't want to use other runners, like those that use kpse + to locate the script as this is exactly what mtxrun itself is doing + already. Therefore the runscript program is adapted to a more direct + approach suitable for mtxrun. + + Compilation: + + with gcc (size optimized): + + gcc -Os -s -shared -o mtxrun.dll mtxrun_dll.c + gcc -Os -s -o mtxrun.exe mtxrun_exe.c -L./ -lmtxrun + + with tcc (extra small size): + + tcc -shared -o mtxrun.dll mtxrun_dll.c + tcc -o mtxrun.exe mtxrun_exe.c mtxrun.def + +************************************************************************/ + +#include +#include +#include + +//#define STATIC +#define IS_WHITESPACE(c) ((c == ' ') || (c == '\t')) +#define MAX_CMD 32768 +#define DIE(...) { \ + fprintf( stderr, "mtxrun: " ); \ + fprintf( stderr, __VA_ARGS__ ); \ + return 1; \ +} + +static char cmdline[MAX_CMD]; +static char dirpath[MAX_PATH]; +static char progname[MAX_PATH]; +static char scriptpath[MAX_PATH]; +static char luatexpath[MAX_PATH]; +HMODULE dllluatex = NULL; +typedef int ( *mainlikeproc )( int, char ** ); + +#ifdef STATIC +int main( int argc, char *argv[] ) +#else +__declspec(dllexport) int dllrunscript( int argc, char *argv[] ) +#endif +{ + char *binary, *s, *luatexfname, *argstr, **lua_argv; + int k, quoted, lua_argc; + int passprogname = 0; + unsigned char is_jit=0; + + // directory of this module/executable + HMODULE module_handle = GetModuleHandle( "mtxrun.dll" ); + // if ( module_handle == NULL ) exe path will be used, which is OK too + k = (int) GetModuleFileName( module_handle, dirpath, MAX_PATH ); + if ( !k || ( k == MAX_PATH ) ) + DIE( "unable to determine a valid module name\n" ); + s = strrchr(dirpath, '\\'); + if ( s == NULL ) DIE( "no directory part in module path: %s\n", dirpath ); + *(++s) = '\0'; //remove file name, leave trailing backslash + + // program name + k = strlen(argv[0]); + while ( k && (argv[0][k-1] != '/') && (argv[0][k-1] != '\\') ) k--; + strcpy(progname, &argv[0][k]); + s = progname; + if ( s = strrchr(s, '.') ) *s = '\0'; // remove file extension part + + /* check "jit" : strlen("jit") = 3 */ + if (strncmp(progname + strlen(progname) - 3, "jit", 3) == 0) { + is_jit = 1; + progname[strlen(progname) - 3]='\0'; + } + else + is_jit = 0; + + // script path + + strcpy( scriptpath, dirpath ); + k = strlen(progname); + if ( k < 6 ) k = 6; // in case the program name is shorter than "mtxrun" + if ( strlen(dirpath) + k + 4 >= MAX_PATH ) + DIE( "path too long: %s%s\n", dirpath, progname ); + + if ( strcmpi(progname,"mtxrun") == 0 ) { + strcat( scriptpath, progname ); + strcat( scriptpath, ".lua" ); + } else if ( strcmpi(progname,"luatools") == 0 ) { + strcat( scriptpath, "mtxrun.lua" ); + strcpy( progname, "base" ); + passprogname = 1; + } else if ( strcmpi(progname,"texmfstart") == 0 ) { + strcat( scriptpath, "mtxrun.lua" ); + } else { + strcat( scriptpath, "mtxrun.lua" ); + passprogname = 1; + } + if ( GetFileAttributes(scriptpath) == INVALID_FILE_ATTRIBUTES ) + DIE( "file not found: %s\n", scriptpath ); + + // find luatex.exe /luajittex.exe + if ( SearchPath( + dirpath, // was getenv( "PATH" ), // path to search (optional) + (is_jit ? "luajittex.exe":"luatex.exe"), // file name to search + NULL, // file extension to add (optional) + MAX_PATH, // output buffer size + luatexpath, // output buffer pointer + &luatexfname ) // pointer to a file part in the output buffer (optional) + ) { + binary = (is_jit ? "luajittex.exe":"luatex.exe"); + } else if ( SearchPath( + dirpath, // was getenv( "PATH" ), // path to search (optional) + (is_jit ? "texluajit.exe":"texlua.exe"), // file name to search + NULL, // file extension to add (optional) + MAX_PATH, // output buffer size + luatexpath, // output buffer pointer + &luatexfname ) // pointer to a file part in the output buffer (optional) + ) { + binary = (is_jit ? "texluajit.exe":"texlua.exe"); + } else if ( SearchPath( + getenv("PATH"), // was dirpath, // path to search (optional) + (is_jit ? "luajittex.exe":"luatex.exe"), // file name to search + NULL, // file extension to add (optional) + MAX_PATH, // output buffer size + luatexpath, // output buffer pointer + &luatexfname ) // pointer to a file part in the output buffer (optional) + ) { + binary = (is_jit ? "luajittex.exe":"luatex.exe"); + } else if ( SearchPath( + getenv("PATH") , // was dirpath, // path to search (optional) + (is_jit ? "texluajit.exe":"texlua.exe"), // file name to search + NULL, // file extension to add (optional) + MAX_PATH, // output buffer size + luatexpath, // output buffer pointer + &luatexfname ) // pointer to a file part in the output buffer (optional) + ) { + binary = (is_jit ? "texluajit.exe":"texlua.exe"); + }else { + DIE( "unable to locate texlua.exe on the search path" ); + } + + /* if ( SearchPath( */ + /* dirpath, // was getenv( "PATH" ), // path to search (optional) */ + /* (is_jit ? "luajittex.exe":"luatex.exe"), // file name to search */ + /* NULL, // file extension to add (optional) */ + /* MAX_PATH, // output buffer size */ + /* luatexpath, // output buffer pointer */ + /* &luatexfname ) // pointer to a file part in the output buffer (optional) */ + /* ) { */ + /* binary = (is_jit ? "luajittex.exe":"luatex.exe"); */ + /* }else if ( SearchPath( */ + /* getenv("PATH"), // was dirpath, // path to search (optional) */ + /* (is_jit ? "luajittex.exe":"luatex.exe"), // file name to search */ + /* NULL, // file extension to add (optional) */ + /* MAX_PATH, // output buffer size */ + /* luatexpath, // output buffer pointer */ + /* &luatexfname ) // pointer to a file part in the output buffer (optional) */ + /* ) { */ + /* binary = (is_jit ? "luajittex.exe":"luatex.exe"); */ + /* }else if ( SearchPath( */ + /* dirpath, // was getenv( "PATH" ), // path to search (optional) */ + /* (is_jit ? "texluajit.exe":"texlua.exe"), // file name to search */ + /* NULL, // file extension to add (optional) */ + /* MAX_PATH, // output buffer size */ + /* luatexpath, // output buffer pointer */ + /* &luatexfname ) // pointer to a file part in the output buffer (optional) */ + /* ) { */ + /* binary = (is_jit ? "texluajit.exe":"texlua.exe"); */ + /* }else if ( SearchPath( */ + /* getenv("PATH") , // was dirpath, // path to search (optional) */ + /* (is_jit ? "texluajit.exe":"texlua.exe"), // file name to search */ + /* NULL, // file extension to add (optional) */ + /* MAX_PATH, // output buffer size */ + /* luatexpath, // output buffer pointer */ + /* &luatexfname ) // pointer to a file part in the output buffer (optional) */ + /* ) { */ + /* binary = (is_jit ? "texluajit.exe":"texlua.exe"); */ + /* }else { */ + /* DIE( "unable to locate texlua.exe on the search path" ); */ + /* } */ + + + + + // link directly with luatex.dll if available in texlua's dir + strcpy( luatexfname, (is_jit ? "luajittex.dll":"luatex.dll") ); + if ( dllluatex = LoadLibrary(luatexpath) ) + { + mainlikeproc dllluatexmain = (mainlikeproc) GetProcAddress( dllluatex, (is_jit ? "dllluajittexmain": "dllluatexmain" )); + if ( dllluatexmain == NULL ) + if (is_jit) + DIE( "unable to locate dllluatexmain procedure in luajittex.dll" ) + else + DIE( "unable to locate dllluatexmain procedure in luatex.dll" ); + + // set up argument list for texlua script + + lua_argv = (char **)malloc( (argc + 5) * sizeof(char *) ); + if ( lua_argv == NULL ) DIE( "out of memory\n" ); + lua_argv[lua_argc=0] = luatexfname; + lua_argv[++lua_argc] = "--luaonly"; + lua_argv[++lua_argc] = scriptpath; // script to execute + if (passprogname) { + lua_argv[++lua_argc] = "--script"; + lua_argv[++lua_argc] = progname; + } + for ( k = 1; k < argc; k++ ) lua_argv[++lua_argc] = argv[k]; + 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 ); + return k; + } + // we are still here, so no luatex.dll; spawn texlua.exe instead + + strcpy( luatexfname,binary); + strcpy( cmdline, " --luaonly " ); + strcpy( cmdline, "\"" ); + strcat( cmdline, luatexpath ); + strcat( cmdline, "\" \"" ); + strcat( cmdline, scriptpath ); + strcat( cmdline, "\"" ); + if (passprogname) { + strcat( cmdline, " --script " ); + strcat( cmdline, progname ); + } + argstr = GetCommandLine(); // get the command line of this process + if ( argstr == NULL ) DIE( "unable to retrieve the command line string\n" ); + + // skip over argv[0] in the argument string + // (it can contain embedded double quotes if launched from cmd.exe!) + + for ( quoted = 0; (*argstr) && ( !IS_WHITESPACE(*argstr) || quoted ); argstr++ ) + if (*argstr == '"') quoted = !quoted; + + // pass through all the arguments + + if ( strlen(cmdline) + strlen(argstr) >= MAX_CMD ) + DIE( "command line string too long:\n%s%s\n", cmdline, argstr ); + strcat( cmdline, argstr ); + + // create child process + + STARTUPINFO si; + PROCESS_INFORMATION pi; + ZeroMemory( &si, sizeof(si) ); + si.cb = sizeof(si); + si.dwFlags = STARTF_USESTDHANDLES;// | STARTF_USESHOWWINDOW; + //si.dwFlags = STARTF_USESHOWWINDOW; + //si.wShowWindow = SW_HIDE ; // can be used to hide console window (requires STARTF_USESHOWWINDOW flag) + si.hStdInput = GetStdHandle( STD_INPUT_HANDLE ); + si.hStdOutput = GetStdHandle( STD_OUTPUT_HANDLE ); + si.hStdError = GetStdHandle( STD_ERROR_HANDLE ); + ZeroMemory( &pi, sizeof(pi) ); + if( !CreateProcess( + NULL, // module name (uses command line if NULL) + cmdline, // command line + NULL, // process security atrributes + NULL, // thread security atrributes + TRUE, // handle inheritance + 0, // creation flags, e.g. CREATE_NEW_CONSOLE, CREATE_NO_WINDOW, DETACHED_PROCESS + NULL, // pointer to environment block (uses parent if NULL) + NULL, // starting directory (uses parent if NULL) + &si, // STARTUPINFO structure + &pi ) // PROCESS_INFORMATION structure + ) DIE( "command execution failed: %s\n", cmdline ); + DWORD ret = 0; + CloseHandle( pi.hThread ); // thread handle is not needed + if ( WaitForSingleObject( pi.hProcess, INFINITE ) == WAIT_OBJECT_0 ) { + if ( !GetExitCodeProcess( pi.hProcess, &ret) ) + DIE( "unable to retrieve process exit code: %s\n", cmdline ); + } else DIE( "failed to wait for process termination: %s\n", cmdline ); + CloseHandle( pi.hProcess ); + + // propagate exit code from the child process + return ret; + +} diff --git a/Build/source/texk/texlive/w64_mingw_wrapper/context/mtxrun_exe.c b/Build/source/texk/texlive/w64_mingw_wrapper/context/mtxrun_exe.c new file mode 100644 index 00000000000..0c27c272e37 --- /dev/null +++ b/Build/source/texk/texlive/w64_mingw_wrapper/context/mtxrun_exe.c @@ -0,0 +1,8 @@ +// This is the .exe part of the mtxrun program, see mtxrun_dll.c +// for more details. + +#include + +__declspec(dllimport) int dllrunscript( int argc, char *argv[] ); + +int main( int argc, char *argv[] ) { return dllrunscript( argc, argv ); } diff --git a/Build/source/texk/texlive/w64_mingw_wrapper/context/readme.txt b/Build/source/texk/texlive/w64_mingw_wrapper/context/readme.txt new file mode 100644 index 00000000000..72892ee2f11 --- /dev/null +++ b/Build/source/texk/texlive/w64_mingw_wrapper/context/readme.txt @@ -0,0 +1,40 @@ +Copyright: + +The originally 'runscript' program was written by in 2009 by T.M.Trzeciak and is +public domain. This derived mtxrun program is an adapted version by Hans Hagen and +Luigi Scarso. + +Comment: + +In ConTeXt MkIV we have two core scripts: luatools.lua and mtxrun.lua where the +second one is used to launch other scripts. The mtxrun.exe program calls luatex.exe. + +Normally a user will use a call like: + + mtxrun --script font --reload + +Here mtxrun is a lua script. In order to avoid the usage of a cmd file on windows this +runner will start texlua directly. In TeXlive a runner is added for each cmd file but +we don't want that overhead (and extra files). By using an exe we can call these +scripts in batch files without the need for using call. + +The mtxrun.exe file can be copied to a mtxrunjit.exe file in which case luajittex.exe +is called. + + mtxrunjit --script font --reload + +We also don't want to use other runners, like those that use kpse to locate the script +as this is exactly what mtxrun itself is doing already. Therefore the runscript program +is adapted to a more direct approach suitable for mtxrun. + +Compilation: + +with gcc (size optimized): + + gcc -Os -s -shared -o mtxrun.dll mtxrun_dll.c + gcc -Os -s -o mtxrun.exe mtxrun_exe.c -L./ -lmtxrun + +with tcc (ver. 0.9.24), extra small size + + tcc -shared -o runscript.dll runscript_dll.c + tcc -o runscript.exe runscript_exe.c runscript.def diff --git a/Build/source/texk/texlive/w64_mingw_wrapper/libkpathsea-6.dll b/Build/source/texk/texlive/w64_mingw_wrapper/libkpathsea-6.dll new file mode 100755 index 00000000000..d821e4a30a4 Binary files /dev/null and b/Build/source/texk/texlive/w64_mingw_wrapper/libkpathsea-6.dll differ diff --git a/Build/source/texk/texlive/w64_mingw_wrapper/readme.txt b/Build/source/texk/texlive/w64_mingw_wrapper/readme.txt new file mode 100644 index 00000000000..a4637d812ae --- /dev/null +++ b/Build/source/texk/texlive/w64_mingw_wrapper/readme.txt @@ -0,0 +1,229 @@ + + 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 + 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 + + 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 . + + 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 arguments] + + If you prefer to call the script program simply by its name, copy + and rename bin/win32/runscript.exe to .exe and put it + somewhere on the search path. + + 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 catched. + + 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): + + x86_64-w64-mingw32-gcc -Os -s -shared -o runscript.dll runscript_dll.c -L./ -ltexlua + x86_64-w64-mingw32-gcc -Os -s -o runscript.exe runscript_exe.c -L./ -lrunscript +Untested (todo): + x86_64-w64-mingw32-gcc -mwindows -Os -s -o wrunscript.exe wrunscript_exe.c -L./ -lrunscript + +Untested (todo): + with tcc (extra small size): + + tiny_impdef texlua.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 + 2019/02/19 + - patches for cross-compiled texlive with Mingw x86_64 from Ubuntu + diff --git a/Build/source/texk/texlive/w64_mingw_wrapper/runscript.dll b/Build/source/texk/texlive/w64_mingw_wrapper/runscript.dll new file mode 100755 index 00000000000..aa418b5d4f6 Binary files /dev/null and b/Build/source/texk/texlive/w64_mingw_wrapper/runscript.dll differ diff --git a/Build/source/texk/texlive/w64_mingw_wrapper/runscript.exe b/Build/source/texk/texlive/w64_mingw_wrapper/runscript.exe new file mode 100755 index 00000000000..d765cdf75a5 Binary files /dev/null and b/Build/source/texk/texlive/w64_mingw_wrapper/runscript.exe differ diff --git a/Build/source/texk/texlive/w64_mingw_wrapper/runscript.tlu b/Build/source/texk/texlive/w64_mingw_wrapper/runscript.tlu new file mode 100755 index 00000000000..0f94c5603aa --- /dev/null +++ b/Build/source/texk/texlive/w64_mingw_wrapper/runscript.tlu @@ -0,0 +1,928 @@ + + +local svnrevision = string.match("$Revision: 49485 $", "%d+") or "0" +local svndate = string.match("$Date: 2018-12-23 16:28:08 +0100 (Sun, 23 Dec 2018) $", "[-%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 . + + 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 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 .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 + os.setenv('RUNSCRIPT_ERROR_MESSAGE', msg) + if 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(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 (guimode or 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') + os.setenv('GS_DLL', TEXDIR..'/tlpkg/tlgs/bin/gsdll32.dll') + GSEXE = TEXDIR..'/tlpkg/tlgs/bin/gswin32c.exe' + GSNAME = 'gswin32c.exe' + GSDIR = TEXDIR..'/tlpkg/tlgs/bin' +end +-- now setup the path so that the gs program will be found +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(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(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(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 = '.tlu;.texlua;.pl;.lua;.rb;.py;.tcl;.jar;.vbs;.js;.bat;.cmd;\0' + local progfullname = search_path(progname, BINDIR, '.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 tclkit? + 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 + TCLEXENAME, TCLEXE = check_command(extension_map['.tcl'][1], PATH) + end + if try_extern_tcl and not TCLEXENAME 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 TCLEXENAME then + ARGV = {[0]=TEXDIR..'/tlpkg/tltcl/tclkit.exe', 'tclkit.exe'} + PATH = prepend_path(PATH, TEXDIR:gsub('/','\\')..'\\tlpkg\\tltcl') + 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) diff --git a/Build/source/texk/texlive/w64_mingw_wrapper/runscript_dll.c b/Build/source/texk/texlive/w64_mingw_wrapper/runscript_dll.c new file mode 100644 index 00000000000..588c84b95bc --- /dev/null +++ b/Build/source/texk/texlive/w64_mingw_wrapper/runscript_dll.c @@ -0,0 +1,127 @@ +/************************************************************************ + + This file is a part of the wrapper program for launching scripts + and programs in TeX Live on Windows. See readme.txt for more details. + + This file was originally written in 2009 by Tomasz M. Trzeciak and + was placed in the Public Domain. + +************************************************************************/ + +#include +#include +#include +#define IS_WHITESPACE(c) ((c == ' ') || (c == '\t')) +#define MAX_MSG 2*MAX_PATH +#define DIE(...) { _snprintf( msg_buf, MAX_MSG - 1, __VA_ARGS__ ); goto DIE; } + +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(dllexport) int dllrunscript( int argc, char *argv[] ) +{ + static char own_path[MAX_PATH]; + static char fpath[MAX_PATH]; + char *fname, *argline, **lua_argv; + char *quoted_argline; + int k, quoted, lua_argc; + HMODULE module_handle = NULL; + + // file path of the executable + k = (int) GetModuleFileName(NULL, own_path, MAX_PATH); + if ( !k || (k == MAX_PATH) ) + DIE("cannot get own path (may be too long): %s\n", own_path); + + // script path (the dir of this library) + module_handle = GetModuleHandle(module_name); + // if ( module_handle == NULL ) exe path will be used, which is OK too + k = (int) GetModuleFileName(module_handle, fpath, MAX_PATH); + if ( !k || (k == MAX_PATH) ) + DIE("cannot get module path (may be too long): %s\n", fpath); + fname = strrchr(fpath, '\\'); + if ( fname == NULL ) DIE("no directory part in module path: %s\n", fpath); + fname++; + if ( fname + strlen(script_name) >= fpath + MAX_PATH - 1 ) + DIE("path too long: %s\n", fpath); + strcpy(fname, script_name); + if ( GetFileAttributes(fpath) == INVALID_FILE_ATTRIBUTES ) + 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"); + quoted_argline = malloc((1+strlen(argline)+1 + 1)*sizeof(char)); + if ( quoted_argline == NULL ) DIE("failed to quote 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 + // we need to quote our string , it seems. + snprintf(quoted_argline, (size_t)(1+strlen(argline)+1 + 1), "\"%s\"", argline); + + // set up argument list for texlua script + lua_argv = (char **)malloc( (argc + 6) * sizeof(char *) ); + lua_argv[lua_argc=0] = texlua_name; + lua_argv[++lua_argc] = fpath; // script to execute + for ( k = 1; k < argc; k++ ) lua_argv[++lua_argc] = argv[k]; // copy argument list + lua_argv[++lua_argc] = subsys_mode; // sentinel argument + lua_argv[++lua_argc] = argc ? argv[0] : own_path; // original argv[0] + //lua_argv[++lua_argc] = argline; // unparsed arguments + lua_argv[++lua_argc] = quoted_argline; // unparsed arguments + lua_argv[++lua_argc] = NULL; + + // call texlua interpreter + // for(int j=0; j + +__declspec(dllimport) int dllrunscript( int argc, char *argv[] ); + +int main( int argc, char *argv[] ) { return dllrunscript( argc, argv ); } diff --git a/Build/source/texk/texlive/w64_mingw_wrapper/texlua.dll b/Build/source/texk/texlive/w64_mingw_wrapper/texlua.dll new file mode 100755 index 00000000000..0a4d2e638bf Binary files /dev/null and b/Build/source/texk/texlive/w64_mingw_wrapper/texlua.dll differ diff --git a/Build/source/texk/texlive/w64_mingw_wrapper/texlua.exe b/Build/source/texk/texlive/w64_mingw_wrapper/texlua.exe new file mode 100755 index 00000000000..daf7cd29ecb Binary files /dev/null and b/Build/source/texk/texlive/w64_mingw_wrapper/texlua.exe differ diff --git a/Build/source/texk/texlive/w64_mingw_wrapper/tl-tray-menu.c b/Build/source/texk/texlive/w64_mingw_wrapper/tl-tray-menu.c new file mode 100644 index 00000000000..fe65d54515a --- /dev/null +++ b/Build/source/texk/texlive/w64_mingw_wrapper/tl-tray-menu.c @@ -0,0 +1,310 @@ +/* + +Simple tray menu + +Originally written in 2011 by Tomasz M. Trzeciak, Public Domain + +compiling with gcc (size optimized): +echo 1 ICON "tl-tray-menu.ico">tl-tray-menu.rc +windres tl-tray-menu.rc tl-tray-menu-rc.o +gcc -Os -s -mwindows -o tl-tray-menu.exe tl-tray-menu-rc.o tl-tray-menu.c + +*/ + +#define _WIN32_IE 0X0500 // minimum support for tray baloon (IE5) + +#include +#include +#include +#include + +#define MAX_STR 32768 + +static char strBuf[MAX_STR]; + +#define DIE(...) { \ + _snprintf( strBuf, 4*MAX_PATH, __VA_ARGS__ ); \ + MessageBox( NULL, strBuf, "ERROR!", MB_ICONERROR | MB_SETFOREGROUND );\ + return 1; \ +} + +#define IDI_ICON 1 // resource number of icon +#define IDI_TRAY 100 +#define WM_TRAYMSG 101 + +#define MAX_MENU_ENTRIES 31 +#define MENU_CONFIG ( MAX_MENU_ENTRIES + 1 ) +#define MENU_EXIT ( MAX_MENU_ENTRIES + 2 ) + +// buffer holding menu labels and commands +// (used only with config file) +static char menuStrings[MAX_STR]; + +// default menu labels +char *menuLabels[MAX_MENU_ENTRIES] = { +"&Package Manager", +"&Documentation", +"&Editor", +"PostScript/PDF &Viewer", +"&Command Prompt", +NULL }; + +// default menu commands +char *menuCommands[MAX_MENU_ENTRIES] = { +"bin\\win32\\tlmgr-gui.exe", +"bin\\win32\\texdoctk.exe", +"bin\\win32\\texworks.exe", +"bin\\win32\\psv.exe", +"tlpkg\\installer\\tl-cmd.bat", +NULL }; + +char configInfo[4*MAX_PATH] = "\ +The menu can be customized with a configuration file.\n\ +For an example and instructions see:\n"; + +HMENU hPopMenu; +NOTIFYICONDATA nid; + +LRESULT CALLBACK WndProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam ) +{ + switch ( msg ) + { + case WM_CREATE: + { + hPopMenu = CreatePopupMenu(); + int i; + for ( i = 0; menuLabels[i]; i++ ) + { + if ( menuCommands[i] ) + AppendMenu( hPopMenu, MF_STRING, i, menuLabels[i] ); + } + AppendMenu( hPopMenu, MF_SEPARATOR, 0, NULL ); + AppendMenu( hPopMenu, MF_STRING, MENU_CONFIG, "More..." ); + AppendMenu( hPopMenu, MF_STRING, MENU_EXIT, "E&xit" ); + } + break; + + case WM_TRAYMSG: + { + switch ( lParam ) + { + case WM_LBUTTONUP: + case WM_RBUTTONUP: + { + POINT pnt; + GetCursorPos( &pnt ); + SetForegroundWindow( hWnd ); // needed to get keyboard focus + TrackPopupMenu( hPopMenu, TPM_LEFTALIGN, pnt.x, pnt.y, 0, hWnd, NULL ); + } + break; + } + } + break; + + case WM_COMMAND: + { + switch ( LOWORD( wParam ) ) + { + case MENU_CONFIG: + MessageBox( NULL, configInfo, nid.szTip, MB_SETFOREGROUND ); + break; + + case MENU_EXIT: + Shell_NotifyIcon( NIM_DELETE, &nid ); + ExitProcess(0); + break; + + default: + { + STARTUPINFO si; + PROCESS_INFORMATION pi; + ZeroMemory( &si, sizeof(si) ); + si.cb = sizeof(si); + //si.dwFlags = STARTF_USESHOWWINDOW; + //si.wShowWindow = SW_HIDE ; + ZeroMemory( &pi, sizeof(pi) ); + if( !CreateProcess( + NULL, // module name (uses command line if NULL) + menuCommands[LOWORD(wParam)], // command line + NULL, // process security atrributes + NULL, // thread security atrributes + TRUE, // handle inheritance + 0, // creation flags, e.g. CREATE_NO_WINDOW, DETACHED_PROCESS + NULL, // pointer to environment block (uses parent if NULL) + NULL, // starting directory (uses parent if NULL) + &si, // STARTUPINFO structure + &pi ) // PROCESS_INFORMATION structure + ) DIE( "Failed to spawn command (error code %d):\n%s", + GetLastError(), menuCommands[LOWORD(wParam)] ); + } + } + } + break; + + default: + return DefWindowProc( hWnd, msg, wParam, lParam ); + + } + + return 0; +} + +int APIENTRY WinMain( + HINSTANCE hInstance, + HINSTANCE hPrevInstance, + LPSTR lpCmdLine, + int nCmdShow ) +{ + + // scratch variables + + char *s; + + // get file name of this executable + + static char dirSelf[MAX_PATH]; + DWORD nchars = GetModuleFileName(NULL, dirSelf, MAX_PATH); + if ( !nchars || ( nchars == MAX_PATH ) ) DIE( "Cannot get own path." ); + if ( s = strrchr( dirSelf, '\\' ) ) *s = '\0'; // remove file name part + + // set current directory + + if ( !SetCurrentDirectory( dirSelf ) ) + DIE( "Failed to change current directory to:\n%s", dirSelf ); + + // prepend bin/win32 to PATH + + strcpy( strBuf, dirSelf ); + strcat( strBuf, "\\bin\\win32;" ); + strcat( strBuf, getenv( "PATH" ) ); + SetEnvironmentVariable( "PATH", strBuf ); + + // configuration + + static char fileConfig[MAX_PATH]; + s = dirSelf + strlen(dirSelf) + 1; + strcpy( fileConfig, s ); + if ( s = strrchr( fileConfig, '.' ) ) *s = '\0'; // remove file extension part + strcat( fileConfig, ".ini" ); + + strcat( configInfo, dirSelf ); + strcat( configInfo, "\\tlpkg\\installer\\" ); + strcat( configInfo, fileConfig ); + + if ( GetFileAttributes( fileConfig ) == INVALID_FILE_ATTRIBUTES ) { + + // validate default configuration (menuCommands should be existing files) + + int i; + for ( i = 0; menuLabels[i]; i++ ) + if ( GetFileAttributes( menuCommands[i] ) == INVALID_FILE_ATTRIBUTES ) + menuCommands[i] = NULL; + + } else { + + // read menu configuration from ini file + + FILE *CONFIG = fopen( fileConfig, "rt" ); + if ( CONFIG == NULL ) + DIE( "Failed to open configuration file:\n%s\\%s", dirSelf, fileConfig ); + + char strSect[] = "[menu]"; + int menuItem = -1; + int i = 0; + int lineNo; + for ( lineNo = 1 ; fgets( strBuf, MAX_STR, CONFIG ) + && menuItem < MAX_MENU_ENTRIES ; lineNo++ ) + { + if ( menuItem < 0 ) + { + if ( *strBuf == '[' && + strncmp( strBuf, strSect, strlen( strSect ) ) == 0 ) menuItem++; + continue; + } + if ( *strBuf == ';' ) continue; // skip comments + if ( *strBuf == '[' ) break; // next section + s = &menuStrings[i]; + i += ExpandEnvironmentStrings( strBuf, s, MAX_STR - i ); + if ( i >= MAX_STR ) + DIE( "Exceeded 32KB limit for configuration." ); + if ( i-2 && menuStrings[i-2] == '\n' ) { menuStrings[i-2] = '\0'; i--; } + menuLabels[menuItem] = s; + while ( *s && *s != '=' ) s++; + if ( *s == '\0' ) + DIE( "Missing '=' on line %d in configuration file:\n%s\\%s", + lineNo, dirSelf, fileConfig ); + *s++ = '\0'; // assign first, then increment + menuCommands[menuItem] = s; + menuItem++; + } + if ( menuItem < 0 ) + DIE( "Missing [menu] section in configuration file:\n%s\\%s", + dirSelf, fileConfig ); + menuLabels[menuItem] = NULL; + menuCommands[menuItem] = NULL; + + fclose( CONFIG ); + + } + + // create a hidden window for messaging + + MSG msg; + WNDCLASS wc; + HWND hWnd; + char szAppName[] = "TrayMenu"; + + ZeroMemory( &wc, sizeof wc ); + wc.hInstance = hInstance; + wc.lpszClassName = szAppName; + wc.lpfnWndProc = (WNDPROC)WndProc; + wc.style = 0; + wc.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH); + wc.hIcon = LoadIcon( NULL, IDI_APPLICATION ); + wc.hCursor = LoadCursor( NULL, IDC_ARROW ); + + if ( FALSE == RegisterClass( &wc ) ) DIE( "Failed to register window class" ); + + hWnd = CreateWindow( + szAppName, + "", + 0, + CW_USEDEFAULT, + CW_USEDEFAULT, + CW_USEDEFAULT, + CW_USEDEFAULT, + 0, + 0, + hInstance, + 0); + + if ( hWnd == NULL ) DIE( "Failed to create window" ); + + // tray icon stuff + + nid.cbSize = sizeof nid; + nid.hWnd = hWnd; + nid.uID = IDI_TRAY; + nid.uFlags = NIF_ICON|NIF_MESSAGE|NIF_TIP; + nid.hIcon = LoadIcon( hInstance, MAKEINTRESOURCE( IDI_ICON ) ); + nid.uCallbackMessage = WM_TRAYMSG; + strcpy( nid.szTip, "TeX Live Menu" ); +#if (_WIN32_IE >= 0X0500) + nid.uFlags |= NIF_INFO; + nid.dwInfoFlags = NIIF_INFO; + strcpy( nid.szInfo, "Click on the tray icon\nto activate the menu." ); + strcpy( nid.szInfoTitle, nid.szTip ); +#endif + Shell_NotifyIcon( NIM_ADD, &nid ); + + // main message loop: + + while ( GetMessage( &msg, NULL, 0, 0 ) > 0 ) + { + TranslateMessage( &msg ); + DispatchMessage( &msg ); + } + + return msg.wParam; +} + diff --git a/Build/source/texk/texlive/w64_mingw_wrapper/tlmgr-gui.txt b/Build/source/texk/texlive/w64_mingw_wrapper/tlmgr-gui.txt new file mode 100644 index 00000000000..559d97ed3f2 --- /dev/null +++ b/Build/source/texk/texlive/w64_mingw_wrapper/tlmgr-gui.txt @@ -0,0 +1,77 @@ +/* + +Launcher stub for tlmgr gui (with hidden console window) + +////////////////////////////////////////////////// + +This version has been replaced with a version which triggers a UAC +prompt when appropriate. See Master/source/tlmgr-gui_UAC.zip. + +////////////////////////////////////////////////// + +Originally written in 2011 by Tomasz M. Trzeciak, Public Domain + +compiling with gcc (size optimized): +echo 1 ICON "tlmgr-gui.ico">tlmgr-gui.rc +windres tlmgr-gui.rc tlmgr-gui-rc.o +gcc -Os -s -mwindows -o tlmgr-gui.exe tlmgr-gui-rc.o tlmgr-gui.c + +compiling with tcc (ver. 0.9.25), extra small size +windres tlmgr-gui.rc tlmgr-gui-rc.o +tcc -o tlmgr-gui.exe tlmgr-gui-rc.o tlmgr-gui.c + +*/ + +#include + +static char msgbuf[4*MAX_PATH]; +#define DIE(...) { \ + _snprintf( msgbuf, 4*MAX_PATH, __VA_ARGS__ ); \ + MessageBox( NULL, msgbuf, "ERROR!", MB_ICONERROR | MB_SETFOREGROUND );\ + return 1; \ +} + +static char cmdln[2*MAX_PATH]; + +int APIENTRY WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShowint ) { + + // get file name of this executable + + static char selfdir[MAX_PATH]; + char *name, *ext, *s; + DWORD nchars = GetModuleFileName(NULL, selfdir, MAX_PATH); + if ( !nchars || (nchars == MAX_PATH) ) DIE( "cannot get own path" ); + + // make command to execute + + if ( s = strrchr(selfdir, '\\') ) *s = '\0'; // remove file name part + strcat( cmdln, "\"" ); + strcat( cmdln, selfdir ); + strcat( cmdln, "\\tlmgr.bat\" -gui" ); + + // create child process + + STARTUPINFO si; + PROCESS_INFORMATION pi; + ZeroMemory( &si, sizeof(si) ); + si.cb = sizeof(si); + si.dwFlags = STARTF_USESHOWWINDOW; + si.wShowWindow = SW_HIDE ; + ZeroMemory( &pi, sizeof(pi) ); + + if( !CreateProcess( + NULL, // module name (uses command line if NULL) + cmdln, // command line + NULL, // process security atrributes + NULL, // thread security atrributes + TRUE, // handle inheritance + 0, // creation flags, e.g. CREATE_NEW_CONSOLE, CREATE_NO_WINDOW, DETACHED_PROCESS + NULL, // pointer to environment block (uses parent if NULL) + NULL, // starting directory (uses parent if NULL) + &si, // STARTUPINFO structure + &pi ) // PROCESS_INFORMATION structure + ) DIE( "command execution failed: %s", cmdln ); + + return 0; + +} diff --git a/Build/source/texk/texlive/w64_mingw_wrapper/tlmgr.ico b/Build/source/texk/texlive/w64_mingw_wrapper/tlmgr.ico new file mode 100644 index 00000000000..6f0c37f54e0 Binary files /dev/null and b/Build/source/texk/texlive/w64_mingw_wrapper/tlmgr.ico differ diff --git a/Build/source/texk/texlive/w64_mingw_wrapper/tlmgr.svg b/Build/source/texk/texlive/w64_mingw_wrapper/tlmgr.svg new file mode 100644 index 00000000000..6e60a8f273c --- /dev/null +++ b/Build/source/texk/texlive/w64_mingw_wrapper/tlmgr.svg @@ -0,0 +1,245 @@ + + + +image/svg+xml + + \ No newline at end of file diff --git a/Build/source/texk/texlive/w64_mingw_wrapper/wrunscript_exe.c b/Build/source/texk/texlive/w64_mingw_wrapper/wrunscript_exe.c new file mode 100644 index 00000000000..573501ae757 --- /dev/null +++ b/Build/source/texk/texlive/w64_mingw_wrapper/wrunscript_exe.c @@ -0,0 +1,27 @@ +/************************************************************************ + + This file is a part of the wrapper program for launching scripts + and programs in TeX Live on Windows. See readme.txt for more details. + + This file was originally written in 2009 by Tomasz M. Trzeciak and + was placed in the Public Domain. + +************************************************************************/ + +#include + +__declspec(dllimport) int dllwrunscript( + HINSTANCE hInstance, + HINSTANCE hPrevInstance, + char *argline, + int winshow + ); + +int APIENTRY WinMain( + HINSTANCE hInstance, + HINSTANCE hPrevInstance, + char *argline, + int winshow +){ + return dllwrunscript( hInstance, hPrevInstance, argline, winshow ); +} diff --git a/Build/source/texk/web2c/luatexdir/am/luatex.am b/Build/source/texk/web2c/luatexdir/am/luatex.am index 0bf46639091..4ee88f114bc 100644 --- a/Build/source/texk/web2c/luatexdir/am/luatex.am +++ b/Build/source/texk/web2c/luatexdir/am/luatex.am @@ -116,17 +116,17 @@ call_luajittex_LDADD = if WIN32 if MINGW32 install-luatex-links: .libs/luatex$(EXEEXT) - $(INSTALL_PROGRAM) .libs/luatex$(EXEEXT) $(DESTDIR)$(bindir)/texlua$(EXEEXT) - $(INSTALL_PROGRAM) .libs/luatex$(EXEEXT) $(DESTDIR)$(bindir)/texluac$(EXEEXT) + $(INSTALL_PROGRAM) .libs/luatex$(EXEEXT) $(DESTDIR)$(bindir)/texlua$(EXEEXT) + $(INSTALL_PROGRAM) .libs/luatex$(EXEEXT) $(DESTDIR)$(bindir)/texluac$(EXEEXT) uninstall-luatex-links: - rm -f $(DESTDIR)$(bindir)/texlua$(EXEEXT) - rm -f $(DESTDIR)$(bindir)/texluac$(EXEEXT) + rm -f $(DESTDIR)$(bindir)/texlua$(EXEEXT) + rm -f $(DESTDIR)$(bindir)/texluac$(EXEEXT) install-luajittex-links: .libs/luajittex$(EXEEXT) - $(INSTALL_PROGRAM) .libs/luajittex$(EXEEXT) $(DESTDIR)$(bindir)/texluajit$(EXEEXT) - $(INSTALL_PROGRAM) .libs/luajittex$(EXEEXT) $(DESTDIR)$(bindir)/texluajitc$(EXEEXT) + $(INSTALL_PROGRAM) .libs/luajittex$(EXEEXT) $(DESTDIR)$(bindir)/texluajit$(EXEEXT) + $(INSTALL_PROGRAM) .libs/luajittex$(EXEEXT) $(DESTDIR)$(bindir)/texluajitc$(EXEEXT) uninstall-luajittex-links: - rm -f $(DESTDIR)$(bindir)/texluajit$(EXEEXT) - rm -f $(DESTDIR)$(bindir)/texluajitc$(EXEEXT) + rm -f $(DESTDIR)$(bindir)/texluajit$(EXEEXT) + rm -f $(DESTDIR)$(bindir)/texluajitc$(EXEEXT) else !MINGW32 install-luatex-links: call_luatex$(EXEEXT) $(INSTALL_PROGRAM) call_luatex$(EXEEXT) $(DESTDIR)$(bindir)/texlua$(EXEEXT) -- cgit v1.2.3