summaryrefslogtreecommitdiff
path: root/support/ltx2x/l2xlib.c
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
committerNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
commite0c6872cf40896c7be36b11dcc744620f10adf1d (patch)
tree60335e10d2f4354b0674ec22d7b53f0f8abee672 /support/ltx2x/l2xlib.c
Initial commit
Diffstat (limited to 'support/ltx2x/l2xlib.c')
-rw-r--r--support/ltx2x/l2xlib.c5629
1 files changed, 5629 insertions, 0 deletions
diff --git a/support/ltx2x/l2xlib.c b/support/ltx2x/l2xlib.c
new file mode 100644
index 0000000000..6b33afde39
--- /dev/null
+++ b/support/ltx2x/l2xlib.c
@@ -0,0 +1,5629 @@
+/* l2xlib.c Main and support routines for ltx2x LaTeX to X translator */
+/* Written by Peter Wilson (ex Catholic University and NIST) */
+/* ex pwilson@cme.nist.gov */
+/* Now at: peter.r.wilson@boeing.com */
+/* Version 0.5, October 1995 */
+/* Extended July 1996 */
+/* Extended November 1996 */
+/* Extended January 1997 */
+/* Extended March 1999 */
+/* Fixed CHAR_COMMAND bug November 1999 */
+/* Eliminated some gcc whines November 1999 */
+/*-----------------------------------------------------------------------*/
+
+char FILE_VERSION[] = "Version 0.92";
+char FILE_DATE[] = "November 1999";
+
+/* VERSION HISTORY:
+ * Version 0.2 (January 1995): First alpha release
+ * Patch 1 (April 1995): Fixed problem with the hex escape sequence
+ * in function "delete_quotes"
+ * NB. gcc compiler gives warnings, but cc does not.
+ * Version 0.5 (October 1995): Beta release
+ * Added capability for TEX_CHAR commands to take parameters
+ * -- this was requested for processing super- and sub-scripts.
+ * Changed calling parameters of functions get_opttag_t and
+ * get_opttag_et from (pos,num) to (pos).
+ * Major restructuring and renaming of source files.
+ * Added capability for a second method of specifying SPECIALs
+ * -- now either in the grammer (as before), or via code additions
+ * to the provided grammer actions. This later avoids re-yaccing
+ * the grammer. Both require recompilation.
+ * Version 0.6 (July 1996)
+ * Added capability for read/write to external files and user buffers
+ * Version 0.7 (November 1996)
+ * Added the SWITCH_XXX capability
+ * Version 0.8 (January 1997)
+ * Added code capability
+ * Replaced the most of the tedious enumeration/string mappings
+ * by cunning use of the l2xlibtc.h include file and defines.
+ * Version 0.9 (March 1999)
+ * Changed the close_down procedure
+ * Version 0.91 (November 1999)
+ * Fixed bug in CHAR_COMMAND processing (ignored parameters)
+ * Version 0.92 (November 1999)
+ * (at request of Thomas Ruedas ruedas@geophysik.uni-frankfurt.de)
+ * Added -h option (some getopts don't return ? if unknown option)
+ * Deleted unused init_page_header and print_page_header from l2xiscan.c
+ * Changed SR order in l2xirexp to stop gcc whine
+ */
+
+/* Development of this software upto and including version 0.7
+ * (November 1996) was funded by the United States Government,
+ * and is not subject to copyright. This version is released
+ * under the LaTeX Project Public License.
+ */
+
+/* National Institute of Standards and Technology (NIST)
+ * Manufacturing Engineering Laboratory (MEL)
+ * Manufacturing Systems Integration Division (MSID)
+ * ********************************************************************
+ * D I S C L A I M E R
+ *
+ * There is no warranty for the LTX2X software.
+ * If the LTX2X software is modified by someone else and passed on,
+ * NIST wants the software's recipients to know that what they
+ * have is not what NIST distributed.
+ *
+ * Policies
+ *
+ * 1. Anyone may copy and distribute verbatim copies of the
+ * source code as received in any medium.
+ *
+ * 2. Anyone may modify your copy or copies of the LTX2X source
+ * code or any portion of it, and copy and distribute such modifications
+ * provided that all modifications are clearly associated with the entity
+ * that performs the modifications.
+ *
+ * NO WARRANTY
+ * ===========
+ *
+ * NIST PROVIDES ABSOLUTELY NO WARRANTY. THE LTX2X SOFTWARE
+ * IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ * THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS
+ * WITH YOU. SHOULD ANY PORTION OF THE LTX2X SOFTWARE PROVE DEFECTIVE,
+ * YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+ *
+ * IN NO EVENT WILL NIST BE LIABLE FOR DAMAGES,
+ * INCLUDING ANY LOST PROFITS, LOST MONIES, OR OTHER SPECIAL,
+ * INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR
+ * INABILITY TO USE (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA
+ * BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY THIRD PARTIES OR A
+ * FAILURE OF THE PROGRAM TO OPERATE WITH PROGRAMS NOT DISTRIBUTED BY
+ * NIST) THE PROGRAMS, EVEN IF YOU HAVE BEEN ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGES, OR FOR ANY CLAIM BY ANY OTHER PARTY.
+ */
+
+#include <string.h>
+#include "getopt.h"
+#include <stdio.h>
+#include <ctype.h>
+#ifndef STRTYPES_H
+#include "strtypes.h"
+#endif
+/* typedef char *STRING; A pointer-to-a-char */
+/* typedef STRING *PTRADR; A pointer-to-a-pointer-to-a-char */
+/* define SNUL '\0' end of a string */
+#ifndef L2XCOM_H
+#include "l2xcom.h"
+#endif
+#include "l2xytab.h"
+
+ /* the symbol table typedefs */
+#ifndef licomsym_h
+#include "licomsym.h"
+#endif
+
+# define MAX_ERRORS 10
+
+FILE *yyin; /* Lexer input file */
+FILE *filerr; /* Error file */
+FILE *yyout; /* Lexer/Parser output file */
+FILE *filtabin; /* Table input file */
+FILE *filtabout; /* Table output file */
+
+int MIN_GRAMM_SPECIAL = 10000; /* min code number for grammer special */
+int MIN_CODE_SPECIAL = 50000; /* min code number for code special */
+
+int LDEBUG = 0; /* >0 for debugging lexer */
+int TDEBUG = FALSE; /* for debugging command table */
+int YDEBUG = 0; /* >0 for debugging parser */
+int DEBUG = 0; /* >0 for debugging interpreter */
+int cdebug = TRUE; /* set FALSE to disable inteprreter Code debug */
+int edebug = TRUE; /* set FALSE to disable interpreter Execution debug */
+int cl_debug = 0; /* command line value for DEBUG */
+int SLD_OFF = TRUE; /* set FALSE to enable interpreter SLD */
+
+
+int num_errors = 0; /* number of errors */
+int lineno = 1; /* input file line number */
+# define MAX_LINE 2000
+# define MAX_BUFFER 2000
+char linebuf[MAX_LINE]; /* buffer for input line */
+int linlen = 0; /* current no of chars in linebuf */
+int line_count = 0; /* count of line printing */
+# define EVERY_N_LINES 100
+int darray[10]; /* dummy array for something */
+
+int leave_comments = FALSE; /* control for leaving in TeX comments */
+int collapse_ws = FALSE; /* control for collapsing whitespace */
+int pretty_print = FALSE; /* control for pretty-printing */
+int max_pretty_line = MAX_BUFFER; /* max length of pretty-print line */
+char pretty_line[MAX_BUFFER]; /* char buffer for pretty-printing */
+
+int no_print = FALSE; /* a control for myprint */
+int print_to_buffer = FALSE; /* a control for myprint */
+char buffer[MAX_BUFFER]; /* character buffer for myprint */
+
+
+/*---------------------6/96 extensions-----------------------------*/
+
+ /* number of user's string buffers */
+# define MAX_USER_BUFFS 64
+ /* max number of user's files */
+# define MAX_USER_FILES 16
+ /* length of a user buffer */
+/* # define MAX_UBUFF_LEN 514 */
+# define MAX_UBUFF_LEN 1026
+
+typedef char UBUFF[MAX_UBUFF_LEN];
+UBUFF user_buffs[MAX_USER_BUFFS]; /* array of user buffers */
+char errstr[MAX_UBUFF_LEN]; /* buffer for assembling error/warning text */
+
+int cur_user_buf = 0; /* number of current user buffer for writing to */
+int num_ubufwrite = 0; /* number of open write to user buffer calls */
+int num_ubuff[MAX_USER_BUFFS]; /* no of times user buffer opened */
+int used_rubuff[MAX_USER_BUFFS]; /* >0 if used_ubuff[N] has been read */
+int used_wubuff[MAX_USER_BUFFS]; /* >0 if used_ubuff[N] has been written */
+int written_from_buff[MAX_USER_BUFFS]; /* TRUE if read from user buffer */
+
+STRING cur_user_fn = NULL; /* name of current user file for writing to */
+int num_fileprint = 0; /* number of open write to file calls */
+int num_filep[MAX_USER_FILES]; /* number of opened to write for file */
+FILE *ufp[MAX_USER_FILES]; /* user file pointer */
+STRING ufn[MAX_USER_FILES]; /* user file name */
+int cur_user_fpos = 0; /* current pos in file array */
+FILE *cur_user_fileid = NULL; /* current user file id */
+
+int num_otherprint = 0; /* total number of non-default open write calls */
+# define SET_NUM_OTHERPRINT (num_noprint + num_bufprint + num_ubufwrite + num_fileprint)
+PSTRWC cur_printc = NULL; /* current print control */
+
+int bverb = FALSE; /* TRUE if starting verbatim print */
+
+int in_noop = FALSE; /* TRUE if doing a no op */
+int start_noop = FALSE; /* TRUE if start of a no op */
+
+#define MAX_MODES 32
+STRING mode_names[MAX_MODES]; /* unordered list of mode names */
+int num_modes = 0; /* number of mode names */
+#define MAX_MODE_STACK 20
+int mode_stack[MAX_MODE_STACK]; /* stack for mode ids */
+int top_mode = 0; /* empty top of mode stack */
+
+/* keywords */
+
+ /* command table commands */
+enum key_word{
+#define kwtc(a, b) a,
+#define lctc(a, b)
+#define pctc(a, b)
+#include "l2xlibtc.h"
+#undef kwtc
+#undef lctc
+#undef pctc
+};
+
+int max_keystr = MAX_KEYSTR;
+
+ /* map from keyword enum to string representation */
+STRING key_array[] = {
+#define kwtc(a, b) b,
+#define lctc(a, b)
+#define pctc(a, b)
+#include "l2xlibtc.h"
+#undef kwtc
+#undef lctc
+#undef pctc
+};
+
+ /* map from print control enum to string representation */
+int max_pcstr = MAX_PCSTR;
+
+STRING pc_array[] = {
+#define kwtc(a, b)
+#define lctc(a, b)
+#define pctc(a, b) b,
+#include "l2xlibtc.h"
+#undef kwtc
+#undef lctc
+#undef pctc
+};
+
+
+/* the types of LaTeX commands */
+
+#define UNKNOWN_CTYPE -10
+/* number of names/enums in command types, update when ctnames changes!! */
+#define NUM_CTIDS 50
+ /* ctnames[] is an alphabetical array of command type strings */
+STRING ctnames[] = {
+#define kwtc(a, b)
+#define lctc(a, b) b,
+#define pctc(a, b)
+#include "l2xlibtc.h"
+#undef kwtc
+#undef lctc
+#undef pctc
+};
+ /* ctenums[] is an array of command type enums to match ctnames[] */
+int ctenums[] = {
+#define kwtc(a, b)
+#define lctc(a, b) a,
+#define pctc(a, b)
+#include "l2xlibtc.h"
+#undef kwtc
+#undef lctc
+#undef pctc
+};
+
+
+
+
+ /* pointers to fixed, predefined print control structs */
+PSTRWC p_default_print; /* default printing i.e., DEFAULT_PRINT */
+PSTRWC p_no_print; /* no printing i.e., NO_PRINT */
+PSTRWC p_print_to_sysbuf; /* print to system buffer i.e., TO_SYSBUF */
+PSTRWC p_print_underflow; /* underflow i.e., PRINT_UNDERFLOW */
+PSTRWC p_unknown_print; /* unknown print i.e., UNKNOWN_PRINT */
+PSTRWC p_print_from_sysbuf; /* print from system buffer i.e., SYSBUF */
+PSTRWC p_print_null; /* print null string i.e., */
+PSTRWC p_reset_print; /* reset printing i.e., RESET */
+PSTRWC p_noop_print; /* no-op i.e., NO_OP */
+
+/* new functions */
+PSTRWC create_st_rwc();
+void init_common_print();
+PSTRWC create_print_tag();
+PSTRWC create_print_source();
+PSTRWC parse_pc();
+void tprint_st_rwc();
+void tprint_tag();
+void set_pc_enum();
+int get_pc_enum();
+void set_pcdata_num();
+int get_pcdata_num();
+void set_pcdata_name();
+STRING get_pcdata_name();
+PSTRWC get_next_write();
+PSTRWC append_to_write();
+PSTRWC initialise_pc();
+FILE *ufopenr();
+FILE *ufopenw();
+int ufclose();
+PSTRWC get_start_pc();
+PSTRWC get_end_pc();
+void flush_pretty();
+int pretty_empty();
+void strtouc(); /* convert string to upper case */
+void tprint_str();
+int lookup_string(); /* finds posn. of string in an ordered array of strings */
+void init_print_control();
+int key_to_int();
+STRING key_to_string();
+void set_pc_cmd();
+int get_pc_cmd();
+int chk_bufnum();
+STRING chk_ufname();
+void init_ubuff(); /* initialises a user buffer */
+void init_ufile(); /* initialise a user file */
+STRING get_mode_str(); /* returns string name of a mode */
+void add_to_modelist(); /* adds a mode to the mode list */
+void set_mode_name(); /* puts mode id into sym entry */
+int get_mode(); /* gets mode id from sym entry */
+PSENTRY get_next_mode(); /* gets next mode of a sym entry */
+int isempty(); /* TRUE if an empty string */
+void push_mode(); /* pushes mode onto stack */
+int pop_mode(); /* pops mode from stack */
+int reset_mode(); /* resets the mode */
+int get_current_mode(); /* gets the current mode */
+PSENTRY get_mode_sym(); /* gets sym entry matching current mode */
+void tag_print(); /* print a tag */
+
+
+ /*-------- 7/96 statistics stuff ---------------------------*/
+
+int used_ubuff_chars = 0; /* max # of chars attempted for buffer storage */
+int used_sbuff_chars = 0; /* max # of chars attempted for system buffer */
+int used_files = 0; /* # of user files used */
+
+int used_clause_stack = 0; /* max clause stack depth usage */
+int used_list_stack = 0; /* list stack */
+
+int used_table_line = 0; /* max length of a table line */
+int used_table_entries = 0; /* # of entries in command table */
+
+int used_print_stack = 0; /* max depth of print stack */
+
+int used_ct_file_stack = 0; /* max depth of command table stack */
+
+void write_stats(); /* write statistics */
+int maxof(); /* max of two integers */
+
+
+/*--------------------------------------------------------------*/
+
+# define CLAUSE_STACK_SIZE 10
+int clause_depth = 0;
+/* 6/96 changed STRING to PSTRWC */
+PSTRWC clause_str_stack[CLAUSE_STACK_SIZE];
+int base_level = CLAUSE_STACK_SIZE - 1; /* Highest doc level not closed off */
+ /* Section is highest and s4clause lowest */
+int current_level = 0; /* level of current doc division */
+int new_level = 0;
+
+# define DEF_LIST_STACK_SIZE 10
+int LIST_STACK_SIZE = DEF_LIST_STACK_SIZE;
+int list_level = 0;
+int num_items[DEF_LIST_STACK_SIZE]; /* holds number of current items in a list */
+/* 6/96 in following changed STRING to PSTRWC */
+PSTRWC list_str_stack[DEF_LIST_STACK_SIZE]; /* holds closing string for an item */
+PSTRWC list_item_start[DEF_LIST_STACK_SIZE]; /* holds start string for an item */
+PSTRWC list_descitemp_start[DEF_LIST_STACK_SIZE]; /* holds start string for the */
+ /* parameter of a descriptive list item */
+PSTRWC list_descitemp_end[DEF_LIST_STACK_SIZE]; /* holds corresponding end string */
+
+
+
+char *strsave();
+void myprint();
+void pprint();
+void verbatim_print();
+void initialise_clause_stack();
+void set_clause_stack();
+void close_all_divs();
+void close_doc_divs();
+void close_down();
+void set_list_stack();
+void print_end_item();
+void yyerror();
+void warning();
+void catl();
+void do_newline();
+void initialise_sysbuf();
+void print_sysbuf();
+void copy_sysbuf();
+void initialise_string();
+
+
+ /* new stuff for l2x */
+
+
+enum opt_pos_enum {NO_OPT_PARAM = -1, FIRST = 0, LAST};
+enum sect_level_enum {UNKNOWN_LEVEL, PARTM2, PARTM1, PART,
+ CHAPTER, SECT, SUBSECT, SUBSUBSECT, PARA, SUBPARA,
+ SUBPARAP1, SUBPARAP2};
+enum cont_enum {CONT_UNKNOWN_ENUM,
+ CONT_TAG,
+ CONT_START_TAG, CONT_END_TAG,
+ CONT_START_OPT, CONT_END_OPT,
+ CONT_START_TAG_1, CONT_END_TAG_1,
+ CONT_START_TAG_2, CONT_END_TAG_2,
+ CONT_START_TAG_3, CONT_END_TAG_3,
+ CONT_START_TAG_4, CONT_END_TAG_4,
+ CONT_START_TAG_5, CONT_END_TAG_5,
+ CONT_START_TAG_6, CONT_END_TAG_6,
+ CONT_START_TAG_7, CONT_END_TAG_7,
+ CONT_START_TAG_8, CONT_END_TAG_8,
+ CONT_START_TAG_9, CONT_END_TAG_9 };
+
+#define MAX_TABLE_LINE 1000
+char table_line[MAX_TABLE_LINE];
+#define MAX_TABLE_ENTRIES 1000
+PSENTRY symbol_table[MAX_TABLE_ENTRIES];
+int num_table_entries = 0;
+int num_table_errors = 0;
+char env_name[MAX_TABLE_LINE];
+
+int DONT_CARE = -100;
+STRING dont_care_str = "!@#$%^&*";
+
+int command_types[] = {COMMAND, COMMAND_1, COMMAND_2, COMMAND_3, COMMAND_4,
+ COMMAND_5, COMMAND_6, COMMAND_7, COMMAND_8, COMMAND_9};
+int command_opt_types[] = {COMMAND_OPT, COMMAND_1_OPT, COMMAND_2_OPT, COMMAND_3_OPT,
+ COMMAND_4_OPT, COMMAND_5_OPT, COMMAND_6_OPT, COMMAND_7_OPT,
+ COMMAND_8_OPT, COMMAND_9};
+
+char escape_char = '\\';
+char newline_char = 'n';
+char horizontal_tab_char = 't';
+char vertical_tab_char = 'v';
+char backspace_char = 'b';
+char carriage_return_char = 'r';
+char formfeed_char = 'f';
+char audible_alert_char = 'a';
+char hex_char = 'x';
+
+
+/* Extended 6/96 */
+STRING unk = "ERROR";
+
+
+int num_print = 0;
+int num_noprint = 0;
+int num_bufprint = 0;
+#define MAX_PRINT_STACK 100
+PSTRWC print_control_stack[MAX_PRINT_STACK]; /* (6/96 changed from int) */
+
+
+ /* positions in command table */
+int pos_bdoc; /* BEGIN_DOCUMENT */
+int pos_edoc; /* END_DOCUMENT */
+int pos_bvbm; /* BEGIN_VERBATIM */
+int pos_evbm; /* END_VERBATIM */
+int pos_bv; /* BEGIN_VERB */
+int pos_ev; /* END_VERB */
+int pos_oc; /* OTHER_COMMAND */
+int pos_ob; /* OTHER_BEGIN */
+int pos_oe; /* OTHER_END */
+int pos_lbrace; /* LEFT_BRACE */
+int pos_rbrace; /* RIGHT_BRACE */
+int pos_para; /* PARAGRAPH */
+int pos_bdol; /* 'begin' $ */
+int pos_edol; /* 'end' $ */
+int pos_bss; /* SLASH_SPACE */
+
+PSENTRY new_table_entry();
+void create_def_reqentry();
+void read_table();
+void print_table();
+int check_table();
+void delete_to_chars();
+int delete_quotes();
+void twarn_noline();
+void table_error();
+void terror_noline();
+void tdebug_tline();
+void tdebug_str_int();
+void tdebug_str();
+void tdebug_char();
+int ctype_to_int();
+char *ctype_to_string();
+int pos_to_int();
+char *pos_to_string();
+int level_to_int();
+char *level_to_string();
+int printc_to_int();
+char *printc_to_string();
+void sort_table();
+int compare_st_entry();
+int lookup_entry();
+void get_env_name();
+void print_to_err();
+void print_debug_1s();
+void print_debug_2s();
+void print_debug_undef();
+void complete_table_entry();
+void complete_entry();
+int command_type();
+int get_user_type();
+int get_special_token();
+/* 6/96 changed following from STRING to PSTRWC */
+PSTRWC get_t();
+PSTRWC get_et();
+PSTRWC get_tag_t();
+PSTRWC get_tag_et();
+PSTRWC get_opttag_t();
+PSTRWC get_opttag_et();
+int get_level();
+PSTRWC get_item_t();
+PSTRWC get_item_et();
+PSTRWC get_itemopt_t();
+PSTRWC get_itemopt_et();
+void warning_3s();
+void set_print();
+void reset_print();
+void push_print_control();
+PSTRWC pop_print_control();
+PSTRWC peek_print_control(); /* added 6/96 */
+/* 6/96 changed following from int to PSTRWC */
+PSTRWC get_com_print();
+PSTRWC get_param_print();
+PSTRWC get_opt_print();
+
+/* Command table file stack stuff */
+# define MAX_CT_STACK 20
+FILE *ct_fp_stack[MAX_CT_STACK]; /* ct file pointers */
+STRING ct_fn_stack[MAX_CT_STACK]; /* ct file names */
+int ct_ln_stack[MAX_CT_STACK]; /* ct line numbers */
+int ct_file_num; /* current ct file */
+
+void initialise_ct_files();
+int set_ct_file();
+int reset_ct_file();
+FILE *get_ct_filep();
+STRING get_ct_filen();
+int get_ct_linenum();
+void incr_ct_linenum();
+
+/* Environment variable defined search path stuff */
+void initialise_senv();
+char path_name[257]; /* name of a path */
+char sys_envname[20]; /* name of environment variable */
+char path_sep[10]; /* path name seperators */
+char dir_cat; /* directory catenation char */
+int senv_debug; /* =1 for debug searchenv() */
+
+
+/*------------------- Additions for interpreting procedural code ------*/
+
+SYMTAB_NODE_PTR code_root; /* where the initial compiled code is stored */
+
+ /* EXTERNALS */
+extern SYMTAB_NODE_PTR code_setup();
+extern int isynt_error_count;
+extern int isynt_warn_count;
+extern int irun_error_count;
+extern int irun_warn_count;
+
+ /* FORWARDS */
+void print_usage(); /* how to call the program */
+void set_pc_code(); /* store a code segment */
+
+/*******************************************************************/
+/* */
+/* MAIN the main program ----------------------------------------- */
+/* */
+/*******************************************************************/
+main(argc, argv)
+int argc;
+char **argv;
+{
+ int optchar;
+ int n;
+ FILE *file;
+ int result;
+ char tabnam[100];
+
+ /* print banner */
+ fprintf(stdout, "\n ltx2x: A LaTeX to X autotagger\n");
+ fprintf(stdout, "\n (%s, %s)\n", FILE_VERSION, FILE_DATE);
+
+ /* open error log file */
+ file = fopen("ltx2x.err", "w");
+ if (!file) {
+ fprintf(stderr, "Fatal Error: Could not open file ltx2x.err\n");
+ exit(1);
+ }
+ filerr = file;
+ fprintf(stdout, "Error file is ltx2x.err\n");
+ fprintf(filerr, "Error file for program ltx2x (%s, %s)\n", FILE_VERSION, FILE_DATE);
+ fprintf(filerr, "Author: Peter Wilson (ex Catholic University and NIST)\n");
+ fprintf(filerr, "Email any comments or suggestions to peter.r.wilson@boeing.com\n\n");
+ /* open Table output file */
+ file = fopen("ltx2xct.lis", "w");
+ if (!file) {
+ fprintf(stderr, "Fatal Error: Could not open file ltx2xct.lis\n");
+ exit(1);
+ }
+ filtabout = file;
+ fprintf(stdout, "Table output file is ltx2xct.lis\n");
+ fprintf(filerr, "Table output file is ltx2xct.lis\n");
+
+ /* set up for Table input file */
+ strcpy(tabnam, "ltx2x.ct");
+ initialise_senv(); /* initialise directory searching */
+
+ /* get command line optional parameters */
+ opterr = 1; /* getopt prints errors if opterr is 1 */
+ while (EOF != (optchar =
+ getopt(argc,argv,"htcwCESl:y:f:p:P:D:i:"))) {
+ /*
+ * Uwe Sassenberg <sassen@hal1.physik.uni-dortmund.de> found
+ * that he had to add this next line of code to stop an infinite
+ * loop of this while (It did not seem to recognise EOF!!)
+ * If it compiles but just sits there chewing CPU cycles, try
+ * uncommenting the next line of code
+ */
+ /* if (optchar == 255) break; */
+ switch(optchar) {
+ case '?': { /* command line error */
+ print_usage();
+ break;
+ }
+ case 'h': { /* command line help */
+ print_usage();
+ break;
+ }
+ case 'l': { /* lexer debugging >0 */
+ LDEBUG = atoi(optarg);
+ if (LDEBUG <= 0) {
+ LDEBUG = 0;
+ }
+ fprintf(stdout, "Lexer debugging set to %d\n", LDEBUG);
+ fprintf(filerr, "Lexer debugging set to %d\n", LDEBUG);
+ break;
+ }
+ case 't': { /* switch on command table & SEARCHENV debugging */
+ TDEBUG = TRUE;
+ senv_debug = 1;
+ fprintf(stdout, "Command table debugging set ON\n");
+ fprintf(filerr, "Command table debugging set ON\n");
+ break;
+ }
+ case 'y': { /* yacc parser debugging >0 */
+ YDEBUG = atoi(optarg);
+ if (YDEBUG <= 0) {
+ YDEBUG = 0;
+ }
+ fprintf(stdout, "Parser debugging set to %d\n", YDEBUG);
+ fprintf(filerr, "Parser debugging set to %d\n", YDEBUG);
+ break;
+ }
+ case 'f': { /* special Table input file */
+ strcpy(tabnam, optarg);
+ break;
+ }
+ case 'c': { /* leave in TeX comments */
+ leave_comments = TRUE;
+ fprintf(stdout, "Print TeX comments set ON\n");
+ fprintf(filerr, "Print TeX comments set ON\n");
+ break;
+ }
+ case 'w': { /* collapse whitespace */
+ collapse_ws = TRUE;
+ fprintf(stdout, "Collapse whitespace set ON\n");
+ fprintf(filerr, "Collapse whitespace set ON\n");
+ break;
+ }
+ case 'P': { /* pathname seperators */
+ strcpy(path_sep, optarg);
+ strcat(path_sep, " ");
+ fprintf(stdout, "Pathname seperators set to (%s)\n", path_sep);
+ fprintf(filerr, "Pathname seperators set to (%s)\n", path_sep);
+ break;
+ }
+ case 'D': { /* directory catenation char */
+ dir_cat = optarg[0];
+ fprintf(stdout, "Directory catenation character set to %c\n", dir_cat);
+ fprintf(filerr, "Directory catenation character set to %c\n", dir_cat);
+ break;
+ }
+ case 'p': { /* pretty-print line length */
+ pretty_print = TRUE;
+ collapse_ws = TRUE;
+ max_pretty_line = atoi(optarg);
+ if (max_pretty_line > MAX_BUFFER) {
+ max_pretty_line = MAX_BUFFER;
+ fprintf(stdout, "Line length too long. Set to %d\n", max_pretty_line);
+ fprintf(filerr, "Line length too long. Set to %d\n", max_pretty_line);
+ }
+ else if (max_pretty_line <= 10) {
+ max_pretty_line = 70;
+ fprintf(stdout, "Line length too short. Set to %d\n", max_pretty_line);
+ fprintf(filerr, "Line length too short. Set to %d\n", max_pretty_line);
+ }
+ else {
+ fprintf(stdout, "Line length set to %d\n", max_pretty_line);
+ fprintf(filerr, "Line length set to %d\n", max_pretty_line);
+ fflush(stdout);
+ fflush(filerr);
+ }
+ break;
+ }
+ case 'i': { /* interpreter code debugging */
+ cl_debug = atoi(optarg);
+ if (cl_debug <= 0) {
+ cl_debug = 0;
+ }
+ fprintf(stdout, "Interpreter debugging set to %d\n", cl_debug);
+ fprintf(filerr, "Interpreter debugging set to %d\n", cl_debug);
+ break;
+ }
+ case 'C': { /* disable any interpreter source Code debug */
+ cdebug = FALSE;
+ fprintf(stdout, "Interpreter source Code debugging disabled\n");
+ fprintf(filerr, "Interpreter source Code debugging disabled\n");
+ break;
+ }
+ case 'E': { /* disable any interpreter Execution debug */
+ edebug = FALSE;
+ fprintf(stdout, "Interpreter Execution debugging disabled\n");
+ fprintf(filerr, "Interpreter Execution debugging disabled\n");
+ break;
+ }
+ case 'S': { /* enable interpreter Source Level Debugger */
+ SLD_OFF = FALSE;
+ fprintf(stdout, "Interpreter Source Level Debugger set ON\n");
+ fprintf(filerr, "Interpreter Source Level Debugger set ON\n");
+ break;
+ }
+ } /* end switch */
+ } /* end of optional parameter processing */
+
+ /* open Table file */
+ if (!searchenv(tabnam, sys_envname, path_name, path_sep, dir_cat, senv_debug)) {
+ fprintf(stderr, "Fatal Error: Could not find file %s\n", tabnam);
+ exit(1);
+ }
+ file = fopen(path_name, "r");
+ if (!file) {
+ fprintf(stderr, "Fatal Error: Could not open file %s\n", path_name);
+ exit(1);
+ }
+ filtabin = file;
+ fprintf(stdout, "Table input file is %s\n", path_name);
+ fprintf(filerr, "Table input file is %s\n", path_name);
+
+ /* rest of parameters are file names (input and output) */
+ n = 0;
+ for (;optind < argc; optind++) {
+ n++;
+ if (n == 1) {
+ file = fopen(argv[optind], "r");
+ if (!file) {
+ fprintf(stderr,"Fatal Error: Could not open input file %s\n",argv[optind]);
+ fprintf(filerr,"Fatal Error: Could not open input file %s\n",argv[optind]);
+ exit(1);
+ }
+ fprintf(stdout,"Reading file %s", argv[optind]);
+ fprintf(filerr,"Reading file %s", argv[optind]);
+ yyin = file;
+ }
+ else { if (n == 2) {
+ file = fopen(argv[optind], "w");
+ if (!file) {
+ fprintf(stderr,"Fatal Error: Could not open output file %s\n",argv[optind]);
+ fprintf(filerr,"Fatal Error: Could not open output file %s\n",argv[optind]);
+ exit(1);
+ }
+ fprintf(stdout," and writing to file %s\n",argv[optind]);
+ fprintf(filerr," and writing to file %s\n",argv[optind]);
+ yyout = file;
+ }
+ else {
+ fprintf(stderr,"Warning: Only two files permitted. File %s ignored\n",argv[optind]);
+ fprintf(filerr,"Warning: Only two files permitted. File %s ignored\n",argv[optind]);
+ }
+ }
+ }
+ if (n == 0) {
+ fprintf(stderr,"Fatal Error: An input and an output file are required.\n");
+ fprintf(filerr,"Fatal Error: An input and an output file are required.\n");
+ exit(1);
+ }
+
+ /* do some initialisations */
+ print_to_err("\n > Starting initialisations\n");
+ initialise_clause_stack();
+ darray[0] = 0;
+ initialise_sysbuf();
+ init_common_print(); /* 6/96 common print structs */
+ init_print_control(); /* 6/96 initialise print control */
+
+ code_root = NULL; /* code interp, initialise to no-code */
+
+ print_to_err(" > Reading command table(s)\n");
+ initialise_ct_files(path_name);
+ read_table();
+ if (TDEBUG) {
+ print_table(filerr);
+ }
+ print_to_err(" > Sorting table\n");
+ sort_table();
+ print_to_err(" > Checking table\n");
+ if (check_table()) {
+ print_to_err(" > Re-sorting table\n");
+ sort_table();
+ print_to_err(" > Re-checking table\n");
+ check_table();
+ }
+ print_to_err(" > Printing table\n");
+ print_table(filtabout);
+ fclose(filtabout);
+
+ /* added for code interp */
+ /* execute initial code */
+ if (code_root != NULL) { /* only process initial code if there is any */
+ exec_startup(code_root);
+ }
+
+ /* process input */
+ print_to_err(" > Processing source file\n");
+ while(!feof(yyin)) {
+ result = yyparse();
+ if (result == 0) {
+ write_stats(" (end of parsing)");
+ exit(0);
+ }
+ }
+ write_stats(" (end of program)");
+ exit(0);
+} /* end MAIN */
+/*------------------------------------------------------------------------*/
+
+/*------------------------------------------------------------------------*/
+/* print_usage Prints the command line parameters */
+
+void print_usage()
+{
+ fprintf(stderr, "\nUsage: [options] infile outfile\n");
+ fprintf(stderr, " Options for the general user\n");
+ fprintf(stderr, " [-c] include LaTeX comments in the output\n");
+ fprintf(stderr, " [-f tablename] use tablename as the command file instead of ltx2x.ct\n");
+ fprintf(stderr, " [-h] print usage (this message)\n");
+ fprintf(stderr, " [-p num] set pretty printing with num characters per line\n");
+ fprintf(stderr, " [-w] collapse whitespace in the output\n");
+ fprintf(stderr, " [-D char] directory catenation character\n");
+ fprintf(stderr, " [-P string] pathname seperator characters\n");
+ fprintf(stderr, " [-S] enable the interpreter's source level debugger\n");
+ fprintf(stderr, " Options for the system developer\n");
+ fprintf(stderr, " [-i num] set level of interpreter debug print output\n");
+ fprintf(stderr, " [-l num] set level of lexer debug print output\n");
+ fprintf(stderr, " [-t] enable command table debug print output\n");
+ fprintf(stderr, " [-y num] unused at present\n");
+ fprintf(stderr, " [-C] disable any interpreter source code debug print\n");
+ fprintf(stderr, " [-E] disable any interpreter execution code debug print\n");
+
+ fprintf(filerr, "\nUsage: [options] infile outfile\n");
+ fprintf(filerr, " Options for the general user\n");
+ fprintf(filerr, " [-c] include LaTeX comments in the output\n");
+ fprintf(filerr, " [-f tablename] use tablename as the command file instead of ltx2x.ct\n");
+ fprintf(filerr, " [-h] print usage (this message)\n");
+ fprintf(filerr, " [-p num] set pretty printing with num characters per line\n");
+ fprintf(filerr, " [-w] collapse whitespace in the output\n");
+ fprintf(filerr, " [-D char] directory catenation character\n");
+ fprintf(filerr, " [-P string] pathname seperator characters\n");
+ fprintf(filerr, " [-S] enable the interpreter's source level debugger\n");
+ fprintf(filerr, " Options for the system developer\n");
+ fprintf(filerr, " [-i num] set level of interpreter debug print output\n");
+ fprintf(filerr, " [-l num] set level of lexer debug print output\n");
+ fprintf(filerr, " [-t] enable command table debug print output\n");
+ fprintf(filerr, " [-y num] unused at present\n");
+ fprintf(filerr, " [-C] disable any interpreter source code debug print\n");
+ fprintf(filerr, " [-E] disable any interpreter execution code debug print\n");
+
+exit(0);
+} /* end PRINT_USAGE */
+/*------------------------------------------------------------------------*/
+
+
+
+
+ /*-----------STRING FUNCTIONS-------------------------*/
+
+/* STRSAVE saves a string somewhere */
+char *strsave(s)
+char *s;
+{
+/* char *p, *malloc(); */
+ char *p;
+
+/* if ((p = malloc(strlen(s)+1)) != NULL) { */
+ if ((p = (char *) malloc(strlen(s)+1)) != NULL) {
+ strcpy(p, s);
+ }
+ else {
+ yyerror("FATAL ERROR: No memory left for STRSAVE");
+ exit(1);
+ }
+ return(p);
+} /* end STRSAVE */
+
+
+/* GET_ENV_NAME puts ...{ name } name into env_name */
+void get_env_name(str)
+char str[];
+{
+ int first, last, i, n;
+ int c;
+ int top;
+
+ top = MAX_TABLE_LINE + 10;
+ first = top;
+ n = 0;
+ env_name[0] = '\0';
+
+ for (i = 0; (c = str[i]) != '\0'; i++) { /* look for opening brace */
+ if (c == '{') {
+ first = i+1;
+ break;
+ }
+ }
+ if (first == top) { /* opening brace not found */
+ yyerror("get_env_name: opening brace not found");
+ return;
+ }
+ last = first;
+ first = top;
+ for (i = last; (c = str[i]) != '\0'; i++) { /* look for start of name */
+ if (!isspace(c)) { /* found it */
+ first = i;
+ break;
+ }
+ }
+ if (first == top) { /* name not found */
+ yyerror("get_env_name: name not found");
+ return;
+ }
+ for (i = first; (c = str[i]) != '\0'; i++) {
+ if (!isspace(c)) { /* a part of the name */
+ if (c == '}') { /* name ended */
+ break;
+ }
+ env_name[n] = c;
+ n++;
+ }
+ }
+ env_name[n] = '\0';
+} /* end GET_ENV_NAME */
+
+
+/* DELETE_TO_CHARS deletes all chars through first occurrence of "c" */
+void delete_to_chars(c,s)
+char c[];
+char s[];
+{
+ int len;
+ int pos;
+ int i, n;
+
+ len = strlen(s);
+ pos = strcspn(s, c);
+ if (pos > 0 && pos < len) { /* = found */
+ n = 0;
+ for (i = (pos+1); i <= len; i++ ) {
+ s[n] = s[i];
+ n++;
+ }
+ }
+} /* end DELETE_TO_CHARS */
+
+
+/* DELETE_QUOTES deletes leading and trailing " and replaces
+ escaped character pairs. Returns # of chars */
+int delete_quotes(s,sout)
+char s[];
+char sout[];
+{
+ int first, last, len;
+ int i, n, j, k;
+ char last_char, this_char;
+ char hex_str[20];
+
+ len = strlen(s);
+ for (i=0; i < len; i++) {
+ first = i;
+ if (s[i] == '"') {
+ break;
+ }
+ }
+ last = first;
+ for (i = (first + 1); i < len; i++) {
+ if (s[i] == '"') {
+ last = i;
+ }
+ }
+ if (first == last) { /* zero or one quote */
+ sout[0] = SNUL;
+ if (first != (len -1) ) { /* one quote */
+ table_error("ERROR: string not enclosed in quotes");
+ }
+ return(0);
+ }
+ n = 0;
+ last_char = '"';
+ for (i= (first+1); i < last; i++) {
+ this_char = s[i];
+ sout[n] = this_char;
+ if (last_char == escape_char) { /* possibly an escaped pair */
+ if (this_char == newline_char) {
+ n--;
+ sout[n] = '\n';
+ }
+ else if (this_char == horizontal_tab_char) {
+ n--;
+ sout[n] = '\t';
+ }
+ else if (this_char == vertical_tab_char) {
+ n--;
+ sout[n] = '\v';
+ }
+ else if (this_char == backspace_char) {
+ n--;
+ sout[n] = '\b';
+ }
+ else if (this_char == carriage_return_char) {
+ n--;
+ sout[n] = '\r';
+ }
+ else if (this_char == formfeed_char) {
+ n--;
+ sout[n] = '\f';
+ }
+ else if (this_char == audible_alert_char) {
+ n--;
+ sout[n] = '\a';
+ }
+ else if (this_char == hex_char) { /* do hex stuff */
+ k = 0;
+ hex_str[k] = '\0';
+ for (j = i+1; j < last; j++) { /* get hex chars */
+ if (isxdigit(s[j])) { /* got hex digit */
+ hex_str[k] = s[j];
+ k++;
+ }
+ else { /* end of hex digits */
+ hex_str[k] = '\0';
+ break;
+ }
+ } /* got all hex digits */
+ n--;
+ sout[n] = strtoul(hex_str, NULL, 16);
+ i = i + k; /* shift i to end of hex digits */
+ }
+ else if (this_char == escape_char) {
+ if (escape_char == '\\' ) { /* default */
+ n--;
+ sout[n] = '\\';
+ this_char = '"';
+ }
+ else {
+ n--;
+ this_char = '"';
+ }
+ }
+ }
+ n++;
+ last_char = this_char;
+ }
+ sout[n] = SNUL;
+ return(n);
+} /* end DELETE_QUOTES */
+
+
+/* STRTOUC converts a string in place to upper case */
+void strtouc(str)
+char str[];
+{
+ int i;
+ for (i = 0; str[i] != SNUL; i++) {
+ str[i] = toupper(str[i]);
+ }
+ return;
+} /* end STRTOUC */
+
+
+
+ /*------------PRINT FUNCTIONS-----------------------*/
+
+/* MYPRINT output to file, buffer or black hole */
+void myprint(s)
+char s[];
+{
+ PSTRWC ptr;
+ int num;
+ int n;
+ int k;
+
+ ptr = cur_printc;
+ if (ptr == NULL) { /* should not be null */
+ yyerror("internal error: cur_printc is NULL in MYPRINT");
+ return;
+ }
+
+ if (s == NULL) { /* nothing to print */
+ return;
+ }
+ if (s[0] == SNUL) { /* nothing to print */
+ return;
+ }
+
+ k = get_pc_enum(ptr);
+ switch (k) {
+ case NO_PRINT: { /* do nothing */
+ return;
+ break;
+ }
+ case NO_OP: { /* do nothing */
+ return;
+ break;
+ }
+ case TO_SYSBUF: { /* store string in system buffer */
+ /* check buffer overflow */
+ n = strlen(buffer) + strlen(s);
+ used_sbuff_chars = maxof(n, used_sbuff_chars);
+ if (n >= MAX_BUFFER - 2) {
+ warning("Unpredictable results due to system buffer overflow");
+ }
+ else { /* add to buffer */
+ strcat(buffer, s);
+ }
+ break;
+ }
+ case TO_BUFFER: { /* store string in user buffer */
+ num = get_pcdata_num(ptr);
+ if ( num < 0 || num > MAX_USER_BUFFS ) { /* buffer out of range */
+ sprintf(errstr, "in MYPRINT user buffer %d is out of range", num);
+ warning(errstr);
+ break;
+ }
+ n = strlen(user_buffs[num]) + strlen(s);
+ used_ubuff_chars = maxof(n, used_ubuff_chars);
+ if (n >= MAX_UBUFF_LEN - 2) {
+ sprintf(errstr, "Unpredictable results; User buffer %d overflowed", num);
+ warning(errstr);
+ }
+ else { /* add to buffer */
+ strcat(user_buffs[num], s);
+ }
+ break;
+ }
+ case TO_FILE: { /* write to file */
+/* name = get_pcdata_name(ptr); */
+ fprintf(cur_user_fileid, "%s", s);
+ fflush(cur_user_fileid);
+ break;
+ }
+ case DEFAULT_PRINT: {
+ if (pretty_print) { /* pretty printing */
+ pprint(s);
+ }
+ else {
+ fprintf(yyout, "%s", s);
+ fflush(yyout);
+ }
+ break;
+ }
+ default: { /* should not be here */
+ sprintf(errstr, "Illegal print option (%d %s) in MYPRINT",
+ k, printc_to_string(k));
+ warning(errstr);
+ return;
+ break;
+ }
+ } /* end switch */
+ return;
+} /* end MYPRINT */
+
+
+int pprint_top = 0; /* pointer into pretty_line */
+int last_space = 0; /* posn of last space in pretty_line */
+int ppoverflow = FALSE; /* pretty_line buffer overflow */
+
+/* PRETTY_EMPTY checks if the pretty line is empty */
+int pretty_empty()
+{
+ return((pretty_line[0] == SNUL));
+} /* end PRETTY_EMPTY */
+
+
+/* FLUSH_PRETTY flushes pretty line buffer and resets it */
+void flush_pretty()
+{
+
+ pretty_line[pprint_top] = SNUL;
+ fprintf(yyout, "%s\n", pretty_line);
+ pprint_top = 0;
+ pretty_line[pprint_top] = SNUL;
+ last_space = 0;
+ ppoverflow = FALSE;
+ return;
+} /* end FLUSH_PRETTY */
+
+
+/* PPRINT pretty printing */
+void pprint(s)
+char s[];
+{
+
+ char c;
+ int i,n,j;
+ int start;
+
+ start = 0;
+ /* add characters from s into pretty_line until overflow. */
+ /* back off to last space. Flush at newline. */
+
+ for (i = start; (c = s[i]) != SNUL; i++) {
+ if (c == '\n') { /* newline, flush */
+ flush_pretty();
+ ppoverflow = FALSE;
+ }
+ else {
+ if (c == ' ' || c == '\t') { /* whitespace */
+ last_space = pprint_top;
+ if (ppoverflow) { /* overflow, flush on whitespace */
+ flush_pretty();
+ ppoverflow = FALSE;
+ }
+ }
+ pretty_line[pprint_top] = c;
+ pprint_top++;
+ if (pprint_top >= (max_pretty_line - 1)) { /* buffer is full, back off */
+ if (last_space > 0) { /* but only if there is a prior space */
+ pretty_line[last_space] = SNUL;
+ fprintf(yyout, "%s\n", pretty_line);
+ j = 0;
+ for (n = last_space + 1; n < pprint_top; n++) { /* move final chars down */
+ pretty_line[j] = pretty_line[n];
+ j++;
+ }
+ pprint_top = j;
+ last_space = 0;
+ ppoverflow = FALSE;
+ }
+ else { /* overflow, print the buffer */
+ flush_pretty();
+ ppoverflow = TRUE;
+ }
+ }
+ }
+ } /* end for loop */
+} /* end PPRINT */
+
+
+/* VERBATIM_PRINT output to file, buffer or black hole (almost identical to myprint ) */
+void verbatim_print(s)
+char s[];
+{
+ PSTRWC ptr;
+ int num;
+ int n;
+ int k;
+
+ ptr = cur_printc;
+ if (ptr == NULL) { /* should not be null */
+ yyerror("internal error: cur_printc is NULL in VERBATIM_PRINT");
+ return;
+ }
+
+ if (s == NULL) { /* nothing to print */
+ return;
+ }
+ if (s[0] == SNUL) { /* nothing to print */
+ return;
+ }
+
+ k = get_pc_enum(ptr);
+ switch (k) {
+ case NO_PRINT: { /* do nothing */
+ return;
+ break;
+ }
+ case NO_OP: { /* do nothing */
+ return;
+ break;
+ }
+ case TO_SYSBUF: { /* store string in system buffer */
+ /* check buffer overflow */
+ n = strlen(buffer) + strlen(s);
+ used_sbuff_chars = maxof(n, used_sbuff_chars);
+ if (n >= MAX_BUFFER - 2) {
+ warning("Unpredictable results due to system buffer overflow");
+ }
+ else { /* add to buffer */
+ strcat(buffer, s);
+ }
+ break;
+ }
+ case TO_BUFFER: { /* store string in user buffer */
+ num = get_pcdata_num(ptr);
+ if ( num < 0 || num > MAX_USER_BUFFS ) { /* buffer out of range */
+ sprintf(errstr, "in VERBATIM_PRINT user buffer %d is out of range", num);
+ warning(errstr);
+ break;
+ }
+ n = strlen(user_buffs[num]) + strlen(s);
+ used_ubuff_chars = maxof(n, used_ubuff_chars);
+ if (n >= MAX_UBUFF_LEN - 2) {
+ sprintf(errstr, "Unpredictable results; User buffer %d overflowed", num);
+ warning(errstr);
+ }
+ else { /* add to buffer */
+ strcat(user_buffs[num], s);
+ }
+ break;
+ }
+ case TO_FILE: { /* write to file */
+ fprintf(cur_user_fileid, "%s", s);
+ fflush(cur_user_fileid);
+ break;
+ }
+ case DEFAULT_PRINT: {
+ if (bverb && pretty_print) { /* at start of verbatim */
+ if (!pretty_empty()) {
+ flush_pretty(); /* flush the current pretty line */
+ }
+ bverb = FALSE;
+ }
+ fprintf(yyout, "%s", s);
+ fflush(yyout);
+ break;
+ }
+ default: { /* should not be here */
+ sprintf(errstr, "Illegal print option (%d %s) in VERBATIM_PRINT",
+ k, printc_to_string(k));
+ warning(errstr);
+ return;
+ break;
+ }
+ } /* end switch */
+ return;
+} /* end VERBATIM_PRINT */
+
+
+/* PRINT_SYSBUF prints system buffer */
+void print_sysbuf()
+{
+ fprintf(yyout, "%s", buffer);
+ fflush(yyout);
+} /* end PRINT_SYSBUF */
+
+
+/* INITIALISE_SYSBUF clears system buffer */
+void initialise_sysbuf()
+{
+ buffer[0] = SNUL;
+} /* end INITIALISE_SYSBUF */
+
+
+/* COPY_SYSBUF copies system buffer to S */
+void copy_sysbuf(s)
+char s[];
+{
+ strcat(s, buffer);
+} /* end COPY_SYSBUF */
+
+
+/* INITIALISE_STRING clears a string S */
+void initialise_string(s)
+char s[];
+{
+ s[0] = SNUL;
+} /* end INITIALISE_STRING */
+
+
+/* INITIALISE_PC initialises print control */
+PSTRWC initialise_pc()
+{
+
+ /* set counters to zero */
+ num_print = 0; /* (empty) top of stack */
+ num_noprint = 0; /* # of open no prints */
+ num_bufprint = 0; /* # of open sys buff prints */
+ num_ubufwrite = 0; /* # of open user buff writes */
+ num_fileprint = 0; /* # of open file writes */
+ num_otherprint = 0; /* # of open non-default prints */
+ /* set flags */
+ no_print = FALSE; /* we are printing */
+ print_to_buffer = FALSE; /* not printing to sys buffer */
+ /* set stack for default printing */
+ push_print_control(p_default_print);
+ cur_printc = p_default_print;
+/* set_print(p_default_print); */
+ return(p_default_print);
+} /* end INITIALISE_PC */
+
+/* SET_PRINT sets myprint and other print behaviours */
+/* 6/96 changed pswitch from int to PSTRWC */
+void set_print(pswitch)
+PSTRWC pswitch;
+{
+ int num;
+ PSTRWC ptr;
+ int k;
+ STRING str;
+ int curpc;
+
+ if (pswitch == NULL) { /* got a problem! */
+ yyerror("internal error: SET_PRINT called with NULL value (setting it to the default)");
+ initialise_pc();
+ return;
+ }
+
+ k = get_pc_enum(pswitch);
+
+ switch (k) { /* check on pswitch */
+ case DEFAULT_PRINT :
+ case NO_PRINT :
+ case TO_SYSBUF :
+ case TO_BUFFER :
+ case NO_OP :
+ case TO_FILE : { /* pswitch is OK */
+ ptr = pswitch;
+ break;
+ }
+ default : { /* should not be here */
+ sprintf(errstr,
+"internal error: SET_PRINT called with illegal value (%d %s), setting it to the default",
+ k, printc_to_string(k));
+ yyerror(errstr);
+ ptr = p_default_print;
+ k = DEFAULT_PRINT;
+ break;
+ }
+ } /* end of switch on pswitch */
+
+ /* possibly start a no op */
+ if (k == NO_OP && !in_noop) {
+ start_noop = TRUE;
+ push_print_control(ptr);
+ cur_printc = ptr;
+ return;
+ }
+
+ curpc = get_pc_enum(cur_printc);
+ switch(curpc) { /* action depends on current state */
+ case DEFAULT_PRINT: { /* default is almost a non-event */
+ push_print_control(ptr);
+ cur_printc = ptr;
+ break;
+ }
+ case NO_PRINT: { /* carry on with no printing */
+ push_print_control(cur_printc);
+ break;
+ }
+ case TO_SYSBUF :
+ case TO_BUFFER :
+ case TO_FILE : {
+ if (k == DEFAULT_PRINT) { /* default doesn't change anything */
+ push_print_control(cur_printc);
+ }
+ else { /* a change */
+ push_print_control(ptr);
+ cur_printc = ptr;
+ }
+ break;
+ }
+ default : { /* should not be here */
+ sprintf(errstr,
+"internal error: SET_PRINT has illegal value (%d %s) for cur_printc, setting it to the default",
+ curpc, printc_to_string(curpc));
+ warning(errstr);
+ cur_printc = p_default_print;
+ break;
+ }
+ } /* end switch on cur_printc */
+
+ switch (get_pc_enum(cur_printc)) { /* finally update counters, etc */
+ case DEFAULT_PRINT : {
+ break;
+ }
+ case NO_PRINT : {
+ num_noprint++;
+ num_otherprint = SET_NUM_OTHERPRINT;
+ no_print = TRUE;
+ break;
+ }
+ case TO_SYSBUF : {
+ num_bufprint++;
+ num_otherprint = SET_NUM_OTHERPRINT;
+ print_to_buffer = TRUE;
+ break;
+ }
+ case TO_BUFFER : {
+ num_ubufwrite++;
+ num_otherprint = SET_NUM_OTHERPRINT;
+ num = get_pcdata_num(cur_printc);
+ num_ubuff[num]++;
+ cur_user_buf = num;
+ if (written_from_buff[num]) { /* have written from this buffer */
+ initialise_string(user_buffs[num]);
+ written_from_buff[num] = FALSE;
+ }
+ break;
+ }
+ case TO_FILE : {
+ num_fileprint++;
+ num_otherprint = SET_NUM_OTHERPRINT;
+ str = get_pcdata_name(cur_printc);
+ num = get_fpos(str);
+ num_filep[num]++;
+ cur_user_fn = str;
+ cur_user_fpos = num;
+ if (num_filep[num] == 1) { /* a first write call to this file */
+ ufp[num] = ufopenw(str);
+ }
+ cur_user_fileid = ufp[num];
+ break;
+ }
+ default : { /* should not be here */
+ sprintf(errstr,
+"internal error: SET_PRINT has set illegal value (%d %s) for cur_printc",
+ curpc, printc_to_string(curpc));
+ yyerror(errstr);
+ break;
+ }
+ } /* end of switch over cur_printc */
+ return;
+} /* end SET_PRINT */
+
+
+/* RESET_PRINT resets myprint, etc behaviour */
+void reset_print()
+{
+
+ PSTRWC ptr;
+ int num;
+ STRING fn;
+ int file_pos; /* pos of file in file list */
+ int k;
+
+ ptr = pop_print_control();
+ k = get_pc_enum(ptr);
+ switch (k) { /* close off the popped print control */
+ case DEFAULT_PRINT : { /* nothing special to do */
+ break;
+ }
+ case NO_PRINT: {
+ num_noprint--;
+ if (num_noprint < 0) {
+ yyerror("at least one too many calls to reset_print after NO_PRINT");
+ num_noprint = 0;
+ }
+ if (num_noprint <= 0) { /* back to some output */
+ no_print = FALSE;
+ }
+ num_otherprint = SET_NUM_OTHERPRINT;
+ break;
+ }
+ case TO_SYSBUF: {
+ num_bufprint--;
+ if (num_bufprint < 0) {
+ yyerror("at least one too many calls to reset_print after PRINT_TO_BUFFER");
+ num_bufprint = 0;
+ }
+ if (num_bufprint <= 0) {
+ print_to_buffer = FALSE;
+ }
+ num_otherprint = SET_NUM_OTHERPRINT;
+ break;
+ }
+ case TO_BUFFER: {
+ num = get_pcdata_num(ptr);
+ num_ubufwrite--;
+ num_ubuff[num]--;
+ if (num_ubufwrite < 0) {
+ yyerror("at least one too many calls to reset_print after WRITE_TO_BUFFER");
+ num_ubufwrite = 0;
+ num_ubuff[num] = 0;
+ }
+ num_otherprint = SET_NUM_OTHERPRINT;
+ break;
+ }
+ case TO_FILE: { /* close file */
+ fn = get_pcdata_name(ptr);
+ num_fileprint--;
+ file_pos = get_fpos(fn);
+/* num_filep[file_pos]--; 10/96 */
+ if (num_fileprint < 0) {
+ yyerror("at least one too many calls to reset_print after WRITE_TO_FILE");
+ num_fileprint = 0;
+ num_filep[file_pos] = 0;
+ }
+ if (num_filep[file_pos] == 0) { /* close the file */
+/* ufclose(fn); 10/96 */
+ }
+ num_otherprint = SET_NUM_OTHERPRINT;
+ break;
+ }
+ case NO_OP: { /* reset flags */
+ start_noop = FALSE;
+ in_noop = FALSE;
+ break;
+ }
+ default: { /* stack underflow */
+ sprintf(errstr,
+"internal error: RESET_PRINT called with illegal value (%d %s), setting it to the default",
+ k, printc_to_string(k));
+ warning(errstr);
+ initialise_pc();
+ break;
+ }
+ } /* end of switch on popped */
+ cur_printc = peek_print_control();
+
+ switch (get_pc_enum(cur_printc)) {
+ case DEFAULT_PRINT : { /* nothing to do */
+ break;
+ }
+ case NO_PRINT : { /* done already */
+ break;
+ }
+ case TO_SYSBUF : { /* done already */
+ break;
+ }
+ case TO_BUFFER : { /* set current buffer */
+ cur_user_buf = get_pcdata_num(cur_printc);
+ break;
+ }
+ case TO_FILE : { /* set current file name */
+ cur_user_fn = get_pcdata_name(cur_printc);
+ break;
+ }
+ default : { /* should not be here, but do nothing */
+ sprintf(errstr,
+"internal error: RESET_PRINT peeked at illegal value (%d %s)",
+ k, printc_to_string(k));
+ yyerror(errstr);
+ break;
+ }
+ } /* end of switch on peeked */
+ return;
+} /* end RESET_PRINT */
+
+
+/* PUSH_PRINT_CONTROL */
+void push_print_control(kind)
+PSTRWC kind;
+{
+
+ used_print_stack = maxof(num_print, used_print_stack);
+ if (num_print >= MAX_PRINT_STACK) { /* stack overflow */
+ yyerror("Somethings wrong: print stack overflow");
+ return;
+ }
+ print_control_stack[num_print] = kind;
+ num_print++;
+} /* end PUSH_PRINT_CONTROL */
+
+
+/* POP_PRINT_CONTROL returns top of print control stack and pops it */
+PSTRWC pop_print_control()
+{
+ PSTRWC item;
+
+ if (num_print < 0) { /* stack underflow */
+ yyerror("Somethings wrong: print stack underflow");
+ return(p_print_underflow);
+ }
+ num_print--;
+ item = print_control_stack[num_print];
+ return(item);
+} /* end POP_PRINT_CONTROL */
+
+
+/* PEEK_PRINT_CONTROL returns top of print control stack */
+PSTRWC peek_print_control()
+{
+ if (num_print < 0) { /* stack underflow */
+ yyerror("Somethings wrong: print stack underflow");
+ return(p_print_underflow);
+ }
+ return(print_control_stack[num_print - 1]);
+} /* end PEEK_PRINT_CONTROL */
+
+
+
+ /*---------------ERROR AND DEBUG PRINTING-------------*/
+
+/* YYERROR prints error message */
+void yyerror(s)
+char *s;
+{
+ fprintf(stderr, "\n%s in line\n%d: %s\n", s, lineno, linebuf);
+ fprintf(filerr, "\n%s in line\n%d: %s\n", s, lineno, linebuf);
+ fflush(stderr);
+ fflush(filerr);
+ num_errors++;
+ if (num_errors >= MAX_ERRORS) {
+ fprintf(stderr, "\n** Translation ended with at least %d errors **\n", num_errors);
+ fprintf(filerr, "\n** Translation ended with at least %d errors **\n", num_errors);
+ fprintf(yyout, "\n** Translation ended with at least %d errors **\n", num_errors);
+ write_stats(" (at error failure)");
+ exit(1);
+ }
+} /* end YYERROR */
+
+
+/* WARNING prints warning message */
+void warning(s)
+char *s;
+{
+ fprintf(stderr, "\nWARNING: %s in line\n%d: %s\n", s, lineno, linebuf);
+ fprintf(filerr, "\nWARNING: %s in line\n%d: %s\n", s, lineno, linebuf);
+ fflush(stderr);
+ fflush(filerr);
+} /* end WARNING */
+
+
+/* WARNING_3S prints 3 warning strings */
+void warning_3s(s1, s2, s3)
+char *s1;
+char *s2;
+char *s3;
+{
+
+ fprintf(stderr, "\nWarning: %s %s %s in line\n%d: %s\n",
+ s1, s2, s3, lineno, linebuf);
+ fprintf(filerr, "\nWarning: %s %s %s in line\n%d: %s\n",
+ s1, s2, s3, lineno, linebuf);
+ fflush(stderr);
+ fflush(filerr);
+} /* end WARNING_3S */
+
+
+/* PRINT_TO_ERR prints one string to error file */
+void print_to_err(s1)
+char s1[];
+{
+ fprintf(filerr, "%s", s1);
+ fflush(filerr);
+} /* end PRINT_TO_ERR */
+
+
+/* PRINT_DEBUG_1S prints LD string to error file */
+void print_debug_1s(s1)
+char s1[];
+{
+ fprintf(filerr, " LD%s", s1);
+ fflush(filerr);
+} /* end PRINT_DEBUG_1S */
+
+
+/* PRINT_DEBUG_2S prints LD two strings to error file */
+void print_debug_2s(s1, s2)
+char s1[];
+char s2[];
+{
+ fprintf(filerr, " LD%s %s", s1, s2);
+ fflush(filerr);
+} /* end PRINT_DEBUG_2S */
+
+/* PRINT_DEBUG_UNDEF prints "undefined table entry" to error file */
+void print_debug_undef(s1, s2)
+char s1[];
+char s2[];
+{
+ fprintf(filerr, "\n %s on line %d not in command table. %s",
+ s1, lineno, s2);
+ fflush(filerr);
+} /* end PRINT_DEBUG_UNDEF */
+
+
+
+/* TABLE_ERROR prints Command table error message */
+void table_error(s)
+char *s;
+{
+ fprintf(stderr, "\nCommand table: %s in file %s line\n%d: %s\n",
+ s, get_ct_filen(), get_ct_linenum(), table_line);
+ fprintf(filerr, "\nCommand table: %s in file %s line\n%d: %s\n",
+ s, get_ct_filen(), get_ct_linenum(), table_line);
+ fflush(stderr);
+ fflush(filerr);
+ num_table_errors++;
+ if (num_table_errors >= MAX_ERRORS) {
+ fprintf(stderr, "\n** Table processing ended with at least %d errors **\n",
+ num_table_errors);
+ fprintf(filerr, "\n** Table processing ended with at least %d errors **\n",
+ num_table_errors);
+ exit(1);
+ }
+} /* end TABLE_ERROR */
+
+
+/* TERROR_NOLINE prints error message without source line id */
+void terror_noline(s)
+char *s;
+{
+ fprintf(stderr, "\nCommand table error: %s\n", s);
+ fprintf(filerr, "\nCommand table error: %s\n", s);
+ fflush(stderr);
+ fflush(filerr);
+ num_table_errors++;
+ if (num_table_errors >= MAX_ERRORS) {
+ fprintf(stderr, "\n** Table processing ended with at least %d errors **\n",
+ num_table_errors);
+ fprintf(filerr, "\n** Table processing ended with at least %d errors **\n",
+ num_table_errors);
+ exit(1);
+ }
+} /* end TERROR_NOLINE */
+
+
+/* TWARN_NOLINE prints table warning */
+void twarn_noline(str)
+char str[];
+{
+/* fprintf(stderr, "\nTable Warning: %s\n", str); */
+ fprintf(filerr, "\nTable Warning: %s\n", str);
+/* fflush(stderr); */
+ fflush(filerr);
+} /* end TWARN_NOLINE */
+
+
+/* TDEBUG_TLINE prints table line */
+void tdebug_tline(str)
+char str[];
+{
+ fprintf(stderr, "\n%s line %d: %s", get_ct_filen(), get_ct_linenum(), str);
+ fprintf(filerr, "\n%s line %d: %s", get_ct_filen(), get_ct_linenum(), str);
+ fflush(stderr);
+ fflush(filerr);
+} /* end TDEBUG_TLINE */
+
+
+/* TDEBUG_STR_INT prints diagnostics */
+void tdebug_str_int(str, num)
+char str[];
+int num;
+{
+ fprintf(stderr, "LD: %s %d\n", str, num);
+ fprintf(filerr, "LD: %s %d\n", str, num);
+ fflush(stderr);
+ fflush(filerr);
+ return;
+} /* end TDEBUG_STR_INT */
+
+
+/* TDEBUG_STR prints diagnostics */
+void tdebug_str(str)
+char str[];
+{
+ fprintf(stderr, "LD: (Read_table) %s", str);
+ fprintf(filerr, "LD: (Read_table) %s", str);
+ fflush(stderr);
+ fflush(filerr);
+} /* end TDEBUG_STR */
+
+
+/* TDEBUG_CHAR prints diagnostics */
+void tdebug_char(c)
+char c;
+{
+ fprintf(stderr, "%c\n", c);
+ fprintf(filerr, "%c\n", c);
+ fflush(stderr);
+ fflush(filerr);
+} /* end TDEBUG_CHAR */
+
+
+
+
+
+ /*----------MISCELLANEOUS (PARSER) FUNCTIONS-----------------*/
+
+
+/* INITIALISE_CLAUSE_STACK */
+void initialise_clause_stack()
+{
+ int i;
+ for (i = 0; i < CLAUSE_STACK_SIZE; i++ ) {
+ clause_str_stack[i] = p_print_null;
+ }
+ clause_depth = 0;
+ base_level = CLAUSE_STACK_SIZE - 1;
+ current_level = 0;
+ new_level = 0;
+} /* end INITIALISE_CLAUSE_STACK */
+
+
+/* SET_CLAUSE_STACK */
+void set_clause_stack(lev, str)
+int lev;
+PSTRWC str;
+{
+ int limit;
+
+ limit = lev;
+ used_clause_stack = maxof(limit, used_clause_stack);
+
+ if (lev < 0) { /* underflow */
+ yyerror("Somethings wrong (set_clause_stack); underflow");
+ limit = 0;
+ }
+ else if (lev >= CLAUSE_STACK_SIZE) { /* overflow */
+ yyerror("Somethings wrong (set_clause_stack): overflow");
+ limit = CLAUSE_STACK_SIZE - 1;
+ }
+ clause_str_stack[limit] = str;
+} /* end SET_CLAUSE_STACK */
+
+
+/* CLOSE_DOC_DIVS Close off prior divisions */
+void close_doc_divs(level)
+int level;
+{
+ int i;
+ int temp_level;
+ int limit;
+
+ myprint("\n");
+ limit = level;
+ if (level < 0) { /* underflow */
+ yyerror("Somethings wrong (close_docs_div); underflow");
+ limit = 0;
+ }
+ else if (level >= CLAUSE_STACK_SIZE) { /* overflow */
+ yyerror("Somethings wrong (close_docs_div): overflow");
+ limit = CLAUSE_STACK_SIZE - 1;
+ }
+ temp_level = limit;
+ if (base_level > limit) {
+ temp_level = base_level;
+ }
+ if (temp_level <= current_level) {
+ for (i = current_level; i >= temp_level; i--) {
+ tag_print(clause_str_stack[i]);
+ }
+ }
+ if (base_level > limit) {
+ base_level = limit;
+ }
+} /* end CLOSE_DOC_DIVS */
+
+
+/* CLOSE_ALL_DIVS closes all open divisions */
+void close_all_divs()
+{
+ close_doc_divs(base_level);
+ initialise_clause_stack();
+} /* end CLOSE_ALL_DIVS */
+
+
+/* CLOSE_DOWN finish off the document */
+void close_down(s)
+STRING s;
+{
+ PSENTRY sym = get_mode_sym(pos_edoc);
+
+ /* this is the original code
+ close_all_divs();
+ myprint("\n");
+ tag_print(get_t(sym));
+ tag_print(get_et(sym));
+ printf("\n");
+ write_stats(s);
+ */
+
+ myprint("\n");
+ tag_print(get_t(sym));
+ close_all_divs();
+ tag_print(get_et(sym));
+ printf("\n");
+ write_stats(s);
+
+} /* end CLOSE_DOWN */
+
+
+/* SET_LIST_STACK sets up list stack */
+/* 6/96 changed from STRING to PSTRWC */
+void set_list_stack(istart, iend, pstart, pend)
+PSTRWC istart; /* start tag for item */
+PSTRWC iend; /* end tag for item */
+PSTRWC pstart; /* start tag for parameter */
+PSTRWC pend; /* end tag for parameter */
+{
+ if (list_level < -1) { /* underflow */
+ yyerror("Somethings wrong (set_list_stack): underflow");
+ list_level = -1;
+ }
+ else if (list_level >= (LIST_STACK_SIZE - 1)) { /* overflow */
+ yyerror("Somethings wrong (set_list_stack): overflow");
+ list_level = LIST_STACK_SIZE - 2;
+ }
+ list_level++;
+ used_list_stack = maxof(list_level, used_list_stack);
+ num_items[list_level] = 0;
+ list_item_start[list_level] = istart;
+ list_str_stack[list_level] = iend;
+ list_descitemp_start[list_level] = pstart;
+ list_descitemp_end[list_level] = pend;
+} /* end SET_LIST_STACK */
+
+
+/* PRINT_END_ITEM closes off an item */
+void print_end_item()
+{
+ if (list_level < 0) { /* underflow */
+ yyerror("Somethings wrong (print_end_item): underflow");
+ }
+ else if (list_level >= LIST_STACK_SIZE) { /* overflow */
+ yyerror("Somethings wrong (print_end_item): overflow");
+ }
+ else if (num_items[list_level] > 0) { /* close off last item */
+ tag_print(list_str_stack[list_level]);
+ }
+} /* end PRINT_END_ITEM */
+
+
+/* CATL concatenates S to line buffer */
+void catl(n,s)
+int n; /* no of chars in s */
+char *s;
+{
+ linlen = linlen + n; /* current chars to be in linebuf */
+ if (linlen >= MAX_LINE) { /* linebuf will overflow */
+ warning("A very long line. Internal buffer size exceeded");
+ linebuf[0] = SNUL;
+ linlen = n;
+ }
+ strcat(linebuf, s);
+} /* end CATL */
+
+
+/* DO_NEWLINE does stuff at start of each line */
+void do_newline()
+{
+ lineno++;
+ linlen = 0;
+ linebuf[0] = SNUL;
+ if ((lineno % EVERY_N_LINES) == 0) {
+ line_count++;
+ fprintf(stdout, "[%d] ", line_count);
+ fflush(stdout);
+ if ((line_count % 10) == 0) {
+ fprintf(stdout, "\n");
+ }
+ }
+} /* end DO_NEWLINE */
+
+
+/*-----------------------------------------------------------------------*/
+/* void read_table() */
+/* keywords are: */
+/* COMMENT= anything */
+/* C= comment (added 6/96) */
+/* ESCAPE_CHAR= single char (default \ ) */
+/* NEWLINE_CHAR= single char (default n ) */
+/* HORIZONTAL_TAB_CHAR= single char (default t ) */
+/* VERTICAL_TAB_CHAR= single char (default v ) */
+/* BACKSPACE_CHAR= single char (default b ) */
+/* CARRIAGE_RETURN_CHAR= single char (default r ) */
+/* FORMFEED_CHAR= single char (default f ) */
+/* AUDIBLE_ALERT_CHAR= single char (default a ) */
+/* HEX_CHAR= single char (default x ) */
+/* INCLUDE= file name for inclusion */
+/* TYPE= command type keyword */
+/* NAME= LaTeX command or environment name */
+/* START_TAG= " print this before NAME " */
+/* END_TAG= " print this after all processing " */
+/* PRINT_CONTROL= NO_PRINT (or maybe extended later) */
+/* OPT_PARAM= FIRST or LAST (position of optional param) */
+/* START_OPT= " print this before optional param " */
+/* END_OPT= " print this after optional param */
+/* PRINT_OPT= NO_PRINT ing of the parameter text */
+/* REQPARAMS= 0 through 9 (number of required params) */
+/* START_TAG_1= " print before req. param 1 " */
+/* END_TAG_1= " print after req. param 1 " */
+/* PRINT_P1= NO_PRINT ing of the parameter text */
+/* ... */
+/* START_TAG_9= " print before req. param 9 " */
+/* END_TAG_9= " print after req. param 9 " */
+/* PRINT_P9= NO_PRINT ing of the parameter text */
+/* SECTIONING_LEVEL keyword describing the level */
+/* START_ITEM= " print before \item " */
+/* END_ITEM= " print after processing \item text " */
+/* START_ITEM_PARAM= " print before \item opt. param " */
+/* END_ITEM_PARAM= " print after \item opt. param " */
+/* CONTINUE= " continuation of previous string " */
+/* SPECIAL_TOKEN= integer (pre-defined as a yac token) */
+/* END_TYPE must be last entry to close off TYPE= */
+/* END_CTFILE= anything, ends file */
+/* OTHER_SOURCE= o/p printing (added 6/96) */
+/* PC_AT_START= (added 6/96) */
+/* PC_AT_END= (added 6/96) */
+/*-----------------------------------------------------------------------*/
+/* READ_TABLE reads command table */
+void read_table()
+{
+
+ char line[MAX_TABLE_LINE];
+ char code_name[MAX_TABLE_LINE];
+ char noquotes[MAX_TABLE_LINE];
+ int num_names;
+ int num;
+ PSENTRY entry;
+ PSENTRY last_entry = NULL; /* last command entry */
+ char str[MAX_TABLE_LINE];
+ int last_string = CONT_UNKNOWN_ENUM;
+ FILE *filtabin; /* input file */
+ char *cin;
+ int endit;
+ PSTRWC lastp = NULL; /* last print control */
+ int key; /* command keyword */
+ int numbuf;
+
+ filtabin = get_ct_filep(); /* get root file */
+
+ for (;;) { /* loop over all files */
+ line[0] = SNUL;
+ cin = fgets(line, MAX_TABLE_LINE, filtabin); /* read a line */
+ used_table_line = maxof(strlen(line), used_table_line);
+ incr_ct_linenum();
+ if (TDEBUG) {
+ tdebug_tline(line);
+ }
+ if (feof(filtabin) != 0) { /* end of this file */
+ if (TDEBUG) {
+ tdebug_str_int("Calling RESET_CT_FILE with ct_file_num=", ct_file_num);
+ }
+ endit = reset_ct_file();
+ if (TDEBUG) {
+ tdebug_str_int("Called RESET_CT_FILE and ct_file_num now=", ct_file_num);
+ tdebug_str_int(" END OF FILE, endit = (reset_ct_file) = ", endit);
+ }
+ filtabin = get_ct_filep();
+ if (endit == EOF) { /* end of all files */
+ break;
+ }
+ continue; /* skip rest of this line processing */
+ }
+ strcpy(table_line, line);
+ /* get first name on line */
+ num_names = sscanf(line, "%s", code_name);
+ if (num_names <= 0) { /* blank line */
+ continue; /* ignore */
+ }
+ strtouc(code_name); /* convert to upper case for comparisons */
+ key = key_to_int(code_name);
+ switch (key) {
+ case END_CTFILE : { /* end of file */
+ if (TDEBUG) {
+ tdebug_str("END_CTFILE=\n");
+ }
+ if (TDEBUG) {
+ tdebug_str_int("Calling RESET_CT_FILE with ct_file_num=", ct_file_num);
+ }
+ endit = reset_ct_file();
+ if (TDEBUG) {
+ tdebug_str_int("Called RESET_CT_FILE and ct_file_num now=", ct_file_num);
+ tdebug_str_int(" END OF FILE, endit = (reset_ct_file) = ", endit);
+ }
+ filtabin = get_ct_filep();
+ if (endit == EOF) { /* end of all files */
+ return;
+ }
+ continue; /* skip rest of this line processing */
+ }
+ case CA :
+ case COMMENT : { /* comment line */
+ if (TDEBUG) {
+ tdebug_str("C=\n");
+ }
+ continue; /* ignore */
+ }
+ case INCLUDE : { /* file inclusion */
+ if (TDEBUG) {
+ tdebug_str("INCLUDE= ");
+ }
+ last_string = CONT_UNKNOWN_ENUM;
+ delete_to_chars("=:", line);
+ sscanf(line, "%s", str );
+ if (TDEBUG) {
+ tdebug_str(str);
+ tdebug_str("\n");
+ tdebug_str_int("Calling SET_CT_FILE with ct_file_num=", ct_file_num);
+ }
+ set_ct_file(str);
+ if (TDEBUG) {
+ tdebug_str_int(" SET_CT_FILE changed ct_file_num to ", ct_file_num);
+ }
+ filtabin = get_ct_filep();
+ break;
+ }
+ case TYPE : { /* start of a record */
+ last_string = CONT_UNKNOWN_ENUM;
+ entry = new_table_entry();
+ last_entry = entry;
+ if (num_table_entries >= MAX_TABLE_ENTRIES) {
+ table_error("FATAL ERROR: Too many table entries");
+ exit(0);
+ }
+ symbol_table[num_table_entries] = entry;
+ num_table_entries++;
+ delete_to_chars("=:", line);
+ sscanf(line, "%s", str);
+ strtouc(str);
+ if (TDEBUG) {
+ sprintf(errstr, "%s %s\n", code_name, str);
+ tdebug_str(errstr);
+ }
+ entry->kind = ctype_to_int(str);
+ break;
+ }
+ case END_TYPE : { /* end of a record */
+ if (TDEBUG) {
+ sprintf(errstr, "%s\n", code_name );
+ tdebug_str(errstr);
+ }
+ lastp = NULL;
+ last_string = CONT_UNKNOWN_ENUM;
+ complete_entry(last_entry);
+ break;
+ }
+ case NAMEK : { /* process NAME= */
+ last_string = CONT_UNKNOWN_ENUM;
+ delete_to_chars("=:", line);
+ sscanf(line, "%s", str);
+ entry->command = strsave(str);
+ if (TDEBUG) {
+ sprintf(errstr, "%s %s\n", code_name, entry->command);
+ tdebug_str(errstr);
+ }
+ break;
+ }
+ case PRINT_CONTROL : { /* process PRINT_CONTROL= */
+ last_string = CONT_UNKNOWN_ENUM;
+ delete_to_chars("=:", line);
+ /* changed 6/96 */
+ entry->printing = parse_pc(line);
+ if (TDEBUG) {
+ sprintf(errstr, "%s %s\n", code_name, line);
+ tdebug_str(errstr);
+ }
+ break;
+ }
+ case START_TAG : { /* process START_TAG= */
+ last_string = CONT_TAG;
+ delete_quotes(line,noquotes);
+ if (TDEBUG) {
+ sprintf(errstr, "%s %s\n", code_name, noquotes);
+ tdebug_str(errstr);
+ }
+ /* 6/96 this, and all like it changed */
+ lastp = create_print_tag(strsave(noquotes));
+ entry->command_t = lastp;
+ break;
+ }
+ case END_TAG : { /* process END_TAG= */
+ last_string = CONT_TAG;
+ delete_quotes(line,noquotes);
+ if (TDEBUG) {
+ sprintf(errstr, "%s %s\n", code_name, noquotes);
+ tdebug_str(errstr);
+ }
+ lastp = create_print_tag(strsave(noquotes));
+ entry->command_et = lastp;
+ break;
+ }
+ case OPT_PARAM : { /* process OPT_PARAM= */
+ last_string = CONT_UNKNOWN_ENUM;
+ delete_to_chars("=:", line);
+ sscanf(line, "%s", str);
+ strtouc(str);
+ if (TDEBUG) {
+ sprintf(errstr, "%s %s\n", code_name, str);
+ tdebug_str(errstr);
+ }
+ entry->opt_param_pos = pos_to_int(str);
+ break;
+ }
+ case PRINT_OPT : { /* process PRINT_OPT= */
+ last_string = CONT_UNKNOWN_ENUM;
+ delete_to_chars("=:", line);
+ /* changed 6/96 */
+ entry->print_opt[1] = parse_pc(line);
+ if (TDEBUG) {
+ sprintf(errstr, "%s\n", code_name);
+ tdebug_str(errstr);
+ }
+ break;
+ }
+ case START_OPT : { /* process START_OPT= */
+ last_string = CONT_TAG;
+ delete_quotes(line,noquotes);
+ if (TDEBUG) {
+ sprintf(errstr, "%s %s\n", code_name, noquotes);
+ tdebug_str(errstr);
+ }
+ lastp = create_print_tag(strsave(noquotes));
+ entry->opt_param_t = lastp;
+ break;
+ }
+ case END_OPT : { /* process END_OPT= */
+ last_string = CONT_TAG;
+ delete_quotes(line,noquotes);
+ if (TDEBUG) {
+ sprintf(errstr, "%s %s\n", code_name, noquotes);
+ tdebug_str(errstr);
+ }
+ lastp = create_print_tag(strsave(noquotes));
+ entry->opt_param_et = lastp;
+ break;
+ }
+ case REQPARAMS : { /* process REQPARAMS= */
+ last_string = CONT_UNKNOWN_ENUM;
+ delete_to_chars("=:", line);
+ sscanf(line, "%d", &num);
+ if (TDEBUG) {
+ sprintf(errstr, "%s %d\n", code_name, num);
+ tdebug_str(errstr);
+ }
+ if (num >= 0 && num <= 9 ) {
+ entry->numparams = num;
+ }
+ else {
+ table_error("REQPARAMS out of range (0-9)");
+ }
+ break;
+ }
+ case START_TAG_1 : { /* process START_TAG_1= */
+ last_string = CONT_TAG;
+ delete_quotes(line,noquotes);
+ if (TDEBUG) {
+ sprintf(errstr, "%s %s\n", code_name, noquotes);
+ tdebug_str(errstr);
+ }
+ lastp = create_print_tag(strsave(noquotes));
+ entry->param_t[0] = lastp;
+ break;
+ }
+ case END_TAG_1 : { /* process END_TAG_1= */
+ last_string = CONT_TAG;
+ delete_quotes(line,noquotes);
+ if (TDEBUG) {
+ sprintf(errstr, "%s %s\n", code_name, noquotes);
+ tdebug_str(errstr);
+ }
+ lastp = create_print_tag(strsave(noquotes));
+ entry->param_et[0] = lastp;
+ break;
+ }
+ case START_TAG_2 : { /* process START_TAG_2= */
+ last_string = CONT_TAG;
+ delete_quotes(line,noquotes);
+ if (TDEBUG) {
+ sprintf(errstr, "%s %s\n", code_name, noquotes);
+ tdebug_str(errstr);
+ }
+ lastp = create_print_tag(strsave(noquotes));
+ entry->param_t[1] =lastp;
+ break;
+ }
+ case END_TAG_2 : { /* process END_TAG_2= */
+ last_string = CONT_TAG;
+ delete_quotes(line,noquotes);
+ if (TDEBUG) {
+ sprintf(errstr, "%s %s\n", code_name, noquotes);
+ tdebug_str(errstr);
+ }
+ lastp = create_print_tag(strsave(noquotes));
+ entry->param_et[1] = lastp;
+ break;
+ }
+ case START_TAG_3 : { /* process START_TAG_3= */
+ last_string = CONT_TAG;
+ delete_quotes(line,noquotes);
+ if (TDEBUG) {
+ sprintf(errstr, "%s %s\n", code_name, noquotes);
+ tdebug_str(errstr);
+ }
+ lastp = create_print_tag(strsave(noquotes));
+ entry->param_t[2] = lastp;
+ break;
+ }
+ case END_TAG_3 : { /* process END_TAG_3= */
+ last_string = CONT_TAG;
+ delete_quotes(line,noquotes);
+ if (TDEBUG) {
+ sprintf(errstr, "%s %s\n", code_name, noquotes);
+ tdebug_str(errstr);
+ }
+ lastp = create_print_tag(strsave(noquotes));
+ entry->param_et[2] = lastp;
+ break;
+ }
+ case START_TAG_4 : { /* process START_TAG_4= */
+ last_string = CONT_TAG;
+ delete_quotes(line,noquotes);
+ if (TDEBUG) {
+ sprintf(errstr, "%s %s\n", code_name, noquotes);
+ tdebug_str(errstr);
+ }
+ lastp = create_print_tag(strsave(noquotes));
+ entry->param_t[3] = lastp;
+ break;
+ }
+ case END_TAG_4 : { /* process END_TAG_4= */
+ last_string = CONT_TAG;
+ delete_quotes(line,noquotes);
+ if (TDEBUG) {
+ sprintf(errstr, "%s %s\n", code_name, noquotes);
+ tdebug_str(errstr);
+ }
+ lastp = create_print_tag(strsave(noquotes));
+ entry->param_et[3] = lastp;
+ break;
+ }
+ case START_TAG_5 : { /* process START_TAG_5= */
+ last_string = CONT_TAG;
+ delete_quotes(line,noquotes);
+ if (TDEBUG) {
+ sprintf(errstr, "%s %s\n", code_name, noquotes);
+ tdebug_str(errstr);
+ }
+ lastp = create_print_tag(strsave(noquotes));
+ entry->param_t[4] = lastp;
+ break;
+ }
+ case END_TAG_5 : { /* process END_TAG_5= */
+ last_string = CONT_TAG;
+ delete_quotes(line,noquotes);
+ if (TDEBUG) {
+ sprintf(errstr, "%s %s\n", code_name, noquotes);
+ tdebug_str(errstr);
+ }
+ lastp = create_print_tag(strsave(noquotes));
+ entry->param_et[4] = lastp;
+ break;
+ }
+ case START_TAG_6 : { /* process START_TAG_6= */
+ last_string = CONT_TAG;
+ delete_quotes(line,noquotes);
+ if (TDEBUG) {
+ sprintf(errstr, "%s %s\n", code_name, noquotes);
+ tdebug_str(errstr);
+ }
+ lastp = create_print_tag(strsave(noquotes));
+ entry->param_t[5] = lastp;
+ break;
+ }
+ case END_TAG_6 : { /* process END_TAG_6= */
+ last_string = CONT_TAG;
+ delete_quotes(line,noquotes);
+ if (TDEBUG) {
+ sprintf(errstr, "%s %s\n", code_name, noquotes);
+ tdebug_str(errstr);
+ }
+ lastp = create_print_tag(strsave(noquotes));
+ entry->param_et[5] = lastp;
+ break;
+ }
+ case START_TAG_7 : { /* process START_TAG_7= */
+ last_string = CONT_TAG;
+ delete_quotes(line,noquotes);
+ if (TDEBUG) {
+ sprintf(errstr, "%s %s\n", code_name, noquotes);
+ tdebug_str(errstr);
+ }
+ lastp = create_print_tag(strsave(noquotes));
+ entry->param_t[6] = lastp;
+ break;
+ }
+ case END_TAG_7 : { /* process END_TAG_7= */
+ last_string = CONT_TAG;
+ delete_quotes(line,noquotes);
+ if (TDEBUG) {
+ sprintf(errstr, "%s %s\n", code_name, noquotes);
+ tdebug_str(errstr);
+ }
+ lastp = create_print_tag(strsave(noquotes));
+ entry->param_et[6] = lastp;
+ break;
+ }
+ case START_TAG_8 : { /* process START_TAG_8= */
+ last_string = CONT_TAG;
+ delete_quotes(line,noquotes);
+ if (TDEBUG) {
+ sprintf(errstr, "%s %s\n", code_name, noquotes);
+ tdebug_str(errstr);
+ }
+ lastp = create_print_tag(strsave(noquotes));
+ entry->param_t[7] = lastp;
+ break;
+ }
+ case END_TAG_8 : { /* process END_TAG_8= */
+ last_string = CONT_TAG;
+ delete_quotes(line,noquotes);
+ if (TDEBUG) {
+ sprintf(errstr, "%s %s\n", code_name, noquotes);
+ tdebug_str(errstr);
+ }
+ lastp = create_print_tag(strsave(noquotes));
+ entry->param_et[7] = lastp;
+ break;
+ }
+ case START_TAG_9 : { /* process START_TAG_9= */
+ last_string = CONT_TAG;
+ delete_quotes(line,noquotes);
+ if (TDEBUG) {
+ sprintf(errstr, "%s %s\n", code_name, noquotes);
+ tdebug_str(errstr);
+ }
+ lastp = create_print_tag(strsave(noquotes));
+ entry->param_t[8] = lastp;
+ break;
+ }
+ case END_TAG_9 : { /* process END_TAG_9= */
+ last_string = CONT_TAG;
+ delete_quotes(line,noquotes);
+ if (TDEBUG) {
+ sprintf(errstr, "%s %s\n", code_name, noquotes);
+ tdebug_str(errstr);
+ }
+ lastp = create_print_tag(strsave(noquotes));
+ entry->param_et[8] = lastp;
+ break;
+ }
+ case PRINT_P1 : { /* process PRINT_P1= */
+ last_string = CONT_UNKNOWN_ENUM;
+ delete_to_chars("=:", line);
+ /* changed 6/96 */
+ entry->print_param[0] = parse_pc(line);
+ if (TDEBUG) {
+ sprintf(errstr, "%s %s\n", code_name, line);
+ tdebug_str(errstr);
+ }
+ break;
+ }
+ case PRINT_P2 : { /* process PRINT_P2= */
+ last_string = CONT_UNKNOWN_ENUM;
+ delete_to_chars("=:", line);
+ /* changed 6/96 */
+ entry->print_param[1] = parse_pc(line);
+ if (TDEBUG) {
+ sprintf(errstr, "%s %s\n", code_name, line);
+ tdebug_str(errstr);
+ }
+ break;
+ }
+ case PRINT_P3 : { /* process PRINT_P3= */
+ last_string = CONT_UNKNOWN_ENUM;
+ delete_to_chars("=:", line);
+ /* changed 6/96 */
+ entry->print_param[2] = parse_pc(line);
+ if (TDEBUG) {
+ sprintf(errstr, "%s %s\n", code_name, line);
+ tdebug_str(errstr);
+ }
+ break;
+ }
+ case PRINT_P4 : { /* process PRINT_P4= */
+ last_string = CONT_UNKNOWN_ENUM;
+ delete_to_chars("=:", line);
+ /* changed 6/96 */
+ entry->print_param[3] = parse_pc(line);
+ if (TDEBUG) {
+ sprintf(errstr, "%s %s\n", code_name, line);
+ tdebug_str(errstr);
+ }
+ break;
+ }
+ case PRINT_P5 : { /* process PRINT_P5= */
+ last_string = CONT_UNKNOWN_ENUM;
+ delete_to_chars("=:", line);
+ /* changed 6/96 */
+ entry->print_param[4] = parse_pc(line);
+ if (TDEBUG) {
+ sprintf(errstr, "%s %s\n", code_name, line);
+ tdebug_str(errstr);
+ }
+ break;
+ }
+ case PRINT_P6 : { /* process PRINT_P6= */
+ last_string = CONT_UNKNOWN_ENUM;
+ delete_to_chars("=:", line);
+ /* changed 6/96 */
+ entry->print_param[5] = parse_pc(line);
+ if (TDEBUG) {
+ sprintf(errstr, "%s %s\n", code_name, line);
+ tdebug_str(errstr);
+ }
+ break;
+ }
+ case PRINT_P7 : { /* process PRINT_P7= */
+ last_string = CONT_UNKNOWN_ENUM;
+ delete_to_chars("=:", line);
+ /* changed 6/96 */
+ entry->print_param[6] = parse_pc(line);
+ if (TDEBUG) {
+ sprintf(errstr, "%s %s\n", code_name, line);
+ tdebug_str(errstr);
+ }
+ break;
+ }
+ case PRINT_P8 : { /* process PRINT_P8= */
+ last_string = CONT_UNKNOWN_ENUM;
+ delete_to_chars("=:", line);
+ /* changed 6/96 */
+ entry->print_param[7] = parse_pc(line);
+ if (TDEBUG) {
+ sprintf(errstr, "%s %s\n", code_name, line);
+ tdebug_str(errstr);
+ }
+ break;
+ }
+ case PRINT_P9 : { /* process PRINT_P9= */
+ last_string = CONT_UNKNOWN_ENUM;
+ delete_to_chars("=:", line);
+ /* changed 6/96 */
+ entry->print_param[8] = parse_pc(line);
+ if (TDEBUG) {
+ sprintf(errstr, "%s %s\n", code_name, line);
+ tdebug_str(errstr);
+ }
+ break;
+ }
+ case START_ITEM : { /* process START_ITEM= */
+ last_string = CONT_TAG;
+ delete_quotes(line,noquotes);
+ if (TDEBUG) {
+ sprintf(errstr, "%s %s\n", code_name, noquotes);
+ tdebug_str(errstr);
+ }
+ lastp = create_print_tag(strsave(noquotes));
+ entry->param_t[7] = lastp;
+ break;
+ }
+ case END_ITEM : { /* process END_ITEM= */
+ last_string = CONT_TAG;
+ delete_quotes(line,noquotes);
+ if (TDEBUG) {
+ sprintf(errstr, "%s %s\n", code_name, noquotes);
+ tdebug_str(errstr);
+ }
+ lastp = create_print_tag(strsave(noquotes));
+ entry->param_et[7] = lastp;
+ break;
+ }
+ case START_ITEM_PARAM : { /* process START_ITEM_PARAM= */
+ last_string = CONT_TAG;
+ delete_quotes(line,noquotes);
+ if (TDEBUG) {
+ sprintf(errstr, "%s %s\n", code_name, noquotes);
+ tdebug_str(errstr);
+ }
+ lastp = create_print_tag(strsave(noquotes));
+ entry->param_t[8] = lastp;
+ break;
+ }
+ case END_ITEM_PARAM : { /* process END_ITEM_PARAM= */
+ last_string = CONT_TAG;
+ delete_quotes(line,noquotes);
+ if (TDEBUG) {
+ sprintf(errstr, "%s %s\n", code_name, noquotes);
+ tdebug_str(errstr);
+ }
+ lastp = create_print_tag(strsave(noquotes));
+ entry->param_et[8] = lastp;
+ break;
+ }
+
+ case CONTINUE : /* process CONTINUE= */
+ case STRINGG : { /* process STRING= */
+ if (last_string == CONT_UNKNOWN_ENUM) {
+ sprintf(errstr, "Can not use %s at this point", code_name);
+ table_error(errstr);
+ }
+ else {
+ delete_quotes(line,noquotes);
+ if (TDEBUG) {
+ sprintf(errstr, "%s %s\n", code_name, noquotes);
+ tdebug_str(errstr);
+ }
+ lastp = append_to_write(lastp, create_print_source(strsave(noquotes)));
+ set_pc_cmd(lastp, STRINGG);
+ }
+ break;
+ }
+
+ case SOURCE : { /* 6/96 process SOURCE= */
+ if (last_string == CONT_UNKNOWN_ENUM) {
+ sprintf(errstr, "Can not use %s at this point", code_name);
+ table_error(errstr);
+ }
+ else {
+ delete_to_chars("=:", line);
+ if (TDEBUG) {
+ sprintf(errstr, "%s %s\n", code_name, line);
+ tdebug_str(errstr);
+ }
+ lastp = append_to_write(lastp, parse_pc(line));
+ set_pc_cmd(lastp, SOURCE);
+ }
+ break;
+ }
+
+ case PC_AT_START : { /* 6/96 process PC_AT_START= */
+ last_string = CONT_UNKNOWN_ENUM;
+ delete_to_chars("=:", line);
+ entry->start_pc = parse_pc(line);
+ if (TDEBUG) {
+ sprintf(errstr, "%s %s\n", code_name, line);
+ tdebug_str(errstr);
+ }
+ break;
+ }
+
+ case PC_AT_END : { /* 6/96 process PC_AT_END= */
+ if (TDEBUG) {
+ tdebug_str("PC_AT_END=\n");
+ }
+ last_string = CONT_UNKNOWN_ENUM;
+ delete_to_chars("=:", line);
+ entry->end_pc = parse_pc(line);
+ if (TDEBUG) {
+ sprintf(errstr, "%s %s\n", code_name, line);
+ tdebug_str(errstr);
+ }
+ break;
+ }
+
+ case SECTIONING_LEVEL : { /* process SECTIONING_LEVEL= */
+ last_string = CONT_UNKNOWN_ENUM;
+ delete_to_chars("=:", line);
+ sscanf(line, "%s", str);
+ strtouc(str);
+ if (TDEBUG) {
+ sprintf(errstr, "%s %s\n", code_name, str);
+ tdebug_str(errstr);
+ }
+ entry->sectioning_level = level_to_int(str);
+ break;
+ }
+
+ case RESET_SYSBUF : { /* 6/96 process RESET_SYSBUF= */
+ if (TDEBUG) {
+ sprintf(errstr, "%s\n", code_name);
+ tdebug_str(errstr);
+ }
+ if (last_string == CONT_UNKNOWN_ENUM) {
+ sprintf(errstr, "Can not use %s at this point", code_name);
+ table_error(errstr);
+ }
+ else { /* takes no value */
+ lastp = append_to_write(lastp, create_st_rwc());
+ set_pc_cmd(lastp, RESET_SYSBUF);
+ }
+ break;
+ }
+
+ case RESET_BUFFER : { /* 6/96 process RESET_BUFFER */
+ if (last_string == CONT_UNKNOWN_ENUM) {
+ sprintf(errstr, "Can not use %s at this point", code_name);
+ table_error(errstr);
+ }
+ else { /* get buffer number */
+ numbuf = 0;
+ sscanf(line, "%s %d", str, &numbuf);
+ if (TDEBUG) {
+ sprintf(errstr, "%s %d\n", code_name, numbuf);
+ tdebug_str(errstr);
+ }
+ lastp = append_to_write(lastp, create_st_rwc());
+ set_pc_cmd(lastp, RESET_BUFFER);
+ set_pc_enum(lastp, BUFFER);
+ set_pcdata_num(lastp, chk_bufnum(numbuf));
+ }
+ break;
+ }
+
+ case RESET_FILE : { /* 6/96 process RESET_FILE */
+ if (last_string == CONT_UNKNOWN_ENUM) {
+ sprintf(errstr, "Can not use %s at this point", code_name);
+ table_error(errstr);
+ }
+ else { /* get file name */
+ delete_to_chars("=:", line);
+ sscanf(line, "%s", str);
+ if (TDEBUG) {
+ sprintf(errstr, "%s %s\n", code_name, str);
+ tdebug_str(errstr);
+ }
+ lastp = append_to_write(lastp, create_st_rwc());
+ set_pc_cmd(lastp, RESET_FILE);
+ set_pc_enum(lastp, FFILE);
+ set_pcdata_name(lastp, chk_ufname(str));
+ }
+ break;
+ }
+
+ case SWITCH_BACK : { /* 11/96 process SWITCH_BACK */
+ if (TDEBUG) {
+ sprintf(errstr, "%s\n", code_name);
+ tdebug_str(errstr);
+ }
+ if (last_string == CONT_UNKNOWN_ENUM) {
+ sprintf(errstr, "Can not use %s at this point", code_name);
+ table_error(errstr);
+ }
+ else { /* takes no value */
+ lastp = append_to_write(lastp, create_st_rwc());
+ set_pc_cmd(lastp, SWITCH_BACK);
+ set_pc_enum(lastp, RESET);
+ }
+ break;
+ }
+
+ case SWITCH_TO_BUFFER : { /* 11/96 process SWITCH_TO_BUFFER */
+ if (last_string == CONT_UNKNOWN_ENUM) {
+ sprintf(errstr, "Can not use %s at this point", code_name);
+ table_error(errstr);
+ }
+ else { /* get buffer number */
+ numbuf = 0;
+ sscanf(line, "%s %d", str, &numbuf);
+ if (TDEBUG) {
+ sprintf(errstr, "%s %d\n", code_name, numbuf);
+ tdebug_str(errstr);
+ }
+ lastp = append_to_write(lastp, create_st_rwc());
+ set_pc_cmd(lastp, SWITCH_TO_BUFFER);
+ set_pc_enum(lastp, TO_BUFFER);
+ set_pcdata_num(lastp, chk_bufnum(numbuf));
+ }
+ break;
+ }
+
+ case SWITCH_TO_FILE : { /* 11/96 process SWITCH_TO_FILE */
+ if (last_string == CONT_UNKNOWN_ENUM) {
+ sprintf(errstr, "Can not use %s at this point", code_name);
+ table_error(errstr);
+ }
+ else { /* get file name */
+ delete_to_chars("=:", line);
+ sscanf(line, "%s", str);
+ if (TDEBUG) {
+ sprintf(errstr, "%s %s\n", code_name, str);
+ tdebug_str(errstr);
+ }
+ lastp = append_to_write(lastp, create_st_rwc());
+ set_pc_cmd(lastp, SWITCH_TO_FILE);
+ set_pc_enum(lastp, TO_FILE);
+ set_pcdata_name(lastp, chk_ufname(str));
+ }
+ break;
+ }
+
+ case SWITCH_TO_SYSBUF : { /* 11/96 process SWITCH_TO_SYSBUF */
+ if (TDEBUG) {
+ sprintf(errstr, "%s\n", code_name);
+ tdebug_str(errstr);
+ }
+ if (last_string == CONT_UNKNOWN_ENUM) {
+ sprintf(errstr, "Can not use %s at this point", code_name);
+ table_error(errstr);
+ }
+ else { /* takes no value */
+ lastp = append_to_write(lastp, create_st_rwc());
+ set_pc_cmd(lastp, SWITCH_TO_SYSBUF);
+ set_pc_enum(lastp, TO_SYSBUF);
+ }
+ break;
+ }
+
+ case SET_MODE : { /* 6/96 process SET_MODE */
+ if (last_string == CONT_UNKNOWN_ENUM) {
+ sprintf(errstr, "Can not use %s at this point", code_name);
+ table_error(errstr);
+ }
+ else { /* get mode name */
+ delete_to_chars("=:", line);
+ sscanf(line, "%s", str);
+ if (TDEBUG) {
+ sprintf(errstr, "%s %s\n", code_name, str);
+ tdebug_str(errstr);
+ }
+ numbuf = add_mode(str);
+ lastp = append_to_write(lastp, create_st_rwc());
+ set_pc_cmd(lastp, SET_MODE);
+ set_pc_enum(lastp, MODE);
+ set_pcdata_num(lastp, numbuf);
+ }
+ break;
+ }
+
+ case RESET_MODE : { /* 6/96 process RESET_MODE */
+ if (TDEBUG) {
+ sprintf(errstr, "%s\n", code_name);
+ tdebug_str(errstr);
+ }
+ if (last_string == CONT_UNKNOWN_ENUM) {
+ sprintf(errstr, "Can not use %s at this point", code_name);
+ table_error(errstr);
+ }
+ else { /* takes no value */
+ lastp = append_to_write(lastp, create_st_rwc());
+ set_pc_cmd(lastp, RESET_MODE);
+ }
+ break;
+ }
+
+ case IN_MODE : { /* 6/96 process IN_MODE */
+ complete_entry(last_entry); /* complete prior defn */
+ delete_to_chars("=:", line);
+ sscanf(line, "%s", str);
+ if (TDEBUG) {
+ sprintf(errstr, "%s %s\n", code_name, str);
+ tdebug_str(errstr);
+ }
+ entry = new_table_entry(); /* create new symbol entry */
+ add_to_modelist(last_entry, entry); /* add it to the list of modes */
+ set_mode_name(str, entry); /* set the mode name in the new entry */
+ last_entry = entry; /* update last entry pointer */
+ break;
+ }
+
+ case END_MODE : { /* 6/96 process END_MODE */
+ if (TDEBUG) {
+ sprintf(errstr, "%s\n", code_name);
+ tdebug_str(errstr);
+ }
+ /* PERHAPS DO STUFF HERE LATER */
+ break;
+ }
+
+
+ case SPECIAL_TOKEN : { /* process SPECIAL_TOKEN= */
+ last_string = CONT_UNKNOWN_ENUM;
+ delete_to_chars("=:", line);
+ sscanf(line, "%d", &num);
+ if (TDEBUG) {
+ sprintf(errstr, "%s %d\n", code_name, num);
+ tdebug_str(errstr);
+ }
+ if (num < MIN_GRAMM_SPECIAL) {
+ table_error("SPECIAL_TOKEN value too small");
+ tdebug_str_int("Value sould be at least",MIN_GRAMM_SPECIAL);
+ }
+ entry->special_token = num;
+ break;
+ }
+
+
+ case ESCAPE_CHAR : { /* escape char */
+ if (TDEBUG) {
+ tdebug_str("ESCAPE_CHAR= ");
+ }
+ last_string = CONT_UNKNOWN_ENUM;
+ delete_to_chars("=:", line);
+ sscanf(line, "%s", str );
+ escape_char = str[0];
+ if (TDEBUG) {
+ tdebug_char(escape_char);
+ }
+ break;
+ }
+ case NEWLINE_CHAR : { /* newline char */
+ if (TDEBUG) {
+ tdebug_str("NEWLINE_CHAR= ");
+ }
+ last_string = CONT_UNKNOWN_ENUM;
+ delete_to_chars("=:", line);
+ sscanf(line, "%s", str );
+ newline_char = str[0];
+ if (TDEBUG) {
+ tdebug_char(newline_char);
+ }
+ break;
+ }
+ case HORIZONTAL_TAB_CHAR : { /* char */
+ if (TDEBUG) {
+ tdebug_str("HORIZONTAL_TAB_CHAR= ");
+ }
+ last_string = CONT_UNKNOWN_ENUM;
+ delete_to_chars("=:", line);
+ sscanf(line, "%s", str);
+ horizontal_tab_char = str[0];
+ if (TDEBUG) {
+ tdebug_char(horizontal_tab_char);
+ }
+ break;
+ }
+ case VERTICAL_TAB_CHAR : { /* char */
+ if (TDEBUG) {
+ tdebug_str("VERTICAL_TAB_CHAR= ");
+ }
+ last_string = CONT_UNKNOWN_ENUM;
+ delete_to_chars("=:", line);
+ sscanf(line, "%s", str);
+ vertical_tab_char = str[0];
+ if (TDEBUG) {
+ tdebug_char(vertical_tab_char);
+ }
+ break;
+ }
+ case BACKSPACE_CHAR : { /* char */
+ if (TDEBUG) {
+ tdebug_str("BACKSPACE_CHAR= ");
+ }
+ last_string = CONT_UNKNOWN_ENUM;
+ delete_to_chars("=:", line);
+ sscanf(line, "%s", str);
+ backspace_char = str[0];
+ if (TDEBUG) {
+ tdebug_char(backspace_char);
+ }
+ break;
+ }
+ case CARRIAGE_RETURN_CHAR : { /* char */
+ if (TDEBUG) {
+ tdebug_str("CARRIAGE_RETURN_CHAR= ");
+ }
+ last_string = CONT_UNKNOWN_ENUM;
+ delete_to_chars("=:", line);
+ sscanf(line, "%s", str);
+ carriage_return_char = str[0];
+ if (TDEBUG) {
+ tdebug_char(carriage_return_char);
+ }
+ break;
+ }
+ case FORMFEED_CHAR : { /* char */
+ if (TDEBUG) {
+ tdebug_str("FORMFEED_CHAR= ");
+ }
+ last_string = CONT_UNKNOWN_ENUM;
+ delete_to_chars("=:", line);
+ sscanf(line, "%s", str);
+ formfeed_char = str[0];
+ if (TDEBUG) {
+ tdebug_char(formfeed_char);
+ }
+ break;
+ }
+ case AUDIBLE_ALERT_CHAR : { /* char */
+ if (TDEBUG) {
+ tdebug_str("AUDIBLE_ALERT_CHAR= ");
+ }
+ last_string = CONT_UNKNOWN_ENUM;
+ delete_to_chars("=:", line);
+ sscanf(line, "%s", str);
+ audible_alert_char = str[0];
+ if (TDEBUG) {
+ tdebug_char(audible_alert_char);
+ }
+ break;
+ }
+ case HEX_CHAR : { /* char */
+ if (TDEBUG) {
+ tdebug_str("HEX_CHAR= ");
+ }
+ last_string = CONT_UNKNOWN_ENUM;
+ delete_to_chars("=:", line);
+ sscanf(line, "%s", str);
+ hex_char = str[0];
+ if (TDEBUG) {
+ tdebug_char(hex_char);
+ }
+ break;
+ }
+
+ case CODE_SETUP : { /* CODE_SETUP added for code interp */
+ last_string = CONT_UNKNOWN_ENUM;
+ if (TDEBUG) {
+ sprintf(errstr, "%s\n", code_name);
+ tdebug_str(errstr);
+ }
+ code_root = code_setup(filtabin); /* parse code and store symtab */
+ break;
+ }
+
+ case CODE : { /* CODE added for code interp */
+ if (last_string == CONT_UNKNOWN_ENUM) {
+ sprintf(errstr, "Can not use %s at this point", code_name);
+ table_error(errstr);
+ }
+ else {
+ if (TDEBUG) {
+ sprintf(errstr, "%s\n", code_name);
+ tdebug_str(errstr);
+ }
+ /* set up new action, parse code and store code segment */
+ lastp = append_to_write(lastp, create_st_rwc());
+ set_pc_code(lastp, code_action(filtabin));
+ }
+ break;
+ }
+
+
+ default : { /* unrecognised */
+ if (TDEBUG) {
+ tdebug_str("UNRECOGNISED CODE NAME\n");
+ }
+ last_string = CONT_UNKNOWN_ENUM;
+ table_error("Unrecognised code");
+ break;
+ }
+ } /* end of switch */
+ } /* end of loop over all files */
+} /* end READ_TABLE */
+
+
+/* NEW_TABLE_ENTRY creates new entry for symbol table */
+/* changed 6/96 */
+struct st_entry *new_table_entry()
+{
+ struct st_entry *p;
+ int i;
+
+
+ if ((p = (struct st_entry *) malloc(sizeof(struct st_entry))) != NULL) {
+ p->command = dont_care_str; /* user defined command string */
+ p->kind = UNKNOWN_CTYPE; /* user defined kind of command */
+ p->parse_kind = UNKNOWN_CTYPE; /* system defined kind of command */
+ p->mode = IERR; /* name of mode for this command */
+ p->next_mode = NULL; /* next mode */
+ p->printing = p_default_print; /* print control (changed 6/96) */
+ p->command_t = NULL; /* start tag: nothing to print */
+ p->command_et = NULL; /* end tag: nothing to print */
+ p->numparams = 0; /* number of params */
+ p->opt_param_pos = NO_OPT_PARAM; /* position of optional param */
+ p->opt_param_t = NULL; /* opt start tag: nothing to print */
+ p->opt_param_et = NULL; /* opt end tag: nothing to print */
+ for (i = 0; i <= 1; i++) {
+ p->popt_param_t[i] = NULL; /* opt param start tags: */
+ p->popt_param_et[i] = NULL; /* opt param end tags: */
+ }
+ p->print_opt[0] = p_no_print; /* print control for opt param */
+ p->print_opt[1] = p_default_print; /* print control for opt param */
+ p->sectioning_level = UNKNOWN_LEVEL; /* sectioning level */
+ for (i = 0; i <= 8; i++) {
+ p->param_t[i] = NULL; /* start param tags: */
+ p->param_et[i] = NULL; /* end param tags: */
+ p->print_param[i] = p_default_print; /* print control for params */
+ }
+ p->start_pc = p_default_print; /* start pc (added 6/96) */
+ p->end_pc = p_default_print; /* end pc (added 6/96) */
+ p->special_token = COMMAND; /* user defined special token */
+ return(p);
+ }
+ yyerror("FATAL ERROR: No memory left for NEW_TABLE_ENTRY");
+ exit(1);
+} /* end NEW_TABLE_ENTRY */
+
+
+/* CREATE_DEF_REQENTRY new default required comm */
+void create_def_reqentry(name)
+int name;
+{
+ struct st_entry *entry;
+
+ entry = new_table_entry();
+ if (num_table_entries >= MAX_TABLE_ENTRIES) {
+ terror_noline("FATAL ERROR: Too many table entries");
+ exit(0);
+ }
+ entry->kind = name;
+ symbol_table[num_table_entries] = entry;
+ complete_table_entry(num_table_entries);
+ num_table_entries++;
+} /* end CREATE_DEF_REQENTRY */
+
+/* COMPLETE_TABLE_ENTRY of an entry in the command table */
+void complete_table_entry(ctpos)
+int ctpos; /* position in comand table */
+{
+ complete_entry(symbol_table[ctpos]);
+ return;
+} /* end COMPLETE_TABLE_ENTRY */
+
+
+/* COMPLETE_ENTRY of a symbol entry */
+void complete_entry(pos)
+PSENTRY pos;
+{
+ int num, user_kind, popt_pos;
+
+ num = pos->numparams;
+ user_kind = pos->kind;
+ popt_pos = pos->opt_param_pos;
+
+ /* do default stuff */
+ pos->parse_kind = user_kind;
+ if (popt_pos != NO_OPT_PARAM) { /* fix up optional parameter stuff */
+ pos->popt_param_t[popt_pos] = pos->opt_param_t;
+ pos->popt_param_et[popt_pos] = pos->opt_param_et;
+ pos->print_opt[0] = pos->print_opt[1];
+ }
+ /* do specific stuff */
+ switch (user_kind) {
+ case COMMAND:
+ case CHAR_COMMAND: /* PRW added 11/99 for version 0.91 */
+ case SPECIAL_COMMAND:
+ case BEGIN_ENV:
+ case SPECIAL_BEGIN_ENV:
+ case END_ENV:
+ case SPECIAL_END_ENV:
+ case BEGIN_LIST_ENV:
+ case SPECIAL_BEGIN_LIST:
+ case END_LIST_ENV:
+ case SPECIAL_END_LIST:
+ case SECTIONING:
+ case SPECIAL_SECTIONING:
+ case BEGIN_VENV:
+ case END_VENV:
+ case VCOMMAND: {
+ if ((popt_pos == LAST) || (popt_pos == FIRST && num == 0)) {
+ pos->parse_kind = command_opt_types[num];
+ }
+ else {
+ pos->parse_kind = command_types[num];
+ }
+ break;
+ }
+/* added 10/95 for TEX_CHAR taking parameters */
+/* If parameters are specified, treat it like a command */
+ case TEX_CHAR: {
+ if ((popt_pos == LAST) || (popt_pos == FIRST && num == 0)) {
+ pos->parse_kind = command_opt_types[num];
+ }
+ else if (num > 0) {
+ pos->parse_kind = command_types[num];
+ }
+ break;
+ }
+/* end of 10/95 TEX_CHAR addition */
+ case BEGIN_PICTURE_CC: {
+ pos->numparams = 2;
+ break;
+ }
+ case END_PICTURE: {
+ pos->numparams = 0;
+ break;
+ }
+ case PICTURE_CCPP: {
+ pos->numparams = 4;
+ break;
+ }
+ case PICTURE_CO: {
+ pos->numparams = 2;
+ break;
+ }
+ case PICTURE_COP: {
+ pos->numparams = 3;
+ break;
+ }
+ case PICTURE_CP: {
+ pos->numparams = 2;
+ break;
+ }
+ case PICTURE_OCC: {
+ pos->numparams = 3;
+ break;
+ }
+ case PICTURE_OCCC: {
+ pos->numparams = 4;
+ break;
+ }
+ case PICTURE_OCO: {
+ pos->numparams = 3;
+ break;
+ }
+ case PICTURE_PCOP: {
+ pos->numparams = 4;
+ break;
+ }
+/* July 1996 additions */
+ case COMMAND_OOP: {
+ pos->numparams = 3;
+ break;
+ }
+ case COMMAND_OOOPP: {
+ pos->numparams = 5;
+ break;
+ }
+ case COMMAND_OPO: {
+ pos->numparams = 3;
+ break;
+ }
+ case COMMAND_POOOP: {
+ pos->numparams = 5;
+ break;
+ }
+ case COMMAND_POOP: {
+ pos->numparams = 4;
+ break;
+ }
+ case COMMAND_POOPP: {
+ pos->numparams = 5;
+ break;
+ }
+ } /* end SWITCH */
+} /* end COMPLETE_ENTRY */
+
+
+/* PRINT_TABLE prints symbol table */
+/* many changes 6/96 */
+void print_table(fout)
+FILE *fout;
+{
+ int i, n, num;
+ PSTRWC ptr;
+ PSENTRY symbol;
+ STRING com = key_to_string(CA); /* comment string */
+ STRING spaces = " ";
+ int pmode;
+
+
+ fprintf(fout, "%s generated command table\n\n", com);
+
+ fprintf(fout, "%s special printing characters\n\n", com);
+ fprintf(fout, "%s %c\n", key_to_string(ESCAPE_CHAR), escape_char);
+ fprintf(fout, "%s %c\n", key_to_string(AUDIBLE_ALERT_CHAR), audible_alert_char);
+ fprintf(fout, "%s %c\n", key_to_string(BACKSPACE_CHAR), backspace_char);
+ fprintf(fout, "%s %c\n", key_to_string(CARRIAGE_RETURN_CHAR), carriage_return_char);
+ fprintf(fout, "%s %c\n", key_to_string(FORMFEED_CHAR), formfeed_char);
+ fprintf(fout, "%s %c\n", key_to_string(HEX_CHAR), hex_char);
+ fprintf(fout, "%s %c\n", key_to_string(HORIZONTAL_TAB_CHAR), horizontal_tab_char);
+ fprintf(fout, "%s %c\n", key_to_string(NEWLINE_CHAR), newline_char);
+ fprintf(fout, "%s %c\n", key_to_string(VERTICAL_TAB_CHAR), vertical_tab_char);
+
+
+ fprintf(fout, "\n\n%s the commands (in the internal ordering)\n\n", com);
+ for (i=0; i < num_table_entries; i++) {
+ symbol = symbol_table[i];
+ fprintf(fout, "\n");
+ if (TDEBUG) {
+ tdebug_str_int("Print_table entry", i);
+ }
+ /* print TYPE= kind */
+ fprintf(fout, "%s %s\n", key_to_string(TYPE), ctype_to_string(symbol->kind) );
+ pmode = 0; /* start of command, so no modes yet */
+ if (TDEBUG) {
+ fprintf(fout, " %s Type stored internally as %d\n",
+ com, symbol->kind);
+ }
+ /* print NAME= command */
+ if (symbol->command != dont_care_str) {
+ fprintf(fout, "%s %s\n", key_to_string(NAMEK), symbol->command );
+ }
+ else {
+ fprintf(fout, "%s %s %s\n", com, key_to_string(NAMEK), symbol->command );
+
+ }
+
+ /* NOTE USE OF GOTO/LABEL HERE */
+ domode:
+
+ /* print PC_AT_START= command */
+ ptr = symbol->start_pc;
+ fprintf(fout, "%s%s ", spaces, key_to_string(PC_AT_START));
+ tprint_st_rwc(fout, ptr);
+ fprintf(fout, "\n");
+ if (TDEBUG) {
+ fprintf(fout, " %s value stored internally as %d\n",
+ com, get_pc_enum(ptr) );
+ }
+
+ /* print PRINT_CONTROL= command */
+ ptr = symbol->printing;
+ fprintf(fout, "%s%s ", spaces, key_to_string(PRINT_CONTROL));
+ tprint_st_rwc(fout, ptr);
+ fprintf(fout, "\n");
+ if (TDEBUG) {
+ fprintf(fout, " %s value stored internally as %d\n",
+ com, ptr->pcenum);
+ }
+
+ /* print START_TAG= command_t */
+ ptr = symbol->command_t;
+ fprintf(fout, "%s%s ", spaces, key_to_string(START_TAG));
+ tprint_tag(fout, ptr);
+
+ /* print END_TAG= command_et */
+ ptr = symbol->command_et;
+ fprintf(fout, "%s%s ", spaces, key_to_string(END_TAG));
+ tprint_tag(fout, ptr);
+
+ /* print OPT_PARAM= opt_param_pos */
+ if (symbol->opt_param_pos != NO_OPT_PARAM) { /* opt param */
+ fprintf(fout, "%s%s %s\n", spaces, key_to_string(OPT_PARAM),
+ pos_to_string(symbol->opt_param_pos) );
+ if (TDEBUG) {
+ fprintf(fout, " %s value stored internally as %d\n",
+ com, symbol->opt_param_pos);
+ }
+
+ /* print PRINT_OPT= command */
+ ptr = symbol->print_opt[0];
+ fprintf(fout, "%s%s ", spaces, key_to_string(PRINT_OPT));
+ tprint_st_rwc(fout, ptr);
+ fprintf(fout, "\n");
+ if (TDEBUG) {
+ fprintf(fout, " %s value stored internally as %d\n",
+ com, get_pc_enum(ptr));
+ }
+
+ /* print START_OPT= opt_param_t */
+ ptr = symbol->opt_param_t;
+ fprintf(fout, "%s%s ", spaces, key_to_string(START_OPT));
+ tprint_tag(fout, ptr);
+
+
+ /* print END_OPT= opt_param_et */
+ ptr = symbol->opt_param_et;
+ fprintf(fout, "%s%s ", spaces, key_to_string(END_OPT));
+ tprint_tag(fout, ptr);
+ } /* end of if over OPT_PARAM */
+
+ /* print parameter info, if any */
+ num = symbol->numparams;
+ if (num > 0) { /* are parameters */
+
+ /* print REQPARAMS= numparams */
+ fprintf(fout, "%sREQPARAMS= %d\n", spaces, num );
+ for (n = 0; n < num; n++) {
+
+ /* print START_TAG_N= param_t[n] */
+ ptr = symbol->param_t[n];
+ fprintf(fout, "%sSTART_TAG_%d= ", spaces, (n+1) );
+ tprint_tag(fout, ptr);
+
+ /* print END_TAG_N= param_et[n] */
+ ptr = symbol->param_et[n];
+ fprintf(fout, "%sEND_TAG_%d= ", spaces, (n+1) );
+ tprint_tag(fout, ptr);
+
+ /* print PRINT_Pn= print_param[n] */
+ ptr = symbol->print_param[n];
+ fprintf(fout, "%sPRINT_P%d= ", spaces, (n+1) );
+ tprint_st_rwc(fout, ptr);
+ fprintf(fout, "\n");
+ if (TDEBUG) {
+ fprintf(fout, " %s PRINT_P%d stored internally as %d\n",
+ com, (n+1), get_pc_enum(ptr));
+ }
+ } /* end loop over nunparams */
+ } /* end if num > 0 */
+
+ /* print SECTIONING_LEVEL= sectioning_level */
+ if (symbol_table[i]->kind == SECTIONING) { /* sectioning command */
+ fprintf(fout, "%s%s %s\n", spaces, key_to_string(SECTIONING_LEVEL),
+ level_to_string(symbol->sectioning_level) );
+ if (TDEBUG) {
+ fprintf(fout, " %s value stored internally as %d\n",
+ com, symbol->sectioning_level);
+ }
+ }
+
+ /* print SPECIAL_TOKEN= token number */
+ if ((TDEBUG) || (symbol->special_token != COMMAND)) {
+ fprintf(fout, "%s%s %d\n", spaces,
+ key_to_string(SPECIAL_TOKEN), get_special_token(symbol) );
+ }
+
+ /* extra debug printing */
+ if (TDEBUG) {
+ /* print internal kind */
+ fprintf(fout, " %s parse_kind= %d\n",
+ com, symbol->parse_kind);
+ }
+
+ /* print PC_AT_END= command */
+ ptr = symbol->end_pc;
+ fprintf(fout, "%s%s ", spaces, key_to_string(PC_AT_END) );
+ tprint_st_rwc(fout, ptr);
+ fprintf(fout, "\n");
+ if (TDEBUG) {
+ fprintf(fout, " %s value stored internally as %d\n",
+ com, get_pc_enum(ptr) );
+ }
+
+ /* do next mode for this entry */
+ if (pmode > 0) { /* not the first */
+ fprintf(fout, "%s\n", key_to_string(END_MODE));
+ }
+ if ((symbol = get_next_mode(symbol)) != NULL) { /* there is another mode */
+ pmode++;
+ fprintf(fout, "%s %s\n",
+ key_to_string(IN_MODE), get_mode_str(get_mode(symbol)));
+ goto domode; /* GOTO print the mode's actions */
+ }
+
+ /* print END_TYPE at end of entry */
+ fprintf(fout, "%s\n", key_to_string(END_TYPE));
+ }
+} /* end PRINT_TABLE */
+
+
+/* CHECK_TABLE = TRUE if missing entries and fixes them up */
+int check_table()
+{
+ int res = FALSE;
+
+ pos_bdoc = lookup_entry(dont_care_str, BEGIN_DOCUMENT);
+ if (pos_bdoc < 0) {
+ twarn_noline("BEGIN_DOCUMENT required but not found. Defaulted to null tags.");
+ res = TRUE;
+ create_def_reqentry(BEGIN_DOCUMENT);
+ }
+ pos_edoc = lookup_entry(dont_care_str, END_DOCUMENT);
+ if (pos_edoc < 0) {
+ twarn_noline("END_DOCUMENT required but not found. Defaulted to null tags.");
+ res = TRUE;
+ create_def_reqentry(END_DOCUMENT);
+ }
+ pos_bvbm = lookup_entry(dont_care_str, BEGIN_VERBATIM);
+ if (pos_bvbm < 0) {
+ twarn_noline("BEGIN_VERBATIM required but not found. Defaulted to null tags.");
+ res = TRUE;
+ create_def_reqentry(BEGIN_VERBATIM);
+ }
+ pos_evbm = lookup_entry(dont_care_str, END_VERBATIM);
+ if (pos_evbm < 0) {
+ twarn_noline("END_VERBATIM required but not found. Defaulted to null tags.");
+ res = TRUE;
+ create_def_reqentry(END_VERBATIM);
+ }
+ pos_bv = lookup_entry(dont_care_str, BEGIN_VERB );
+ if (pos_bv < 0) {
+ twarn_noline("BEGIN_VERB required but not found. Defaulted to null tags.");
+ res = TRUE;
+ create_def_reqentry(BEGIN_VERB);
+ }
+ pos_ev = lookup_entry(dont_care_str, END_VERB);
+ if (pos_ev < 0) {
+ twarn_noline("END_VERB required but not found. Defaulted to null tags.");
+ res = TRUE;
+ create_def_reqentry(END_VERB);
+ }
+ pos_oc = lookup_entry(dont_care_str, OTHER_COMMAND);
+ if (pos_oc < 0) {
+ twarn_noline("OTHER_COMMAND required but not found. Defaulted to null tags.");
+ res = TRUE;
+ create_def_reqentry(OTHER_COMMAND);
+ }
+ pos_ob = lookup_entry(dont_care_str, OTHER_BEGIN );
+ if (pos_ob < 0) {
+ twarn_noline("OTHER_BEGIN required but not found. Defaulted to null tags.");
+ res = TRUE;
+ create_def_reqentry(OTHER_BEGIN);
+ }
+ pos_oe = lookup_entry(dont_care_str, OTHER_END );
+ if (pos_oe < 0) {
+ twarn_noline("OTHER_END required but not found. Defaulted to null tags.");
+ res = TRUE;
+ create_def_reqentry(OTHER_END);
+ }
+ pos_lbrace = lookup_entry(dont_care_str, LBRACE);
+ if (pos_lbrace < 0) {
+ twarn_noline("LBRACE required but not found. Defaulted to null tags.");
+ res = TRUE;
+ create_def_reqentry(LBRACE);
+ }
+ pos_rbrace = lookup_entry(dont_care_str, RBRACE);
+ if (pos_rbrace < 0) {
+ twarn_noline("RBRACE required but not found. Defaulted to null tags.");
+ res = TRUE;
+ create_def_reqentry(RBRACE);
+ }
+ pos_para = lookup_entry(dont_care_str, PARAGRAPH);
+ if (pos_para < 0) {
+ twarn_noline("PARAGRAPH required but not found. Defaulted to null tags.");
+ res = TRUE;
+ create_def_reqentry(PARAGRAPH);
+ }
+ pos_bdol = lookup_entry(dont_care_str, BEGIN_DOLLAR);
+ if (pos_bdol < 0) {
+ twarn_noline("BEGIN_DOLLAR required but not found. Defaulted to null tags.");
+ res = TRUE;
+ create_def_reqentry(BEGIN_DOLLAR);
+ }
+ pos_edol = lookup_entry(dont_care_str, END_DOLLAR);
+ if (pos_bdol < 0) {
+ twarn_noline("END_DOLLAR required but not found. Defaulted to null tags.");
+ res = TRUE;
+ create_def_reqentry(END_DOLLAR);
+ }
+ pos_bss = lookup_entry(dont_care_str, SLASH_SPACE);
+ if (pos_bss < 0) {
+ twarn_noline("SLASH_SPACE required but not found. Defaulted to a space tag.");
+ res = TRUE;
+ create_def_reqentry(SLASH_SPACE);
+ symbol_table[num_table_entries - 1]->command_t = create_print_tag(" ");
+ }
+
+ return(res);
+} /* end CHECK_TABLE */
+
+
+
+/* CTYPE_TO_INT returns enum value corrsponding to a command type string */
+int ctype_to_int(s)
+STRING s;
+{
+ int pos;
+ pos = lookup_string(s, ctnames, NUM_CTIDS);
+ if (pos == -1) {
+ table_error("TYPE entry is unrecognised");
+ return(UNKNOWN_CTYPE);
+ }
+ return(ctenums[pos]);
+} /* end CTYPE_TO_INT */
+
+/* CTYPE_TO_STRING returns enum string (the inverse of CTYPE_TO_INT) */
+char *ctype_to_string(ienum)
+int ienum;
+{
+
+ switch (ienum) {
+ case UNKNOWN_CTYPE: {
+ return("UNKNOWN_CTYPE");
+ }
+ case TEX_CHAR: {
+ return("TEX_CHAR");
+ }
+ case CHAR_COMMAND: {
+ return("CHAR_COMMAND");
+ }
+ case COMMAND: {
+ return("COMMAND");
+ }
+ case BEGIN_ENV: {
+ return("BEGIN_ENV");
+ }
+ case END_ENV: {
+ return("END_ENV");
+ }
+ case BEGIN_LIST_ENV: {
+ return("BEGIN_LIST_ENV");
+ }
+ case END_LIST_ENV: {
+ return("END_LIST_ENV");
+ }
+ case BEGIN_VERBATIM: {
+ return("BEGIN_VERBATIM");
+ }
+ case END_VERBATIM: {
+ return("END_VERBATIM");
+ }
+ case BEGIN_VERB: {
+ return("BEGIN_VERB");
+ }
+ case END_VERB: {
+ return("END_VERB");
+ }
+ case SECTIONING: {
+ return("SECTIONING");
+ }
+ case SPECIAL: {
+ return("SPECIAL");
+ }
+ case SPECIAL_COMMAND: {
+ return("SPECIAL_COMMAND");
+ }
+ case SPECIAL_BEGIN_ENV: {
+ return("SPECIAL_BEGIN_ENV");
+ }
+ case SPECIAL_END_ENV: {
+ return("SPECIAL_END_ENV");
+ }
+ case SPECIAL_BEGIN_LIST: {
+ return("SPECIAL_BEGIN_LIST");
+ }
+ case SPECIAL_END_LIST: {
+ return("SPECIAL_END_LIST");
+ }
+ case SPECIAL_SECTIONING: {
+ return("SPECIAL_SECTIONING");
+ }
+ case OTHER_COMMAND: {
+ return("OTHER_COMMAND");
+ }
+ case OTHER_BEGIN: {
+ return("OTHER_BEGIN");
+ }
+ case OTHER_END: {
+ return("OTHER_END");
+ }
+ case LBRACE: {
+ return("LBRACE");
+ }
+ case RBRACE: {
+ return("RBRACE");
+ }
+ case BEGIN_PICTURE_CC: {
+ return("BEGIN_PICTURE_CC");
+ }
+ case END_PICTURE: {
+ return("END_PICTURE");
+ }
+ case PICTURE_CCPP: {
+ return("PICTURE_CCPP");
+ }
+ case PICTURE_CO: {
+ return("PICTURE_CO");
+ }
+ case PICTURE_COP: {
+ return("PICTURE_COP");
+ }
+ case PICTURE_CP: {
+ return("PICTURE_CP");
+ }
+ case PICTURE_OCC: {
+ return("PICTURE_OCC");
+ }
+ case PICTURE_OCCC: {
+ return("PICTURE_OCCC");
+ }
+ case PICTURE_OCO: {
+ return("PICTURE_OCO");
+ }
+ case PICTURE_PCOP: {
+ return("PICTURE_PCOP");
+ }
+ case BEGIN_VENV: {
+ return("BEGIN_VENV");
+ }
+ case END_VENV: {
+ return("END_VENV");
+ }
+ case VCOMMAND: {
+ return("VCOMMAND");
+ }
+ case BEGIN_DOCUMENT: {
+ return("BEGIN_DOCUMENT");
+ }
+ case END_DOCUMENT: {
+ return("END_DOCUMENT");
+ }
+ case PARAGRAPH: {
+ return("PARAGRAPH");
+ }
+ case BEGIN_DOLLAR: {
+ return("BEGIN_DOLLAR");
+ }
+ case END_DOLLAR: {
+ return("END_DOLLAR");
+ }
+ case SLASH_SPACE: {
+ return("SLASH_SPACE");
+ }
+ case COMMAND_OOP: {
+ return("COMMAND_OOP");
+ }
+ case COMMAND_OOOPP: {
+ return("COMMAND_OOOPP");
+ }
+ case COMMAND_OPO: {
+ return("COMMAND_OPO");
+ }
+ case COMMAND_POOOP: {
+ return("COMMAND_POOOP");
+ }
+ case COMMAND_POOP: {
+ return("COMMAND_POOP");
+ }
+ case COMMAND_POOPP: {
+ return("COMMAND_POOPP");
+ }
+ default: {
+ return("UNKNOWN_CTYPE");
+ }
+ }
+} /* end CTYPE_TO_STRING */
+
+
+/* POS_TO_INT converts an opt_pos_enum enum string to an int */
+int pos_to_int(s)
+char s[];
+{
+
+ if (strcmp(s, "NO_OPT_PARAM") == 0) {
+ return(NO_OPT_PARAM);
+ }
+ else if (strcmp(s, "FIRST") == 0) {
+ return(FIRST);
+ }
+ else if (strcmp(s, "LAST") == 0) {
+ return(LAST);
+ }
+ else {
+ table_error("OPT_PARAM entry is unrecognised");
+ return(NO_OPT_PARAM);
+ }
+} /* end POS_TO_INT */
+
+
+/* POS_TO_STRING returns enum string (the inverse of POS_TO_INT) */
+char *pos_to_string(ienum)
+int ienum;
+{
+
+ switch (ienum) {
+ case NO_OPT_PARAM: {
+ return("NO_OPT_PARAM");
+ }
+ case FIRST: {
+ return("FIRST");
+ }
+ case LAST: {
+ return("LAST");
+ }
+ default: {
+ return("NO_OPT_PARAM");
+ }
+ }
+} /* end POS_TO_STRING */
+
+
+/* LEVEL_TO_INT converts an sect_level_enum enum string to an int */
+int level_to_int(s)
+char s[];
+{
+
+ if (strcmp(s, "UNKNOWN_LEVEL") == 0) {
+ return(UNKNOWN_LEVEL);
+ }
+ else if (strcmp(s, "PARTM2") == 0) {
+ return(PARTM2);
+ }
+ else if (strcmp(s, "PARTM1") == 0) {
+ return(PARTM1);
+ }
+ else if (strcmp(s, "PART") == 0) {
+ return(PART);
+ }
+ else if (strcmp(s, "CHAPTER") == 0) {
+ return(CHAPTER);
+ }
+ else if (strcmp(s, "SECT") == 0) {
+ return(SECT);
+ }
+ else if (strcmp(s, "SUBSECT") == 0) {
+ return(SUBSECT);
+ }
+ else if (strcmp(s, "SUBSUBSECT") == 0) {
+ return(SUBSUBSECT);
+ }
+ else if (strcmp(s, "PARA") == 0) {
+ return(PARA);
+ }
+ else if (strcmp(s, "SUBPARA") == 0) {
+ return(SUBPARA);
+ }
+ else if (strcmp(s, "SUBPARAP1") == 0) {
+ return(SUBPARAP1);
+ }
+ else if (strcmp(s, "SUBPARAP2") == 0) {
+ return(SUBPARAP2);
+ }
+ else {
+ table_error("SECTIONING_LEVEL entry is unrecognised");
+ return(UNKNOWN_LEVEL);
+ }
+} /* end LEVEL_TO_INT */
+
+
+/* LEVEL_TO_STRING returns enum string (the inverse of LEVEL_TO_INT) */
+char *level_to_string(ienum)
+int ienum;
+{
+
+ switch (ienum) {
+ case UNKNOWN_LEVEL: {
+ return("UNKNOWN_LEVEL");
+ }
+ case PARTM2: {
+ return("PARTM2");
+ }
+ case PARTM1: {
+ return("PARTM1");
+ }
+ case PART: {
+ return("PART");
+ }
+ case CHAPTER: {
+ return("CHAPTER");
+ }
+ case SECT: {
+ return("SECT");
+ }
+ case SUBSECT: {
+ return("SUBSECT");
+ }
+ case SUBSUBSECT: {
+ return("SUBSUBSECT");
+ }
+ case PARA: {
+ return("PARA");
+ }
+ case SUBPARA: {
+ return("SUBPARA");
+ }
+ case SUBPARAP1: {
+ return("SUBPARAP1");
+ }
+ case SUBPARAP2: {
+ return("SUBPARAP2");
+ }
+ default: {
+ return("UNKNOWN_LEVEL");
+ }
+ }
+} /* end LEVEL_TO_STRING */
+
+
+
+
+/* SORT_TABLE sorts command table. From K&R Ed 2, p 62 */
+void sort_table()
+{
+
+ int gap, i, j;
+ struct st_entry *temp;
+
+ for (gap = num_table_entries/2; gap > 0; gap /= 2) {
+ for (i = gap; i < num_table_entries; i++) {
+ for (j = (i-gap);
+ j >= 0 && compare_st_entry(symbol_table[j], symbol_table[j+gap]) > 0;
+ j-=gap) {
+ temp = symbol_table[j];
+ symbol_table[j] = symbol_table[j+gap];
+ symbol_table[j+gap] = temp;
+ }
+ }
+ }
+} /* end SORT_TABLE */
+
+
+/* COMPARE_ST_ENTRY compares two st_entry */
+int compare_st_entry(e1, e2)
+struct st_entry *e1;
+struct st_entry *e2;
+{
+ int result;
+
+ /* compare on command name */
+ result = strcmp(e1->command, e2->command);
+ if (result != 0) {
+ return(result);
+ }
+ /* compare on kind */
+ return(e1->kind - e2->kind);
+} /* end COMPARE_ST_ENTRY */
+
+
+/* LOOKUP_ENTRY searches for command s in table. From K&R 2 Ed, p 58 */
+int lookup_entry(s,k)
+char s[];
+int k;
+{
+ int low, mid, high, result;
+
+ low = 0;
+ high = num_table_entries - 1;
+ while (low <= high) {
+ mid = (low + high)/2;
+ result = compare_id_to_entry(s,k,symbol_table[mid]);
+ if (result < 0) {
+ high = mid - 1;
+ }
+ else if (result > 0) {
+ low = mid + 1;
+ }
+ else { /* found a match */
+ return(mid);
+ }
+ }
+ return(-1); /* not found */
+} /* end LOOKUP_ENTRY */
+
+
+/* COMPARE_ID_TO_ENTRY similar to COMPARE_ST_ENTRY */
+int compare_id_to_entry(s,k,e)
+char s[];
+int k;
+struct st_entry *e;
+{
+ int result;
+
+ /* compare on command name */
+ result = strcmp(s, e->command);
+ if (result != 0) {
+ return(result);
+ }
+ if (k == DONT_CARE) {
+ return(result);
+ }
+ else { /* compare on kind */
+ return(k - e->kind);
+ }
+} /* end COMPARE_ID_TO_ENTRY */
+
+
+ /*-----------------GET_ FUNCTIONS-----------------------------*/
+
+
+
+/* COMMAND_TYPE returns system-assigned kind of command */
+int command_type(pos)
+PSENTRY pos;
+{
+ if (pos == NULL) { /* out of range */
+ return(IERR);
+ }
+ return(pos->parse_kind);
+} /* end COMMAND_TYPE */
+
+/* 6/96 changed STRING to PSTRWC and pos to PSENTRY in following */
+/* GET_T returns command start tag */
+PSTRWC get_t(pos)
+PSENTRY pos;
+{
+ if (pos == NULL) { /* out of range */
+ return(NULL);
+ }
+ return(pos->command_t);
+} /* end GET_T */
+
+
+/* GET_ET returns command end tag */
+PSTRWC get_et(pos)
+PSENTRY pos;
+{
+ if (pos == NULL) { /* out of range */
+ return(NULL);
+ }
+ return(pos->command_et);
+} /* end GET_ET */
+
+
+/* GET_TAG_T returns param start tag for n'th req param */
+PSTRWC get_tag_t(pos,num)
+PSENTRY pos;
+int num;
+{
+ if (pos == NULL) { /* out of range */
+ return(NULL);
+ }
+ if (num < 1 || num > 9) { /* out of range */
+ yyerror("Tag number out of range");
+ return(NULL);
+ }
+ return(pos->param_t[num-1]);
+} /* end GET_TAG_T */
+
+
+/* GET_TAG_ET returns param end tag for n'th req param */
+PSTRWC get_tag_et(pos,num)
+PSENTRY pos;
+int num;
+{
+ if (pos == NULL) { /* out of range */
+ return(NULL);
+ }
+ if (num < 1 || num > 9) { /* out of range */
+ yyerror("Tag number out of range");
+ return(NULL);
+ }
+ return(pos->param_et[num-1]);
+} /* end GET_TAG_ET */
+
+
+/* GET_OPTTAG_T returns opt param start tag */
+PSTRWC get_opttag_t(pos)
+PSENTRY pos;
+{
+ if (pos == NULL) { /* out of range */
+ return(NULL);
+ }
+ return(pos->opt_param_t);
+} /* end GET_OPTTAG_T */
+
+/* GET_OPTTAG_ET returns param end tag */
+PSTRWC get_opttag_et(pos)
+PSENTRY pos;
+{
+ if (pos == NULL) { /* out of range */
+ return(NULL);
+ }
+ return(pos->opt_param_et);
+} /* end GET_OPTTAG_ET */
+
+
+/* GET_LEVEL returns sectioning level */
+int get_level(pos)
+PSENTRY pos;
+{
+ if (pos == NULL) { /* out of range */
+ return(IERR);
+ }
+ return(pos->sectioning_level);
+} /* end GET_LEVEL */
+
+
+/* GET_ITEM_T returns item start tag */
+PSTRWC get_item_t(pos)
+PSENTRY pos;
+{
+ if (pos == NULL) { /* out of range */
+ return(NULL);
+ }
+ return(pos->param_t[7]);
+} /* end GET_ITEM_T */
+
+
+/* GET_ITEM_ET returns item end tag */
+PSTRWC get_item_et(pos)
+PSENTRY pos;
+{
+ if (pos == NULL) { /* out of range */
+ return(NULL);
+ }
+ return(pos->param_et[7]);
+} /* end GET_ITEM_ET */
+
+
+/* GET_ITEMOPT_T returns item optional param start tag */
+PSTRWC get_itemopt_t(pos)
+PSENTRY pos;
+{
+ if (pos == NULL) { /* out of range */
+ return(NULL);
+ }
+ return(pos->param_t[8]);
+} /* end GET_ITEMOPT_T */
+
+
+/* GET_ITEMOPT_ET returns item optional param end tag */
+PSTRWC get_itemopt_et(pos)
+PSENTRY pos;
+{
+ if (pos == NULL) { /* out of range */
+ return(NULL);
+ }
+ return(pos->param_et[8]);
+} /* end GET_ITEMOPT_ET */
+
+
+/* GET_USER_TYPE returns user's command type */
+int get_user_type(pos)
+PSENTRY pos;
+{
+ if (pos == NULL) { /* out of range */
+ return(IERR);
+ }
+ return(pos->kind);
+} /* end GET_USER_TYPE */
+
+
+/* GET_SPECIAL_TOKEN returns special token */
+int get_special_token(pos)
+PSENTRY pos;
+{
+ if (pos == NULL) { /* out of range */
+ return(OTHER);
+ }
+ return(pos->special_token);
+} /* end GET_SPECIAL_TOKEN */
+
+
+/* GET_COM_PRINT returns command print control */
+PSTRWC get_com_print(pos)
+PSENTRY pos;
+{
+ if (pos == NULL) { /* out of range */
+ return(NULL);
+ }
+ return(pos->printing);
+} /* end GET_COM_PRINT */
+
+
+/* GET_PARAM_PRINT returns param print control */
+PSTRWC get_param_print(pos,num)
+PSENTRY pos;
+int num;
+{
+ if (pos == NULL) { /* out of range */
+ return(NULL);
+ }
+ if (num < 1 || num > 9) { /* out of range */
+ yyerror("Parameter number out of range");
+ return(NULL);
+ }
+ return(pos->print_param[num-1]);
+} /* end GET_PARAM_PRINT */
+
+
+/* GET_OPT_PRINT returns opt param print control */
+PSTRWC get_opt_print(pos)
+PSENTRY pos;
+{
+ if (pos == NULL) { /* out of range */
+ return(NULL);
+ }
+ return(pos->print_opt[0]);
+} /* end GET_PARAM_PRINT */
+
+
+ /*---------------FILE INCLUSION-------------------*/
+
+/* INITIALISE_SENV initialises path searching */
+void initialise_senv()
+{
+ strcpy(sys_envname,"LTX2XTABLES"); /* environment variable name */
+ strcpy(path_sep," :;"); /* path seperators */
+ dir_cat = '/'; /* dir catenation char */
+ senv_debug = 0; /* debugging off */
+} /* end INITIALISE_SENV */
+
+
+/* INITIALISE_CT_FILES */
+void initialise_ct_files(tabnam)
+char tabnam[];
+{
+ ct_file_num = 0;
+ ct_fp_stack[ct_file_num] = filtabin;
+ ct_fn_stack[ct_file_num] = strsave(tabnam);
+ ct_ln_stack[ct_file_num] = 0;
+ fprintf(stdout, "\nReading command table file %s\n", tabnam);
+ fprintf(filerr, "\nReading command table file %s\n", tabnam);
+} /* end INITIALISE_CT_FILES */
+
+
+/* SET_CT_FILE opens new ct file */
+int set_ct_file(str)
+char str[];
+{
+ FILE *file;
+ char answer[MAX_TABLE_LINE];
+ char path[257];
+ int i;
+
+ if (ct_file_num >= MAX_CT_STACK - 1) { /* overflow */
+ table_error("FATAL ERROR: Attempting to open too many files");
+ exit(1);
+ }
+
+ strcpy(answer, str);
+ for (i = 1; i <= 4; i++) { /* 4 attempts to open a file */
+ if (searchenv(answer, sys_envname, path, path_sep, dir_cat, senv_debug)) {
+ file = fopen(path, "r");
+ if (file) { /* file is opened */
+ break;
+ }
+ }
+ if (i == 3) { /* last attempt failed */
+ fprintf(stdout, "\nLast attempt. Can't open file %s. I'm giving up.\n", answer);
+ exit(0);
+ }
+ fprintf(stdout, "\nCan't open file %s\n", answer);
+ fprintf(filerr, "\nCan't open file %s\n", answer);
+ fprintf(stdout, "Enter new file name, or I to ignore, or Q to quit\n: ");
+ fflush(stdout);
+ scanf("%s", answer);
+ if (strcmp("Q", answer) == 0 || strcmp("q", answer) == 0) {
+ exit(0);
+ }
+ else if (strcmp("I", answer) == 0 || strcmp("i", answer) == 0) {
+ return(FALSE);
+ }
+ }
+ /* file has been opened sucessfully */
+ ct_file_num++;
+ used_ct_file_stack = maxof(ct_file_num, used_ct_file_stack);
+ ct_fp_stack[ct_file_num] = file;
+ ct_fn_stack[ct_file_num] = strsave(path);
+ ct_ln_stack[ct_file_num] = 0;
+ fprintf(stdout, "\nReading command table file %s\n", path);
+ fprintf(filerr, "\nReading command table file %s\n", path);
+ return(TRUE);
+} /* end SET_CT_FILE */
+
+
+/* RESET_CT_FILE pops file stack */
+int reset_ct_file()
+{
+
+ if (ct_file_num < 0) { /* underflow */
+ table_error("Command table stack underflow");
+ return(EOF);
+ }
+ fclose(ct_fp_stack[ct_file_num]);
+ fprintf(stdout, "\n Closing command table file %s\n", ct_fn_stack[ct_file_num]);
+ fprintf(filerr, "\n Closing command table file %s\n", ct_fn_stack[ct_file_num]);
+ free(ct_fn_stack[ct_file_num]);
+ ct_fp_stack[ct_file_num] = NULL;
+ ct_fn_stack[ct_file_num] = NULL;
+ ct_ln_stack[ct_file_num] = 0;
+ ct_file_num--;
+ if (ct_file_num < 0) { /* empty stack, end of files */
+ return(EOF);
+ }
+ else {
+ return(ct_file_num);
+ }
+} /* end RESET_CT_FILE */
+
+
+/* GET_CT_FILEP returns file pointer */
+FILE *get_ct_filep()
+{
+ return(ct_fp_stack[ct_file_num]);
+} /* end GET_CT_FILEP */
+
+
+/* GET_CT_FILEN returns file name */
+STRING get_ct_filen()
+{
+ return(ct_fn_stack[ct_file_num]);
+} /* end GET_CT_FILEN */
+
+
+/* GET_CT_LINENUM returns line number */
+int get_ct_linenum()
+{
+ return(ct_ln_stack[ct_file_num]);
+} /* end GET_CT_LINENUM */
+
+
+/* INCR_CT_LINENUM increments line number */
+void incr_ct_linenum()
+{
+ ct_ln_stack[ct_file_num]++;
+} /* end INCR_CT_LINENUM */
+
+/* SET_CT_LINENUM sets command table line number */
+void set_ct_linenum(linenum)
+int linenum; /* the line number */
+{
+ ct_ln_stack[ct_file_num] = linenum;
+} /* end SET_CT_LINENUM */
+
+
+/*---------------------------------------------------------------*/
+/* 6/96 extras */
+
+/* CREATE_ST_RWC creates new struct */
+PSTRWC create_st_rwc()
+{
+ PSTRWC p;
+
+ if ((p = (PSTRWC ) malloc(sizeof(struct st_rwc))) != NULL) {
+ p->next = NULL;
+ p->cmd = -1;
+ p->pcenum = UNKNOWN_PRINT;
+ p->rwcode.bfnum = 0;
+ return(p);
+ }
+ yyerror("FATAL ERROR: No memory left for CREATE_ST_RWC");
+ exit(1);
+} /* end CREATE_ST_RWC */
+
+/* INIT_COMMON_PRINT initialises common print structures */
+void init_common_print()
+{
+ PSTRWC p;
+
+ /* default print */
+ p = create_st_rwc();
+ set_pc_enum(p, DEFAULT_PRINT);
+ p_default_print = p;
+
+ /* no print */
+ p = create_st_rwc();
+ set_pc_enum(p, NO_PRINT);
+ p_no_print = p;
+
+ /* print to buffer */
+ p = create_st_rwc();
+ set_pc_enum(p, TO_SYSBUF);
+ p_print_to_sysbuf = p;
+
+ /* print_underflow */
+ p = create_st_rwc();
+ set_pc_enum(p, PRINT_UNDERFLOW);
+ p_print_underflow = p;
+
+
+ /* unknown print */
+ p = create_st_rwc();
+ set_pc_enum(p, UNKNOWN_PRINT);
+ p_unknown_print = p;
+
+
+ /* print from buffer */
+ p = create_st_rwc();
+ set_pc_enum(p, SYSBUF);
+ p_print_from_sysbuf = p;
+
+ /* print null string */
+ p = create_st_rwc();
+ set_pc_enum(p, FIRST_STRING);
+ set_pcdata_name(p, "");
+ p_print_null = p;
+
+ /* reset print */
+ p = create_st_rwc();
+ set_pc_enum(p, RESET);
+ p_reset_print = p;
+
+ /* no op */
+ p = create_st_rwc();
+ set_pc_enum(p, NO_OP);
+ p_noop_print = p;
+
+} /* end INIT_COMMON_PRINT */
+
+/* CREATE_PRINT_TAG creates a tag print string structure */
+PSTRWC create_print_tag(a_str)
+ char a_str[]; /* a string */
+{
+ PSTRWC p;
+
+ p = create_st_rwc();
+ set_pc_enum(p, FIRST_STRING);
+ set_pcdata_name(p, a_str);
+ return(p);
+} /* end CREATE_PRINT_TAG */
+
+/* CREATE_PRINT_SOURCE creates a source print string structure */
+PSTRWC create_print_source(a_str)
+ char a_str[]; /* a string */
+{
+ PSTRWC p;
+
+ p = create_st_rwc();
+ set_pc_enum(p, SOURCE_STRING);
+ set_pcdata_name(p, a_str);
+ set_pc_cmd(p, SOURCE);
+ return(p);
+} /* end CREATE_PRINT_SOURCE */
+
+
+
+/* PARSE_PC parses print control and returns new structure */
+PSTRWC parse_pc(a_line)
+ char a_line[];
+{
+ char key_name[MAX_TABLE_LINE];
+ int key_enum;
+ int num;
+ char name[MAX_TABLE_LINE];
+ PSTRWC p;
+
+
+ /* get first keyword on line */
+ sscanf(a_line, "%s", key_name);
+ strtouc(key_name);
+ /* convert to enumeration type */
+ key_enum = printc_to_int(key_name);
+ /* switch to get all the data */
+ switch (key_enum) {
+ case DEFAULT_PRINT: { /* got it all */
+ return(p_default_print);
+ }
+ case NO_PRINT: { /* got it all */
+ return(p_no_print);
+ }
+ case TO_SYSBUF: { /* got it all */
+ return(p_print_to_sysbuf);
+ }
+ case PRINT_UNDERFLOW: { /* got it all */
+ return(p_print_underflow);
+ }
+ case UNKNOWN_PRINT: { /* got it all */
+ return(p_unknown_print);
+ }
+
+ case TO_BUFFER: { /* get buffer number */
+ sscanf(a_line, "%s %d", key_name, &num);
+ p = create_st_rwc();
+ set_pc_enum(p, TO_BUFFER);
+ set_pcdata_num(p, chk_bufnum(num));
+ used_wubuff[num]++;
+ return(p);
+ }
+
+ case TO_FILE: { /* get file */
+ sscanf(a_line, "%s %s", key_name, name);
+ p = create_st_rwc();
+ set_pc_enum(p, TO_FILE);
+ /* do file name stuff, adding it to the file array */
+ set_pcdata_name(p, chk_ufname(name));
+ return(p);
+ }
+
+ case SYSBUF: { /* got it all */
+ return(p_print_from_sysbuf);
+ }
+
+ case BUFFER: { /* get buffer number */
+ sscanf(a_line, "%s %d", key_name, &num);
+ p = create_st_rwc();
+ set_pc_enum(p, BUFFER);
+ set_pcdata_num(p, chk_bufnum(num));
+ used_rubuff[num]++;
+ return(p);
+ }
+
+ case FFILE: { /* get file */
+ sscanf(a_line, "%s %s", key_name, name);
+ p = create_st_rwc();
+ set_pc_enum(p, FFILE);
+ /* do file name stuff, adding it to the file array */
+ set_pcdata_name(p, chk_ufname(name));
+ return(p);
+ }
+
+ case FIRST_STRING: { /* get string */
+ return(p_unknown_print);
+ }
+
+ case RESET: { /* got it all */
+ return(p_reset_print);
+ }
+
+ case NO_OP: { /* got it all */
+ return(p_noop_print);
+ }
+
+ default: {
+ return(p_unknown_print);
+ }
+ }
+} /* end PARSE_PC */
+
+
+/* TPRINT_ST_RWC print out the st_rwc structure */
+void tprint_st_rwc(fout, prwc)
+FILE *fout;
+PSTRWC prwc;
+{
+
+ STRING str;
+ int kind;
+ STRING indent = " ";
+
+ if (prwc == NULL) { /* nothing to print */
+ return;
+ }
+
+ kind = get_pc_enum(prwc);
+ str = printc_to_string(kind);
+ switch (kind) {
+ case DEFAULT_PRINT: { /* got it all */
+ fprintf(fout, "%s", str);
+ return;
+ }
+ case NO_PRINT: { /* got it all */
+ fprintf(fout, "%s", str);
+ return;
+ }
+ case TO_SYSBUF: { /* got it all */
+ fprintf(fout, "%s", str);
+ return;
+ }
+ case PRINT_UNDERFLOW: { /* got it all */
+ fprintf(fout, "%s", str);
+ return;
+ }
+ case UNKNOWN_PRINT: { /* got it all */
+ fprintf(fout, "%s", str);
+ return;
+ }
+ case TO_BUFFER: { /* write buffer number */
+ fprintf(fout, "%s", str);
+ fprintf(fout, " %d", get_pcdata_num(prwc));
+ return;
+ }
+ case TO_FILE: { /* write file id */
+ fprintf(fout, "%s", str);
+ fprintf(fout, " %s", get_pcdata_name(prwc));
+ return;
+ }
+ case SYSBUF: { /* got it all */
+ fprintf(fout, "%s", str);
+ return;
+ }
+ case BUFFER: { /* write buffer number */
+ fprintf(fout, "%s", str);
+ fprintf(fout, " %d", get_pcdata_num(prwc));
+ return;
+ }
+ case FFILE: { /* write file id */
+ fprintf(fout, "%s", str);
+ fprintf(fout, " %s", get_pcdata_name(prwc));
+ return;
+ }
+ case FIRST_STRING: { /* write the string only */
+ tprint_str(fout, get_pcdata_name(prwc));
+ return;
+ }
+ case SOURCE_STRING: { /* write the string only */
+ tprint_str(fout, get_pcdata_name(prwc));
+ return;
+ }
+ case RESET: { /* got it all */
+ fprintf(fout, "%s", str);
+ return;
+ }
+ default: { /* should not be here */
+ }
+ }
+} /* end TPRINT_ST_RWC */
+
+
+/* TPRINT_TAG prints tag data from table */
+void tprint_tag(fout, prwc)
+FILE *fout;
+PSTRWC prwc;
+{
+
+ PSTRWC ptr;
+ int kmd;
+ STRING indent = " ";
+
+ if (prwc == NULL) { /* nothing, so just do a new line */
+ fprintf(fout, "\n");
+ return;
+ }
+
+ ptr = prwc;
+ while (ptr != NULL) {
+ kmd = get_pc_cmd(ptr);
+ switch (kmd) { /* some are special, need to add command */
+ case SOURCE : {
+ fprintf(fout, "%s %s ", indent, key_to_string(SOURCE));
+ tprint_st_rwc(fout, ptr);
+ break;
+ }
+ case STRINGG : {
+ fprintf(fout, "%s %s ", indent, key_to_string(STRINGG));
+ tprint_st_rwc(fout, ptr);
+ break;
+ }
+ case RESET_SYSBUF : {
+ fprintf(fout, "%s %s", indent, key_to_string(RESET_SYSBUF));
+ break;
+ }
+ case RESET_BUFFER : {
+ fprintf(fout, "%s %s ", indent, key_to_string(RESET_BUFFER));
+ fprintf(fout, "%d", get_pcdata_num(ptr));
+ break;
+ }
+ case RESET_FILE : {
+ fprintf(fout, "%s %s ", indent, key_to_string(RESET_FILE));
+ fprintf(fout, "%s", get_pcdata_name(ptr));
+ break;
+ }
+ case SET_MODE : {
+ fprintf(fout, "%s %s ", indent, key_to_string(SET_MODE));
+ fprintf(fout, "%s", get_mode_str(get_pcdata_num(ptr)));
+ break;
+ }
+ case RESET_MODE : {
+ fprintf(fout, "%s %s ", indent, key_to_string(RESET_MODE));
+ break;
+ }
+ case SWITCH_BACK : {
+ fprintf(fout, "%s%s ", indent, key_to_string(SWITCH_BACK));
+ break;
+ }
+ case SWITCH_TO_BUFFER : {
+ fprintf(fout, "%s%s ", indent, key_to_string(SWITCH_TO_BUFFER));
+ fprintf(fout, "%d", get_pcdata_num(ptr));
+ break;
+ }
+ case SWITCH_TO_FILE : {
+ fprintf(fout, "%s%s ", indent, key_to_string(SWITCH_TO_FILE));
+ fprintf(fout, "%s", get_pcdata_name(ptr));
+ break;
+ }
+ case SWITCH_TO_SYSBUF : {
+ fprintf(fout, "%s%s ", indent, key_to_string(SWITCH_TO_SYSBUF));
+ break;
+ }
+
+ default : {
+ tprint_st_rwc(fout, ptr);
+ break;
+ }
+ } /* end switch */
+ fprintf(fout, "\n");
+ ptr = ptr->next;
+ } /* end loop */
+} /* end TPRINT_TAG */
+
+
+/* GET_PC_ENUM returns the control code from printing data */
+int get_pc_enum(ptr)
+PSTRWC ptr;
+{
+
+ if (ptr == NULL) {
+ return(UNKNOWN_PRINT);
+ }
+ return(ptr->pcenum);
+
+} /* end GET_PC_ENUM */
+
+/* SET_PC_ENUM sets the control code for printing data */
+void set_pc_enum(ptr, cenum)
+PSTRWC ptr;
+int cenum;
+{
+ if (ptr != NULL) {
+ ptr->pcenum = cenum;
+ }
+ return;
+} /* end SET_PC_ENUM */
+
+
+/* GET_PCDATA_NUM returns the number code from printing data */
+int get_pcdata_num(ptr)
+PSTRWC ptr;
+{
+
+ if (ptr == NULL) {
+ return(0);
+ }
+ return(ptr->rwcode.bfnum);
+
+} /* end GET_PCDATA_NUM */
+
+/* SET_PCDATA_NUM sets the number code for printing data */
+void set_pcdata_num(ptr, num)
+PSTRWC ptr;
+int num;
+{
+ if (ptr != NULL) {
+ ptr->rwcode.bfnum = num;
+ }
+ return;
+} /* end SET_PCDATA_NUM */
+
+/* GET_PCDATA_NAME returns the string code from printing data */
+STRING get_pcdata_name(ptr)
+PSTRWC ptr;
+{
+
+ if (ptr == NULL) {
+ return(NULL);
+ }
+ return(ptr->rwcode.defstr);
+
+} /* end GET_PCDATA_NAME */
+
+/* SET_PCDATA_NAME sets the number code for printing data */
+void set_pcdata_name(ptr, str)
+PSTRWC ptr;
+STRING str;
+{
+ if (ptr != NULL) {
+ ptr->rwcode.defstr = str;
+ }
+ return;
+} /* end SET_PCDATA_NAME */
+
+/* GET_PC_CMD returns command name from print control */
+int get_pc_cmd(ptr)
+PSTRWC ptr;
+{
+ if (ptr == NULL) {
+ return(IERR);
+ }
+ return(ptr->cmd);
+} /* end GET_PC_CMD */
+
+
+/* SET_PC_CMD sets command name in print control */
+void set_pc_cmd(ptr, kmd)
+PSTRWC ptr;
+int kmd;
+{
+ if (ptr != NULL) {
+ ptr->cmd = kmd;
+ }
+ return;
+} /* end SET_PC_CMD */
+
+ /* next two added for code interp */
+/* SET_PC_CODE sets print control for compiled code */
+void set_pc_code(ptr, code_seg)
+PSTRWC ptr;
+ICT *code_seg;
+{
+
+ if (ptr == NULL) return;
+ set_pc_cmd(ptr, CODE);
+ ptr->rwcode.bytecode = code_seg;
+ return;
+} /* end SET_PC_CODE */
+
+/* GET_PC_CODE gets compiled code from print control */
+ICT *get_pc_code(ptr)
+PSTRWC ptr;
+{
+
+ if (ptr == NULL) return(NULL);
+ return(ptr->rwcode.bytecode);
+} /* end GET_PC_CODE */
+
+
+/* GET_NEXT_WRITE returns the next output instruction */
+PSTRWC get_next_write(ptr)
+PSTRWC ptr;
+{
+
+ if (ptr == NULL) {
+ return(NULL);
+ }
+ return(ptr->next);
+} /* end GET_NEXT_WRITE */
+
+
+/* APPEND_TO_WRITE adds the next output instruction */
+PSTRWC append_to_write(list, new)
+PSTRWC list;
+PSTRWC new;
+{
+
+ if (list != NULL) {
+ list->next = new;
+ }
+ return(new);
+
+} /* end APPEND_TO_WRITE */
+
+
+/* TAG_PRINT passes off tag strings to myprint for printing */
+void tag_print(ptr)
+PSTRWC ptr;
+{
+
+ char temp[MAX_UBUFF_LEN];
+ STRING fname;
+ int num;
+ FILE *fin;
+ int opt;
+ int kmd;
+
+ if (ptr == NULL) { /* nothing there */
+ return;
+ }
+ while (ptr != NULL) {
+ kmd = get_pc_cmd(ptr); /* do special command types first */
+ switch (kmd) {
+ case RESET_SYSBUF : { /* reset system buffer */
+ initialise_sysbuf();
+ break;
+ }
+ case RESET_BUFFER : { /* reset user buffer */
+ num = get_pcdata_num(ptr);
+ init_ubuff(num);
+ break;
+ }
+ case RESET_FILE : { /* reset file */
+ fname = get_pcdata_name(ptr);
+ init_ufile(fname);
+ break;
+ }
+ case SET_MODE : { /* set the mode */
+ num = get_pcdata_num(ptr);
+ push_mode(num);
+ break;
+ }
+ case RESET_MODE : { /* reset the mode */
+ reset_mode();
+ break;
+ }
+ /* 10/96 extensions */
+ case SWITCH_BACK : {
+ reset_print(); /* reset the print mode */
+ break;
+ }
+ case SWITCH_TO_BUFFER : {
+ set_print(ptr);
+ break;
+ }
+ case SWITCH_TO_FILE : {
+ set_print(ptr);
+ break;
+ }
+ case SWITCH_TO_SYSBUF : {
+ set_print(ptr);
+ break;
+ }
+ case CODE : { /* added for code interp */
+ exec_statements(get_pc_code(ptr)); /* execute code */
+ break;
+ }
+ default : { /* now "ordinary " commands */
+ opt = get_pc_enum(ptr);
+ switch (opt) {
+ case FIRST_STRING: { /* get the specified string */
+ myprint(get_pcdata_name(ptr));
+ break;
+ }
+ case STRINGG: {
+ myprint(get_pcdata_name(ptr));
+ break;
+ }
+ case SOURCE_STRING : {
+ myprint(get_pcdata_name(ptr));
+ break;
+ }
+ case SYSBUF: { /* get the system buffer */
+ myprint(buffer);
+ break;
+ }
+ case BUFFER: { /* get users buffer */
+ num = get_pcdata_num(ptr);
+ written_from_buff[num] = TRUE;
+ myprint(user_buffs[num]);
+ break;
+ }
+ case FFILE: { /* get file */
+ fname = get_pcdata_name(ptr);
+ fin = ufopenr(fname);
+ if (fin == NULL) {
+ warning_3s("In TAG_PRINT could not open file ", fname, " for reading.");
+ }
+ else {
+ temp[0] = SNUL;
+ while (fgets(temp, MAX_UBUFF_LEN - 2, fin) != NULL) {
+ myprint(temp);
+ temp[0] = SNUL;
+ } /* end loop */
+ ufclose(fname); /* close file */
+ }
+ break;
+ }
+ default: { /* should not be here */
+ sprintf(errstr,
+ "internal error: Illegal print option (%d %s) in TAG_PRINT",
+ opt, printc_to_string(opt));
+ yyerror(errstr);
+ break;
+ }
+ } /* end (opt) switch */
+ break;
+ } /* end kmd default */
+ } /* end (kmd) switch */
+ ptr = get_next_write(ptr);
+ } /* end while */
+
+} /* end TAG_PRINT */
+
+
+/* GET_FPOS given a name, returns position in file array */
+int get_fpos(str)
+STRING str;
+{
+ int i;
+
+ for (i = 0; i < used_files; i++) { /* search along array */
+ if (ufn[i] == str) { /* got it */
+ return(i);
+ }
+ }
+ /* should not be here, file not in array */
+ sprintf(errstr, "Unknown user file %s (list follows in error file)", str);
+ yyerror(errstr);
+ ufn[MAX_USER_FILES - 1] = str;
+ for (i = 0; i < used_files; i++) {
+ sprintf(errstr, "(%d) File %s\n", i, ufn[i]);
+ print_to_err(errstr);
+ }
+ return(MAX_USER_FILES - 1);
+} /* end GET_FPOS */
+
+
+/* UFOPENR function to open user file "name" for reading */
+FILE *ufopenr(name)
+STRING name;
+{
+ FILE *fil;
+ int i;
+
+ i = get_fpos(name);
+ /* 10/96 if already open then close it */
+ if (num_filep[i] > 0) {
+ ufclose(name);
+ }
+ sprintf(errstr, "Opening file %s number %d for reading\n", name, i);
+ print_to_err(errstr);
+ fil = fopen(name, "r");
+ if (fil == NULL) { /* can't open the file */
+ sprintf(errstr, "Cannot open file %s for reading", name);
+ yyerror(errstr);
+ ufp[i] = NULL;
+ }
+ else {
+ ufp[i] = fil; /* set it in the file array */
+ num_filep[i] = 0; /* 10/96 */
+ }
+ return(fil);
+} /* end UFOPENR */
+
+
+/* UFOPENW function to open user file "name" for writing */
+FILE *ufopenw(name)
+STRING name;
+{
+ FILE *fil;
+ int i;
+
+ i = get_fpos(name);
+ sprintf(errstr, "Opening file %s number %d for writing\n", name, i);
+ print_to_err(errstr);
+ fil = fopen(name, "w");
+ if (fil == NULL) { /* can't open the file */
+ sprintf(errstr, "Cannot open file %s for writing", name);
+ yyerror(errstr);
+ ufp[i] = NULL;
+ }
+ else {
+ ufp[i] = fil; /* set it in the file array */
+ }
+ return(fil);
+} /* end UFOPENW */
+
+
+/* UFCLOSE function to close user file "name" */
+int ufclose(name)
+STRING name;
+{
+ int i;
+ FILE *fil;
+
+ i = get_fpos(name);
+ sprintf(errstr, " Closing file %s numbered %d\n", name, i);
+ print_to_err(errstr);
+ fil = ufp[i];
+ num_filep[i] = 0; /* 10/96 set to closed */
+
+ i = fclose(fil);
+ if (i == EOF) { /* error in closing file */
+ sprintf(errstr, "Cannot close file %s", name);
+ yyerror(errstr);
+ }
+ return(i);
+} /* end UFCLOSE */
+
+
+/* WRITE_STATS writes statistics to error file */
+void write_stats(s)
+STRING s;
+{
+
+ int num;
+ int i;
+
+ print_to_err("\n STATISTICS");
+ print_to_err(s);
+ print_to_err("\n\n");
+
+ num = MAX_TABLE_ENTRIES;
+ used_table_entries = num_table_entries;
+ sprintf(errstr, "Used %d table entries out of %d (MAX_TABLE_ENTRIES)\n",
+ used_table_entries, num);
+ print_to_err(errstr);
+
+ num = MAX_TABLE_LINE;
+ sprintf(errstr, "Max table line %d characters out of %d (MAX_TABLE_LINE)\n",
+ used_table_line, num);
+ print_to_err(errstr);
+
+ num = MAX_USER_BUFFS;
+ sprintf(errstr, "Max number of user buffers %d (MAX_USER_BUFFS)\n",
+ num);
+ print_to_err(errstr);
+ print_to_err(" Written to buffers: ");
+ for (i = 0; i < MAX_USER_BUFFS; i++) {
+ if (used_wubuff[i] >= 0) {
+ sprintf(errstr,"%d ",i);
+ print_to_err(errstr);
+ }
+ }
+ print_to_err("\n Read from buffers: ");
+ for (i = 0; i < MAX_USER_BUFFS; i++) {
+ if (used_rubuff[i] > 0) {
+ sprintf(errstr,"%d ",i);
+ print_to_err(errstr);
+ }
+ }
+ print_to_err("\n");
+
+ num = MAX_UBUFF_LEN;
+ sprintf(errstr, "Max user buffer %d characters out of %d (MAX_UBUFF_LEN)\n",
+ used_ubuff_chars, num);
+ print_to_err(errstr);
+
+ num = MAX_BUFFER;
+ sprintf(errstr, "Used system buffer %d characters out of %d (MAX_BUFFER)\n",
+ used_sbuff_chars, num);
+ print_to_err(errstr);
+
+ num = MAX_USER_FILES;
+ sprintf(errstr, "Used %d user files out of %d (MAX_USER_FILES)\n",
+ used_files, num);
+ print_to_err(errstr);
+
+ num = EVERY_N_LINES;
+ sprintf(errstr, "Progress reported every %d (EVERY_N_LINES) lines\n",
+ num);
+ print_to_err(errstr);
+
+ num = CLAUSE_STACK_SIZE;
+ sprintf(errstr, "Max clause nesting depth %d out of %d (CLAUSE_STACK_SIZE)\n",
+ used_clause_stack, num);
+ print_to_err(errstr);
+
+ num = DEF_LIST_STACK_SIZE;
+ sprintf(errstr, "Max list nesting depth %d out of %d (DEF_LIST_STACK_SIZE)\n",
+ used_list_stack, num);
+ print_to_err(errstr);
+
+ num = MAX_PRINT_STACK;
+ sprintf(errstr, "Max print stack depth %d out of %d (MAX_PRINT_STACK)\n",
+ used_print_stack, num);
+ print_to_err(errstr);
+
+ num = MAX_CT_STACK;
+ sprintf(errstr, "Max command table stack depth %d out of %d (MAX_CT_STACK)\n",
+ used_ct_file_stack, num);
+ print_to_err(errstr);
+
+ /* interpreter statistics */
+ sprintf(errstr, "\nNumber of interpreter syntax errors: %d\n", isynt_error_count);
+ print_to_err(errstr);
+
+ sprintf(errstr, "Number of interpreter syntax warnings: %d\n", isynt_warn_count);
+ print_to_err(errstr);
+
+ sprintf(errstr, "Number of interpreter runtime errors: %d\n", irun_error_count);
+ print_to_err(errstr);
+
+ sprintf(errstr, "Number of interpreter runtime warnings: %d\n", irun_warn_count);
+ print_to_err(errstr);
+
+ return;
+} /* end WRITE_STATS */
+
+
+/* MAXOF returns the maximum of two integers */
+int maxof(n,m)
+int n;
+int m;
+{
+ if (n >= m) {
+ return(n);
+ }
+ return(m);
+} /* end MAXOF */
+
+
+/* GET_START_PC returns start pc struct */
+PSTRWC get_start_pc(pos)
+PSENTRY pos;
+{
+
+ if (pos == NULL) { /* out of range */
+ return(NULL);
+ }
+ return(pos->start_pc);
+} /* end GET_START_PC */
+
+
+/* GET_END_PC returns end pc struct */
+PSTRWC get_end_pc(pos)
+PSENTRY pos;
+{
+
+ if (pos == NULL) { /* out of range */
+ return(NULL);
+ }
+ return(pos->end_pc);
+} /* end GET_START_PC */
+
+
+/* TPRINT_STR prints string from command table */
+void tprint_str(fout, str)
+FILE *fout;
+char str[];
+{
+ int i;
+ char c, k;
+
+ if (isempty(str)) { /* empty string */
+ return;
+ }
+
+ fputc('"', fout); /* write starting quote */
+ for (i = 0; (c = str[i]) != SNUL; i++) { /* loop over all characters */
+ if (iscntrl(c)) { /* treat controls specially */
+ fputc(escape_char, fout); /* write table escape char */
+ switch (c) {
+ case '\n' : {
+ k = newline_char;
+ break;
+ }
+ case '\t' : {
+ k = horizontal_tab_char;
+ break;
+ }
+ case '\v' : {
+ k = vertical_tab_char;
+ break;
+ }
+ case '\b' : {
+ k = backspace_char;
+ break;
+ }
+ case '\r' : {
+ k = carriage_return_char;
+ break;
+ }
+ case '\f' : {
+ k = formfeed_char;
+ break;
+ }
+ case '\a' : {
+ k = audible_alert_char;
+ break;
+ }
+ default : { /* should not be here */
+ k = escape_char;
+ break;
+ }
+ } /* end switch */
+ fputc(k, fout);
+ }
+ else { /* normal character for printing */
+ fputc(c, fout); /* DO HEX LATER */
+ }
+ } /* all charcters processed */
+ fputc('"', fout); /* add closing quote */
+ return;
+} /* end TPRINT_STR */
+
+
+
+/* LOOKUP_STRING returns position of string in an array of strings */
+int lookup_string(str, array, numstr)
+STRING str; /* string to search for */
+STRING array[]; /* array of strings */
+int numstr; /* number of strings in array */
+{
+ int low, mid, high, result;
+
+ low = 0;
+ high = numstr - 1;
+ while (low <= high) {
+ mid = (low + high)/2;
+ result = strcmp(str, array[mid]);
+ if (result < 0) { /* not in top half */
+ high = mid - 1;
+ }
+ else if (result > 0) { /* not in bottom half */
+ low = mid + 1;
+ }
+ else { /* found it */
+ return(mid);
+ }
+ }
+ return(-1); /* str not in array */
+} /* end LOOKUP_STRING */
+
+/* INIT_PRINT_CONTROL initialises print control stuff */
+void init_print_control()
+{
+
+ int n;
+
+ initialise_pc(); /* set default printing */
+
+ /* initialise buffers */
+ for (n = 0; n < MAX_USER_BUFFS; n++) {
+ num_ubuff[n] = 0;
+ used_wubuff[n] = -1;
+ used_rubuff[n] = 0;
+ written_from_buff[n] = FALSE;
+ initialise_string(user_buffs[n]);
+ }
+ /* initialise files */
+ for (n = 0; n < MAX_USER_FILES; n++) {
+ num_filep[n] = 0;
+ ufp[n] = NULL;
+ ufn[n] = NULL;
+ }
+ /* initialise modes */
+ for (n = 0; n < MAX_MODES; n++) {
+ mode_names[n] = NULL;
+ }
+ num_modes = 0; /* no modes defined */
+ top_mode = 0; /* empty mode stack */
+} /* end INIT_PRINT_CONTROL */
+
+/* PRINTC_TO_INT converts print control string to enum */
+int printc_to_int(s)
+STRING s;
+{
+ int pos;
+
+ pos = lookup_string(s, pc_array, max_pcstr);
+ if (pos == -1) { /* unknown string */
+ table_error("PRINT_CONTROL unrecognised");
+ return(UNKNOWN_PRINT);
+ }
+ return(pos);
+} /* end PRINTC_TO_INT */
+
+
+/* PRINTC_TO_STRING converts print control enum to a string */
+STRING printc_to_string(pos)
+int pos;
+{
+ if (pos >= 0 && pos < max_pcstr) {
+ return(pc_array[pos]);
+ }
+ table_error("PRINT_CONTROL out of range");
+ return(unk);
+} /* end PRINTC_TO_STRING */
+
+
+
+/* KEY_TO_INT converts a keyword string to an integer */
+int key_to_int(s)
+STRING s;
+{
+ int pos;
+
+ pos = lookup_string(s, key_array, max_keystr);
+ if (pos == -1) { /* unknown string */
+ table_error("KEYWORD unrecognised");
+ }
+ return(pos);
+} /* end KEY_TO_INT */
+
+
+/* KEY_TO_STRING converts a keyword integer to a string */
+STRING key_to_string(pos)
+int pos;
+{
+ if (pos >= 0 && pos < max_keystr) {
+ return(key_array[pos]);
+ }
+ table_error("KEYWORD out of range");
+ return(unk);
+} /* end KEY_TO_STRING */
+
+
+/* CHK_BUFNUM returns a valid user buffer number */
+int chk_bufnum(num)
+int num;
+{
+
+ if (num < 0 || num > MAX_USER_BUFFS) {
+ table_error("User buffer number out of range (I have set it to 0)");
+ num = 0;
+ }
+ return(num);
+} /* end CHK_BUFNUM */
+
+/* CHK_UFNAME checks the name of a user's file */
+STRING chk_ufname(name)
+char name[];
+{
+ int i;
+ STRING str;
+
+ for (i = 0; i < used_files; i++) { /* check existing names */
+ if (strcmp(name, ufn[i]) == 0) { /* already in array */
+ return(ufn[i]);
+ }
+ } /* not in array, so add it */
+ if (used_files == MAX_USER_FILES) { /* array overflow */
+ table_error("Too many file names (I have set this one to NULL)");
+ return(NULL);
+ }
+ str = strsave(name);
+ ufn[used_files] = str;
+ used_files++;
+ return(str);
+} /* end CHK_UFNAME */
+
+
+/* INIT_UBUFF initialises a user buffer */
+void init_ubuff(bufnum)
+int bufnum;
+{
+ int n;
+ n = chk_bufnum(bufnum);
+ initialise_string(user_buffs[n]);
+ return;
+} /* end INIT_UBUFF */
+
+/* INIT_UFILE initialises a user file */
+void init_ufile(name)
+STRING name;
+{
+ int i;
+ FILE *fil;
+
+ i = get_fpos(name);
+ fil = ufp[i];
+
+ if (fil == NULL) { /* unknown or closed file */
+ return;
+ }
+ fclose(fil); /* close it */
+ ufp[i] = NULL; /* and set to NULL in file array */
+ num_filep[i] = 0; /* 10/96 flag as closed */
+ return;
+} /* end INIT_UFILE */
+
+
+/* ADD_MODE checks mode name and adds to list if necessary */
+int add_mode(str)
+char str[];
+{
+
+ int i;
+
+ for (i = 0; i < num_modes; i++) {
+ if (strcmp(mode_names[i], str) == 0) { /* in the list */
+ return(i);
+ }
+ } /* not in the list */
+ if (num_modes >= MAX_MODES) { /* list is full */
+ table_error("Too many mode names");
+ return(-1);
+ }
+ mode_names[num_modes] = strsave(str);
+ num_modes++;
+ return(num_modes - 1);
+} /* end ADD_MODE */
+
+/* CHK_MODE_NUM checks if mode number is in range */
+int chk_mode_num(num)
+int num;
+{
+ if (num < 0 || num >= num_modes) { /* out of range */
+ sprintf(errstr,
+ "internal error: mode number %d out of range (0 to %d)",
+ num, (num_modes - 1) );
+ yyerror(errstr);
+ return(-1);
+ }
+ return(num);
+} /* end CHK_MODE_NUM */
+
+
+/* GET_MODE_STR returns string corresponding to a mode */
+STRING get_mode_str(pos)
+int pos;
+{
+ if (chk_mode_num(pos) < 0) { /* out of range */
+ return(NULL);
+ }
+ return(mode_names[pos]);
+} /* end GET_MODE_STR */
+
+
+/* ADD_TO_MODELIST adds a new mode into a list of modes */
+void add_to_modelist(last, new)
+PSENTRY last;
+PSENTRY new;
+{
+
+ if (last == NULL) {
+ return;
+ }
+ last->next_mode = new; /* attach new to last */
+ new->kind = last->kind;
+ new->command = last->command;
+ return;
+} /* end ADD_TO_MODELIST */
+
+
+/* SET_MODE_NAME sets the mode name in an entry */
+void set_mode_name(str, entry)
+char str[];
+PSENTRY entry;
+{
+ int pos;
+
+ pos = add_mode(str);
+ entry->mode = pos;
+ return;
+} /* end SET_MODE_NAME */
+
+/* GET_MODE gets the mode code from an entry */
+int get_mode(sym)
+PSENTRY sym;
+{
+
+ if (sym == NULL) {
+ return(IERR);
+ }
+ return(sym->mode);
+} /* end GET_MODE */
+
+
+/* GET_NEXT_MODE gets the next mode from an entry */
+PSENTRY get_next_mode(sym)
+PSENTRY sym;
+{
+
+ if (sym == NULL) {
+ return(NULL);
+ }
+ return(sym->next_mode);
+} /* end GET_NEXT_MODE */
+
+
+/* ISEMPTY returns TRUE if string is empty */
+int isempty(str)
+char str[];
+{
+ if (str == NULL) {
+ return(TRUE);
+ }
+ if (str[0] == SNUL) {
+ return(TRUE);
+ }
+ return(FALSE);
+} /* end ISEMPTY */
+
+
+/* PUSH_MODE pushes mode onto the stack */
+void push_mode(id)
+int id;
+{
+
+ if (top_mode >= MAX_MODE_STACK) { /* overflow */
+ yyerror("Something is wrong: mode stack overflow when pushing");
+ return;
+ }
+ mode_stack[top_mode] = id;
+ top_mode++;
+ return;
+} /* end PUSH_MODE */
+
+
+/* POP_MODE returns top of mode stack and pops it */
+int pop_mode()
+{
+
+ if (top_mode <= 0) { /* underflow */
+ yyerror("Something is wrong: mode stack underflow when popping");
+ top_mode = 0;
+ return(IERR);
+ }
+ top_mode--;
+ return(mode_stack[top_mode]);
+} /* end POP_MODE */
+
+
+/* GET_CURRENT_MODE returns the current mode */
+int get_current_mode()
+{
+
+ if (top_mode <= 0) { /* underflow, but its OK */
+ return(IERR);
+ }
+ return(mode_stack[top_mode - 1]);
+} /* end GET_CURRENT_MODE */
+
+/* RESET_MODE resets the current mode */
+int reset_mode()
+{
+ return(pop_mode());
+} /* end RESET_MODE */
+
+
+/* GET_MODE_SYM returns the sym entry for the current mode */
+PSENTRY get_mode_sym(pos)
+int pos; /* position in command table */
+{
+
+ PSENTRY start = symbol_table[pos]; /* default mode defn */
+ int cur_mode = get_current_mode();
+ PSENTRY next;
+
+ if (cur_mode == IERR) { /* unknown or default mode */
+ return(start);
+ }
+ if (get_mode(start) == cur_mode) { /* modes match */
+ return(start);
+ }
+ next = get_next_mode(start); /* look for next in the list */
+ while (next != NULL) {
+ if (get_mode(next) == cur_mode) { /* modes match */
+ return(next);
+ }
+ next = get_next_mode(next); /* repeat */
+ } /* no mode match, return non-mode entry */
+ return(start);
+} /* end GET_MODE_SYM */
+