summaryrefslogtreecommitdiff
path: root/Build/source/texk/web2c/luatexdir/lua/luainit.c
diff options
context:
space:
mode:
Diffstat (limited to 'Build/source/texk/web2c/luatexdir/lua/luainit.c')
-rw-r--r--Build/source/texk/web2c/luatexdir/lua/luainit.c520
1 files changed, 520 insertions, 0 deletions
diff --git a/Build/source/texk/web2c/luatexdir/lua/luainit.c b/Build/source/texk/web2c/luatexdir/lua/luainit.c
new file mode 100644
index 00000000000..c76b676c0f4
--- /dev/null
+++ b/Build/source/texk/web2c/luatexdir/lua/luainit.c
@@ -0,0 +1,520 @@
+#include <sys/stat.h>
+
+#include "luatex-api.h"
+#include <ptexlib.h>
+
+#include <luatexdir/luatexextra.h>
+
+#ifndef program_invocation_name
+/* char *program_invocation_name = NULL; */
+#endif
+
+extern void parse_src_specials_option (char *n) ;
+
+const_string LUATEX_IHELP[] = {
+ "Usage: luatex --lua=FILE [OPTION]... [TEXNAME[.tex]] [COMMANDS]",
+ " or: luatex --lua=FILE [OPTION]... \\FIRST-LINE",
+ " or: luatex --lua=FILE [OPTION]... &FMT ARGS",
+ " Run luaTeX on TEXNAME, usually creating TEXNAME.pdf.",
+ " Any remaining COMMANDS are processed as luatex input, after TEXNAME is read.",
+ "",
+ " Alternatively, if the first non-option argument begins with a backslash,",
+ " interpret all non-option arguments as a line of luatex input.",
+ "",
+ " Alternatively, if the first non-option argument begins with a &, the",
+ " next word is taken as the FMT to read, overriding all else. Any",
+ " remaining arguments are processed as above.",
+ "",
+ " If no arguments or options are specified, prompt for input.",
+ "",
+ " --lua=FILE the lua initialization file",
+ " --safer disable some easily exploitable lua commands",
+ " --fmt=FORMAT load the format file FORMAT",
+ " --ini be initex, for dumping formats",
+ " --help display this help and exit",
+ " --version output version information and exit",
+ "",
+ " Alternate behaviour models can be obtained by special switches",
+ "",
+ " --luaonly run a lua file, then exit",
+ " --luaconly byte-compile a lua file, then exit",
+ NULL
+};
+
+static void
+prepare_cmdline(lua_State * L, char **argv, int argc, int zero_offset)
+{
+ int i;
+ luaL_checkstack(L, argc + 3, "too many arguments to script");
+ lua_createtable(L, 0, 0);
+ for (i = 0; i < argc; i++) {
+ lua_pushstring(L, argv[i]);
+ lua_rawseti(L, -2, (i-zero_offset));
+ }
+ lua_setglobal(L, "arg");
+ return;
+}
+
+extern string dump_name;
+extern const_string c_job_name;
+extern boolean srcspecialsoption;
+extern char *last_source_name;
+extern int last_lineno;
+
+string input_name = NULL;
+
+static string user_progname = NULL;
+
+extern char *ptexbanner;
+extern int program_name_set; /* in lkpselib.c */
+
+/* for topenin() */
+extern char **argv;
+extern int argc;
+
+char *startup_filename = NULL;
+int lua_only = 0;
+int lua_offset = 0;
+
+int safer_option = 0;
+
+/* Reading the options. */
+
+/* Test whether getopt found an option ``A''.
+ Assumes the option index is in the variable `option_index', and the
+ option table in a variable `long_options'. */
+#define ARGUMENT_IS(a) STREQ (long_options[option_index].name, a)
+
+/* SunOS cc can't initialize automatic structs, so make this static. */
+static struct option long_options[]
+ = { { "fmt", 1, 0, 0},
+ { "lua", 1, 0, 0},
+ { "luaonly", 0, 0, 0},
+ { "safer", 0, &safer_option, 1},
+ { "help", 0, 0, 0 },
+ { "ini", 0, &ini_version, 1 },
+ { "interaction", 1, 0, 0 },
+ { "halt-on-error", 0, &haltonerrorp, 1 },
+ { "kpathsea-debug", 1, 0, 0 },
+ { "progname", 1, 0, 0 },
+ { "version", 0, 0, 0 },
+ { "recorder", 0, &recorder_enabled, 1 },
+ { "etex", 0, 0, 0 },
+ { "output-comment", 1, 0, 0 },
+ { "output-directory", 1, 0, 0 },
+ { "draftmode", 0, 0, 0 },
+ { "output-format", 1, 0, 0 },
+ { "shell-escape", 0, &shellenabledp, 1 },
+ { "no-shell-escape", 0, &shellenabledp, -1 },
+ { "debug-format", 0, &debug_format_file, 1 },
+ { "src-specials", 2, 0, 0 },
+ { "file-line-error-style", 0, &filelineerrorstylep, 1 },
+ { "no-file-line-error-style", 0, &filelineerrorstylep, -1 },
+ /* Shorter option names for the above. */
+ { "file-line-error", 0, &filelineerrorstylep, 1 },
+ { "no-file-line-error", 0, &filelineerrorstylep, -1 },
+ { "jobname", 1, 0, 0 },
+ { "parse-first-line", 0, &parsefirstlinep, 1 },
+ { "no-parse-first-line", 0, &parsefirstlinep, -1 },
+ { "translate-file", 1, 0, 0 },
+ { "default-translate-file", 1, 0, 0 },
+ { "8bit", 0, 0, 0 },
+ { "mktex", 1, 0, 0 },
+ { "no-mktex", 1, 0, 0 },
+{0, 0, 0, 0}
+};
+
+static void
+parse_options(int argc, char **argv)
+{
+ int g; /* `getopt' return code. */
+ int option_index;
+ char *firstfile = NULL;
+ opterr = 0; /* dont whine */
+ for (;;) {
+ g = getopt_long_only(argc, argv, "+", long_options, &option_index);
+
+ if (g == -1) /* End of arguments, exit the loop. */
+ break;
+ if (g == '?') /* Unknown option. */
+ continue;
+
+ assert(g == 0); /* We have no short option names. */
+
+ if (ARGUMENT_IS("luaonly")) {
+ lua_only = 1;
+ lua_offset = optind;
+ luainit = 1 ;
+ } else if (ARGUMENT_IS("lua")) {
+ startup_filename = optarg;
+ lua_offset = (optind-1);
+ luainit = 1 ;
+
+ } else if (ARGUMENT_IS ("kpathsea-debug")) {
+ kpathsea_debug |= atoi (optarg);
+
+ } else if (ARGUMENT_IS("progname")) {
+ user_progname = optarg;
+
+ } else if (ARGUMENT_IS ("jobname")) {
+ c_job_name = optarg;
+
+ } else if (ARGUMENT_IS("fmt")) {
+ dump_name = optarg;
+
+ } else if (ARGUMENT_IS ("output-directory")) {
+ output_directory = optarg;
+
+ } else if (ARGUMENT_IS ("output-comment")) {
+ unsigned len = strlen (optarg);
+ if (len < 256) {
+ output_comment = optarg;
+ } else {
+ WARNING2 ("Comment truncated to 255 characters from %d. (%s)",
+ len, optarg);
+ output_comment = (string)xmalloc (256);
+ strncpy (output_comment, optarg, 255);
+ output_comment[255] = 0;
+ }
+
+ } else if (ARGUMENT_IS ("src-specials")) {
+ last_source_name = xstrdup("");
+ /* Option `--src" without any value means `auto' mode. */
+ if (optarg == NULL) {
+ insertsrcspecialeverypar = true;
+ insertsrcspecialauto = true;
+ srcspecialsoption = true;
+ srcspecialsp = true;
+ } else {
+ parse_src_specials_option(optarg);
+ }
+
+ } else if (ARGUMENT_IS ("output-format")) {
+ pdf_output_option = 1;
+ if (strcmp(optarg, "dvi") == 0) {
+ pdf_output_value = 0;
+ } else if (strcmp(optarg, "pdf") == 0) {
+ pdf_output_value = 2;
+ } else {
+ WARNING1 ("Ignoring unknown value `%s' for --output-format", optarg);
+ pdf_output_option = 0;
+ }
+
+ } else if (ARGUMENT_IS ("draftmode")) {
+ pdf_draftmode_option = 1;
+ pdf_draftmode_value = 1;
+
+ } else if (ARGUMENT_IS ("mktex")) {
+ kpse_maketex_option (optarg, true);
+
+ } else if (ARGUMENT_IS ("no-mktex")) {
+ kpse_maketex_option (optarg, false);
+
+ } else if (ARGUMENT_IS ("interaction")) {
+ /* These numbers match @d's in *.ch */
+ if (STREQ (optarg, "batchmode")) {
+ interactionoption = 0;
+ } else if (STREQ (optarg, "nonstopmode")) {
+ interactionoption = 1;
+ } else if (STREQ (optarg, "scrollmode")) {
+ interactionoption = 2;
+ } else if (STREQ (optarg, "errorstopmode")) {
+ interactionoption = 3;
+ } else {
+ WARNING1 ("Ignoring unknown argument `%s' to --interaction", optarg);
+ }
+
+ } else if (ARGUMENT_IS("help")) {
+ usagehelp(LUATEX_IHELP, BUG_ADDRESS);
+
+ } else if (ARGUMENT_IS("version")) {
+ char *versions;
+ initversionstring(&versions);
+ print_version_banner();
+
+ puts(
+"\n\nLuaTeX merges and builds upon (parts of) the code from these projects:\n\n"
+"tex by Donald Knuth\n"
+"etex by Peter Breitenlohner, Phil Taylor and friends\n"
+"omega by John Plaice and Yannis Haralambous\n"
+"aleph by Giuseppe Bilotta\n"
+"pdftex by Han The Thanh and friends\n"
+"kpathsea by Karl Berry, Olaf Weber and others\n"
+"lua by Roberto Ierusalimschy, Waldemar Celes,\n"
+" Luiz Henrique de Figueiredo\n"
+"metapost by John Hobby, Taco Hoekwater and friends.\n"
+"xpdf by Derek Noonberg (partial)\n"
+"fontforge by George Williams (partial)\n\n"
+"Some extensions to lua and additional lua libraries are used, as well as\n"
+"libraries for graphic inclusion. More details can be found in the source.\n"
+"Code development was sponsored by a grant from Colorado State University\n"
+"via the 'oriental tex' project, the TeX User Groups, and donations.\n\n"
+"The LuaTeX team is Hans Hagen, Hartmut Henkel, Taco Hoekwater.\n\n"
+"There is NO warranty. Redistribution of this software is covered by\n"
+"the terms of the GNU General Public License, version 2. For more\n"
+"information about these matters, see the file named COPYING and\n"
+"the LuaTeX source.\n\n"
+"Copyright 2008 Taco Hoekwater, the LuaTeX Team.\n");
+
+ puts(versions);
+ uexit(0);
+ }
+ }
+ /* attempt to find dump_name */
+ if (argv[optind] && argv[optind][0] == '&') {
+ dump_name = strdup(argv[optind] + 1);
+ } else if (argv[optind] && argv[optind][0] != '\\') {
+ if (argv[optind][0] == '*') {
+ input_name = strdup(argv[optind] + 1);
+ } else {
+ firstfile = strdup(argv[optind]);
+ if (lua_only) {
+ startup_filename = firstfile;
+ } else {
+ if ((strstr(firstfile,".lua") == firstfile+strlen(firstfile)-4) ||
+ (strstr(firstfile,".luc") == firstfile+strlen(firstfile)-4) ||
+ (strstr(firstfile,".LUA") == firstfile+strlen(firstfile)-4) ||
+ (strstr(firstfile,".LUC") == firstfile+strlen(firstfile)-4) ||
+ (strstr(argv[0],"luatexlua") != NULL) ||
+ (strstr(argv[0],"texlua") != NULL)) {
+ startup_filename = firstfile;
+ lua_only = 1;
+ lua_offset = optind;
+ luainit = 1 ;
+ } else {
+ input_name = firstfile;
+ }
+ }
+ }
+ } else {
+ if ((strstr(argv[0],"luatexlua") != NULL)||
+ (strstr(argv[0],"texlua") != NULL)) {
+ lua_only = 1;
+ luainit = 1 ;
+ }
+ }
+}
+
+/* test for readability */
+#define is_readable(a) (stat(a,&finfo)==0) && S_ISREG(finfo.st_mode) && \
+ (f=fopen(a,"r")) != NULL && !fclose(f)
+
+char *
+find_filename(char *name, char *envkey)
+{
+ struct stat finfo;
+ char *dirname = NULL;
+ char *filename = NULL;
+ FILE *f;
+ if (is_readable(name)) {
+ return name;
+ } else {
+ dirname = getenv(envkey);
+ if ((dirname != NULL) && strlen(dirname)) {
+ dirname = strdup(getenv(envkey));
+ if (*(dirname + strlen(dirname) - 1) == '/') {
+ *(dirname + strlen(dirname) - 1) = 0;
+ }
+ filename = xmalloc(strlen(dirname) + strlen(name) + 2);
+ filename = concat3(dirname, "/", name);
+ if (is_readable(filename)) {
+ xfree(dirname);
+ return filename;
+ }
+ xfree(filename);
+ }
+ }
+ return NULL;
+}
+
+
+void
+init_kpse (void) {
+
+ if (!user_progname) {
+ user_progname = dump_name;
+ } else if (!dump_name) {
+ dump_name = user_progname;
+ }
+ if (!user_progname) {
+ if (ini_version) {
+ user_progname = input_name;
+ } else {
+ if(!startup_filename) {
+ if (!dump_name) {
+ dump_name = strdup(argv[0]);
+ user_progname = dump_name;
+ }
+ }
+ }
+ }
+ if (!user_progname) {
+ fprintf(stdout,
+ "kpathsea mode needs a --progname or --fmt switch\n");
+ exit(1);
+ }
+ kpse_set_program_name(argv[0], user_progname);
+ program_name_set=1;
+}
+
+void
+fix_dumpname (void) {
+ int dist;
+ if (dump_name) {
+ /* adjust array for Pascal and provide extension, if needed */
+ dist = strlen(dump_name) - strlen(DUMP_EXT);
+ if (strstr(dump_name, DUMP_EXT) == dump_name + dist)
+ DUMP_VAR = concat(" ", dump_name);
+ else
+ DUMP_VAR = concat3(" ", dump_name, DUMP_EXT);
+ DUMP_LENGTH_VAR = strlen(DUMP_VAR + 1);
+ } else {
+ /* For dump_name to be NULL is a bug. */
+ if (!ini_version)
+ abort();
+ }
+}
+
+void
+lua_initialize(int ac, char **av)
+{
+
+ char *given_file = NULL;
+ int kpse_init;
+ int tex_table_id;
+ int pdf_table_id;
+ int token_table_id;
+ int node_table_id;
+ /* Save to pass along to topenin. */
+ argc = ac;
+ argv = av;
+
+ ptexbanner = BANNER;
+ program_invocation_name = argv[0];
+
+ /* be 'luac' */
+ if (argc>1 &&
+ (STREQ(argv[0],"texluac") ||
+ STREQ(argv[1],"--luaconly") ||
+ STREQ(argv[1],"--luac"))) {
+ exit(luac_main(ac,av));
+ }
+
+ /* Must be initialized before options are parsed. */
+ interactionoption = 4;
+ dump_name = NULL;
+ /* parse commandline */
+ parse_options(ac, av);
+
+ /* make sure that the locale is 'sane' (for lua) */
+ putenv("LC_CTYPE=C");
+ putenv("LC_COLLATE=C");
+ putenv("LC_NUMERIC=C");
+
+ /* this is sometimes needed */
+ putenv("engine=luatex");
+
+ luainterpreter(0);
+
+ prepare_cmdline(Luas[0], argv, argc, lua_offset); /* collect arguments */
+
+ if (startup_filename != NULL) {
+ given_file = xstrdup(startup_filename);
+ startup_filename = find_filename(startup_filename, "LUATEXDIR");
+ }
+ /* now run the file */
+ if (startup_filename != NULL) {
+ /* hide the 'tex' and 'pdf' table */
+ tex_table_id = hide_lua_table(Luas[0], "tex");
+ token_table_id = hide_lua_table(Luas[0], "token");
+ node_table_id = hide_lua_table(Luas[0], "node");
+ pdf_table_id = hide_lua_table(Luas[0], "pdf");
+
+ if (luaL_loadfile(Luas[0], startup_filename)) {
+ fprintf(stdout, "%s\n",lua_tostring(Luas[0], -1));
+ exit(1);
+ }
+ if (lua_pcall(Luas[0], 0, 0, 0)) {
+ fprintf(stdout, "%s\n",lua_tostring(Luas[0], -1));
+ exit(1);
+ }
+ /* no filename? quit now! */
+ if (!input_name) {
+ get_lua_string("texconfig", "jobname", &input_name);
+ }
+ if (!dump_name) {
+ get_lua_string("texconfig", "formatname", &dump_name);
+ }
+ if ((lua_only) || ((!input_name) && (!dump_name))) {
+ exit(0);
+ }
+ /* unhide the 'tex' and 'pdf' table */
+ unhide_lua_table(Luas[0], "tex", tex_table_id);
+ unhide_lua_table(Luas[0], "pdf", pdf_table_id);
+ unhide_lua_table(Luas[0], "token", token_table_id);
+ unhide_lua_table(Luas[0], "node", node_table_id);
+
+ /* kpse_init */
+ kpse_init = -1;
+ get_lua_boolean("texconfig", "kpse_init", &kpse_init);
+
+ if (kpse_init != 0) {
+ init_kpse();
+ }
+ /* prohibit_file_trace (boolean) */
+ tracefilenames = 1;
+ get_lua_boolean("texconfig", "trace_file_names", &tracefilenames);
+
+ /* src_special_xx */
+ insertsrcspecialauto = insertsrcspecialeverypar =
+ insertsrcspecialeveryparend = insertsrcspecialeverycr =
+ insertsrcspecialeverymath = insertsrcspecialeveryhbox =
+ insertsrcspecialeveryvbox = insertsrcspecialeverydisplay =
+ false;
+ get_lua_boolean("texconfig", "src_special_auto",
+ &insertsrcspecialauto);
+ get_lua_boolean("texconfig", "src_special_everypar",
+ &insertsrcspecialeverypar);
+ get_lua_boolean("texconfig", "src_special_everyparend",
+ &insertsrcspecialeveryparend);
+ get_lua_boolean("texconfig", "src_special_everycr",
+ &insertsrcspecialeverycr);
+ get_lua_boolean("texconfig", "src_special_everymath",
+ &insertsrcspecialeverymath);
+ get_lua_boolean("texconfig", "src_special_everyhbox",
+ &insertsrcspecialeveryhbox);
+ get_lua_boolean("texconfig", "src_special_everyvbox",
+ &insertsrcspecialeveryvbox);
+ get_lua_boolean("texconfig", "src_special_everydisplay",
+ &insertsrcspecialeverydisplay);
+
+ srcspecialsp = insertsrcspecialauto | insertsrcspecialeverypar |
+ insertsrcspecialeveryparend | insertsrcspecialeverycr |
+ insertsrcspecialeverymath | insertsrcspecialeveryhbox |
+ insertsrcspecialeveryvbox | insertsrcspecialeverydisplay;
+
+ /* file_line_error */
+ filelineerrorstylep = false;
+ get_lua_boolean("texconfig", "file_line_error",
+ &filelineerrorstylep);
+
+ /* halt_on_error */
+ haltonerrorp = false;
+ get_lua_boolean("texconfig", "halt_on_error", &haltonerrorp);
+
+ fix_dumpname();
+ } else {
+ if (luainit) {
+ if (given_file) {
+ fprintf(stdout, "%s file %s not found\n", (lua_only ? "Script" : "Configuration"), given_file);
+ } else {
+ fprintf(stdout, "No %s file given\n", (lua_only ? "script" : "configuration"));
+ }
+ exit(1);
+ } else {
+ /* init */
+ init_kpse();
+ fix_dumpname();
+ }
+ }
+}