/* printct.c Main and support routines for printing ltx2x ct file */
/* Written by Peter Wilson (Catholic University and NIST) */
/*
[email protected] */
/* 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 <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 */
# 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
[email protected]\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
[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 */
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 */