/* 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 #include "getopt.h" #include #include #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 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 */