4.3BSD/usr/ingres/source/ovqp/interp1.c
# include <ingres.h>
# include <aux.h>
# include <symbol.h>
# include <tree.h>
# include "../decomp/globs.h"
# include <sccs.h>
# include <errors.h>
SCCSID(@(#)interp1.c 8.3 2/8/85)
/*
** INTERP1.C
**
** symbol I/O utility routines for OVQP interpreter.
**
*/
/*
** GETSYMBOL
**
** Gets (type, len, value) symbols from list
** A ptr to the list is advanced after
** call. Symbols are moved to a target location
** (typically a slot on the interpreter's De.ov_stack).
** Legality of symbol type and length is checked.
** Returns 1 if no more symbols in list
** 0 otherwise
**
*/
getsymbol(ts, p)
SYMBOL *ts; /* target location (on stack) */
SYMBOL ***p; /* pointer to list */
{
int len; /*length of target symbol*/
register union symvalue *d; /* ptr to data for target symbol */
register SYMBOL *cp; /* the item in the list */
register SYMBOL *tops; /* target location on stack */
register union symvalue *val;
register STRKEEPER *seen; /* Have we seen an s? */
register char *c; /* For debugging */
int start; /* save the start pos of a string */
seen = 0;
tops = ts; /* copy stack pointer */
cp = **p; /* get list pointer */
tops->start = -1; /* initialize start to impossible value */
# ifdef xOTR1
if (tTf(84, 0))
{
printf("GETSYM: ");
prsym(cp);
}
# endif
if (tops >= (SYMBOL *) &De.ov_stack[STACKSIZ])
ov_err(STACKOVER);
val = &cp->value;
/* decomp will put the s_var's value in the right place
* if this is the case
*/
if (cp->type == VAR || cp->type == S_VAR)
{
tops->type = val->sym_var.varfrmt;
len = tops->len = val->sym_var.varfrml;
d = (union symvalue *) val->sym_var.valptr;
seen = (STRKEEPER *) val->sym_var.varstr;
val->sym_var.varstr = 0;
}
else
{
tops->type = cp->type;
len = tops->len = cp->len;
len &= I1MASK;
d = &cp->value;
}
/* advance De.ov_qvect sequencing pointer p */
*p += 1;
switch(tops->type)
{
case INT:
switch (len)
{
case 1:
tops->value.sym_data.i2type = d->sym_data.i1type;
break;
case 2:
case 4:
bmove((char *) d, (char *) &tops->value.sym_data, len);
break;
default:
syserr("getsym:bad int len %d",len);
}
break;
case FLOAT:
switch (len)
{
case 4:
tops->value.sym_data.f8type = d->sym_data.f4type;
break;
case 8:
tops->value.sym_data.f8type = d->sym_data.f8type;
break;
default:
syserr("getsym:bad FLOAT len %d",len);
}
break;
case CHAR:
{
if ( seen )
{
if ((c = (char *)grabstring(seen,d,1+(char *)tops, &start)) != NULL)
{
tops->value.sym_data.cptype = c;
/*tops->leavebl = 1; */
tops->start = start;
}
else
{
tops->value.sym_data.cptype = "\0";
tops->len = 0;
}
}
else
{
tops->value.sym_data.cptype = (char *)d;
seen = 0;
}
break;
}
case AOP:
case BOP:
case UOP:
case COP:
tops->value.sym_op.opno = d->sym_op.opno;
break;
case RESDOM:
tops->value.sym_resdom.resno = d->sym_resdom.resno;
break;
case AND:
case OR:
break;
case AGHEAD:
case BYHEAD:
case ROOT:
case QLEND:
return (1); /* all these are delimitors between lists */
default:
syserr("getsym:bad type %d", tops->type);
}
return(0);
}
/*
** TOUT
**
** Copies a symbol value into the Output tuple buffer.
** Used to write target
** list elements or aggregate values into the output tuple.
*/
tout(s, offp, rlen)
register SYMBOL *s;
char *offp;
int rlen;
{
register int i;
register char *p;
int slen;
# ifdef xOTR1
if (tTf(84, 3))
{
printf("TOUT: s=");
prstack(s);
printf(" offset=%d, rlen=%d\n", offp-De.ov_outtup, rlen);
}
# endif
if (s->type == CHAR)
{
slen = s->len & I1MASK;
rlen &= I1MASK;
i = rlen - slen; /* compute difference between sizes */
if (i <= 0)
{
bmove(s->value.sym_data.cptype, offp, rlen);
}
else
{
p = s->value.sym_data.cptype;
bmove(p, offp, slen);
p = &offp[slen];
while (i--)
*p++ = ' '; /* blank out remainder */
}
}
else
{
bmove((char *)&s->value, offp, rlen);
}
}
/*
** RCVT - convert a symbol to a given type
**
** Parameters:
** tos - the symbol
** restype - the type to convert it to
** reslen - the length of the type
**
** Trace Flags:
** 84.6
**
** Called by:
** interpret()
** setallkey()
** typecoerce()
*/
rcvt(tos, restype, reslen)
register SYMBOL *tos;
int restype, reslen;
{
register int rtype, rlen;
int stype, slen;
rtype = restype;
rlen = reslen;
stype = tos->type;
slen= tos->len;
# ifdef xOTR1
if (tTf(84, 6))
{
printf("RCVT:type=");
xputchar(rtype);
printf("%3d, tos=", rlen);
prstack(tos);
}
# endif
if (rtype != stype)
{
if (rtype == CHAR || stype == CHAR)
ov_err(BADCONV); /* bad char to numeric conversion requested */
if (rtype == FLOAT)
itof(tos);
else
{
if (rlen == 4)
ftoi4(tos);
else
ftoi2(tos);
}
tos->len = rlen; /* handles conversion to i1 or f4 */
}
else
{
if (rtype != CHAR && rlen != slen)
{
if (rtype == INT)
{
if (rlen == 4)
i2toi4(tos);
else if (slen == 4)
i4toi2(tos);
}
tos->len = rlen; /* handles conversion to i1 or f4 */
}
}
# ifdef xOTR3
if (tTf(84, 6))
{
printf("RCVT rets: symbol: ");
prsym(tos);
}
# endif
}