/* l2xlib.c Main and support routines for ltx2x LaTeX to X translator */
/* Written by Peter Wilson (ex Catholic University and NIST) */
/* ex
[email protected] */
/* Now at:
[email protected] */
/* 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
[email protected])
* Added -h option (some getopts don't return ? if unknown option)
* Deleted unused init_page_header and print_page_header from l2xiscan.c
* Changed SR order in l2xirexp to stop gcc whine
*/
/* Development of this software upto and including version 0.7
* (November 1996) was funded by the United States Government,
* and is not subject to copyright. This version is released
* under the LaTeX Project Public License.
*/
/* National Institute of Standards and Technology (NIST)
* Manufacturing Engineering Laboratory (MEL)
* Manufacturing Systems Integration Division (MSID)
* ********************************************************************
* D I S C L A I M E R
*
* There is no warranty for the LTX2X software.
* If the LTX2X software is modified by someone else and passed on,
* NIST wants the software's recipients to know that what they
* have is not what NIST distributed.
*
* Policies
*
* 1. Anyone may copy and distribute verbatim copies of the
* source code as received in any medium.
*
* 2. Anyone may modify your copy or copies of the LTX2X source
* code or any portion of it, and copy and distribute such modifications
* provided that all modifications are clearly associated with the entity
* that performs the modifications.
*
* NO WARRANTY
* ===========
*
* NIST PROVIDES ABSOLUTELY NO WARRANTY. THE LTX2X SOFTWARE
* IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
* THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS
* WITH YOU. SHOULD ANY PORTION OF THE LTX2X SOFTWARE PROVE DEFECTIVE,
* YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
*
* IN NO EVENT WILL NIST BE LIABLE FOR DAMAGES,
* INCLUDING ANY LOST PROFITS, LOST MONIES, OR OTHER SPECIAL,
* INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR
* INABILITY TO USE (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA
* BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY THIRD PARTIES OR A
* FAILURE OF THE PROGRAM TO OPERATE WITH PROGRAMS NOT DISTRIBUTED BY
* NIST) THE PROGRAMS, EVEN IF YOU HAVE BEEN ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGES, OR FOR ANY CLAIM BY ANY OTHER PARTY.
*/
#include <string.h>
#include "getopt.h"
#include <stdio.h>
#include <ctype.h>
#ifndef STRTYPES_H
#include "strtypes.h"
#endif
/* typedef char *STRING; A pointer-to-a-char */
/* typedef STRING *PTRADR; A pointer-to-a-pointer-to-a-char */
/* define SNUL '\0' end of a string */
#ifndef L2XCOM_H
#include "l2xcom.h"
#endif
#include "l2xytab.h"
/* the symbol table typedefs */
#ifndef licomsym_h
#include "licomsym.h"
#endif
# define MAX_ERRORS 10
FILE *yyin; /* Lexer input file */
FILE *filerr; /* Error file */
FILE *yyout; /* Lexer/Parser output file */
FILE *filtabin; /* Table input file */
FILE *filtabout; /* Table output file */
int MIN_GRAMM_SPECIAL = 10000; /* min code number for grammer special */
int MIN_CODE_SPECIAL = 50000; /* min code number for code special */
int LDEBUG = 0; /* >0 for debugging lexer */
int TDEBUG = FALSE; /* for debugging command table */
int YDEBUG = 0; /* >0 for debugging parser */
int DEBUG = 0; /* >0 for debugging interpreter */
int cdebug = TRUE; /* set FALSE to disable inteprreter Code debug */
int edebug = TRUE; /* set FALSE to disable interpreter Execution debug */
int cl_debug = 0; /* command line value for DEBUG */
int SLD_OFF = TRUE; /* set FALSE to enable interpreter SLD */
int num_errors = 0; /* number of errors */
int lineno = 1; /* input file line number */
# define MAX_LINE 2000
# define MAX_BUFFER 2000
char linebuf[MAX_LINE]; /* buffer for input line */
int linlen = 0; /* current no of chars in linebuf */
int line_count = 0; /* count of line printing */
# define EVERY_N_LINES 100
int darray[10]; /* dummy array for something */
int leave_comments = FALSE; /* control for leaving in TeX comments */
int collapse_ws = FALSE; /* control for collapsing whitespace */
int pretty_print = FALSE; /* control for pretty-printing */
int max_pretty_line = MAX_BUFFER; /* max length of pretty-print line */
char pretty_line[MAX_BUFFER]; /* char buffer for pretty-printing */
int no_print = FALSE; /* a control for myprint */
int print_to_buffer = FALSE; /* a control for myprint */
char buffer[MAX_BUFFER]; /* character buffer for myprint */
/*---------------------6/96 extensions-----------------------------*/
/* number of user's string buffers */
# define MAX_USER_BUFFS 64
/* max number of user's files */
# define MAX_USER_FILES 16
/* length of a user buffer */
/* # define MAX_UBUFF_LEN 514 */
# define MAX_UBUFF_LEN 1026
typedef char UBUFF[MAX_UBUFF_LEN];
UBUFF user_buffs[MAX_USER_BUFFS]; /* array of user buffers */
char errstr[MAX_UBUFF_LEN]; /* buffer for assembling error/warning text */
int cur_user_buf = 0; /* number of current user buffer for writing to */
int num_ubufwrite = 0; /* number of open write to user buffer calls */
int num_ubuff[MAX_USER_BUFFS]; /* no of times user buffer opened */
int used_rubuff[MAX_USER_BUFFS]; /* >0 if used_ubuff[N] has been read */
int used_wubuff[MAX_USER_BUFFS]; /* >0 if used_ubuff[N] has been written */
int written_from_buff[MAX_USER_BUFFS]; /* TRUE if read from user buffer */
STRING cur_user_fn = NULL; /* name of current user file for writing to */
int num_fileprint = 0; /* number of open write to file calls */
int num_filep[MAX_USER_FILES]; /* number of opened to write for file */
FILE *ufp[MAX_USER_FILES]; /* user file pointer */
STRING ufn[MAX_USER_FILES]; /* user file name */
int cur_user_fpos = 0; /* current pos in file array */
FILE *cur_user_fileid = NULL; /* current user file id */
int num_otherprint = 0; /* total number of non-default open write calls */
# define SET_NUM_OTHERPRINT (num_noprint + num_bufprint + num_ubufwrite + num_fileprint)
PSTRWC cur_printc = NULL; /* current print control */
int bverb = FALSE; /* TRUE if starting verbatim print */
int in_noop = FALSE; /* TRUE if doing a no op */
int start_noop = FALSE; /* TRUE if start of a no op */
#define MAX_MODES 32
STRING mode_names[MAX_MODES]; /* unordered list of mode names */
int num_modes = 0; /* number of mode names */
#define MAX_MODE_STACK 20
int mode_stack[MAX_MODE_STACK]; /* stack for mode ids */
int top_mode = 0; /* empty top of mode stack */
/* keywords */
/* command table commands */
enum key_word{
#define kwtc(a, b) a,
#define lctc(a, b)
#define pctc(a, b)
#include "l2xlibtc.h"
#undef kwtc
#undef lctc
#undef pctc
};
int max_keystr = MAX_KEYSTR;
/* map from keyword enum to string representation */
STRING key_array[] = {
#define kwtc(a, b) b,
#define lctc(a, b)
#define pctc(a, b)
#include "l2xlibtc.h"
#undef kwtc
#undef lctc
#undef pctc
};
/* map from print control enum to string representation */
int max_pcstr = MAX_PCSTR;
STRING pc_array[] = {
#define kwtc(a, b)
#define lctc(a, b)
#define pctc(a, b) b,
#include "l2xlibtc.h"
#undef kwtc
#undef lctc
#undef pctc
};
/* the types of LaTeX commands */
#define UNKNOWN_CTYPE -10
/* number of names/enums in command types, update when ctnames changes!! */
#define NUM_CTIDS 50
/* ctnames[] is an alphabetical array of command type strings */
STRING ctnames[] = {
#define kwtc(a, b)
#define lctc(a, b) b,
#define pctc(a, b)
#include "l2xlibtc.h"
#undef kwtc
#undef lctc
#undef pctc
};
/* ctenums[] is an array of command type enums to match ctnames[] */
int ctenums[] = {
#define kwtc(a, b)
#define lctc(a, b) a,
#define pctc(a, b)
#include "l2xlibtc.h"
#undef kwtc
#undef lctc
#undef pctc
};
/* pointers to fixed, predefined print control structs */
PSTRWC p_default_print; /* default printing i.e., DEFAULT_PRINT */
PSTRWC p_no_print; /* no printing i.e., NO_PRINT */
PSTRWC p_print_to_sysbuf; /* print to system buffer i.e., TO_SYSBUF */
PSTRWC p_print_underflow; /* underflow i.e., PRINT_UNDERFLOW */
PSTRWC p_unknown_print; /* unknown print i.e., UNKNOWN_PRINT */
PSTRWC p_print_from_sysbuf; /* print from system buffer i.e., SYSBUF */
PSTRWC p_print_null; /* print null string i.e., */
PSTRWC p_reset_print; /* reset printing i.e., RESET */
PSTRWC p_noop_print; /* no-op i.e., NO_OP */
/* new functions */
PSTRWC create_st_rwc();
void init_common_print();
PSTRWC create_print_tag();
PSTRWC create_print_source();
PSTRWC parse_pc();
void tprint_st_rwc();
void tprint_tag();
void set_pc_enum();
int get_pc_enum();
void set_pcdata_num();
int get_pcdata_num();
void set_pcdata_name();
STRING get_pcdata_name();
PSTRWC get_next_write();
PSTRWC append_to_write();
PSTRWC initialise_pc();
FILE *ufopenr();
FILE *ufopenw();
int ufclose();
PSTRWC get_start_pc();
PSTRWC get_end_pc();
void flush_pretty();
int pretty_empty();
void strtouc(); /* convert string to upper case */
void tprint_str();
int lookup_string(); /* finds posn. of string in an ordered array of strings */
void init_print_control();
int key_to_int();
STRING key_to_string();
void set_pc_cmd();
int get_pc_cmd();
int chk_bufnum();
STRING chk_ufname();
void init_ubuff(); /* initialises a user buffer */
void init_ufile(); /* initialise a user file */
STRING get_mode_str(); /* returns string name of a mode */
void add_to_modelist(); /* adds a mode to the mode list */
void set_mode_name(); /* puts mode id into sym entry */
int get_mode(); /* gets mode id from sym entry */
PSENTRY get_next_mode(); /* gets next mode of a sym entry */
int isempty(); /* TRUE if an empty string */
void push_mode(); /* pushes mode onto stack */
int pop_mode(); /* pops mode from stack */
int reset_mode(); /* resets the mode */
int get_current_mode(); /* gets the current mode */
PSENTRY get_mode_sym(); /* gets sym entry matching current mode */
void tag_print(); /* print a tag */
/*-------- 7/96 statistics stuff ---------------------------*/
int used_ubuff_chars = 0; /* max # of chars attempted for buffer storage */
int used_sbuff_chars = 0; /* max # of chars attempted for system buffer */
int used_files = 0; /* # of user files used */
int used_clause_stack = 0; /* max clause stack depth usage */
int used_list_stack = 0; /* list stack */
int used_table_line = 0; /* max length of a table line */
int used_table_entries = 0; /* # of entries in command table */
int used_print_stack = 0; /* max depth of print stack */
int used_ct_file_stack = 0; /* max depth of command table stack */
void write_stats(); /* write statistics */
int maxof(); /* max of two integers */
/*--------------------------------------------------------------*/
# define CLAUSE_STACK_SIZE 10
int clause_depth = 0;
/* 6/96 changed STRING to PSTRWC */
PSTRWC clause_str_stack[CLAUSE_STACK_SIZE];
int base_level = CLAUSE_STACK_SIZE - 1; /* Highest doc level not closed off */
/* Section is highest and s4clause lowest */
int current_level = 0; /* level of current doc division */
int new_level = 0;
# define DEF_LIST_STACK_SIZE 10
int LIST_STACK_SIZE = DEF_LIST_STACK_SIZE;
int list_level = 0;
int num_items[DEF_LIST_STACK_SIZE]; /* holds number of current items in a list */
/* 6/96 in following changed STRING to PSTRWC */
PSTRWC list_str_stack[DEF_LIST_STACK_SIZE]; /* holds closing string for an item */
PSTRWC list_item_start[DEF_LIST_STACK_SIZE]; /* holds start string for an item */
PSTRWC list_descitemp_start[DEF_LIST_STACK_SIZE]; /* holds start string for the */
/* parameter of a descriptive list item */
PSTRWC list_descitemp_end[DEF_LIST_STACK_SIZE]; /* holds corresponding end string */
char *strsave();
void myprint();
void pprint();
void verbatim_print();
void initialise_clause_stack();
void set_clause_stack();
void close_all_divs();
void close_doc_divs();
void close_down();
void set_list_stack();
void print_end_item();
void yyerror();
void warning();
void catl();
void do_newline();
void initialise_sysbuf();
void print_sysbuf();
void copy_sysbuf();
void initialise_string();
/* new stuff for l2x */
enum opt_pos_enum {NO_OPT_PARAM = -1, FIRST = 0, LAST};
enum sect_level_enum {UNKNOWN_LEVEL, PARTM2, PARTM1, PART,
CHAPTER, SECT, SUBSECT, SUBSUBSECT, PARA, SUBPARA,
SUBPARAP1, SUBPARAP2};
enum cont_enum {CONT_UNKNOWN_ENUM,
CONT_TAG,
CONT_START_TAG, CONT_END_TAG,
CONT_START_OPT, CONT_END_OPT,
CONT_START_TAG_1, CONT_END_TAG_1,
CONT_START_TAG_2, CONT_END_TAG_2,
CONT_START_TAG_3, CONT_END_TAG_3,
CONT_START_TAG_4, CONT_END_TAG_4,
CONT_START_TAG_5, CONT_END_TAG_5,
CONT_START_TAG_6, CONT_END_TAG_6,
CONT_START_TAG_7, CONT_END_TAG_7,
CONT_START_TAG_8, CONT_END_TAG_8,
CONT_START_TAG_9, CONT_END_TAG_9 };
#define MAX_TABLE_LINE 1000
char table_line[MAX_TABLE_LINE];
#define MAX_TABLE_ENTRIES 1000
PSENTRY symbol_table[MAX_TABLE_ENTRIES];
int num_table_entries = 0;
int num_table_errors = 0;
char env_name[MAX_TABLE_LINE];
int DONT_CARE = -100;
STRING dont_care_str = "!@#$%^&*";
int command_types[] = {COMMAND, COMMAND_1, COMMAND_2, COMMAND_3, COMMAND_4,
COMMAND_5, COMMAND_6, COMMAND_7, COMMAND_8, COMMAND_9};
int command_opt_types[] = {COMMAND_OPT, COMMAND_1_OPT, COMMAND_2_OPT, COMMAND_3_OPT,
COMMAND_4_OPT, COMMAND_5_OPT, COMMAND_6_OPT, COMMAND_7_OPT,
COMMAND_8_OPT, COMMAND_9};
char escape_char = '\\';
char newline_char = 'n';
char horizontal_tab_char = 't';
char vertical_tab_char = 'v';
char backspace_char = 'b';
char carriage_return_char = 'r';
char formfeed_char = 'f';
char audible_alert_char = 'a';
char hex_char = 'x';
/* Extended 6/96 */
STRING unk = "ERROR";
int num_print = 0;
int num_noprint = 0;
int num_bufprint = 0;
#define MAX_PRINT_STACK 100
PSTRWC print_control_stack[MAX_PRINT_STACK]; /* (6/96 changed from int) */
/* positions in command table */
int pos_bdoc; /* BEGIN_DOCUMENT */
int pos_edoc; /* END_DOCUMENT */
int pos_bvbm; /* BEGIN_VERBATIM */
int pos_evbm; /* END_VERBATIM */
int pos_bv; /* BEGIN_VERB */
int pos_ev; /* END_VERB */
int pos_oc; /* OTHER_COMMAND */
int pos_ob; /* OTHER_BEGIN */
int pos_oe; /* OTHER_END */
int pos_lbrace; /* LEFT_BRACE */
int pos_rbrace; /* RIGHT_BRACE */
int pos_para; /* PARAGRAPH */
int pos_bdol; /* 'begin' $ */
int pos_edol; /* 'end' $ */
int pos_bss; /* SLASH_SPACE */
PSENTRY new_table_entry();
void create_def_reqentry();
void read_table();
void print_table();
int check_table();
void delete_to_chars();
int delete_quotes();
void twarn_noline();
void table_error();
void terror_noline();
void tdebug_tline();
void tdebug_str_int();
void tdebug_str();
void tdebug_char();
int ctype_to_int();
char *ctype_to_string();
int pos_to_int();
char *pos_to_string();
int level_to_int();
char *level_to_string();
int printc_to_int();
char *printc_to_string();
void sort_table();
int compare_st_entry();
int lookup_entry();
void get_env_name();
void print_to_err();
void print_debug_1s();
void print_debug_2s();
void print_debug_undef();
void complete_table_entry();
void complete_entry();
int command_type();
int get_user_type();
int get_special_token();
/* 6/96 changed following from STRING to PSTRWC */
PSTRWC get_t();
PSTRWC get_et();
PSTRWC get_tag_t();
PSTRWC get_tag_et();
PSTRWC get_opttag_t();
PSTRWC get_opttag_et();
int get_level();
PSTRWC get_item_t();
PSTRWC get_item_et();
PSTRWC get_itemopt_t();
PSTRWC get_itemopt_et();
void warning_3s();
void set_print();
void reset_print();
void push_print_control();
PSTRWC pop_print_control();
PSTRWC peek_print_control(); /* added 6/96 */
/* 6/96 changed following from int to PSTRWC */
PSTRWC get_com_print();
PSTRWC get_param_print();
PSTRWC get_opt_print();
/* Command table file stack stuff */
# define MAX_CT_STACK 20
FILE *ct_fp_stack[MAX_CT_STACK]; /* ct file pointers */
STRING ct_fn_stack[MAX_CT_STACK]; /* ct file names */
int ct_ln_stack[MAX_CT_STACK]; /* ct line numbers */
int ct_file_num; /* current ct file */
void initialise_ct_files();
int set_ct_file();
int reset_ct_file();
FILE *get_ct_filep();
STRING get_ct_filen();
int get_ct_linenum();
void incr_ct_linenum();
/* Environment variable defined search path stuff */
void initialise_senv();
char path_name[257]; /* name of a path */
char sys_envname[20]; /* name of environment variable */
char path_sep[10]; /* path name seperators */
char dir_cat; /* directory catenation char */
int senv_debug; /* =1 for debug searchenv() */
/*------------------- Additions for interpreting procedural code ------*/
SYMTAB_NODE_PTR code_root; /* where the initial compiled code is stored */
/* EXTERNALS */
extern SYMTAB_NODE_PTR code_setup();
extern int isynt_error_count;
extern int isynt_warn_count;
extern int irun_error_count;
extern int irun_warn_count;
/* FORWARDS */
void print_usage(); /* how to call the program */
void set_pc_code(); /* store a code segment */
/*******************************************************************/
/* */
/* MAIN the main program ----------------------------------------- */
/* */
/*******************************************************************/
main(argc, argv)
int argc;
char **argv;
{
int optchar;
int n;
FILE *file;
int result;
char tabnam[100];
/* print banner */
fprintf(stdout, "\n ltx2x: A LaTeX to X autotagger\n");
fprintf(stdout, "\n (%s, %s)\n", FILE_VERSION, FILE_DATE);
/* open error log file */
file = fopen("ltx2x.err", "w");
if (!file) {
fprintf(stderr, "Fatal Error: Could not open file ltx2x.err\n");
exit(1);
}
filerr = file;
fprintf(stdout, "Error file is ltx2x.err\n");
fprintf(filerr, "Error file for program ltx2x (%s, %s)\n", FILE_VERSION, FILE_DATE);
fprintf(filerr, "Author: Peter Wilson (ex Catholic University and NIST)\n");
fprintf(filerr, "Email any comments or suggestions to
[email protected]\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 <
[email protected]> 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 */