/* printct.c Main and support routines for printing ltx2x ct file */ /* Written by Peter Wilson (Catholic University and NIST) */ /* pwilson@cme.nist.gov */ /* Version 0.1, July 1996 */ /* 0.2, November 1996 */ /*---------------------------------------------------------------------*/ char FILE_VERSION[] = "Version 0.2"; char FILE_DATE[] = "November 1996"; /* VERSION HISTORY: * Version 0.1 (July 1996): First release * Version 0.2 (November 1996): Added SWITCH_TO_XXX and SWITCH_BACK * Added CODE and friends * */ /* Development of this software was funded by the United States Government, * and is not subject to copyright. */ /* 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 PRINTCT software. * If the PRINTCT 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 PRINTCT 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 PRINTCT 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 PRINTCT SOFTWARE PROVE DEFECTIVE, * YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. * * IN NO EVENT WILL NIST BE LIABLE FOR DAMAGES, * INCLUDING ANY LOST PROFITS, LOST MONIES, OR OTHER SPECIAL, * INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR * INABILITY TO USE (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA * BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY THIRD PARTIES OR A * FAILURE OF THE PROGRAM TO OPERATE WITH PROGRAMS NOT DISTRIBUTED BY * NIST) THE PROGRAMS, EVEN IF YOU HAVE BEEN ADVISED OF THE POSSIBILITY OF * SUCH DAMAGES, OR FOR ANY CLAIM BY ANY OTHER PARTY. */ #include #include "getopt.h" #include #include #ifndef STRTYPES_H #include "strtypes.h" #endif /* typedef char *STRING; A pointer-to-a-char */ /* typedef STRING *PTRADR; A pointer-to-a-pointer-to-a-char */ /* define SNUL '\0' end of a string */ # define MAX_ERRORS 10 FILE *filerr; /* Error file */ FILE *filtabin; /* Table input file */ FILE *filtabout; /* Table output file */ int TDEBUG = FALSE; /* for debugging command table */ /* length of a user buffer */ # define MAX_UBUFF_LEN 514 char errstr[MAX_UBUFF_LEN]; /* buffer for assembling error/warning text */ /* keywords */ enum key_word{AUDIBLE_ALERT_CHAR, BACKSPACE_CHAR, CA, CARRIAGE_RETURN_CHAR, CODE, CODE_SETUP, COMMENT, CONTINUE, END_CODE, END_CTFILE, END_ITEM, END_ITEM_PARAM, END_MODE, END_OPT, END_TAG, END_TAG_1, END_TAG_2, END_TAG_3, END_TAG_4, END_TAG_5, END_TAG_6, END_TAG_7, END_TAG_8, END_TAG_9, END_TYPE, ESCAPE_CHAR, FORMFEED_CHAR, HEX_CHAR, HORIZONTAL_TAB_CHAR, INCLUDE, IN_MODE, NAMEK, NEWLINE_CHAR, OPT_PARAM, PC_AT_END, PC_AT_START, PRINT_CONTROL, PRINT_OPT, PRINT_P1, PRINT_P2, PRINT_P3, PRINT_P4, PRINT_P5, PRINT_P6, PRINT_P7, PRINT_P8, PRINT_P9, REQPARAMS, RESET_BUFFER, RESET_FILE, RESET_MODE, RESET_SYSBUF, SECTIONING_LEVEL, SET_MODE, SOURCE, SPECIAL_TOKEN, START_ITEM, START_ITEM_PARAM, START_OPT, START_TAG, START_TAG_1, START_TAG_2, START_TAG_3, START_TAG_4, START_TAG_5, START_TAG_6, START_TAG_7, START_TAG_8, START_TAG_9, STRINGG, SWITCH_BACK, SWITCH_TO_BUFFER, SWITCH_TO_FILE, SWITCH_TO_SYSBUF, TYPE, VERTICAL_TAB_CHAR, MAX_KEYSTR}; int max_keystr = MAX_KEYSTR; STRING key_array[MAX_KEYSTR]; void strtouc(); /* convert string to upper case */ int lookup_string(); /* finds posn. of string in an ordered array of strings */ void init_print_control(); void init_keys(); int key_to_int(); STRING key_to_string(); enum cont_enum {CONT_UNKNOWN_ENUM, CONT_TAG}; #define MAX_TABLE_LINE 1000 char table_line[MAX_TABLE_LINE]; #define MAX_TABLE_ENTRIES 1000 int num_table_errors = 0; STRING unk = "ERROR"; enum print_control{BUFFER, DEFAULT_PRINT, FFILE, FIRST_STRING, MODE, NO_OP, NO_PRINT, PRINT_UNDERFLOW, RESET, SOURCE_STRING, SYSBUF, TO_BUFFER, TO_FILE, TO_SYSBUF, UNKNOWN_PRINT, MAX_PCSTR}; int max_pcstr = MAX_PCSTR; STRING pc_array[MAX_PCSTR]; void delete_to_chars(); void table_error(); void tdebug_tline(); void tdebug_str_str_int(); void tdebug_str_int(); void tdebug_str(); void process_table(); void process_pc(); int ct_lineno = 0; /* table line number */ /* 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() */ /*-----------------------------------------------------------------*/ /* MAIN the main program ----------------------------------------- */ main(argc, argv) int argc; char **argv; { int optchar; FILE *file; char tabnam[100]; /* print banner */ fprintf(stdout, "\n printct: An ltx2x command table printer\n"); fprintf(stdout, "\n (%s, %s)\n", FILE_VERSION, FILE_DATE); /* open error log file */ file = fopen("printct.err", "w"); if (!file) { fprintf(stderr, "Fatal Error: Could not open file printct.err\n"); exit(1); } filerr = file; fprintf(stdout, "Error file is printct.err\n"); fprintf(filerr, "Error file for program printct (%s, %s)\n", FILE_VERSION, FILE_DATE); fprintf(filerr, "Author: Peter Wilson (Catholic University and NIST)\n"); fprintf(filerr, "Email any comments or suggestions to pwilson@cme.nist.gov\n\n"); /* open Table output file */ file = fopen("printct.lis", "w"); if (!file) { fprintf(stderr, "Fatal Error: Could not open file printct.lis\n"); exit(1); } filtabout = file; fprintf(stdout, "Table output file is printct.lis\n"); fprintf(filerr, "Table output file is printct.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,"tf:P:D:"))) { /* Uwe Sassenberg sassen@hal1.physik.uni-dortmund.de found * that he had to add this next line of code to stop an infinite * loop of this while (It did not seem to recognise EOF !!) * If it compiles but just sits there chewing CPU cycles, try * uncommenting the next line of code */ /* if (optchar == 255) break; */ switch(optchar) { case '?': /* command line error */ fprintf(stderr, "\nUsage: [-t] [-f tablename] [-P chars] [-D char]\n"); fprintf(filerr, "\nUsage: [-t] [-f tablename] [-P chars] [-D char]\n"); 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 'f': /* special Table input file */ strcpy(tabnam, optarg); 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; } /* end of 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); /* No other parameters */ /* do some initialisations */ init_keys(); /* 6/96 initialise command keywords */ init_print_control(); /* initialise pc keywords */ process_table(filtabin, filtabout); fclose(filtabin); fclose(filtabout); exit(0); } /* end MAIN */ /*------------------------------------------------------------------------*/ /*-----------STRING FUNCTIONS-------------------------*/ /* 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 */ /* 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 */ /*---------------ERROR AND DEBUG PRINTING-------------*/ /* TABLE_ERROR prints Command table error message */ void table_error(s) char *s; { fprintf(stderr, "\nCommand table: %s line\n%d: %s\n", s, ct_lineno, table_line); fprintf(filerr, "\nCommand table: %s line\n%d: %s\n", s, ct_lineno, 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 */ /* TDEBUG_TLINE prints table line */ void tdebug_tline(str) char str[]; { fprintf(stderr, "\nline %d: %s", ct_lineno, str); fprintf(filerr, "\nline %d: %s", ct_lineno, str); fflush(stderr); fflush(filerr); } /* end TDEBUG_TLINE */ /* 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 */ /* PROCESS_TABLE reads and writes a command table */ /* Just checks keyword at start of line then prints the line out */ /* Keywords are specified in key_word enumeration */ /*-----------------------------------------------------------------------*/ int in_code; /* global flag TRUE while processing CODE */ void process_table(fin, fout) FILE *fin; /* input file */ FILE *fout; /* output file */ { char line[MAX_TABLE_LINE]; char code_name[MAX_TABLE_LINE]; int num_names; int num; char str[MAX_TABLE_LINE]; int last_string = CONT_UNKNOWN_ENUM; char *cin; int key; /* command keyword */ STRING tab0 = ""; STRING tab1 = " "; STRING tab2 = " "; STRING tab3 = " "; char code_tab[20]; in_code = FALSE; /* flag for CODE processing */ for (;;) { /* loop over all files */ line[0] = SNUL; cin = fgets(line, MAX_TABLE_LINE, fin); /* read a line */ ct_lineno++; if (TDEBUG) { tdebug_tline(line); } if (feof(fin) != 0) { /* end of this file */ return; } strcpy(table_line, line); /* get first name on line */ num_names = sscanf(line, "%s", code_name); if (num_names <= 0) { /* blank line */ fprintf(fout, "\n"); 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"); } delete_to_chars("=:", line); fprintf(fout, "%s%s%s", tab0, key_to_string(key), line); break; } case CA : case COMMENT : { /* comment line */ if (TDEBUG) { tdebug_str("C=\n"); } delete_to_chars("=:", line); fprintf(fout, "%sc=%s", tab3, line); /* print lower case c= */ break; } case INCLUDE : { /* file inclusion */ if (TDEBUG) { tdebug_str(code_name); } last_string = CONT_UNKNOWN_ENUM; delete_to_chars("=:", line); fprintf(fout, "%s%s%s", tab0, key_to_string(key), line); break; } case TYPE : { /* start of a record */ last_string = CONT_UNKNOWN_ENUM; delete_to_chars("=:", line); fprintf(fout, "%s%s%s", tab0, key_to_string(key), line); break; } case END_TYPE : { /* end of a record */ last_string = CONT_UNKNOWN_ENUM; /* delete_to_chars("=:", line); */ fprintf(fout, "%s%s", tab0, line); break; } case NAMEK : { /* process NAME= */ last_string = CONT_UNKNOWN_ENUM; delete_to_chars("=:", line); fprintf(fout, "%s%s%s", tab0, key_to_string(key), line); break; } case PRINT_CONTROL : { /* process PRINT_CONTROL= */ last_string = CONT_UNKNOWN_ENUM; delete_to_chars("=:", line); if (TDEBUG) { sprintf(errstr, "%s %s\n", code_name, line); tdebug_str(errstr); } fprintf(fout, "%s%s", tab1, key_to_string(key)); process_pc(fout, line); break; } case START_TAG : case END_TAG : { /* process START/END__TAG= */ last_string = CONT_TAG; delete_to_chars("=:", line); fprintf(fout, "%s%s%s", tab1, key_to_string(key), line); break; } case OPT_PARAM : { /* process OPT_PARAM= */ last_string = CONT_UNKNOWN_ENUM; delete_to_chars("=:", line); fprintf(fout, "%s%s%s", tab1, key_to_string(key), line); break; } case PRINT_OPT : { /* process PRINT_OPT= */ last_string = CONT_UNKNOWN_ENUM; delete_to_chars("=:", line); fprintf(fout, "%s%s%s", tab1, key_to_string(key), line); break; } case START_OPT : case END_OPT : { /* process START/END_OPT= */ last_string = CONT_TAG; delete_to_chars("=:", line); fprintf(fout, "%s%s%s", tab1, key_to_string(key), line); 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 ) { ; } else { table_error("REQPARAMS out of range (0-9)"); } fprintf(fout, "%s%s%s", tab1, key_to_string(key), line); break; } case START_TAG_1 : case END_TAG_1 : case START_TAG_2 : case END_TAG_2 : case START_TAG_3 : case END_TAG_3 : case START_TAG_4 : case END_TAG_4 : case START_TAG_5 : case END_TAG_5 : case START_TAG_6 : case END_TAG_6 : case START_TAG_7 : case END_TAG_7 : case START_TAG_8 : case END_TAG_8 : case START_TAG_9 : case END_TAG_9 : { /* process START/END_TAG_N= */ last_string = CONT_TAG; delete_to_chars("=:", line); fprintf(fout, "%s%s%s", tab1, key_to_string(key), line); break; } case PRINT_P1 : case PRINT_P2 : case PRINT_P3 : case PRINT_P4 : case PRINT_P5 : case PRINT_P6 : case PRINT_P7 : case PRINT_P8 : case PRINT_P9 : { /* process PRINT_PN= */ last_string = CONT_UNKNOWN_ENUM; delete_to_chars("=:", line); fprintf(fout, "%s%s", tab1, key_to_string(key)); process_pc(fout, line); break; } case START_ITEM : case END_ITEM : { /* process START/END_ITEM= */ last_string = CONT_TAG; delete_to_chars("=:", line); fprintf(fout, "%s%s%s", tab1, key_to_string(key), line); break; } case START_ITEM_PARAM : case END_ITEM_PARAM : { /* process START/END_ITEM_PARAM= */ last_string = CONT_TAG; delete_to_chars("=:", line); fprintf(fout, "%s%s%s", tab1, key_to_string(key), line); break; } case CONTINUE : /* process CONTINUE= */ case STRINGG : { /* process STRING= */ delete_to_chars("=:", line); fprintf(fout, "%s%s%s", tab2, key_to_string(STRINGG), line); 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); } delete_to_chars("=:", line); fprintf(fout, "%s%s%s", tab2, key_to_string(key), line); break; } case PC_AT_START : case PC_AT_END : { /* 6/96 process PC_AT_START/END= */ last_string = CONT_UNKNOWN_ENUM; delete_to_chars("=:", line); fprintf(fout, "%s%s", tab1, key_to_string(key)); process_pc(fout, 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); fprintf(fout, "%s%s%s", tab1, key_to_string(key), line); if (TDEBUG) { sprintf(errstr, "%s %s\n", code_name, str); tdebug_str(errstr); } break; } case RESET_SYSBUF : case RESET_BUFFER : case RESET_FILE : case RESET_MODE : case SET_MODE : { /* process (RE)SET_X= */ 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); } delete_to_chars("=:", line); fprintf(fout, "%s%s%s", tab2, key_to_string(key), line); break; } case SWITCH_BACK : case SWITCH_TO_BUFFER : case SWITCH_TO_FILE : case SWITCH_TO_SYSBUF : { /* 11/96 process SWITCH-XXX */ 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); } delete_to_chars("=:", line); fprintf(fout, "%s%s%s", tab2, key_to_string(key), line); break; } case IN_MODE : { /* 6/96 process IN_MODE */ last_string = CONT_UNKNOWN_ENUM; delete_to_chars("=:", line); fprintf(fout, "%s%s%s", tab0, key_to_string(key), line); break; } case END_MODE : { /* 6/96 process END_MODE */ last_string = CONT_UNKNOWN_ENUM; /* delete_to_chars("=:", line); */ fprintf(fout, "%s%s", tab0, line); break; } case SPECIAL_TOKEN : { /* process SPECIAL_TOKEN= */ last_string = CONT_UNKNOWN_ENUM; delete_to_chars("=:", line); fprintf(fout, "%s%s%s", tab0, key_to_string(key), line); break; } case ESCAPE_CHAR : case NEWLINE_CHAR : case HORIZONTAL_TAB_CHAR : case VERTICAL_TAB_CHAR : case BACKSPACE_CHAR : case CARRIAGE_RETURN_CHAR : case FORMFEED_CHAR : case AUDIBLE_ALERT_CHAR : case HEX_CHAR : { /* process characters */ if (TDEBUG) { tdebug_str(code_name); } last_string = CONT_UNKNOWN_ENUM; delete_to_chars("=:", line); fprintf(fout, "%s%s%s", tab0, key_to_string(key), line); break; } case CODE_SETUP : { /* CODE_SETUP added for code interp */ if (TDEBUG) { sprintf(errstr, "%s\n", code_name); tdebug_str(errstr); } last_string = CONT_UNKNOWN_ENUM; fprintf(fout, "%s%s\n", tab0, key_to_string(key)); strcpy(code_tab, tab0); in_code = TRUE; break; } case CODE : { /* CODE added for code interp */ 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); } fprintf(fout, "%s%s\n", tab2, key_to_string(key)); strcpy(code_tab, tab2); in_code = TRUE; break; } default : { /* possibly unrecognised */ if (!in_code) { /* unrecognised! */ if (TDEBUG) { tdebug_str("UNRECOGNISED CODE NAME\n"); } last_string = CONT_UNKNOWN_ENUM; table_error("Unrecognised code"); break; } /* are in CODE processing */ if (key == END_CODE) { /* end of CODE */ if (TDEBUG) { sprintf(errstr, "%s\n", code_name); tdebug_str(errstr); } fprintf(fout, "%s%s\n", code_tab, key_to_string(key)); in_code = FALSE; break; } else { /* still in CODE, just print */ fprintf(fout, "%s%s", code_tab, table_line); break; } break; } /* end of default case */ } /* end of switch */ fflush(fout); } /* end of loop over all files */ } /* end PROCESS_TABLE */ /*---------------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 */ /*---------------------------------------------------------------*/ /* 6/96 extras */ /* PARSE_PC parses print control and returns new structure */ void process_pc(fout, a_line) FILE *fout; char a_line[]; { char key_name[MAX_TABLE_LINE]; int key_enum; /* 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 */ fprintf(fout, "%s", a_line); return; } case NO_PRINT: { /* got it all */ fprintf(fout, "%s", a_line); return; } case TO_SYSBUF: { /* got it all */ fprintf(fout, "%s", a_line); return; } case PRINT_UNDERFLOW: { /* got it all */ fprintf(fout, "%s", a_line); return; } case UNKNOWN_PRINT: { /* got it all */ fprintf(fout, "%s", a_line); return; } case TO_BUFFER: { /* get buffer number */ fprintf(fout, "%s", a_line); return; } case TO_FILE: { /* get file */ fprintf(fout, "%s", a_line); return; } case SYSBUF: { /* got it all */ fprintf(fout, "%s", a_line); return; } case BUFFER: { /* get buffer number */ fprintf(fout, "%s", a_line); return; } case FFILE: { /* get file */ fprintf(fout, "%s", a_line); return; } case FIRST_STRING: { /* get string */ fprintf(fout, "%s", a_line); return; } case RESET: { /* got it all */ fprintf(fout, "%s", a_line); return; } case NO_OP: { /* got it all */ fprintf(fout, "%s", a_line); return; } default: { fprintf(fout, "**** %s", a_line); return; } } } /* end PROCESS_PC */ /* 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() { /* set up enum/str array */ pc_array[BUFFER] = "BUFFER"; pc_array[DEFAULT_PRINT] = "DEFAULT_PRINT"; pc_array[FFILE] = "FILE"; pc_array[FIRST_STRING] = "FIRST_STRING"; pc_array[MODE] = "MODE"; pc_array[NO_OP] = "NO_OP"; pc_array[NO_PRINT] = "NO_PRINT"; pc_array[PRINT_UNDERFLOW] = "PRINT_UNDERFLOW"; pc_array[RESET] = "RESET"; pc_array[SOURCE_STRING] = "SOURCE_STRING"; pc_array[SYSBUF] = "SYSBUF"; pc_array[TO_BUFFER] = "TO_BUFFER"; pc_array[TO_FILE] = "TO_FILE"; pc_array[TO_SYSBUF] = "TO_SYSBUF"; pc_array[UNKNOWN_PRINT] = "UNKNOWN_PRINT"; } /* 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 */ /* INIT_KEYS initialises keyword stuff */ void init_keys() { /* set up enum/string array */ key_array[AUDIBLE_ALERT_CHAR] = "AUDIBLE_ALERT_CHAR="; key_array[BACKSPACE_CHAR] = "BACKSPACE_CHAR="; key_array[CA] = "C="; key_array[CARRIAGE_RETURN_CHAR] = "CARRIAGE_RETURN_CHAR="; key_array[CODE] = "CODE:"; key_array[CODE_SETUP] = "CODE_SETUP="; key_array[COMMENT] = "COMMENT="; key_array[CONTINUE] = "CONTINUE="; key_array[END_CODE] = "END_CODE"; key_array[END_CTFILE] = "END_CTFILE="; key_array[END_ITEM] = "END_ITEM="; key_array[END_ITEM_PARAM] = "END_ITEM_PARAM="; key_array[END_MODE] = "END_MODE"; key_array[END_OPT] = "END_OPT="; key_array[END_TAG] = "END_TAG="; key_array[END_TAG_1] = "END_TAG_1="; key_array[END_TAG_2] = "END_TAG_2="; key_array[END_TAG_3] = "END_TAG_3="; key_array[END_TAG_4] = "END_TAG_4="; key_array[END_TAG_5] = "END_TAG_5="; key_array[END_TAG_6] = "END_TAG_6="; key_array[END_TAG_7] = "END_TAG_7="; key_array[END_TAG_8] = "END_TAG_8="; key_array[END_TAG_9] = "END_TAG_9="; key_array[END_TYPE] = "END_TYPE"; key_array[ESCAPE_CHAR] = "ESCAPE_CHAR="; key_array[FORMFEED_CHAR] = "FORMFEED_CHAR="; key_array[HEX_CHAR] = "HEX_CHAR="; key_array[HORIZONTAL_TAB_CHAR] = "HORIZONTAL_TAB_CHAR="; key_array[INCLUDE] = "INCLUDE="; key_array[IN_MODE] = "IN_MODE="; key_array[NAMEK] = "NAME="; key_array[NEWLINE_CHAR] = "NEWLINE_CHAR="; key_array[OPT_PARAM] = "OPT_PARAM="; key_array[PC_AT_END] = "PC_AT_END="; key_array[PC_AT_START] = "PC_AT_START="; key_array[PRINT_CONTROL] = "PRINT_CONTROL="; key_array[PRINT_OPT] = "PRINT_OPT="; key_array[PRINT_P1] = "PRINT_P1="; key_array[PRINT_P2] = "PRINT_P2="; key_array[PRINT_P3] = "PRINT_P3="; key_array[PRINT_P4] = "PRINT_P4="; key_array[PRINT_P5] = "PRINT_P5="; key_array[PRINT_P6] = "PRINT_P6="; key_array[PRINT_P7] = "PRINT_P7="; key_array[PRINT_P8] = "PRINT_P8="; key_array[PRINT_P9] = "PRINT_P9="; key_array[REQPARAMS] = "REQPARAMS="; key_array[RESET_BUFFER] = "RESET_BUFFER:"; key_array[RESET_FILE] = "RESET_FILE:"; key_array[RESET_MODE] = "RESET_MODE:"; key_array[RESET_SYSBUF] = "RESET_SYSBUF:"; key_array[SECTIONING_LEVEL] = "SECTIONING_LEVEL="; key_array[SET_MODE] = "SET_MODE:"; key_array[SOURCE] = "SOURCE:"; key_array[SPECIAL_TOKEN] = "SPECIAL_TOKEN="; key_array[START_ITEM] = "START_ITEM="; key_array[START_ITEM_PARAM] = "START_ITEM_PARAM="; key_array[START_OPT] = "START_OPT="; key_array[START_TAG] = "START_TAG="; key_array[START_TAG_1] = "START_TAG_1="; key_array[START_TAG_2] = "START_TAG_2="; key_array[START_TAG_3] = "START_TAG_3="; key_array[START_TAG_4] = "START_TAG_4="; key_array[START_TAG_5] = "START_TAG_5="; key_array[START_TAG_6] = "START_TAG_6="; key_array[START_TAG_7] = "START_TAG_7="; key_array[START_TAG_8] = "START_TAG_8="; key_array[START_TAG_9] = "START_TAG_9="; key_array[STRINGG] = "STRING:"; key_array[SWITCH_BACK] = "SWITCH_BACK:"; key_array[SWITCH_TO_BUFFER] = "SWITCH_TO_BUFFER:"; key_array[SWITCH_TO_FILE] = "SWITCH_TO_FILE:"; key_array[SWITCH_TO_SYSBUF] = "SWITCH_TO_SYSBUF:"; key_array[TYPE] = "TYPE="; key_array[VERTICAL_TAB_CHAR] = "VERTICAL_TAB_CHAR="; } /* end INIT_KEYS */ /* KEY_TO_INT converts a keyword string to an integer */ int key_to_int(s, no_error) STRING s; { int pos; pos = lookup_string(s, key_array, max_keystr); if (pos == -1) { /* unknown string */ if (!in_code) { 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 */