|
|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: T c
Length: 8569 (0x2179)
Types: TextFile
Names: »code.c«
└─⟦2d1937cfd⟧ Bits:30007241 EUUGD22: P.P 5.0
└─⟦dc59850a2⟧ »EurOpenD22/pp5.0/pp-5.tar.Z«
└─⟦e5a54fb17⟧
└─⟦this⟧ »pp-5.0/Chans/822-local/code.c«
/* code.c: interpreter code */
# ifndef lint
static char Rcsid[] = "@(#)$Header: /cs/research/pp/hubris/pp-beta/Chans/822-local/RCS/code.c,v 5.0 90/09/20 15:44:51 pp Exp Locker: pp $";
# endif
/*
* $Header: /cs/research/pp/hubris/pp-beta/Chans/822-local/RCS/code.c,v 5.0 90/09/20 15:44:51 pp Exp Locker: pp $
*
* $Log: code.c,v $
* Revision 5.0 90/09/20 15:44:51 pp
* rcsforce : 5.0 public release
*
*/
/* This stuff based heavily on Kernigan & Pike's hoc */
#include "util.h"
#include "loc.h"
#include "retcode.h"
#include "expand.h"
#include <isode/cmd_srch.h>
#ifndef NULLCP
#define NULLCP ((char *)0)
#endif
#define NSTACK 1024
static Datum stack[NSTACK];
static Datum *stackp;
#define NPROG 2000
Inst prog[NPROG];
Inst *progp, *pc;
static char true[] = "true", false[] = "", rp_agn[] = "again",
delivered[] = "delivered";
#define istrue(x) (*x)
int lineno;
int debug = 0;
static struct {
char *name;
char *val;
} consts[] = {
"TRUE", true,
"FALSE", false,
"OK", true,
"PERMFAIL", false,
"TEMPFAIL", rp_agn,
0, 0
};
static CMD_TABLE tbl_codes[] = {
true, RP_OK,
rp_agn, RP_AGN,
false, RP_BAD,
0, -1
};
static int exiting;
extern char *strdup ();
initialise ()
{
Symbol *sp;
int i;
stackp = stack;
progp = prog;
if (!lookup (delivered)) {
sp = install (delivered, strvar);
sp -> str = false;
for (i = 0; consts[i].name; i++) {
sp = install (consts[i].name, constant);
sp -> str = consts[i].val;
}
}
exiting = 0;
}
#ifdef DISASS
static CMD_TABLE procs[] = {
"ifcode", (int) ifcode,
"eq", (int) eq,
"ne", (int) ne,
"or", (int) or,
"and", (int) and,
"stringpush", (int) stringpush,
"tofile", (int) tofile,
"topipe", (int) topipe,
"exitproc", (int) exitproc,
"varpush", (int) varpush,
"setdeliver", (int) setdeliver,
"eval", (int) eval,
"defexitproc", (int) defexitproc,
"not", (int) not,
"unixmail", (int) tounixmail,
"STOP", 0,
0, -1
};
#endif
run ()
{
Symbol *sp;
int retval;
#ifdef DISASS
Inst *p;
char *cp;
for (p = prog; p < progp; p++)
if (cp = rcmd_srch (*p, procs))
PP_TRACE (("%d %s", p - prog, cp));
else
PP_TRACE (("%d %x", p - prog, *p));
#endif
execute (prog);
sp = lookup (delivered);
if (sp == NULL)
adios (NULLCP, "symbol %s not defined!!", delivered);
switch (retval = cmd_srch (sp -> str, tbl_codes)) {
case RP_AGN:
case RP_BAD:
case RP_OK:
break;
default:
adios (NULLCP, "Unknown return state '%s'", sp -> str);
}
return retval;
}
execute (p)
Inst *p;
{
Inst tmppc;
for (pc = p; *pc != STOP && !exiting; ) {
tmppc = *pc ++; /* work around ultrix bug */
(*tmppc) ();
}
}
Datum pop ()
{
if (stackp == stack)
adios (NULLCP, "stack underflow");
return *--stackp;
}
push (d)
Datum d;
{
if (stackp >= &stack[NSTACK])
adios (NULLCP, "stack overflow");
*stackp++ = d;
}
Inst *code (f)
Inst f;
{
Inst *oprogp = progp;
if (progp >= &prog[NPROG])
adios (NULLCP, "program too big");
*progp++ = f;
return oprogp;
}
void or ()
{
Datum d1, d2;
d1 = pop ();
d2 = pop ();
PP_TRACE (("%s or %s", d1.str, d2.str));
d1.str = (istrue(d1.str) || istrue(d2.str) ? true : false);
push (d1);
}
void and ()
{
Datum d1, d2;
d1 = pop ();
d2 = pop ();
PP_TRACE (("%s and %s", d1.str, d2.str));
d1.str = (istrue(d1.str) && istrue(d2.str) ? true : false);
push (d1);
}
void eq ()
{
Datum d1, d2;
d2 = pop ();
d1 = pop ();
PP_TRACE (("%s eq %s", d1.str, d2.str));
d1.str = (lexequ (d1.str, d2.str) == 0 ? true : false);
push (d1);
}
void ne ()
{
PP_TRACE (("not (psuedo)"));
eq ();
not ();
}
void req ()
{
Datum d1, d2;
char *cp, *re_comp ();
d2 = pop ();
d1 = pop ();
PP_TRACE (("%s req %s", d1.str, d2.str));
if (cp = re_comp (d2.str))
adios (NULLCP, "Bad re expression %s: %s", d2.str, cp);
if (re_exec (d1.str))
d1.str = true;
else d1.str = false;
push (d1);
}
void not ()
{
Datum d;
d = pop ();
PP_TRACE (("not %s", d.str));
d.str = istrue(d.str) ? false : true;
push (d);
}
void eval ()
{
Datum d;
d = pop ();
PP_TRACE (("eval %s", d.sym -> str ? d.sym -> str :
"<empty>"));
if (d.sym -> str == (char *)0)
d.str = false;
else d.str = d.sym -> str;
push(d);
}
void stringpush ()
{
Datum d;
d.str = (char *)*pc ++;
PP_TRACE (("stringpush %s", d.str));
push (d);
}
void varpush ()
{
Datum d;
d.sym = (Symbol *)(*pc ++);
PP_TRACE (("varpush %s", d.sym -> str));
push (d);
}
void ifcode ()
{
Datum d;
Inst *savepc = pc;
PP_TRACE (("ifcode"));
execute (savepc+3); /* then part */
d = pop ();
if (istrue(d.str)) {
PP_TRACE (("then code"));
execute (*((Inst **)(savepc)));
}
else if (*((Inst **)(savepc+1))) { /* else part */
PP_TRACE (("else code"));
execute (*((Inst **)(savepc + 1)));
}
PP_TRACE (("endif"));
if (!exiting)
pc = *((Inst **)(savepc + 2)); /* next statement */
}
void tofile ()
{
Datum d;
d = pop ();
PP_TRACE (("tofile %s", d.str));
switch (putfile (d.str)) {
case RP_OK:
d.str = true;
break;
case RP_AGN:
d.str = rp_agn;
break;
default:
case RP_BAD:
d.str = false;
break;
}
push (d);
}
void tounixfile ()
{
Datum d;
d = pop ();
PP_TRACE (("tounixfile %s", d.str));
switch (putunixfile (d.str)) {
case RP_OK:
d.str = true;
break;
case RP_AGN:
d.str = rp_agn;
break;
default:
case RP_BAD:
d.str = false;
break;
}
push (d);
}
void topipe ()
{
Datum d;
d = pop ();
PP_TRACE (("topipe %s", d.str));
switch (putpipe (d.str)) {
case RP_OK:
d.str = true;
break;
case RP_BAD:
d.str = false;
break;
default:
case RP_AGN:
d.str = rp_agn;
break;
}
PP_TRACE (("topipe = %s", d.str));
push (d);
}
void setdeliver ()
{
Datum d;
Symbol *sym;
d = pop ();
PP_TRACE (("setdelivered %s", d.str));
sym = lookup (delivered);
if (sym == NULL)
adios (NULLCP, "symbol %s not defined!!", delivered);
sym -> str = d.str;
if (lexequ (d.str, rp_agn) == 0)
exiting = 1;
push (d);
}
void exitproc ()
{
Datum d;
Symbol *sym;
d = pop ();
PP_TRACE (("exitproc %s", d.str));
sym = lookup (delivered);
if (sym == NULL)
adios (NULLCP, "symbol %s not defined!!", delivered);
sym -> str = d.str;
exiting = 1;
}
void defexitproc ()
{
Symbol *sym;
Datum d;
PP_TRACE (("defexitproc"));
sym = lookup (delivered);
if (sym == NULL)
adios (NULLCP, "symbol %s not defined!!", delivered);
d.str = sym -> str;
push (d);
exiting = 1;
}
void prexpr ()
{
Datum d;
d = pop ();
printit (d.str);
}
void assign ()
{
Datum d1, d2;
d1 = pop ();
d2 = pop ();
if (d1.sym -> type != strvar)
adios (NULLCP, "assignment to non-variable '%s'",
d1.sym -> name);
PP_TRACE (("%s = %s", d1.sym -> name, d2.str));
d1.sym -> str = d2.str;
push (d2);
}
checkmacro (s)
char *s;
{
char *p, *q;
extern char *index ();
for (q = s; p = index(q, '$'); q = p + 1) {
if (p[1] == '(') {
char *cp, buf[1024];
for (p += 2, cp = buf; *p; p++)
if (*p == ')')
break;
else *cp ++ = *p;
*cp = 0;
if (lookup (buf) == (Symbol *)0)
install (strdup (buf), field);
}
}
}
static Symbol *symlist;
Symbol *lookup (s)
char *s;
{
Symbol *sp;
for (sp = symlist; sp; sp = sp -> next)
if (strcmp (sp -> name, s) == 0)
return sp;
return 0;
}
Symbol *install (str, t)
char *str;
stype t;
{
Symbol *sp;
PP_TRACE (("Install %s",str));
sp = (Symbol *) smalloc (sizeof *sp);
sp -> name = str;
sp -> type = t;
sp -> str = false;
sp -> next = symlist;
symlist = sp;
return sp;
}
reset_syms ()
{
Symbol **spp, *sp;
PP_TRACE (("reset symbols"));
for (spp = &symlist; *spp; ) { /* half hearted free attempt */
sp = *spp;
spp = &(*spp) -> next;
if (sp -> name && *sp -> name)
free (sp -> name);
free ((char *)sp);
}
symlist = 0;
}
int yywrap ()
{
return 1;
}
yyerror (s)
char *s;
{
extern char yytext[];
adios (NULLCP, "%s near line %d (last token was '%s')",
s, lineno, yytext);
}
fillin_var (str, dest)
char *str;
char dest[];
{
Symbol *sp;
if (sp = lookup (str))
(void) sprintf (dest, "PATH=%s", sp -> str);
}
install_vars (vars, n, maxv)
Expand vars[];
int n;
int maxv;
{
int i;
Symbol *sp;
for (i = n, sp = symlist; i < maxv && sp;
sp = sp -> next) {
if (sp -> type == field)
continue;
vars[i].macro = strdup (sp -> name);
vars[i].expansion = strdup (sp -> str);
i++;
}
vars[i].macro = vars[i].expansion = NULLCP;
}
void create_var (var)
Expand *var;
{
Symbol *sp;
if ((sp = lookup (var -> macro)) == NULL)
sp = install (var -> macro, field);
sp -> str = var -> expansion;
}