aboutsummaryrefslogtreecommitdiffstats
path: root/z01.c
diff options
context:
space:
mode:
authorJeffrey H. Kingston <jeff@it.usyd.edu.au>2010-09-14 19:21:41 +0000
committerJeffrey H. Kingston <jeff@it.usyd.edu.au>2010-09-14 19:21:41 +0000
commit71bdb35d52747e6d7d9f55df4524d57c2966be94 (patch)
tree480ee5eefccc40d5f3331cc52d66f722fd19bfb9 /z01.c
parentb41263ea7578fa9742486135c762803b52794105 (diff)
downloadlout-71bdb35d52747e6d7d9f55df4524d57c2966be94.tar.gz
Lout 3.17.
git-svn-id: http://svn.savannah.nongnu.org/svn/lout/trunk@2 9365b830-b601-4143-9ba8-b4a8e2c3339c
Diffstat (limited to 'z01.c')
-rw-r--r--z01.c866
1 files changed, 866 insertions, 0 deletions
diff --git a/z01.c b/z01.c
new file mode 100644
index 0000000..6338ae5
--- /dev/null
+++ b/z01.c
@@ -0,0 +1,866 @@
+/*@z01.c:Supervise:StartSym, AllowCrossDb, Encapsulated, etc.@****************/
+/* */
+/* THE LOUT DOCUMENT FORMATTING SYSTEM (VERSION 3.17) */
+/* COPYRIGHT (C) 1991, 1999 Jeffrey H. Kingston */
+/* */
+/* Jeffrey H. Kingston (jeff@cs.usyd.edu.au) */
+/* Basser Department of Computer Science */
+/* The University of Sydney 2006 */
+/* AUSTRALIA */
+/* */
+/* This program is free software; you can redistribute it and/or modify */
+/* it under the terms of the GNU General Public License as published by */
+/* the Free Software Foundation; either Version 2, or (at your option) */
+/* any later version. */
+/* */
+/* This program is distributed in the hope that it will be useful, */
+/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
+/* GNU General Public License for more details. */
+/* */
+/* You should have received a copy of the GNU General Public License */
+/* along with this program; if not, write to the Free Software */
+/* Foundation, Inc., 59 Temple Place, Suite 330, Boston MA 02111-1307 USA */
+/* */
+/* FILE: z01.c */
+/* MODULE: Supervise */
+/* EXTERNS: main(), StartSym, GalleySym, ForceGalleySym, InputSym, */
+/* PrintSym, AllowCrossDb, Encapsulated */
+/* */
+/*****************************************************************************/
+#include "externs.h"
+
+/* On DOS/Win32 we need to set binary mode on stdout (Uwe) */
+#if OS_DOS
+#include <io.h>
+#include <fcntl.h>
+#ifdef __DJGPP__
+#define _setmode(fd, mode) setmode((fd), (mode))
+#define _fileno(stream) fileno((stream))
+#endif
+#endif
+
+/*****************************************************************************/
+/* */
+/* MemCheck - check this memory location */
+/* */
+/*****************************************************************************/
+
+POINTER MemCheck = 0;
+
+
+/*****************************************************************************/
+/* */
+/* StartSym the symbol table entry for \Start (overall scope) */
+/* GalleySym the symbol table entry for @Galley */
+/* ForceGalleySym the symbol table entry for @ForceGalley */
+/* InputSym the symbol table entry for @LInput */
+/* PrintSym the symbol table entry for \Print (root target) */
+/* OptGallSym the symbol table entry for @OptGall (optimal galley rec) */
+/* FilterInSym the symbol table entry for @FilterIn */
+/* FilterOutSym the symbol table entry for @FilterOut */
+/* FilterErrSym the symbol table entry for @FilterErr */
+/* */
+/*****************************************************************************/
+
+OBJECT StartSym, GalleySym, ForceGalleySym, InputSym, PrintSym, OptGallSym,
+ FilterInSym, FilterOutSym, FilterErrSym, VerbatimSym, RawVerbatimSym;
+
+
+/*****************************************************************************/
+/* */
+/* CommandOptions Command-line options (ACAT of objects) */
+/* */
+/*****************************************************************************/
+
+OBJECT CommandOptions;
+
+
+/*****************************************************************************/
+/* */
+/* UseCollate Use local collation sequence rather than ASCII */
+/* AllowCrossDb Allow references to OldCrossDb and NewCrossDb */
+/* InMemoryDbIndexes True if cr database index file is to be in-memory */
+/* Encapsulated Produce a one-page encapsulated PostScript file */
+/* Kern Do kerning */
+/* SafeExecution Execute safely, i.e. prohibit system() calls */
+/* AltErrorFormat Use alternative error message format */
+/* */
+/*****************************************************************************/
+
+BOOLEAN UseCollate;
+BOOLEAN AllowCrossDb;
+BOOLEAN InMemoryDbIndexes;
+BOOLEAN Encapsulated;
+BOOLEAN Kern;
+BOOLEAN SafeExecution;
+BOOLEAN AltErrorFormat;
+
+
+/*****************************************************************************/
+/* */
+/* BackEnd POSTSCRIPT, PLAINTEXT or PDF */
+/* BackEndWord "PostScript" or "PlainText" */
+/* PlainCharWidth if PLAINTEXT, the width of each character */
+/* PlainCharHeight if PLAINTEXT, the height of each character */
+/* PlainFormFeed if PLAINTEXT, TRUE if separate components with \f. */
+/* InitializeAll TRUE if this is an initializing run. */
+/* MsgCat category for locale-specific messages */
+/* TotalWordCount total number of words printed */
+/* */
+/*****************************************************************************/
+
+int BackEnd;
+FULL_CHAR *BackEndWord;
+FULL_LENGTH PlainCharWidth, PlainCharHeight;
+BOOLEAN PlainFormFeed;
+BOOLEAN InitializeAll;
+#if LOCALE_ON
+nl_catd MsgCat;
+#endif
+int TotalWordCount;
+
+
+/*****************************************************************************/
+/* */
+/* static OBJECT load(xstr, xpredefined, xleft, xright, xindef, xprec) */
+/* */
+/* Load a predefined operator with these attributes into the symbol table. */
+/* If the operator has parameters, load symbols for those also. */
+/* */
+/*****************************************************************************/
+
+static OBJECT load(FULL_CHAR *xstr, unsigned xpre,
+BOOLEAN xleft, BOOLEAN xright, BOOLEAN xindef, unsigned char xprec)
+{ OBJECT s;
+ s = InsertSym(xstr, LOCAL, no_fpos, xprec, xindef, FALSE, xpre,
+ StartSym, nilobj);
+ if( xleft ) InsertSym( AsciiToFull("pa"), LPAR, no_fpos, DEFAULT_PREC,
+ FALSE, FALSE, 0, s, nilobj);
+ if( xright ) InsertSym( AsciiToFull("pb"), RPAR, no_fpos, DEFAULT_PREC,
+ FALSE, FALSE, 0, s, nilobj);
+ if( xleft && xright && xpre != PLUS && xpre != MINUS )
+ right_assoc(s) = TRUE;
+ return s;
+} /* end load */
+
+
+/*****************************************************************************/
+/* */
+/* static void PrintUsage(fp) */
+/* */
+/* Print usage information on file fp. */
+/* */
+/*****************************************************************************/
+#define lput(str) fprintf(fp, "%s\n", str)
+
+static void PrintUsage(FILE *fp)
+{
+ lput("" );
+ lput("usage: lout options files" );
+ lput("" );
+ lput(" -s suppress access to cross reference database" );
+ lput(" -EPS EPS (Encapsulated PostScript) output" );
+ lput(" -PDF or -Z PDF (Adobe Portable Document Format) output" );
+ lput(" -p plain text output instead of PostScript" );
+ lput(" -P like -p but with form-feed char between pages" );
+ lput(" -S safe execution (disable calls to system(3))" );
+ lput(" -U unsafe execution (allow calls to system(3))" );
+ lput(" -l ASCII collation order when sorting indexes etc." );
+ lput(" -L locale collation order when sorting indexes etc." );
+ lput(" -o file output to file instead of stdout" );
+ lput(" -e file error messages to file instead of stderr" );
+ lput(" -a alternative error format: file:line:col ..." );
+ lput(" -w print total number of words in output" );
+ lput(" -i file like @SysInclude { file }; not recommended" );
+ lput(" -I directory add directory to include file search path" );
+ lput(" -C directory add directory to LCM file search path" );
+ lput(" -F directory add directory to font metrics file search path" );
+ lput(" -H directory add directory to hyphenation file search path" );
+ lput(" -D directory add directory to database file search path" );
+ lput(" --option{value} set option e.g. --'@InitialFont{Times Base 10p}'" );
+ lput(" -c file use file.li instead of lout.li for crossrefs" );
+ lput(" -M save memory (don't read in database indexes)" );
+ lput(" -x initializing run, not for ordinary use" );
+ lput(" -u print this usage message on stderr and exit" );
+ lput(" -V print version and configuration information" );
+ lput(" - a file name denoting standard input" );
+ lput("" );
+
+} /* end PrintUsage */
+
+
+/*@::GetArg(), main()@********************************************************/
+/* */
+/* GetArg(argv, argc, i) */
+/* */
+/* Get the next argument from the command line and return it. */
+/* Return NULL if it isn't there. */
+/* */
+/*****************************************************************************/
+
+static FULL_CHAR *GetArg(char *argv[], int argc, int *i)
+{ if( !StringEqual(AsciiToFull(argv[*i]+2), STR_EMPTY) )
+ return AsciiToFull(argv[*i]+2);
+ else if( *i < argc-1 && *argv[*i + 1] != CH_HYPHEN )
+ return AsciiToFull(argv[(*i)++ +1]);
+ else
+ return (FULL_CHAR *) NULL;
+} /* end GetArg */
+
+
+/*****************************************************************************/
+/* */
+/* main(argc, argv) */
+/* */
+/* Read command line, initialise everything, read definitions, read */
+/* galleys, clean up and exit. */
+/* */
+/*****************************************************************************/
+
+int main(int argc, char *argv[])
+{ int i, len; FULL_CHAR *arg;
+ OBJECT t, y, res, s; /* current token, parser output */
+ BOOLEAN stdin_seen; /* TRUE when stdin file seen */
+ int source_file_count; /* number of source files in command */
+ FULL_CHAR *cross_db; /* name of cross reference database */
+ FULL_CHAR *outfile; /* name of output file */
+ FULL_CHAR *lib; /* name of library directory */
+ FILE *out_fp;
+ long MemCheckLong;
+ FULL_CHAR oname[MAX_BUFF], oval[MAX_BUFF], buff[MAX_BUFF], *p;
+ int bp; OBJECT z;
+ BOOLEAN seen_wordcount;
+#if LOCALE_ON
+ char catname[MAX_BUFF], *loc;
+#endif
+
+ /* find the name of the library directory, from envt or else from -D */
+ lib = AsciiToFull(getenv("LOUTLIB"));
+ if( lib == (FULL_CHAR *) NULL )
+ lib = AsciiToFull(LIB_DIR);
+
+ /* set locale if that's what we are doing */
+#if LOCALE_ON
+ loc = setlocale(LC_MESSAGES, "");
+ if( loc == (char *) NULL )
+ { Error(1, 6, "unable to initialize locale", WARN, no_fpos);
+ loc = "C";
+ }
+ sprintf(catname, "%s/%s/%s/LC_MESSAGES/errors.%s",
+ lib, LOCALE_DIR, loc, loc);
+ MsgCat = catopen(catname, 0);
+#endif
+
+ /* initialise various modules, add current directory to search paths */
+ TotalWordCount = 0;
+ seen_wordcount = FALSE;
+ BackEnd = POSTSCRIPT;
+ BackEndWord = STR_POSTSCRIPT;
+ PlainCharWidth = PLAIN_WIDTH;
+ PlainCharHeight = PLAIN_HEIGHT;
+ PlainFormFeed = FALSE;
+ InitializeAll = FALSE;
+ UseCollate = COLLATE;
+ AllowCrossDb = TRUE;
+ InMemoryDbIndexes = TRUE;
+ Encapsulated = FALSE;
+ SafeExecution = SAFE_DFT ? TRUE : FALSE;
+ Kern = TRUE;
+ MemInit();
+ InitSym();
+ LexInit();
+ InitFiles();
+ AddToPath(SOURCE_PATH, MakeWord(WORD, STR_EMPTY, no_fpos));
+ AddToPath(DATABASE_PATH, MakeWord(WORD, STR_EMPTY, no_fpos));
+ AddToPath(INCLUDE_PATH, MakeWord(WORD, STR_EMPTY, no_fpos));
+
+ /* read command line */
+ stdin_seen = FALSE;
+ AltErrorFormat = FALSE;
+ cross_db = CROSS_DB;
+ outfile = STR_STDOUT;
+ source_file_count = 0;
+ New(CommandOptions, ACAT);
+ for( i = 1; i < argc; i++ )
+ {
+ if( *argv[i] == CH_HYPHEN ) switch( *(argv[i]+1) )
+ {
+ case CH_FLAG_OUTFILE:
+
+ /* read name of output file */
+ if( (outfile = GetArg(argv, argc, &i)) == NULL )
+ Error(1, 7, "usage: -o <filename>", FATAL, no_fpos);
+ if( StringEndsWith(outfile, SOURCE_SUFFIX) )
+ Error(1, 28, "-o: output file name %s ends with %s",
+ FATAL, no_fpos, outfile, SOURCE_SUFFIX);
+ break;
+
+
+ case CH_FLAG_SUPPRESS:
+
+ /* suppress references to OldCrossDb and NewCrossDb */
+ AllowCrossDb = FALSE;
+ break;
+
+
+ case CH_FLAG_MEMCR:
+
+ /* don't use in-memory database indexes */
+ InMemoryDbIndexes = FALSE;
+ break;
+
+
+ case CH_FLAG_NOKERN:
+
+ /* suppress kerning */
+ Kern = FALSE;
+ break;
+
+
+ case CH_FLAG_NOCOLLATE:
+
+ /* suppress local collation */
+ UseCollate = FALSE;
+ break;
+
+
+ case CH_FLAG_COLLATE:
+
+ /* invoke local collation */
+ UseCollate = TRUE;
+ break;
+
+
+ case CH_FLAG_CROSS:
+
+ /* read name of cross reference database */
+ if( (cross_db = GetArg(argv, argc, &i)) == NULL )
+ Error(1, 8, "usage: -c <filename>", FATAL, no_fpos);
+ break;
+
+
+ case CH_FLAG_ERRFILE:
+
+ /* read log file name */
+ if( (arg = GetArg(argv, argc, &i)) == NULL )
+ Error(1, 9, "usage: -e <filename>", FATAL, no_fpos);
+ ErrorInit(arg);
+ break;
+
+
+ case CH_FLAG_ALTERR:
+
+ /* alternative error message format */
+ AltErrorFormat = TRUE;
+ break;
+
+
+ case CH_FLAG_EPSFIRST:
+
+ /* -EPS produces encapsulated PostScript output */
+ if( !StringEqual(AsciiToFull(argv[i]+1), STR_EPS) )
+ Error(1, 10, "usage: -EPS", FATAL, no_fpos);
+ Encapsulated = TRUE;
+ break;
+
+
+ case CH_FLAG_DIRPATH:
+
+ /* add directory to database and sysdatabase paths */
+ if( (arg = GetArg(argv, argc, &i)) == NULL )
+ Error(1, 11, "usage: -D <directoryname>", FATAL, no_fpos);
+ AddToPath(DATABASE_PATH, MakeWord(WORD, arg, no_fpos));
+ AddToPath(SYSDATABASE_PATH, MakeWord(WORD, arg, no_fpos));
+ break;
+
+
+ case CH_FLAG_ENCPATH:
+
+ /* add directory to character mapping path */
+ if( (arg = GetArg(argv, argc, &i)) == NULL )
+ Error(1, 12, "usage: -C <directoryname>", FATAL, no_fpos);
+ AddToPath(MAPPING_PATH, MakeWord(WORD, arg, no_fpos));
+ break;
+
+
+ case CH_FLAG_FNTPATH:
+
+ /* add directory to font path */
+ if( (arg = GetArg(argv, argc, &i)) == NULL )
+ Error(1, 13, "usage: -F <directoryname>", FATAL, no_fpos);
+ AddToPath(FONT_PATH, MakeWord(WORD, arg, no_fpos));
+ break;
+
+
+ case CH_FLAG_HYPPATH:
+
+ /* add directory to hyph path */
+ if( (arg = GetArg(argv, argc, &i)) == NULL )
+ Error(1, 14, "usage: -H <directoryname>", FATAL, no_fpos);
+ AddToPath(HYPH_PATH, MakeWord(WORD, arg, no_fpos));
+ break;
+
+
+ case CH_FLAG_INCPATH:
+
+ /* add directory to include and sysinclude paths */
+ if( (arg = GetArg(argv, argc, &i)) == NULL )
+ Error(1, 15, "usage: -I <directoryname>", FATAL, no_fpos);
+ AddToPath(INCLUDE_PATH, MakeWord(WORD, arg, no_fpos));
+ AddToPath(SYSINCLUDE_PATH, MakeWord(WORD, arg, no_fpos));
+ break;
+
+
+ case CH_FLAG_INCLUDE:
+
+ /* read sysinclude file and strip any .lt suffix */
+ if( (arg = GetArg(argv, argc, &i)) == NULL )
+ Error(1, 16, "usage: -i <filename>", FATAL, no_fpos);
+ len = StringLength(arg) - StringLength(SOURCE_SUFFIX);
+ if( len >= 0 && StringEqual(&arg[len], SOURCE_SUFFIX) )
+ StringCopy(&arg[len], STR_EMPTY);
+ debug0(DFS, D, " calling DefineFile from main (1)");
+ DefineFile(arg, STR_EMPTY, no_fpos, SOURCE_FILE, SYSINCLUDE_PATH);
+ break;
+
+
+ case CH_FLAG_HYPHEN:
+
+ /* declare hyphenation file */
+ if( FirstFile(HYPH_FILE) != NO_FILE )
+ Error(1, 17, "two -h options illegal", FATAL, no_fpos);
+ if( (arg = GetArg(argv, argc, &i)) == NULL )
+ Error(1, 18, "usage: -h <filename>", FATAL, no_fpos);
+ debug0(DFS, D, " calling DefineFile from main (2)");
+ DefineFile(arg, STR_EMPTY, no_fpos, HYPH_FILE, INCLUDE_PATH);
+ DefineFile(arg, HYPH_SUFFIX, no_fpos, HYPH_PACKED_FILE, INCLUDE_PATH);
+ break;
+
+
+ case CH_FLAG_VERSION:
+
+ fprintf(stderr, "%s\n", LOUT_VERSION);
+ fprintf(stderr, "%-28s %s\n",
+ "Basser Lout written by:", "Jeffrey H. Kingston (jeff@cs.usyd.edu.au)");
+ fprintf(stderr, "%-28s %s\n",
+ "Free source available from:", "ftp://ftp.cs.usyd.edu.au/jeff/lout");
+ fprintf(stderr, "%-28s %s %s\n",
+ "This executable compiled:", __TIME__, __DATE__);
+ fprintf(stderr, "%-28s %s%s%s\n", "System include directory:",
+ lib, STR_DIR, INCL_DIR);
+ fprintf(stderr, "%-28s %s%s%s\n", "System database directory:",
+ lib, STR_DIR, DATA_DIR);
+ fprintf(stderr, "Database index files created afresh automatically:%s\n",
+ USE_STAT ? " yes" : " no");
+ fprintf(stderr, "Safe execution (disabling system()) is default:%s\n",
+ SAFE_DFT ? " yes" : " no");
+ fprintf(stderr, "strcoll() used for sorting by default:%s\n",
+ COLLATE ? " yes" : " no");
+ fprintf(stderr, "\n");
+ fprintf(stderr, "Basser Lout comes with ABSOLUTELY NO WARRANTY.\n");
+ fprintf(stderr, "This is free software, and you are welcome to\n");
+ fprintf(stderr, "redistribute it under certain conditions. For\n");
+ fprintf(stderr, "details on both points, consult the GNU General\n");
+ fprintf(stderr, "Public License (distributed with this software).\n");
+ exit(0);
+ break;
+
+
+ case CH_FLAG_WORDS:
+
+ seen_wordcount = TRUE;
+ break;
+
+
+ case CH_FLAG_PDF:
+
+ BackEnd = PDF;
+ BackEndWord = STR_PDF;
+ break;
+
+
+ case CH_FLAG_FFPLAIN:
+
+ if( StringEqual(AsciiToFull(argv[i]+1), STR_PDF) )
+ {
+ BackEnd = PDF;
+ BackEndWord = STR_PDF;
+ break;
+ }
+ PlainFormFeed = TRUE;
+ /* NB NO BREAK */
+
+
+ case CH_FLAG_PLAIN:
+
+ BackEnd = PLAINTEXT;
+ BackEndWord = STR_PLAINTEXT;
+ if( *(argv[i]+2) != '\0' )
+ { float len1, len2; FULL_CHAR units1, units2;
+ if( sscanf(argv[i]+2, "%f%c%f%c",&len1,&units1,&len2,&units2) != 4 )
+ { Error(1, 19, "usage: lout -%c<length><length>",
+ FATAL, no_fpos, *(argv[i]+1));
+ }
+ switch( units1 )
+ {
+ case CH_UNIT_CM: PlainCharWidth = len1 * CM; break;
+ case CH_UNIT_IN: PlainCharWidth = len1 * IN; break;
+ case CH_UNIT_PT: PlainCharWidth = len1 * PT; break;
+ case CH_UNIT_EM: PlainCharWidth = len1 * EM; break;
+
+ default: Error(1, 20, "lout -%c: units must be c, i, p, or m",
+ FATAL, no_fpos, *(argv[i]+1));
+ break;
+ }
+ switch( units2 )
+ {
+ case CH_UNIT_CM: PlainCharHeight = len2 * CM; break;
+ case CH_UNIT_IN: PlainCharHeight = len2 * IN; break;
+ case CH_UNIT_PT: PlainCharHeight = len2 * PT; break;
+ case CH_UNIT_EM: PlainCharHeight = len2 * EM; break;
+
+ default: Error(1, 21, "lout -%c: units must be c, i, p, or m",
+ FATAL, no_fpos, *(argv[i]+1));
+ break;
+ }
+ }
+ break;
+
+
+ case CH_FLAG_INITALL:
+
+ InitializeAll = TRUE;
+ AllowCrossDb = FALSE;
+ break;
+
+
+ case CH_FLAG_USAGE:
+
+ PrintUsage(stderr);
+ exit(0);
+ break;
+
+
+ case CH_FLAG_DEBUG:
+
+ debug_init(AsciiToFull(argv[i]));
+ break;
+
+
+ case CH_FLAG_MEMCHECK:
+
+ sscanf(argv[i], "-m%ld", &MemCheckLong);
+ MemCheck = (POINTER) MemCheckLong;
+ fprintf(stderr, "checking memory location %ld\n", (long) MemCheck);
+ break;
+
+
+ case '\0':
+
+ /* read stdin as file name */
+ if( stdin_seen )
+ Error(1, 23, "standard input specified twice", FATAL, no_fpos);
+ stdin_seen = TRUE;
+ debug0(DFS, D, " calling DefineFile from main (3)");
+ DefineFile(STR_STDIN, STR_EMPTY, no_fpos, SOURCE_FILE, SOURCE_PATH);
+ break;
+
+
+ case CH_FLAG_OPTION:
+
+ /* read command-line document option */
+ if( sscanf(argv[i]+2, "%[^{ ] { %[^}] }", oname, oval) != 2 ||
+ StringLength(oname) == 0 || StringLength(oval) == 0 )
+ Error(1, 24, "error in command-line option %s", FATAL, no_fpos,
+ argv[i]+2);
+ y = MakeWord(WORD, oname, no_fpos);
+ Link(CommandOptions, y);
+ New(y, ACAT);
+ Link(CommandOptions, y);
+ bp = 0;
+ for( p = oval; *p != '\0'; p++ ) switch( *p )
+ {
+ case ' ':
+ case '\t':
+ case '\n':
+ case '{':
+ case '}':
+
+ if( bp > 0 )
+ { buff[bp++] = '\0';
+ if( Down(y) != y )
+ { OBJECT g;
+ New(g, GAP_OBJ);
+ hspace(g) = 1; vspace(g) = 0;
+ FposCopy(fpos(g), *no_fpos);
+ Link(y, g);
+ }
+ z = MakeWord(WORD, buff, no_fpos);
+ Link(y, z);
+ bp = 0;
+ }
+ break;
+
+
+ default:
+
+ buff[bp++] = *p;
+ break;
+ }
+ if( bp > 0 )
+ { buff[bp++] = '\0';
+ z = MakeWord(WORD, buff, no_fpos);
+ Link(y, z);
+ }
+ if( Down(y) == y )
+ Error(1, 25, "error in command-line option %s", FATAL, no_fpos,
+ argv[i]+2);
+ break;
+
+
+ case CH_FLAG_SAFE:
+
+ /* ensure safe execution by disabling system calls */
+ SafeExecution = TRUE;
+ break;
+
+ case CH_FLAG_UNSAFE:
+
+ /* allow unsafe execution */
+ SafeExecution = FALSE;
+ break;
+
+ default:
+
+ PrintUsage(stderr);
+ Error(1, 26, "unknown command line flag %s", FATAL, no_fpos, argv[i]);
+ break;
+
+ }
+ else
+ { /* argument is source file, strip any .lout suffix and define it */
+ arg = AsciiToFull(argv[i]);
+ len = StringLength(arg) - StringLength(SOURCE_SUFFIX);
+ if( len >= 0 && StringEqual(&arg[len], SOURCE_SUFFIX) )
+ StringCopy(&arg[len], STR_EMPTY);
+ debug0(DFS, D, " calling DefineFile from main (4)");
+ DefineFile(AsciiToFull(argv[i]), STR_EMPTY, no_fpos,
+ SOURCE_FILE, SOURCE_PATH);
+ source_file_count++;
+ }
+ } /* for */
+
+ if( UseCollate )
+ {
+ if (!setlocale (LC_COLLATE, ""))
+ Error(1, 30, "unable to initialize collation", WARN, no_fpos);
+ }
+
+ /* start timing if required */
+ ifdebug(DPP, D, ProfileOn("main"));
+
+ /* open output file, or stdout if none specified, and initialize printer */
+ if( StringEqual(outfile, STR_STDOUT) )
+ {
+#if OS_DOS
+ /* For DOS/Win32 we need to set binary mode on stdout to prevent
+ PDF compressed streams and xrefs from being corrupted - Uwe 12/98 */
+ if( BackEnd != PLAINTEXT && _setmode(_fileno(stdout), _O_BINARY) == -1 )
+ Error(1, 31, "cannot set binary mode on stdout", FATAL, no_fpos);
+#endif
+ out_fp = stdout;
+ }
+ else
+ { out_fp = StringFOpen(outfile, BackEnd==PLAINTEXT ? WRITE_TEXT:WRITE_BINARY);
+ if( out_fp == null )
+ Error(1, 27, "cannot open output file %s", FATAL, no_fpos, outfile);
+ }
+ FontInit();
+ ColourInit();
+ LanguageInit();
+ PrintInit(out_fp);
+
+ /* append default directories to file search paths */
+ AddToPath(FONT_PATH, MakeWordThree(lib, STR_DIR, AsciiToFull(FONT_DIR)));
+ AddToPath(HYPH_PATH, MakeWordThree(lib, STR_DIR, AsciiToFull(HYPH_DIR)));
+ AddToPath(MAPPING_PATH, MakeWordThree(lib, STR_DIR, AsciiToFull(MAPS_DIR)));
+ AddToPath(SYSDATABASE_PATH,MakeWordThree(lib, STR_DIR, AsciiToFull(DATA_DIR)));
+ AddToPath(DATABASE_PATH, MakeWordThree(lib, STR_DIR, AsciiToFull(DATA_DIR)));
+ AddToPath(SYSINCLUDE_PATH, MakeWordThree(lib, STR_DIR, AsciiToFull(INCL_DIR)));
+ AddToPath(INCLUDE_PATH, MakeWordThree(lib, STR_DIR, AsciiToFull(INCL_DIR)));
+
+ /* use stdin if no source files were mentioned */
+ if( source_file_count == 0 )
+ { debug0(DFS, D, " calling DefineFile from main (5)");
+ DefineFile(STR_STDIN, STR_EMPTY, no_fpos, SOURCE_FILE, SOURCE_PATH);
+ }
+
+ /* load predefined symbols into symbol table */
+ StartSym = nilobj; /* Not a mistake */
+ StartSym = load(KW_START, 0, FALSE, FALSE, TRUE, NO_PREC );
+ GalleySym = load(KW_GALLEY, 0, FALSE, FALSE, TRUE, NO_PREC );
+ ForceGalleySym = load(KW_FORCE_GALLEY, 0, FALSE, FALSE, TRUE, NO_PREC );
+ InputSym = load(KW_INPUT, 0, FALSE, FALSE, TRUE, NO_PREC );
+ PrintSym = load(KW_PRINT, 0, FALSE, FALSE, TRUE, NO_PREC );
+ FilterInSym = load(KW_FILTERIN, 0, FALSE, FALSE, FALSE, NO_PREC );
+ FilterOutSym = load(KW_FILTEROUT, 0, FALSE, FALSE, FALSE, NO_PREC );
+ FilterErrSym = load(KW_FILTERERR, 0, FALSE, FALSE, FALSE, NO_PREC );
+ OptGallSym = load(KW_OPTGALL, 0, FALSE, TRUE, FALSE, DEFAULT_PREC);
+ VerbatimSym = load(KW_VERBATIM,VERBATIM,FALSE, TRUE, FALSE, DEFAULT_PREC);
+ RawVerbatimSym = load(KW_RAWVERBATIM,RAW_VERBATIM,FALSE, TRUE, FALSE, DEFAULT_PREC);
+
+
+ load(KW_BEGIN, BEGIN, FALSE, FALSE, FALSE, BEGIN_PREC );
+ load(KW_END, END, FALSE, FALSE, FALSE, END_PREC );
+ load(KW_ENV, ENV, FALSE, FALSE, FALSE, NO_PREC );
+ load(KW_ENVA, ENVA, FALSE, FALSE, FALSE, NO_PREC );
+ load(KW_ENVB, ENVB, FALSE, FALSE, FALSE, NO_PREC );
+ load(KW_ENVC, ENVC, FALSE, FALSE, FALSE, NO_PREC );
+ load(KW_ENVD, ENVD, FALSE, FALSE, FALSE, NO_PREC );
+ load(KW_CENV, CENV, FALSE, FALSE, FALSE, NO_PREC );
+ load(KW_CLOS, CLOS, FALSE, FALSE, FALSE, NO_PREC );
+ load(KW_LVIS, LVIS, FALSE, FALSE, FALSE, NO_PREC );
+ load(KW_LUSE, LUSE, FALSE, FALSE, FALSE, NO_PREC );
+ load(KW_LEO, LEO, FALSE, FALSE, FALSE, NO_PREC );
+ load(KW_LBR, LBR, FALSE, FALSE, FALSE, LBR_PREC );
+ load(KW_RBR, RBR, FALSE, FALSE, FALSE, RBR_PREC );
+ load(KW_INCLUDE, INCLUDE, FALSE, FALSE, FALSE, NO_PREC );
+ load(KW_SYSINCLUDE, SYS_INCLUDE, FALSE, FALSE, FALSE, NO_PREC );
+ load(KW_PREPEND, PREPEND, FALSE, FALSE, FALSE, NO_PREC );
+ load(KW_SYSPREPEND, SYS_PREPEND, FALSE, FALSE, FALSE, NO_PREC );
+ load(KW_DATABASE, DATABASE, FALSE, FALSE, FALSE, NO_PREC );
+ load(KW_SYSDATABASE, SYS_DATABASE, FALSE, FALSE, FALSE, NO_PREC );
+ load(KW_USE, USE, FALSE, FALSE, FALSE, NO_PREC );
+ load(KW_NOT_REVEALED, NOT_REVEALED, FALSE, FALSE, FALSE, NO_PREC );
+ load(KW_CASE, CASE, TRUE, TRUE, FALSE, DEFAULT_PREC);
+ load(KW_YIELD, YIELD, TRUE, TRUE, FALSE, DEFAULT_PREC);
+ load(KW_BACKEND, BACKEND, FALSE, FALSE, FALSE, DEFAULT_PREC);
+ load(KW_XCHAR, XCHAR, FALSE, TRUE, FALSE, DEFAULT_PREC);
+ load(KW_FONT, FONT, TRUE, TRUE, FALSE, DEFAULT_PREC);
+ load(KW_SPACE, SPACE, TRUE, TRUE, FALSE, DEFAULT_PREC);
+ load(KW_YUNIT, YUNIT, TRUE, TRUE, FALSE, DEFAULT_PREC);
+ load(KW_ZUNIT, ZUNIT, TRUE, TRUE, FALSE, DEFAULT_PREC);
+ load(KW_BREAK, BREAK, TRUE, TRUE, FALSE, DEFAULT_PREC);
+ load(KW_UNDERLINE, UNDERLINE, FALSE, TRUE, FALSE, DEFAULT_PREC);
+ load(KW_COLOUR, COLOUR, TRUE, TRUE, FALSE, DEFAULT_PREC);
+ load(KW_COLOR, COLOUR, TRUE, TRUE, FALSE, DEFAULT_PREC);
+ load(KW_LANGUAGE, LANGUAGE, TRUE, TRUE, FALSE, DEFAULT_PREC);
+ load(KW_CURR_LANG, CURR_LANG, FALSE, FALSE, FALSE, DEFAULT_PREC);
+ load(KW_CURR_FAMILY, CURR_FAMILY, FALSE, FALSE, FALSE, DEFAULT_PREC);
+ load(KW_CURR_FACE, CURR_FACE, FALSE, FALSE, FALSE, DEFAULT_PREC);
+ load(KW_COMMON, COMMON, TRUE, TRUE, FALSE, DEFAULT_PREC);
+ load(KW_RUMP, RUMP, TRUE, TRUE, FALSE, DEFAULT_PREC);
+ load(KW_MELD, MELD, TRUE, TRUE, FALSE, DEFAULT_PREC);
+ load(KW_INSERT, INSERT, TRUE, TRUE, FALSE, DEFAULT_PREC);
+ load(KW_ONE_OF, ONE_OF, FALSE, TRUE, FALSE, DEFAULT_PREC);
+ load(KW_NEXT, NEXT, FALSE, TRUE, FALSE, DEFAULT_PREC);
+ load(KW_PLUS, PLUS, TRUE, TRUE, FALSE, DEFAULT_PREC);
+ load(KW_MINUS, MINUS, TRUE, TRUE, FALSE, DEFAULT_PREC);
+ load(KW_OPEN, OPEN, TRUE, TRUE, FALSE, DEFAULT_PREC);
+ load(KW_TAGGED, TAGGED, TRUE, TRUE, FALSE, DEFAULT_PREC);
+ load(KW_WIDE, WIDE, TRUE, TRUE, FALSE, DEFAULT_PREC);
+ load(KW_HIGH, HIGH, TRUE, TRUE, FALSE, DEFAULT_PREC);
+ load(KW_HSHIFT, HSHIFT, TRUE, TRUE, FALSE, DEFAULT_PREC);
+ load(KW_VSHIFT, VSHIFT, TRUE, TRUE, FALSE, DEFAULT_PREC);
+ load(KW_ONE_COL, ONE_COL, FALSE, TRUE, FALSE, DEFAULT_PREC);
+ load(KW_ONE_ROW, ONE_ROW, FALSE, TRUE, FALSE, DEFAULT_PREC);
+ load(KW_HSCALE, HSCALE, FALSE, TRUE, FALSE, DEFAULT_PREC);
+ load(KW_VSCALE, VSCALE, FALSE, TRUE, FALSE, DEFAULT_PREC);
+ load(KW_HCOVER, HCOVER, FALSE, TRUE, FALSE, DEFAULT_PREC);
+ load(KW_VCOVER, VCOVER, FALSE, TRUE, FALSE, DEFAULT_PREC);
+ load(KW_KERN_SHRINK, KERN_SHRINK, TRUE, TRUE, FALSE, DEFAULT_PREC);
+ load(KW_SCALE, SCALE, TRUE, TRUE, FALSE, DEFAULT_PREC);
+ load(KW_HCONTRACT, HCONTRACT, FALSE, TRUE, FALSE, DEFAULT_PREC);
+ load(KW_VCONTRACT, VCONTRACT, FALSE, TRUE, FALSE, DEFAULT_PREC);
+ load(KW_HLIMITED, HLIMITED, FALSE, TRUE, FALSE, DEFAULT_PREC);
+ load(KW_VLIMITED, VLIMITED, FALSE, TRUE, FALSE, DEFAULT_PREC);
+ load(KW_HEXPAND, HEXPAND, FALSE, TRUE, FALSE, DEFAULT_PREC);
+ load(KW_VEXPAND, VEXPAND, FALSE, TRUE, FALSE, DEFAULT_PREC);
+ load(KW_STARTHVSPAN, START_HVSPAN, FALSE, TRUE, FALSE, DEFAULT_PREC);
+ load(KW_STARTHSPAN, START_HSPAN, FALSE, TRUE, FALSE, DEFAULT_PREC);
+ load(KW_STARTVSPAN, START_VSPAN, FALSE, TRUE, FALSE, DEFAULT_PREC);
+ load(KW_HSPAN, HSPAN, FALSE, FALSE, FALSE, DEFAULT_PREC);
+ load(KW_VSPAN, VSPAN, FALSE, FALSE, FALSE, DEFAULT_PREC);
+ load(KW_PADJUST, PADJUST, FALSE, TRUE, FALSE, DEFAULT_PREC);
+ load(KW_HADJUST, HADJUST, FALSE, TRUE, FALSE, DEFAULT_PREC);
+ load(KW_VADJUST, VADJUST, FALSE, TRUE, FALSE, DEFAULT_PREC);
+ load(KW_ROTATE, ROTATE, TRUE, TRUE, FALSE, DEFAULT_PREC);
+ load(KW_BACKGROUND, BACKGROUND, TRUE, TRUE, FALSE, DEFAULT_PREC);
+ load(KW_INCGRAPHIC, INCGRAPHIC, FALSE, TRUE, FALSE, DEFAULT_PREC);
+ load(KW_SINCGRAPHIC, SINCGRAPHIC, FALSE, TRUE, FALSE, DEFAULT_PREC);
+ load(KW_PLAINGRAPHIC, PLAIN_GRAPHIC, TRUE, TRUE, FALSE, DEFAULT_PREC);
+ load(KW_GRAPHIC, GRAPHIC, TRUE, TRUE, FALSE, DEFAULT_PREC);
+ load(KW_CROSS, CROSS, TRUE, TRUE, FALSE, CROSSOP_PREC);
+ load(KW_FORCE_CROSS, FORCE_CROSS, TRUE, TRUE, FALSE, CROSSOP_PREC);
+ load(KW_NULL, NULL_CLOS, FALSE, FALSE, TRUE, NO_PREC );
+ load(KW_PAGE_LABEL, PAGE_LABEL, FALSE, TRUE, TRUE, DEFAULT_PREC);
+
+#define setcat(s, mk, jn) has_mark(s)=mk, has_join(s)=jn
+
+ s=load(KW_VCAT_NN, VCAT, TRUE, TRUE, FALSE, VCAT_PREC); setcat(s,FALSE,FALSE);
+ s=load(KW_VCAT_MN, VCAT, TRUE, TRUE, FALSE, VCAT_PREC); setcat(s,TRUE, FALSE);
+ s=load(KW_VCAT_NJ, VCAT, TRUE, TRUE, FALSE, VCAT_PREC); setcat(s,FALSE,TRUE);
+ s=load(KW_VCAT_MJ, VCAT, TRUE, TRUE, FALSE, VCAT_PREC); setcat(s,TRUE, TRUE);
+ s=load(KW_HCAT_NN, HCAT, TRUE, TRUE, FALSE, HCAT_PREC); setcat(s,FALSE,FALSE);
+ s=load(KW_HCAT_MN, HCAT, TRUE, TRUE, FALSE, HCAT_PREC); setcat(s,TRUE, FALSE);
+ s=load(KW_HCAT_NJ, HCAT, TRUE, TRUE, FALSE, HCAT_PREC); setcat(s,FALSE,TRUE);
+ s=load(KW_HCAT_MJ, HCAT, TRUE, TRUE, FALSE, HCAT_PREC); setcat(s,TRUE, TRUE);
+ s=load(KW_ACAT_NJ, ACAT, TRUE, TRUE, FALSE, ACAT_PREC); setcat(s,FALSE,TRUE);
+ s=load(KW_ACAT_MJ, ACAT, TRUE, TRUE, FALSE, ACAT_PREC); setcat(s,TRUE, TRUE);
+
+ /* intialize current time and load @Moment symbol */
+ InitTime();
+
+ /* initialize filter module */
+ FilterInit();
+
+ /* initialize enviroment table module */
+ EnvInit();
+
+ /* initialise scope chain to <StartSym> */
+ PushScope(StartSym, FALSE, FALSE);
+
+ /* initialise lexical analyser */
+ LexPush(FirstFile(SOURCE_FILE), 0, SOURCE_FILE, 1, FALSE);
+
+ /* process input files */
+ InitParser(cross_db);
+ t = NewToken(BEGIN, no_fpos, 0, 0, BEGIN_PREC, StartSym);
+ res = Parse(&t, StartSym, TRUE, TRUE);
+ debug0(DGT, D, "calling TransferEnd(res) from main()");
+ DisposeObject(CommandOptions);
+ TransferEnd(res);
+ TransferClose();
+
+ /* close various modules */
+ PrintAfterLast();
+ CrossClose();
+ CloseFiles();
+
+ /* remove any leftover filter temporary files */
+ FilterScavenge(TRUE);
+
+ /* print word count, if required */
+ if( seen_wordcount )
+ Error(1, 29, "total of all words printed: %d", WARN,no_fpos,TotalWordCount);
+
+ /* check for unbalanced error blocks */
+ CheckErrorBlocks();
+
+ /* wrapup */
+ ifdebug(DST, D, CheckSymSpread() );
+ ifdebug(ANY, D, DeleteEverySym() );
+ debug0(DMA, D, "at end of run:");
+ ifdebug(DMA, D, DebugMemory() );
+ ifdebug(DPP, D, ProfileOff("main"));
+ ifdebug(DPP, D, ProfilePrint());
+ ifdebug(DET, D, EnvDebug());
+
+#if LOCALE_ON
+ catclose(MsgCat);
+#endif
+
+ exit(0);
+ return 0;
+} /* end main */