/***********************************************************************
* *
* This software is part of the ast package *
* Copyright (c) 1989-2012 AT&T Intellectual Property *
* and is licensed under the *
* Eclipse Public License, Version 1.0 *
* by AT&T Intellectual Property *
* *
* A copy of the License is available at *
* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
* *
* Information and Software Systems Research *
* AT&T Research *
* Florham Park NJ *
* *
* Glenn Fowler <gsf@research.att.com> *
* *
***********************************************************************/
#pragma prototyped
/*
* grammar support routines
* stuffed in a header so exparse.y can work
* with both yacc and bison
* sometimes free stuff can cost a lot
*/
#define _EXGRAM_H
#if !defined(_EXPARSE_H)
#define _EXPARSE_H
#endif
#include "exlib.h"
/*
* allocate and initialize a new expression node in the current program
*/
{
register Exnode_t* x;
return x;
}
/*
* free node x and its children
*/
void
{
register Exref_t* r;
int i;
switch (x->op)
{
case CALL:
break;
case CONSTANT:
break;
case DEFAULT:
break;
case DYNAMIC:
{
}
break;
case ITERATE:
break;
case ID:
while (r = rn)
{
}
break;
case PRINTF:
case SPRINTF:
{
}
break;
default:
break;
}
}
/*
* cast x to type
*/
static char* typename[] =
{
"external", "integer", "unsigned", "float", "string"
};
{
};
{
register int t2t;
char* s;
char* e;
{
if (!x->type)
{
return x;
}
return x;
else switch (t2t)
{
case F2X:
case I2X:
case S2X:
case X2F:
case X2I:
case X2S:
{
exerror("%s: cannot cast constant %s to %s", xref->data.variable.symbol->name, TYPENAME(x->type), TYPENAME(type));
}
break;
case F2I:
break;
case F2S:
break;
case I2F:
break;
case I2S:
break;
case S2F:
if (*e)
break;
case S2I:
if (*e)
break;
default:
break;
}
}
return x;
}
#if 0
/*
* convert value v from type from to type to
* string data placed in buf
*/
{
register int t2t;
int n;
{
switch (t2t)
{
case F2X:
case I2X:
case S2X:
case X2F:
case X2I:
case X2S:
{
if (n >= size)
n = size - 1;
buf[n] = 0;
}
case F2I:
break;
case F2S:
break;
case I2F:
break;
case I2S:
break;
case S2F:
break;
case S2I:
break;
default:
break;
}
}
return v;
}
#endif
/*
* force ref . sym qualification
*/
static Exid_t*
{
register Exid_t* x;
char* s;
{
{
}
else
{
exnospace();
x = sym;
}
}
return x;
}
/*
* check function call arg types and count
* return function identifier node
*/
static Exnode_t*
{
register int t;
register int type;
Exnode_t* x;
int num;
num = 0;
N(t);
while (type = T(t))
{
if (!args)
{
return args;
}
num++;
N(t);
}
if (args)
return x;
}
/*
*/
static Print_t*
{
register Print_t* x;
register char* s;
register int c;
int t;
int i;
int n;
char* e;
char* f;
Print_t* p;
Print_t* q;
exerror("format string argument expected");
{
memzero(x, sizeof(*x));
return x;
}
for (s = f; *s; s++)
{
if (*s == '%')
{
if (!*++s)
exerror("%s: trailing %% in format", f);
if (*s != '%')
break;
if (args)
}
}
x = 0;
for (;;)
{
if (x)
x->next = q;
else
p = q;
x = q;
memzero(x, sizeof(*x));
if (*s)
{
i = 0;
t = INTEGER;
for (;;)
{
switch (c = *s++)
{
case 0:
exerror("unterminated %%... in format");
goto done;
case '*':
if (i >= elementsof(x->param))
{
*s = 0;
exerror("format %s has too many * arguments", f);
goto done;
}
if (!args)
{
*s = 0;
exerror("format %s * argument expected", f);
goto done;
}
break;
case '(':
n = 1;
for (;;)
{
switch (c = *s++)
{
case 0:
s--;
break;
case '(':
n++;
continue;
case ')':
if (--n <= 0)
break;
continue;
default:
continue;
}
break;
}
break;
case 'c':
case 'd':
goto specified;
case 'e':
case 'f':
case 'g':
t = FLOATING;
goto specified;
case 'h':
exerror("short formats not supported");
goto done;
case 'l':
t = INTEGER;
break;
case 'o':
case 'u':
case 'x':
case 'T':
t = UNSIGNED;
goto specified;
case 's':
case 'S':
t = STRING;
goto specified;
case '[':
e = s;
c = *s++;
while (c)
{
if ((c = *s++) == ']')
{
t = STRING;
goto specified;
}
}
s = e;
break;
default:
if (isalpha(c))
goto specified;
break;
}
}
for (e = s; *s; s++)
{
if (*s == '%')
{
if (!*++s)
{
*e = 0;
exerror("%s: trailing %% in format", f);
goto done;
}
if (*s != '%')
{
s--;
break;
}
}
}
if (!args)
{
*e = 0;
exerror("%s format argument expected", f);
goto done;
}
switch (t)
{
case FLOATING:
x->arg = exnewnode(expr.program, x->arg->type == STRING ? S2F : INTEGRAL(x->arg->type) ? I2F : X2F, 0, FLOATING, x->arg, x->arg->op == ID ? x->arg : (Exnode_t*)0);
break;
case INTEGER:
case UNSIGNED:
x->arg = exnewnode(expr.program, x->arg->type == STRING ? S2I : x->arg->type == FLOATING ? F2I : X2I, 0, INTEGER, x->arg, x->arg->op == ID ? x->arg : (Exnode_t*)0);
break;
case STRING:
{
{
if ((*expr.program->disc->convertf)(expr.program, x->arg, STRING, x->arg->data.constant.reference, 0, expr.program->disc) < 0)
exerror("cannot convert string format argument");
else x->arg->data.constant.value.string = vmstrdup(expr.program->vm, x->arg->data.constant.value.string);
}
else if (!expr.program->disc->convertf || x->arg->op != ID && x->arg->op != DYNAMIC && x->arg->op != F2X && x->arg->op != I2X && x->arg->op != S2X)
exerror("string format argument expected");
else
x->arg = exnewnode(expr.program, x->arg->type == FLOATING ? F2S : INTEGRAL(x->arg->type) ? I2S : X2S, 0, STRING, x->arg, x->arg->op == ID ? x->arg : (Exnode_t*)0);
}
break;
}
}
if (!*s)
break;
f = s;
}
if (args)
exerror("too many format arguments");
done:
return p;
}
/*
* push a new input stream and program
*/
int
{
register char* s;
{
exnospace();
return -1;
}
if (!p->input)
{
else if (name)
{
if (!(s = pathfind(name, p->disc->lib, p->disc->type, buf, sizeof(buf))) || !(in->fp = sfopen(NiL, s, "r")))
{
}
else
{
}
}
}
{
p->errors = 0;
{
if (line >= 0)
}
else if (!error_info.line)
}
else if (line >= 0)
setcontext(p);
p->eof = 0;
if (line >= 0)
return 0;
}
/*
* pop the current input stream
*/
int
{
register int c;
return -1;
exerror("unbalanced quote or nesting construct");
else
{
if (c == '\n')
{
error_info.line++;
break;
}
}
setcontext(p);
if (p->program)
return 0;
}
/*
* compile the expression in [sf]p
*/
int
{
Exid_t* v;
int eof;
p->more = 0;
{
if (!p->input)
return -1;
}
return -1;
else
exparse();
expop(p);
{
if (v->isstatic)
{
break;
}
}
return 0;
}
/*
* free the program p
*/
void
{
register int i;
if (p)
{
if (all)
{
if (p->file[i])
if (p->vm)
if (p->ve)
if (p->symbols)
if (p->tmp)
{
}
free(p);
}
else
{
}
}
}
#endif