diff options
author | Norbert Preining <norbert@preining.info> | 2019-09-02 13:46:59 +0900 |
---|---|---|
committer | Norbert Preining <norbert@preining.info> | 2019-09-02 13:46:59 +0900 |
commit | e0c6872cf40896c7be36b11dcc744620f10adf1d (patch) | |
tree | 60335e10d2f4354b0674ec22d7b53f0f8abee672 /support/ltx2x/l2xlib.c |
Initial commit
Diffstat (limited to 'support/ltx2x/l2xlib.c')
-rw-r--r-- | support/ltx2x/l2xlib.c | 5629 |
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 */ + |