home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Power-Programmierung
/
CD1.mdf
/
icon
/
dos
/
src
/
common
/
rtdb.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-02-10
|
42KB
|
1,501 lines
/*
* Routines to read a data base of run-time information.
*/
#include <ctype.h>
#include "../h/gsupport.h"
#include "../h/version.h"
#define GetInt(n, c)\
n = 0;\
while (isdigit(c)) {\
n = n * 10 + (c - '0');\
c = getc(db);\
}
#define SkipWhSp(c)\
while (isspace(c)) {\
if (c == '\n')\
++dbline;\
c = getc(db);\
}
/*
* prototypes for static functions.
*/
hidden int cmp_1_pre Params((int p1, int p2));
hidden struct il_code *db_abstr Params((noargs));
hidden novalue db_case Params((struct il_code *il, int num_cases));
hidden novalue db_err3 Params((int fatal,char *s1,char *s2,char *s3));
hidden int db_icntyp Params((noargs));
hidden struct il_c *db_ilc Params((noargs));
hidden struct il_c *db_ilcret Params((int il_c_type));
hidden struct il_code *db_inlin Params((noargs));
hidden struct il_code *db_ilvar Params((noargs));
hidden int db_rtflg Params((noargs));
hidden int db_tndtyp Params((noargs));
hidden struct il_c *new_ilc Params((int il_c_type));
hidden novalue quoted Params((int delim));
extern char *progname;
static char *dbname;
static FILE *db;
static int dbline;
static struct str_buf db_sbuf;
/*
* opendb - open data base and do other house keeping.
*/
int db_open(s, lrgintflg)
char *s;
char **lrgintflg;
{
char *msg_buf;
static int first_time = 1;
if (first_time) {
first_time = 0;
init_sbuf(&db_sbuf);
}
dbname = s;
dbline = 0;
*lrgintflg = NULL;
db = fopen(dbname, "r");
if (db == NULL)
return 0;
++dbline;
s = db_string();
if (strcmp(s, DVersion) != 0) {
msg_buf = (char *)alloc((unsigned int) 35 + (int)(strlen(s) +
strlen(progname) + strlen(DVersion)));
sprintf(msg_buf, "found version %s, %s requires version %s",
s, progname, DVersion);
db_err1(1, msg_buf);
}
*lrgintflg = db_string();
return 1;
}
novalue db_close()
{
fclose(db);
}
char *db_string()
{
register int c;
/*
* Look for the start of the string; '$' starts a special indicator.
* Copy characters into string buffer until white space is found.
*/
c = getc(db);
SkipWhSp(c);
if (c == EOF)
db_err1(1, "unexpeced EOF");
if (c == '$')
return NULL;
while (!isspace(c) && c != EOF) {
AppChar(db_sbuf, c);
c = getc(db);
}
if (c == '\n')
++dbline;
return str_install(&db_sbuf);
}
/*
* db_impl reads basic implementation information into a structure and
* returns it.
*/
struct implement *db_impl(oper_typ)
int oper_typ;
{
register struct implement *ip;
register int c;
int i;
char *name;
long n;
if ((name = db_string()) == NULL)
return NULL;
ip = NewStruct(implement);
ip->blink = NULL;
ip->iconc_flgs = 0; /* reserved for internal use by compiler */
ip->oper_typ = oper_typ;
ip->name = name;
ip->op = NULL;
c = getc(db);
SkipWhSp(c)
if (isalpha(c) || isdigit(c))
ip->prefix[0] = c;
else
db_err2(1, "invalid prefix for", ip->name);
c = getc(db);
if (isalpha(c) || isdigit(c))
ip->prefix[1] = c;
else
db_err2(1, "invalid prefix for", ip->name);
c = getc(db);
SkipWhSp(c)
if (!isdigit(c))
db_err2(1, "number of parameters missing for", ip->name);
GetInt(n, c)
ip->nargs = n;
if (n == 0)
ip->arg_flgs = NULL;
else
ip->arg_flgs = (int *)alloc((unsigned int) (sizeof(int) * n));
if (c != '(')
db_err2(1, "parameter flags missing for", ip->name);
c = getc(db);
for (i = 0; i < n; ++i) {
if (c == ',' || c == ')')
db_err2(1, "parameter flag missing for", ip->name);
ip->arg_flgs[i] = 0;
while (c != ',' && c != ')') {
switch (c) {
case 'u':
ip->arg_flgs[i] |= RtParm;
break;
case 'd':
ip->arg_flgs[i] |= DrfPrm;
break;
case 'v':
ip->arg_flgs[i] |= VarPrm;
break;
default:
db_err2(1, "invalid parameter flag for", ip->name);
}
c = getc(db);
}
if (c == ',')
c = getc(db);
}
if (c != ')')
db_err2(1, "invalid parameter flag list for", ip->name);
c = getc(db);
SkipWhSp(c)
if (c != '{')
db_err2(1, "result sequence missing for", ip->name);
c = getc(db);
ip->resume = 0;
if (c == '}') {
ip->min_result = NoRsltSeq;
ip->max_result = NoRsltSeq;
}
else {
if (!isdigit(c))
db_err2(1, "invalid result sequence for", ip->name);
GetInt(n, c)
ip->min_result = n;
if (c != ',')
db_err2(1, "invalid result sequence for", ip->name);
c = getc(db);
if (c == '*') {
ip->max_result = UnbndSeq;
c = getc(db);
}
else if (isdigit(c)) {
GetInt(n, c)
ip->max_result = n;
}
else
db_err2(1, "invalid result sequence for", ip->name);
if (c == '+') {
ip->resume = 1;
c = getc(db);
}
if (c != '}')
db_err2(1, "invalid result sequence for", ip->name);
}
ip->ret_flag = db_rtflg();
c = getc(db);
SkipWhSp(c)
switch (c) {
case 't':
ip->use_rslt = 1;
break;
case 'f':
ip->use_rslt = 0;
break;
default:
db_err2(1, "invalid 'result' use indicator for", ip->name);
}
return ip;
}
/*
* db_code - read the in-line code for an operation.
*/
novalue db_code(ip)
struct implement *ip;
{
register int c;
char *s;
word n;
int var_type;
int i;
/*
* read the descriptive string.
*/
c = getc(db);
SkipWhSp(c)
if (c != '"')
db_err1(1, "operation description expected");
for (c = getc(db); c != '"' && c != '\n' && c != EOF; c = getc(db)) {
if (c == '\\') {
AppChar(db_sbuf, c);
c = getc(db);
}
AppChar(db_sbuf, c);
}
if (c != '"')
db_err1(1, "expected '\"'");
ip->comment = str_install(&db_sbuf);
c = getc(db);
SkipWhSp(c)
GetInt(n, c)
ip->ntnds = n;
if (n == 0)
ip->tnds = NULL;
else
ip->tnds = (struct tend_var *)alloc((unsigned int)
(sizeof(struct tend_var) * n));
for (i = 0; i < n; ++i) {
var_type = db_tndtyp();
ip->tnds[i].var_type = var_type;
ip->tnds[i].blk_name = NULL;
if (var_type == TndBlk) {
s = db_string();
if (s == NULL)
db_err1(1, "block name expected");
if (*s != '*')
ip->tnds[i].blk_name = s;
}
ip->tnds[i].init = db_ilc();
}
c = getc(db);
SkipWhSp(c)
GetInt(n, c)
ip->nvars = n;
if (n == 0)
ip->vars = NULL;
else
ip->vars = (struct ord_var *)alloc((unsigned int)
(sizeof(struct ord_var) * n));
for (i = 0; i < n; ++i) {
s = db_string();
if (s == NULL)
db_err1(1, "variable name expected");
ip->vars[i].name = s;
ip->vars[i].dcl = db_ilc();
}
ip->in_line = db_inlin();
c = getc(db);
SkipWhSp(c)
if (c != '$')
db_err1(1, "expected $end");
}
/*
* db_inlin - read in the in-line code for an operation.
*/
static struct il_code *db_inlin()
{
struct il_code *il;
register int c;
int i;
int indx;
int n, n1;
c = getc(db);
SkipWhSp(c)
switch (c) {
case 'a':
db_chstr("a", "bstr");
il = new_il(IL_Abstr, 2);
il->u[0].fld = db_abstr();
il->u[1].fld = db_abstr();
break;
case 'b':
db_chstr("b", "lock");
c = getc(db);
SkipWhSp(c)
GetInt(n, c) /* number of local tended */
il = new_il(IL_Block, 2 + n);
il->u[0].n = n;
for (i = 1; i <= n; ++i)
il->u[i].n = db_tndtyp();
il->u[i].c_cd = db_ilc(); /* body of block */
break;
case 'c':
switch (getc(db)) {
case 'a': {
char prfx3;
int ret_val;
int ret_flag;
int rslt;
int num_sbuf;
int num_cbuf;
db_chstr("ca", "ll");
c = getc(db);
SkipWhSp(c)
prfx3 = c;
c = getc(db);
SkipWhSp(c)
switch (c) {
case 'i':
ret_val = RetInt;
break;
case 'd':
ret_val = RetDbl;
break;
case 'n':
ret_val = RetNoVal;
break;
case 's':
ret_val = RetSig;
break;
default:
db_err1(1, "invalid indicator for type of return value");
}
c = getc(db);
ret_flag = db_rtflg();
c = getc(db);
SkipWhSp(c)
switch (c) {
case 't':
rslt = 1;
break;
case 'f':
rslt = 0;
break;
default:
db_err1(1, "t or f expected");
}
c = getc(db);
SkipWhSp(c)
GetInt(num_sbuf, c)
c = getc(db);
SkipWhSp(c)
GetInt(num_cbuf, c)
c = getc(db);
SkipWhSp(c)
GetInt(n, c) /* num args */
il = new_il(IL_Call, 8 + n * 2);
il->u[0].n = 0; /* reserved for internal use by compiler */
il->u[1].n = prfx3;
il->u[2].n = ret_val;
il->u[3].n = ret_flag;
il->u[4].n = rslt;
il->u[5].n = num_sbuf;
il->u[6].n = num_cbuf;
il->u[7].n = n;
indx = 8;
/*
* get the prototype parameter declarations and actual arguments.
*/
n *= 2;
while (n--)
il->u[indx++].c_cd = db_ilc();
}
break;
case 'n':
if (getc(db) != 'v')
db_err1(1, "expected cnv1 or cnv2");
switch (getc(db)) {
case '1':
il = new_il(IL_Cnv1, 2);
il->u[0].n = db_icntyp(); /* type code */
il->u[1].fld = db_ilvar(); /* source */
break;
case '2':
il = new_il(IL_Cnv2, 3);
il->u[0].n = db_icntyp(); /* type code */
il->u[1].fld = db_ilvar(); /* source */
il->u[2].c_cd = db_ilc(); /* destination */
break;
default:
db_err1(1, "expected cnv1 or cnv2");
}
break;
case 'o':
db_chstr("co", "nst");
il = new_il(IL_Const, 2);
il->u[0].n = db_icntyp(); /* type code */
c = getc(db);
SkipWhSp(c)
if (c == '"' || c == '\'') {
quoted(c);
c = getc(db);
}
else
while (c != EOF && !isspace(c)) {
AppChar(db_sbuf, c);
c = getc(db);
}
il->u[1].s = str_install(&db_sbuf);
break;
default:
db_err1(1, "expected call, const, cnv1, or cnv2");
}
break;
case 'd':
if (getc(db) != 'e' || getc(db) != 'f')
db_err1(1, "expected def1 or def2");
switch (getc(db)) {
case '1':
il = new_il(IL_Def1, 3);
il->u[0].n = db_icntyp(); /* type code */
il->u[1].fld = db_ilvar(); /* source */
il->u[2].c_cd = db_ilc(); /* default value */
break;
case '2':
il = new_il(IL_Def2, 4);
il->u[0].n = db_icntyp(); /* type code */
il->u[1].fld = db_ilvar(); /* source */
il->u[2].c_cd = db_ilc(); /* default value */
il->u[3].c_cd = db_ilc(); /* destination */
break;
default:
db_err1(1, "expected dflt1 or dflt2");
}
break;
case 'r':
if (getc(db) != 'u' || getc(db) != 'n' || getc(db) != 'e' ||
getc(db) != 'r' || getc(db) != 'r')
db_err1(1, "expected runerr1 or runerr2");
switch (getc(db)) {
case '1':
il = new_il(IL_Err1, 1);
c = getc(db);
SkipWhSp(c)
GetInt(n, c)
il->u[0].n = n; /* error number */
break;
case '2':
il = new_il(IL_Err2, 2);
c = getc(db);
SkipWhSp(c)
GetInt(n, c)
il->u[0].n = n; /* error number */
il->u[1].fld = db_ilvar(); /* variable */
break;
default:
db_err1(1, "expected runerr1 or runerr2");
}
break;
case 'i':
switch (getc(db)) {
case 'f':
switch (getc(db)) {
case '1':
il = new_il(IL_If1, 2);
il->u[0].fld = db_inlin(); /* condition */
il->u[1].fld = db_inlin(); /* then clause */
break;
case '2':
il = new_il(IL_If2, 3);
il->u[0].fld = db_inlin(); /* condition */
il->u[1].fld = db_inlin(); /* then clause */
il->u[2].fld = db_inlin(); /* else clause */
break;
default:
db_err1(1, "expected if1 or if2");
}
break;
case 's':
il = new_il(IL_Is, 2);
il->u[0].n = db_icntyp(); /* type code */
il->u[1].fld = db_ilvar(); /* variable */
break;
default:
db_err1(1, "expected if1, if2, or is");
}
break;
case 'l':
switch (getc(db)) {
case 'c':
db_chstr("lc", "ase");
c = getc(db);
SkipWhSp(c)
GetInt(n, c) /* number of cases */
il = new_il(IL_Lcase, 2 + 2 * n);
il->u[0].n = n;
indx = 1;
while (n--) {
c = getc(db);
SkipWhSp(c)
GetInt(n1, c)
il->u[indx++].n = n1; /* selection number */
il->u[indx++].fld = db_inlin(); /* action */
}
il->u[indx].fld = db_inlin(); /* default */
break;
case 's':
if (getc(db) != 't')
db_err1(1, "expected lst");
il = new_il(IL_Lst, 2);
il->u[0].fld = db_inlin();
il->u[1].fld = db_inlin();
break;
default:
db_err1(1, "expected lcase or lst");
}
break;
case 'n':
db_chstr("n", "il");
il = NULL;
break;
case 't': {
struct il_code *var;
if (getc(db) != 'c' || getc(db) != 'a' || getc(db) != 's' ||
getc(db) != 'e')
db_err1(1, "expected tcase1 or tcase2");
switch (getc(db)) {
case '1':
var = db_ilvar(); /* variable */
c = getc(db);
SkipWhSp(c)
GetInt(n, c)
il = new_il(IL_Tcase1, 3 * n + 2);
il->u[0].fld = var;
db_case(il, n);
break;
case '2':
var = db_ilvar(); /* variable */
c = getc(db);
SkipWhSp(c)
GetInt(n, c)
il = new_il(IL_Tcase2, 3 * n + 3);
il->u[0].fld = var;
db_case(il, n);
il->u[3 * n + 2].fld = db_inlin(); /* default */
break;
default:
db_err1(1, "expected tcase1 or tcase2");
}
}
break;
case '!':
il = new_il(IL_Bang, 1);
il->u[0].fld = db_inlin();
break;
case '&':
if (getc(db) != '&')
db_err1(1, "expected &&");
il = new_il(IL_And, 2);
il->u[0].fld = db_inlin();
il->u[1].fld = db_inlin();
break;
default:
db_err1(1, "syntax error");
}
return il;
}
static int db_rtflg()
{
register int c;
int ret_flag;
ret_flag = 0;
c = getc(db);
SkipWhSp(c)
if (c == 'f')
ret_flag |= DoesFail;
else if (c != '_')
db_err1(1, "invalid return indicator");
c = getc(db);
if (c == 'r')
ret_flag |= DoesRet;
else if (c != '_')
db_err1(1, "invalid return indicator");
c = getc(db);
if (c == 's')
ret_flag |= DoesSusp;
else if (c != '_')
db_err1(1, "invalid return indicator");
c = getc(db);
if (c == 'e')
ret_flag |= DoesEFail;
else if (c != '_')
db_err1(1, "invalid return indicator");
c = getc(db);
if (c == 't')
ret_flag |= DoesFThru;
else if (c != '_' && c != ' ')
db_err1(1, "invalid return indicator");
return ret_flag;
}
static novalue db_case(il, num_cases)
struct il_code *il;
int num_cases;
{
register int c;
int *typ_vect;
int i, j;
int num_types;
int indx;
il->u[1].n = num_cases;
indx = 2;
for (i = 0; i < num_cases; ++i) {
c = getc(db);
SkipWhSp(c)
GetInt(num_types, c)
il->u[indx++].n = num_types;
typ_vect = (int *)alloc((unsigned int)(sizeof(int) * num_types));
il->u[indx++].vect = typ_vect;
for (j = 0; j < num_types; ++j)
typ_vect[j] = db_icntyp(); /* type code */
il->u[indx++].fld = db_inlin(); /* action */
}
}
static struct il_code *db_ilvar()
{
struct il_code *il;
register int c;
int n;
c = getc(db);
SkipWhSp(c)
if (isdigit(c)) {
il = new_il(IL_Var, 1);
GetInt(n, c)
il->u[0].n = n; /* symbol table index */
}
else {
if (c != '[')
db_err1(1, "expected symbol table index or '['");
il = new_il(IL_Subscr, 2);
c = getc(db);
SkipWhSp(c);
GetInt(n, c)
il->u[0].n = n; /* symbol table index */
c = getc(db);
SkipWhSp(c)
GetInt(n, c)
il->u[1].n = n; /* subscripting index */
}
return il;
}
static struct il_code *db_abstr()
{
struct il_code *il;
register int c;
word typcd;
word indx;
int nargs;
c = getc(db);
SkipWhSp(c)
switch (c) {
case 'f':
db_chstr("f", "lds");
il = new_il(IL_Fields, 1);
il->u[0].fld = db_abstr(); /* record type */
break;
case 'l':
if (getc(db) != 's' || getc(db) != 't')
db_err1(1, "expected lst or lstelm");
switch (getc(db)) {
case ' ':
case '\t':
case '\n':
il = new_il(IL_Lst, 2);
il->u[0].fld = db_abstr();
il->u[1].fld = db_abstr();
break;
case 'e':
db_chstr("lste", "lm");
il = new_il(IL_LstElm, 1);
il->u[0].fld = db_abstr(); /* list type */
break;
default:
db_err1(1, "expected lst or lstelm");
}
break;
case 'n':
switch (getc(db)) {
case 'e':
if (getc(db) != 'w')
db_err1(1, "expected new");
typcd = db_icntyp();
c = getc(db);
SkipWhSp(c)
GetInt(nargs, c)
il = new_il(IL_New, 2 + nargs);
il->u[0].n = typcd;
il->u[1].n = nargs;
indx = 2;
while (nargs--)
il->u[indx++].fld = db_abstr();
break;
case 'i':
if (getc(db) != 'l')
db_err1(1, "expected nil");
il = NULL;
break;
default:
db_err1(1, "expected new or nil");
}
break;
case 's':
switch (getc(db)) {
case 'e':
db_chstr("se", "telm");
il = new_il(IL_SetElm, 1);
il->u[0].fld = db_abstr(); /* set type */
break;
case 't':
switch (getc(db)) {
case 'o':
db_chstr("sto", "re");
il = new_il(IL_Store, 1);
il->u[0].fld = db_abstr(); /* type to "dereference" */
break;
case 'r':
db_chstr("str", "var");
il = new_il(IL_StrVar, 1);
il->u[0].fld = db_abstr(); /* substring variable type */
break;
default:
db_err1(1, "expected store or strvar");
}
break;
default:
db_err1(1, "expected setelm, store, or strvar");
}
break;
case 't':
switch (getc(db)) {
case 'b':
if (getc(db) != 'l')
db_err1(1, "expected tbldf, tblelm, or tblkey");
switch (getc(db)) {
case 'd':
db_chstr("tbld", "ft");
il = new_il(IL_TblDft, 1);
il->u[0].fld = db_abstr(); /* table type */
break;
case 'e':
db_chstr("tble", "lm");
il = new_il(IL_TblElm, 1);
il->u[0].fld = db_abstr(); /* table type */
break;
case 'k':
db_chstr("tblk", "ey");
il = new_il(IL_TblKey, 1);
il->u[0].fld = db_abstr(); /* table type */
break;
default:
db_err1(1, "expected tbldf, tblelm, or tblkey");
}
break;
case 'r':
db_chstr("tr", "ptbl");
il = new_il(IL_TrpTbl, 1);
il->u[0].fld = db_abstr(); /* table trapped variable type */
break;
case 'y':
if (getc(db) != 'p')
db_err1(1, "expected typ");
il = new_il(IL_IcnTyp, 1);
il->u[0].n = db_icntyp(); /* type code */
break;
default:
db_err1(1, "expected tbldft, tblelm, tblkey, or typ");
}
break;
case 'v':
db_chstr("v", "artyp");
il = new_il(IL_VarTyp, 1);
il->u[0].fld = db_ilvar(); /* variable */
break;
case '=':
il = new_il(IL_TpAsgn, 2);
il->u[0].fld = db_abstr();
il->u[1].fld = db_abstr();
break;
case '+':
if (getc(db) != '+')
db_err1(1, "expected ++");
il = new_il(IL_Union, 2);
il->u[0].fld = db_abstr();
il->u[1].fld = db_abstr();
break;
case '*':
if (getc(db) != '*')
db_err1(1, "expected **");
il = new_il(IL_Inter, 2);
il->u[0].fld = db_abstr();
il->u[1].fld = db_abstr();
break;
}
return il;
}
/*
* db_ilc - read a piece of in-line C code.
*/
static struct il_c *db_ilc()
{
register int c;
int old_c;
word n;
struct il_c *base = NULL;
struct il_c **nxtp = &base;
c = getc(db);
SkipWhSp(c)
switch (c) {
case '$':
/*
* This had better be the starting $c.
*/
c = getc(db);
if (c == 'c') {
c = getc(db);
for (;;) {
SkipWhSp(c)
if (c == '$') {
c = getc(db);
switch (c) {
case 'c': /* $cb or $cgoto <cond> <lbl num> */
c = getc(db);
switch (c) {
case 'b':
*nxtp = new_ilc(ILC_CBuf);
c = getc(db);
break;
case 'g':
db_chstr("$cg", "oto");
*nxtp = new_ilc(ILC_CGto);
(*nxtp)->code[0] = db_ilc();
c = getc(db);
SkipWhSp(c);
if (!isdigit(c))
db_err1(1, "$cgoto: expected label number");
GetInt(n, c);
(*nxtp)->n = n;
break;
default:
db_err1(1, "expected $cb or $cgoto");
}
break;
case 'e':
c = getc(db);
if (c == 'f') { /* $efail */
db_chstr("$ef", "ail");
*nxtp = new_ilc(ILC_EFail);
c = getc(db);
break;
}
else
return base; /* $e */
case 'f': /* $fail */
db_chstr("$f", "ail");
*nxtp = new_ilc(ILC_Fail);
c = getc(db);
break;
case 'g': /* $goto <lbl num> */
db_chstr("$g", "oto");
*nxtp = new_ilc(ILC_Goto);
c = getc(db);
SkipWhSp(c);
if (!isdigit(c))
db_err1(1, "$goto: expected label number");
GetInt(n, c);
(*nxtp)->n = n;
break;
case 'l': /* $lbl <lbl num> */
db_chstr("$l", "bl");
*nxtp = new_ilc(ILC_Lbl);
c = getc(db);
SkipWhSp(c);
if (!isdigit(c))
db_err1(1, "$lbl: expected label number");
GetInt(n, c);
(*nxtp)->n = n;
break;
case 'm': /* $m[d]<indx> */
*nxtp = new_ilc(ILC_Mod);
c = getc(db);
if (c == 'd') {
(*nxtp)->s = "d";
c = getc(db);
}
if (isdigit(c)) {
GetInt(n, c);
(*nxtp)->n = n;
}
else if (c == 'r') {
(*nxtp)->n = RsltIndx;
c = getc(db);
}
else
db_err1(1, "$m: expected symbol table index");
break;
case 'r': /* $r[d]<indx> or $ret ... */
c = getc(db);
if (isdigit(c) || c == 'd') {
*nxtp = new_ilc(ILC_Ref);
if (c == 'd') {
(*nxtp)->s = "d";
c = getc(db);
}
GetInt(n, c);
(*nxtp)->n = n;
}
else if (c == 'r') {
*nxtp = new_ilc(ILC_Ref);
(*nxtp)->n = RsltIndx;
c = getc(db);
}
else {
if (c != 'e' || getc(db) != 't')
db_err1(1, "expected $ret");
*nxtp = db_ilcret(ILC_Ret);
c = getc(db);
}
break;
case 's': /* $sb or $susp ... */
c = getc(db);
switch (c) {
case 'b':
*nxtp = new_ilc(ILC_SBuf);
c = getc(db);
break;
case 'u':
db_chstr("$su", "sp");
*nxtp = db_ilcret(ILC_Susp);
c = getc(db);
break;
default:
db_err1(1, "expected $sb or $susp");
}
break;
case 't': /* $t[d]<indx> */
*nxtp = new_ilc(ILC_Tend);
c = getc(db);
if (!isdigit(c))
db_err1(1, "$t: expected index");
GetInt(n, c);
(*nxtp)->n = n;
break;
case '{':
*nxtp = new_ilc(ILC_LBrc);
c = getc(db);
break;
case '}':
*nxtp = new_ilc(ILC_RBrc);
c = getc(db);
break;
default:
db_err1(1, "invalid $ escape in C code");
}
}
else {
/*
* Arbitrary code - gather into a string.
*/
while (c != '$' && c != EOF) {
if (c == '"' || c == '\'') {
quoted(c);
c = getc(db);
}
old_c = c;
AppChar(db_sbuf, c);
c = getc(db);
if (old_c == ' ')
while (c == ' ')
c = getc(db);
}
*nxtp = new_ilc(ILC_Str);
(*nxtp)->s = str_install(&db_sbuf);
}
nxtp = &(*nxtp)->next;
}
}
break;
case 'n':
db_chstr("n", "il");
return NULL;
}
db_err1(1, "expected C code of the form $c ... $e or nil");
}
static novalue quoted(delim)
int delim;
{
register int c;
AppChar(db_sbuf, delim);
c = getc(db);
while (c != delim && c != EOF) {
if (c == '\\') {
AppChar(db_sbuf, c);
c = getc(db);
if (c == EOF)
db_err1(1, "unexpected EOF in quoted literal");
}
AppChar(db_sbuf, c);
c = getc(db);
}
if (c == EOF)
db_err1(1, "unexpected EOF in quoted literal");
AppChar(db_sbuf, c);
}
static struct il_c *db_ilcret(il_c_type)
int il_c_type;
{
struct il_c *ilc;
int c;
int n;
int i;
ilc = new_ilc(il_c_type);
ilc->n = db_icntyp();
c = getc(db);
SkipWhSp(c)
GetInt(n, c)
for (i = 0; i < n; ++i)
ilc->code[i] = db_ilc();
return ilc;
}
static int db_tndtyp()
{
int c;
c = getc(db);
SkipWhSp(c)
switch (c) {
case 'b':
db_chstr("b", "lkptr");
return TndBlk;
case 'd':
db_chstr("d", "esc");
return TndDesc;
case 's':
db_chstr("s", "tr");
return TndStr;
default:
db_err1(1, "expected blkptr, desc, or str");
/* NOTREACHED */
}
}
static int db_icntyp()
{
int c;
c = getc(db);
SkipWhSp(c)
switch (c) {
case 'c':
switch (getc(db)) {
case 'i':
return TypCInt;
case 'd':
return TypCDbl;
case 's':
return TypCStr;
case ' ':
case '\n':
case '\t':
return TypCset;
}
break;
case 'd':
return RetDesc;
case 'e':
switch (getc(db)) {
case 'c':
if (getc(db) == 'i')
return TypECInt;
break;
case 'i':
return TypEInt;
case ' ':
case '\n':
case '\t':
return TypEmpty;
}
break;
case 'f':
return TypFile;
case 'i':
return TypInt;
case 'k':
switch (getc(db)) {
case 'i':
return TypKyInt;
case 's':
return TypKySub;
case 'p':
return TypKyPos;
}
break;
case 'n':
switch (getc(db)) {
case 'v':
return RetNVar;
case ' ':
case '\n':
case '\t':
return TypNull;
}
break;
case 'p':
return TypProc;
case 'r':
switch (getc(db)) {
case 'n':
return RetNone;
case ' ':
case '\n':
case '\t':
return TypReal;
}
break;
case 's':
switch (getc(db)) {
case 's':
return TypTvStr;
case 'v':
return RetSVar;
case ' ':
case '\n':
case '\t':
return TypStr;
}
break;
case 't':
switch (getc(db)) {
case 'c':
return TypTCset;
case 's':
return TypTStr;
case 't':
return TypTvTbl;
}
break;
case 'v':
return TypVar;
case 'C':
return TypCoExp;
case 'L':
return TypList;
case 'R':
return TypRec;
case 'S':
return TypSet;
case 'T':
return TypTbl;
}
db_err1(1, "invalid type code");
/* NOTREACHED */
}
static struct il_c *new_ilc(il_c_type)
int il_c_type;
{
struct il_c *ilc;
int i;
ilc = NewStruct(il_c);
ilc->next = NULL;
ilc->il_c_type = il_c_type;
for (i = 0; i < 3; ++i)
ilc->code[i] = NULL;
ilc->n = 0;
ilc->s = NULL;
return ilc;
}
struct il_code *new_il(il_type, size)
int il_type;
int size;
{
struct il_code *il;
il = (struct il_code *)alloc((unsigned int)
(sizeof(struct il_code) + (size-1) * sizeof(union il_fld)));
il->il_type = il_type;
return il;
}
/*
* db_dscrd - discard an implementation, skipping the in-line code.
*/
novalue db_dscrd(ip)
struct implement *ip;
{
char state; /* how far along we are at recognizing $end */
free(ip);
state = '\0';
for (;;) {
switch (getc(db)) {
case '$':
state = '$';
continue;
case 'e':
if (state == '$') {
state = 'e';
continue;
}
break;
case 'n':
if (state == 'e') {
state = 'n';
continue;
}
break;
case 'd':
if (state == 'n')
return;
break;
case '\n':
++dbline;
break;
case EOF:
db_err1(1, "unexpected EOF");
}
state = '\0';
}
}
/*
* db_chstr - we are expecting a specific string. We may already have
* read a prefix of it.
*/
novalue db_chstr(prefix, suffix)
char *prefix;
char *suffix;
{
int c;
c = getc(db);
SkipWhSp(c)
for (;;) {
if (*suffix == '\0' && (isspace(c) || c == EOF)) {
if (c == '\n')
++dbline;
return;
}
else if (*suffix != c)
break;
c = getc(db);
++suffix;
}
db_err3(1, "expected:", prefix, suffix);
}
/*
* db_tbl - fill in a table of implementation information for the given section.
*/
int db_tbl(section, tbl)
char *section;
struct implement **tbl;
{
struct implement *ip;
int num_added = 0;
unsigned hashval;
/*
* Get past the section header.
*/
db_chstr("", section);
while ((ip = db_impl(toupper(section[0]))) != NULL) {
if (db_ilkup(ip->name, tbl) == NULL) {
db_code(ip);
hashval = IHasher(ip->name);
ip->blink = tbl[hashval];
tbl[hashval] = ip;
++num_added;
db_chstr("", "end");
}
else
db_dscrd(ip);
}
db_chstr("", "endsect");
return num_added;
}
/*
* db_ilkup looks up id in a table of implementation information and returns
* pointer it or NULL if it is not there.
*/
struct implement *db_ilkup(id, tbl)
char *id;
struct implement **tbl;
{
register struct implement *ptr;
ptr = tbl[IHasher(id)];
while (ptr != NULL && ptr->name != id)
ptr = ptr->blink;
return ptr;
}
/*
* nxt_pre - assign next prefix. A prefix is 2 characters from 0-9 and a-z,
* at least one of which is numeric.
*
* Warning - ascii dependence, must be changed for ebcdic.
*
*/
novalue nxt_pre(pre, nxt)
char *pre;
char *nxt;
{
if (nxt[0] == 'z' + 1) {
fprintf(stderr, "out of unique prefixes\n");
exit(ErrorExit);
}
pre[0] = nxt[0];
pre[1] = nxt[1];
/*
* increment next nxtfix.
*/
if (nxt[1] == '9') {
if (isdigit(nxt[0]))
nxt[1] = 'a';
else {
if (nxt[0] == '9')
nxt[0] = 'a';
else
++nxt[0];
nxt[1] = '0';
}
}
else if (nxt[1] == 'z') {
if (nxt[0] == '9')
nxt[0] = 'a';
else
++nxt[0];
nxt[1] = '0';
}
else
++nxt[1];
}
int cmp_pre(pre1, pre2)
char *pre1;
char *pre2;
{
int cmp;
cmp = cmp_1_pre(pre1[0], pre2[0]);
if (cmp == 0)
return cmp_1_pre(pre1[1], pre2[1]);
else
return cmp;
}
static int cmp_1_pre(p1, p2)
int p1;
int p2;
{
if (isdigit(p1)) {
if (isdigit(p2))
return p1 - p2;
else
return -1;
}
else {
if (isdigit(p2))
return 1;
else
return p1 - p2;
}
}
novalue db_err1(fatal, s)
int fatal;
char *s;
{
if (fatal)
fprintf(stderr, "error, ");
else
fprintf(stderr, "warning, ");
fprintf(stderr, "data base \"%s\", line %d - %s\n", dbname, dbline, s);
if (fatal)
exit(ErrorExit);
}
novalue db_err2(fatal, s1, s2)
int fatal;
char *s1;
char *s2;
{
if (fatal)
fprintf(stderr, "error, ");
else
fprintf(stderr, "warning, ");
fprintf(stderr, "data base \"%s\", line %d - %s %s\n", dbname, dbline, s1,
s2);
if (fatal)
exit(ErrorExit);
}
static novalue db_err3(fatal, s1, s2, s3)
int fatal;
char *s1;
char *s2;
char *s3;
{
if (fatal)
fprintf(stderr, "error, ");
else
fprintf(stderr, "warning, ");
fprintf(stderr, "data base \"%s\", line %d - %s %s%s\n", dbname, dbline, s1,
s2, s3);
if (fatal)
exit(ErrorExit);
}