recognize expressions
This commit is contained in:
parent
2c9fbebe4e
commit
24920dfa75
15 changed files with 527 additions and 84 deletions
|
@ -75,6 +75,8 @@ HSRC = {
|
||||||
scope.h,
|
scope.h,
|
||||||
langdep.h,
|
langdep.h,
|
||||||
sizes.h,
|
sizes.h,
|
||||||
|
token.h,
|
||||||
|
expr.h,
|
||||||
rd.h
|
rd.h
|
||||||
} ;
|
} ;
|
||||||
|
|
||||||
|
|
|
@ -14,28 +14,24 @@
|
||||||
#include "idf.h"
|
#include "idf.h"
|
||||||
#include "symbol.h"
|
#include "symbol.h"
|
||||||
#include "tree.h"
|
#include "tree.h"
|
||||||
|
#include "langdep.h"
|
||||||
|
#include "token.h"
|
||||||
|
|
||||||
extern char *Salloc();
|
extern char *Salloc();
|
||||||
extern t_lineno currline;
|
extern t_lineno currline;
|
||||||
extern FILE *db_in;
|
extern FILE *db_in;
|
||||||
|
|
||||||
int errorgiven;
|
int errorgiven;
|
||||||
int extended_charset = 0;
|
static int extended_charset = 0;
|
||||||
|
static int in_expression = 0;
|
||||||
jmp_buf jmpbuf;
|
jmp_buf jmpbuf;
|
||||||
|
|
||||||
static int init_del();
|
static int init_del();
|
||||||
static int skip_to_eol();
|
static int skip_to_eol();
|
||||||
|
|
||||||
static struct token {
|
struct token tok, aside;
|
||||||
int tokno;
|
|
||||||
long ival;
|
|
||||||
char *str;
|
|
||||||
double fval;
|
|
||||||
struct idf *idf;
|
|
||||||
} tok, aside;
|
|
||||||
|
|
||||||
#define TOK tok.tokno
|
#define prio(op) ((*(currlang->op_prio))(op))
|
||||||
#define ASIDE aside.tokno
|
|
||||||
}
|
}
|
||||||
%start Commands, commands;
|
%start Commands, commands;
|
||||||
|
|
||||||
|
@ -160,7 +156,7 @@ trace_command(p_tree *p;)
|
||||||
{ p_tree whr = 0, cond = 0, exp = 0; }
|
{ p_tree whr = 0, cond = 0, exp = 0; }
|
||||||
:
|
:
|
||||||
TRACE
|
TRACE
|
||||||
[ ON expression(&exp) ]?
|
[ ON expression(&exp, 1) ]?
|
||||||
where(&whr)?
|
where(&whr)?
|
||||||
condition(&cond)? { *p = mknode(OP_TRACE, whr, cond, exp); }
|
condition(&cond)? { *p = mknode(OP_TRACE, whr, cond, exp); }
|
||||||
;
|
;
|
||||||
|
@ -234,19 +230,19 @@ delete_command(p_tree *p;)
|
||||||
|
|
||||||
print_command(p_tree *p;)
|
print_command(p_tree *p;)
|
||||||
:
|
:
|
||||||
PRINT expression(p) { *p = mknode(OP_PRINT, *p);
|
PRINT expression(p, 1){ *p = mknode(OP_PRINT, *p);
|
||||||
p = &((*p)->t_args[0]);
|
p = &((*p)->t_args[0]);
|
||||||
}
|
}
|
||||||
[ ',' { *p = mknode(OP_LINK, *p, (p_tree) 0);
|
[ ',' { *p = mknode(OP_LINK, *p, (p_tree) 0);
|
||||||
p = &((*p)->t_args[1]);
|
p = &((*p)->t_args[1]);
|
||||||
}
|
}
|
||||||
expression(p)
|
expression(p, 1)
|
||||||
]*
|
]*
|
||||||
;
|
;
|
||||||
|
|
||||||
condition(p_tree *p;)
|
condition(p_tree *p;)
|
||||||
:
|
:
|
||||||
IF expression(p)
|
IF expression(p, 1)
|
||||||
;
|
;
|
||||||
|
|
||||||
where(p_tree *p;)
|
where(p_tree *p;)
|
||||||
|
@ -256,9 +252,57 @@ where(p_tree *p;)
|
||||||
position(p)
|
position(p)
|
||||||
;
|
;
|
||||||
|
|
||||||
expression(p_tree *p;)
|
expression(p_tree *p; int level;)
|
||||||
|
{ int currprio, currop; }
|
||||||
|
: { in_expression++; }
|
||||||
|
factor(p)
|
||||||
|
[ %while ((currprio = prio(currop = (int) tok.ival)) > level)
|
||||||
|
[ BIN_OP | PREF_OR_BIN_OP ]
|
||||||
|
{ *p = mknode(OP_BINOP, *p, (p_tree) 0);
|
||||||
|
(*p)->t_whichoper = currop;
|
||||||
|
}
|
||||||
|
expression(&((*p)->t_args[1]), currprio)
|
||||||
|
]*
|
||||||
|
{ in_expression--; }
|
||||||
|
;
|
||||||
|
|
||||||
|
factor(p_tree *p;)
|
||||||
:
|
:
|
||||||
qualified_name(p)
|
'(' expression(p, 1) ')'
|
||||||
|
|
|
||||||
|
INTEGER { *p = mknode(OP_INTEGER, tok.ival); }
|
||||||
|
|
|
||||||
|
REAL { *p = mknode(OP_REAL, tok.fval); }
|
||||||
|
|
|
||||||
|
STRING { *p = mknode(OP_STRING, tok.str); }
|
||||||
|
|
|
||||||
|
designator(p)
|
||||||
|
|
|
||||||
|
PREF_OP { *p = mknode(OP_UNOP, (p_tree) 0);
|
||||||
|
(*p)->t_whichoper = (int) tok.ival;
|
||||||
|
}
|
||||||
|
factor(&(*p)->t_args[0])
|
||||||
|
;
|
||||||
|
|
||||||
|
designator(p_tree *p;)
|
||||||
|
:
|
||||||
|
qualified_name(p)
|
||||||
|
[
|
||||||
|
SEL_OP { *p = mknode(OP_BINOP, *p, (p_tree) 0);
|
||||||
|
(*p)->t_whichoper = (int) tok.ival;
|
||||||
|
}
|
||||||
|
name(&(*p)->t_args[1])
|
||||||
|
|
|
||||||
|
'[' { *p = mknode(OP_BINOP, *p, (p_tree) 0);
|
||||||
|
(*p)->t_whichoper = '[';
|
||||||
|
}
|
||||||
|
expression(&(*p)->t_args[1], 1)
|
||||||
|
']'
|
||||||
|
|
|
||||||
|
POST_OP { *p = mknode(OP_UNOP, *p);
|
||||||
|
(*p)->t_whichoper = (int) tok.ival;
|
||||||
|
}
|
||||||
|
]*
|
||||||
;
|
;
|
||||||
|
|
||||||
position(p_tree *p;)
|
position(p_tree *p;)
|
||||||
|
@ -357,10 +401,11 @@ LLlex()
|
||||||
if (c == EOF) return c;
|
if (c == EOF) return c;
|
||||||
switch(class(c)) {
|
switch(class(c)) {
|
||||||
case STSTR:
|
case STSTR:
|
||||||
TOK = get_string(c);
|
TOK = (*currlang->get_string)(c);
|
||||||
break;
|
break;
|
||||||
case STIDF:
|
case STIDF:
|
||||||
TOK = get_name(c);
|
if (in_expression) TOK = (*currlang->get_name)(c);
|
||||||
|
else TOK = get_name(c);
|
||||||
break;
|
break;
|
||||||
case STDOT:
|
case STDOT:
|
||||||
c = getc(db_in);
|
c = getc(db_in);
|
||||||
|
@ -371,15 +416,20 @@ LLlex()
|
||||||
}
|
}
|
||||||
/* Fall through */
|
/* Fall through */
|
||||||
case STNUM:
|
case STNUM:
|
||||||
TOK = get_number(c);
|
TOK = (*currlang->get_number)(c);
|
||||||
break;
|
break;
|
||||||
case STNL:
|
case STNL:
|
||||||
case STSIMP:
|
|
||||||
TOK = c;
|
TOK = c;
|
||||||
break;
|
break;
|
||||||
|
case STSIMP:
|
||||||
|
if (! in_expression) {
|
||||||
|
TOK = c;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
/* Fall through */
|
||||||
default:
|
default:
|
||||||
error("illegal character '\\0%o'", c);
|
TOK = (*currlang->get_token)(c);
|
||||||
return LLlex();
|
break;
|
||||||
}
|
}
|
||||||
return TOK;
|
return TOK;
|
||||||
}
|
}
|
||||||
|
@ -450,7 +500,8 @@ quoted(ch)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int get_string(c)
|
int
|
||||||
|
get_string(c)
|
||||||
int c;
|
int c;
|
||||||
{
|
{
|
||||||
register int ch;
|
register int ch;
|
||||||
|
|
|
@ -447,16 +447,24 @@ type(p_type *ptp; int *type_index;)
|
||||||
;
|
;
|
||||||
|
|
||||||
structure_type(register p_type tp;)
|
structure_type(register p_type tp;)
|
||||||
{ register struct fields *fldp; }
|
{ register struct fields *fldp;
|
||||||
|
register p_symbol s;
|
||||||
|
}
|
||||||
:
|
:
|
||||||
integer_const(&(tp->ty_size)) /* size in bytes */
|
integer_const(&(tp->ty_size)) /* size in bytes */
|
||||||
|
{ open_scope((p_symbol) 0, 0); }
|
||||||
[ { fldp = get_field_space(tp); }
|
[ { fldp = get_field_space(tp); }
|
||||||
name(&(fldp->fld_name))
|
name(&(fldp->fld_name))
|
||||||
|
{ s = NewSymbol(fldp->fld_name, CurrentScope, FIELD, currnam);
|
||||||
|
s->sy_field = fldp;
|
||||||
|
}
|
||||||
type(&(fldp->fld_type), (int *) 0) ','
|
type(&(fldp->fld_type), (int *) 0) ','
|
||||||
integer_const(&(fldp->fld_pos)) ',' /* offset in bits */
|
integer_const(&(fldp->fld_pos)) ',' /* offset in bits */
|
||||||
integer_const(&(fldp->fld_bitsize)) ';' /* size in bits */
|
integer_const(&(fldp->fld_bitsize)) ';' /* size in bits */
|
||||||
]*
|
]*
|
||||||
';' { end_field(tp); }
|
';' { end_field(tp);
|
||||||
|
close_scope();
|
||||||
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
enum_type(register p_type tp;)
|
enum_type(register p_type tp;)
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
#include "position.h"
|
#include "position.h"
|
||||||
#include "operator.h"
|
#include "operator.h"
|
||||||
#include "tree.h"
|
#include "tree.h"
|
||||||
|
#include "expr.h"
|
||||||
|
|
||||||
int
|
int
|
||||||
eval_cond(p)
|
eval_cond(p)
|
||||||
|
|
|
@ -23,6 +23,11 @@ struct langdep {
|
||||||
/* language dependant routines: */
|
/* language dependant routines: */
|
||||||
int (*printstring)();
|
int (*printstring)();
|
||||||
long (*arrayelsize)();
|
long (*arrayelsize)();
|
||||||
|
int (*op_prio)();
|
||||||
|
int (*get_string)();
|
||||||
|
int (*get_name)();
|
||||||
|
int (*get_number)();
|
||||||
|
int (*get_token)();
|
||||||
};
|
};
|
||||||
|
|
||||||
extern struct langdep *m2_dep, *currlang;
|
extern struct langdep *m2_dep, *currlang;
|
||||||
|
|
|
@ -30,7 +30,7 @@ main(argc, argv)
|
||||||
while (p = strindex(progname, '/')) {
|
while (p = strindex(progname, '/')) {
|
||||||
progname = p + 1;
|
progname = p + 1;
|
||||||
}
|
}
|
||||||
if (argv[1][0] == '-') {
|
if (argv[1] && argv[1][0] == '-') {
|
||||||
switch(argv[1][1]) {
|
switch(argv[1][1]) {
|
||||||
case 'd':
|
case 'd':
|
||||||
debug++;
|
debug++;
|
||||||
|
|
|
@ -4,12 +4,27 @@
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include "class.h"
|
||||||
#include "langdep.h"
|
#include "langdep.h"
|
||||||
|
#include "Lpars.h"
|
||||||
|
#include "idf.h"
|
||||||
|
#include "token.h"
|
||||||
|
#include "expr.h"
|
||||||
|
|
||||||
extern FILE *db_out;
|
extern FILE *db_out, *db_in;
|
||||||
|
|
||||||
|
extern int
|
||||||
|
get_string();
|
||||||
|
|
||||||
|
extern double
|
||||||
|
atof();
|
||||||
|
|
||||||
static int
|
static int
|
||||||
print_string();
|
print_string(),
|
||||||
|
get_number(),
|
||||||
|
get_name(),
|
||||||
|
get_token(),
|
||||||
|
op_prio();
|
||||||
|
|
||||||
static long
|
static long
|
||||||
array_elsize();
|
array_elsize();
|
||||||
|
@ -31,7 +46,12 @@ static struct langdep m2 = {
|
||||||
"}",
|
"}",
|
||||||
|
|
||||||
print_string,
|
print_string,
|
||||||
array_elsize
|
array_elsize,
|
||||||
|
op_prio,
|
||||||
|
get_string,
|
||||||
|
get_name,
|
||||||
|
get_number,
|
||||||
|
get_token
|
||||||
};
|
};
|
||||||
|
|
||||||
struct langdep *m2_dep = &m2;
|
struct langdep *m2_dep = &m2;
|
||||||
|
@ -59,3 +79,295 @@ array_elsize(size)
|
||||||
if (! (size % int_size)) return size;
|
if (! (size % int_size)) return size;
|
||||||
return ((size + int_size - 1) / int_size) * int_size;
|
return ((size + int_size - 1) / int_size) * int_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
op_prio(op)
|
||||||
|
int op;
|
||||||
|
{
|
||||||
|
/* ??? to be written ??? */
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
get_number(ch)
|
||||||
|
register int ch;
|
||||||
|
{
|
||||||
|
/* The problem arising with the "parsing" of a number
|
||||||
|
is that we don't know the base in advance so we
|
||||||
|
have to read the number with the help of a rather
|
||||||
|
complex finite automaton.
|
||||||
|
*/
|
||||||
|
enum statetp {Oct,Hex,Dec,OctEndOrHex,End,Real};
|
||||||
|
register enum statetp state;
|
||||||
|
char buf[512+1];
|
||||||
|
register int base = 10;
|
||||||
|
register char *np = &buf[0];
|
||||||
|
|
||||||
|
*np++ = ch;
|
||||||
|
state = is_oct(ch) ? Oct : Dec;
|
||||||
|
ch = getc(db_in);
|
||||||
|
for (;;) {
|
||||||
|
switch(state) {
|
||||||
|
case Oct:
|
||||||
|
while (is_oct(ch)) {
|
||||||
|
if (np < &buf[512]) *np++ = ch;
|
||||||
|
ch = getc(db_in);
|
||||||
|
}
|
||||||
|
if (ch == 'B' || ch == 'C') {
|
||||||
|
state = OctEndOrHex;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
/* Fall Through */
|
||||||
|
case Dec:
|
||||||
|
base = 10;
|
||||||
|
while (is_dig(ch)) {
|
||||||
|
if (np < &buf[512]) {
|
||||||
|
*np++ = ch;
|
||||||
|
}
|
||||||
|
ch = getc(db_in);
|
||||||
|
}
|
||||||
|
if (is_hex(ch)) state = Hex;
|
||||||
|
else if (ch == '.') state = Real;
|
||||||
|
else {
|
||||||
|
state = End;
|
||||||
|
if (ch == 'H') base = 16;
|
||||||
|
else ungetc(ch, db_in);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Hex:
|
||||||
|
while (is_hex(ch)) {
|
||||||
|
if (np < &buf[512]) *np++ = ch;
|
||||||
|
ch = getc(db_in);
|
||||||
|
}
|
||||||
|
base = 16;
|
||||||
|
state = End;
|
||||||
|
if (ch != 'H') {
|
||||||
|
error("H expected after hex number");
|
||||||
|
ungetc(ch, db_in);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case OctEndOrHex:
|
||||||
|
if (np < &buf[512]) *np++ = ch;
|
||||||
|
ch = getc(db_in);
|
||||||
|
if (ch == 'H') {
|
||||||
|
base = 16;
|
||||||
|
state = End;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (is_hex(ch)) {
|
||||||
|
state = Hex;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
ungetc(ch, db_in);
|
||||||
|
ch = *--np;
|
||||||
|
*np++ = '\0';
|
||||||
|
/* Fall through */
|
||||||
|
|
||||||
|
case End:
|
||||||
|
*np = '\0';
|
||||||
|
if (np >= &buf[512]) {
|
||||||
|
tok.ival = 1;
|
||||||
|
error("constant too long");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
np = &buf[0];
|
||||||
|
while (*np == '0') np++;
|
||||||
|
tok.ival = 0;
|
||||||
|
while (*np) {
|
||||||
|
int c;
|
||||||
|
|
||||||
|
if (is_dig(*np)) {
|
||||||
|
c = *np++ - '0';
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
c = *np++ - 'A' + 10;
|
||||||
|
}
|
||||||
|
tok.ival *= base;
|
||||||
|
tok.ival += c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return INTEGER;
|
||||||
|
}
|
||||||
|
if (state == Real) break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* a real real constant */
|
||||||
|
if (np < &buf[512]) *np++ = '.';
|
||||||
|
|
||||||
|
while (is_dig(ch)) {
|
||||||
|
/* Fractional part
|
||||||
|
*/
|
||||||
|
if (np < &buf[512]) *np++ = ch;
|
||||||
|
ch = getc(db_in);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ch == 'E') {
|
||||||
|
/* Scale factor
|
||||||
|
*/
|
||||||
|
if (np < &buf[512]) *np++ = ch;
|
||||||
|
ch = getc(db_in);
|
||||||
|
if (ch == '+' || ch == '-') {
|
||||||
|
/* Signed scalefactor
|
||||||
|
*/
|
||||||
|
if (np < &buf[512]) *np++ = ch;
|
||||||
|
ch = getc(db_in);
|
||||||
|
}
|
||||||
|
if (is_dig(ch)) {
|
||||||
|
do {
|
||||||
|
if (np < &buf[512]) *np++ = ch;
|
||||||
|
ch = getc(db_in);
|
||||||
|
} while (is_dig(ch));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
error("bad scale factor");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
*np++ = '\0';
|
||||||
|
ungetc(ch, db_in);
|
||||||
|
|
||||||
|
if (np >= &buf[512]) {
|
||||||
|
tok.fval = 0.0;
|
||||||
|
error("real constant too long");
|
||||||
|
}
|
||||||
|
else tok.fval = atof(buf);
|
||||||
|
return REAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
get_name(c)
|
||||||
|
register int c;
|
||||||
|
{
|
||||||
|
char buf[512+1];
|
||||||
|
register char *p = &buf[0];
|
||||||
|
register struct idf *id;
|
||||||
|
|
||||||
|
do {
|
||||||
|
if (p - buf < 512) *p++ = c;
|
||||||
|
c = getc(db_in);
|
||||||
|
} while (in_idf(c));
|
||||||
|
ungetc(c, db_in);
|
||||||
|
*p = 0;
|
||||||
|
/* now recognize AND, DIV, IN, MOD, NOT, OR */
|
||||||
|
switch(buf[0]) {
|
||||||
|
case 'A':
|
||||||
|
if (strcmp(buf, "AND") == 0) {
|
||||||
|
tok.ival = E_AND;
|
||||||
|
return BIN_OP;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'D':
|
||||||
|
if (strcmp(buf, "DIV") == 0) {
|
||||||
|
tok.ival = E_DIV;
|
||||||
|
return BIN_OP;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'I':
|
||||||
|
if (strcmp(buf, "IN") == 0) {
|
||||||
|
tok.ival = E_IN;
|
||||||
|
return BIN_OP;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'M':
|
||||||
|
if (strcmp(buf, "MOD") == 0) {
|
||||||
|
tok.ival = E_MOD;
|
||||||
|
return BIN_OP;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'N':
|
||||||
|
if (strcmp(buf, "NOT") == 0) {
|
||||||
|
tok.ival = E_NOT;
|
||||||
|
return PREF_OP;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'O':
|
||||||
|
if (strcmp(buf, "OR") == 0) {
|
||||||
|
tok.ival = E_OR;
|
||||||
|
return BIN_OP;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
id = str2idf(buf, 1);
|
||||||
|
tok.idf = id;
|
||||||
|
tok.str = id->id_text;
|
||||||
|
return id->id_reserved ? id->id_reserved : NAME;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
get_token(c)
|
||||||
|
register int c;
|
||||||
|
{
|
||||||
|
switch(c) {
|
||||||
|
case '(':
|
||||||
|
case ')':
|
||||||
|
case '[':
|
||||||
|
case ']':
|
||||||
|
case '`':
|
||||||
|
case '{':
|
||||||
|
case '}':
|
||||||
|
case ':':
|
||||||
|
case ',':
|
||||||
|
return c;
|
||||||
|
|
||||||
|
case '.':
|
||||||
|
tok.ival = E_SELECT;
|
||||||
|
return SEL_OP;
|
||||||
|
case '+':
|
||||||
|
tok.ival = E_PLUS;
|
||||||
|
return PREF_OR_BIN_OP;
|
||||||
|
case '-':
|
||||||
|
tok.ival = E_MIN;
|
||||||
|
return PREF_OR_BIN_OP;
|
||||||
|
case '*':
|
||||||
|
tok.ival = E_MUL;
|
||||||
|
return BIN_OP;
|
||||||
|
case '/':
|
||||||
|
tok.ival = E_DIV;
|
||||||
|
return BIN_OP;
|
||||||
|
case '&':
|
||||||
|
tok.ival = E_AND;
|
||||||
|
return BIN_OP;
|
||||||
|
case '|':
|
||||||
|
tok.ival = E_OR;
|
||||||
|
return BIN_OP;
|
||||||
|
case '=':
|
||||||
|
tok.ival = E_EQUAL;
|
||||||
|
return BIN_OP;
|
||||||
|
case '#':
|
||||||
|
tok.ival = E_NOTEQUAL;
|
||||||
|
return BIN_OP;
|
||||||
|
case '<':
|
||||||
|
c = getc(db_in);
|
||||||
|
if (c == '>') {
|
||||||
|
tok.ival = E_NOTEQUAL;
|
||||||
|
return BIN_OP;
|
||||||
|
}
|
||||||
|
if (c == '=') {
|
||||||
|
tok.ival = E_LTEQUAL;
|
||||||
|
return BIN_OP;
|
||||||
|
}
|
||||||
|
ungetc(c, db_in);
|
||||||
|
tok.ival = E_LT;
|
||||||
|
return BIN_OP;
|
||||||
|
case '>':
|
||||||
|
c = getc(db_in);
|
||||||
|
if (c == '=') {
|
||||||
|
tok.ival = E_GTEQUAL;
|
||||||
|
return BIN_OP;
|
||||||
|
}
|
||||||
|
ungetc(c, db_in);
|
||||||
|
tok.ival = E_GT;
|
||||||
|
return BIN_OP;
|
||||||
|
case '^':
|
||||||
|
tok.ival = E_DEREF;
|
||||||
|
return POST_OP;
|
||||||
|
case '~':
|
||||||
|
tok.ival = E_NOT;
|
||||||
|
return PREF_OP;
|
||||||
|
default:
|
||||||
|
error("illegal character 0%o", c);
|
||||||
|
return LLlex();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -5,6 +5,8 @@ OP_RUN 1 start_child
|
||||||
OP_INPUT 1 0
|
OP_INPUT 1 0
|
||||||
OP_OUTPUT 1 0
|
OP_OUTPUT 1 0
|
||||||
OP_INTEGER 0 0
|
OP_INTEGER 0 0
|
||||||
|
OP_REAL 0 0
|
||||||
|
OP_STRING 0 0
|
||||||
OP_NAME 0 0
|
OP_NAME 0 0
|
||||||
OP_AT 0 0
|
OP_AT 0 0
|
||||||
OP_IN 1 0
|
OP_IN 1 0
|
||||||
|
@ -22,3 +24,5 @@ OP_PRINT 1 do_print
|
||||||
OP_DUMP 0 do_dump
|
OP_DUMP 0 do_dump
|
||||||
OP_RESTORE 0 do_restore
|
OP_RESTORE 0 do_restore
|
||||||
OP_TRACE 3 do_trace
|
OP_TRACE 3 do_trace
|
||||||
|
OP_UNOP 1 0
|
||||||
|
OP_BINOP 2 0
|
||||||
|
|
|
@ -99,11 +99,11 @@ print_params(tp, AB, static_link)
|
||||||
fprintf(db_out, currlang->addr_fmt, BUFTOA(p));
|
fprintf(db_out, currlang->addr_fmt, BUFTOA(p));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
print_val(par->par_type, q, 1, 0, param_bytes);
|
print_val(par->par_type, size, q, 1, 0);
|
||||||
}
|
}
|
||||||
free(q);
|
free(q);
|
||||||
}
|
}
|
||||||
else print_val(par->par_type, p, 1, 0, param_bytes);
|
else print_val(par->par_type, par->par_type->ty_size, p, 1, 0);
|
||||||
if (i) fputs(", ", db_out);
|
if (i) fputs(", ", db_out);
|
||||||
p += param_size(par->par_type, par->par_kind);
|
p += param_size(par->par_type, par->par_kind);
|
||||||
par++;
|
par++;
|
||||||
|
@ -111,29 +111,27 @@ print_params(tp, AB, static_link)
|
||||||
free(param_bytes);
|
free(param_bytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
print_val(tp, addr, compressed, indent, AB)
|
print_val(tp, tp_sz, addr, compressed, indent)
|
||||||
p_type tp; /* type of value to be printed */
|
p_type tp; /* type of value to be printed */
|
||||||
|
long tp_sz; /* size of object to be printed */
|
||||||
char *addr; /* address to get value from */
|
char *addr; /* address to get value from */
|
||||||
int compressed; /* for parameter lists */
|
int compressed; /* for parameter lists */
|
||||||
int indent; /* indentation */
|
int indent; /* indentation */
|
||||||
char *AB; /* argument base for dynamic subranges */
|
|
||||||
{
|
{
|
||||||
long sz;
|
|
||||||
register int i;
|
register int i;
|
||||||
long elsize;
|
long elsize;
|
||||||
|
|
||||||
if (indent == 0) indent = 4;
|
if (indent == 0) indent = 4;
|
||||||
switch(tp->ty_class) {
|
switch(tp->ty_class) {
|
||||||
case T_SUBRANGE:
|
case T_SUBRANGE:
|
||||||
print_val(tp->ty_base, addr, compressed, indent, AB);
|
print_val(tp->ty_base, tp->ty_size, addr, compressed, indent);
|
||||||
break;
|
break;
|
||||||
case T_ARRAY:
|
case T_ARRAY:
|
||||||
if (tp->ty_elements == char_type ||
|
if (tp->ty_elements == char_type ||
|
||||||
tp->ty_elements == uchar_type) {
|
tp->ty_elements == uchar_type) {
|
||||||
print_val(string_type, addr, compressed, indent, AB);
|
print_val(string_type, tp_sz, addr, compressed, indent);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if ((sz = tp->ty_size) == 0) sz = compute_size(tp, AB);
|
|
||||||
if (compressed) {
|
if (compressed) {
|
||||||
fprintf(db_out, currlang->open_array_display);
|
fprintf(db_out, currlang->open_array_display);
|
||||||
}
|
}
|
||||||
|
@ -146,8 +144,8 @@ print_val(tp, addr, compressed, indent, AB)
|
||||||
}
|
}
|
||||||
indent += 4;
|
indent += 4;
|
||||||
elsize = (*currlang->arrayelsize)(tp->ty_elements->ty_size);
|
elsize = (*currlang->arrayelsize)(tp->ty_elements->ty_size);
|
||||||
for (i = sz/elsize; i; i--) {
|
for (i = tp_sz/elsize; i; i--) {
|
||||||
print_val(tp->ty_elements, addr, compressed, indent, AB);
|
print_val(tp->ty_elements, tp->ty_elements->ty_size, addr, compressed, indent);
|
||||||
addr += elsize;
|
addr += elsize;
|
||||||
if (compressed && i > 1) {
|
if (compressed && i > 1) {
|
||||||
fprintf(db_out, ", ...");
|
fprintf(db_out, ", ...");
|
||||||
|
@ -176,13 +174,14 @@ print_val(tp, addr, compressed, indent, AB)
|
||||||
}
|
}
|
||||||
indent += 4;
|
indent += 4;
|
||||||
for (i = tp->ty_nfields; i; i--, fld++) {
|
for (i = tp->ty_nfields; i; i--, fld++) {
|
||||||
|
long sz = fld->fld_type->ty_size;
|
||||||
if (! compressed) fprintf(db_out, "%s = ", fld->fld_name);
|
if (! compressed) fprintf(db_out, "%s = ", fld->fld_name);
|
||||||
if (fld->fld_bitsize != fld->fld_type->ty_size << 3) {
|
if (fld->fld_bitsize != sz << 3) {
|
||||||
/* apparently a bit field */
|
/* apparently a bit field */
|
||||||
/* ??? */
|
/* ??? */
|
||||||
fprintf(db_out, "<bitfield, %d, %d>", fld->fld_bitsize, fld->fld_type->ty_size);
|
fprintf(db_out, "<bitfield, %d, %d>", fld->fld_bitsize, fld->fld_type->ty_size);
|
||||||
}
|
}
|
||||||
else print_val(fld->fld_type, addr+(fld->fld_pos>>3), compressed, indent, AB);
|
else print_val(fld->fld_type, sz, addr+(fld->fld_pos>>3), compressed, indent);
|
||||||
if (compressed && i > 1) {
|
if (compressed && i > 1) {
|
||||||
fprintf(db_out, ", ...");
|
fprintf(db_out, ", ...");
|
||||||
break;
|
break;
|
||||||
|
@ -200,9 +199,9 @@ print_val(tp, addr, compressed, indent, AB)
|
||||||
fprintf(db_out, "<union>");
|
fprintf(db_out, "<union>");
|
||||||
break;
|
break;
|
||||||
case T_ENUM:
|
case T_ENUM:
|
||||||
print_literal(tp, tp->ty_size == 1
|
print_literal(tp, tp_sz == 1
|
||||||
? (*addr & 0xFF)
|
? (*addr & 0xFF)
|
||||||
: tp->ty_size == 2
|
: tp_sz == 2
|
||||||
? (BUFTOS(addr) & 0xFFFF)
|
? (BUFTOS(addr) & 0xFFFF)
|
||||||
: (int) BUFTOL(addr));
|
: (int) BUFTOL(addr));
|
||||||
break;
|
break;
|
||||||
|
@ -281,16 +280,16 @@ print_val(tp, addr, compressed, indent, AB)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case T_UNSIGNED:
|
case T_UNSIGNED:
|
||||||
print_unsigned(tp, tp->ty_size == 1
|
print_unsigned(tp, tp_sz == 1
|
||||||
? (*addr & 0xFF)
|
? (*addr & 0xFF)
|
||||||
: tp->ty_size == 2
|
: tp_sz == 2
|
||||||
? (BUFTOS(addr) & 0xFFFF)
|
? (BUFTOS(addr) & 0xFFFF)
|
||||||
: BUFTOL(addr));
|
: BUFTOL(addr));
|
||||||
break;
|
break;
|
||||||
case T_INTEGER:
|
case T_INTEGER:
|
||||||
print_integer(tp, tp->ty_size == 1
|
print_integer(tp, tp_sz == 1
|
||||||
? *addr
|
? *addr
|
||||||
: tp->ty_size == 2
|
: tp_sz == 2
|
||||||
? BUFTOS(addr)
|
? BUFTOS(addr)
|
||||||
: BUFTOL(addr));
|
: BUFTOL(addr));
|
||||||
break;
|
break;
|
||||||
|
@ -308,13 +307,12 @@ print_sym(sym)
|
||||||
p_symbol sym;
|
p_symbol sym;
|
||||||
{
|
{
|
||||||
char *buf;
|
char *buf;
|
||||||
char *AB;
|
long size;
|
||||||
|
|
||||||
if (get_value(sym, &buf, &AB)) {
|
if (get_value(sym, &buf, &size)) {
|
||||||
fputs(" = ", db_out);
|
fputs(" = ", db_out);
|
||||||
print_val(sym->sy_type, buf, 0, 0, AB);
|
print_val(sym->sy_type, size, buf, 0, 0);
|
||||||
if (buf) free(buf);
|
if (buf) free(buf);
|
||||||
if (AB) free(AB);
|
|
||||||
fputs("\n", db_out);
|
fputs("\n", db_out);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,7 +31,7 @@ typedef struct symbol {
|
||||||
#define REGVAR 0x0080
|
#define REGVAR 0x0080
|
||||||
#define LOCVAR 0x0100
|
#define LOCVAR 0x0100
|
||||||
#define VARPAR 0x0200
|
#define VARPAR 0x0200
|
||||||
/* #define SYMENTRY 0x0400 /* a non-dbx entry */
|
#define FIELD 0x0400
|
||||||
#define FILESYM 0x0800 /* a filename */
|
#define FILESYM 0x0800 /* a filename */
|
||||||
#define FILELINK 0x1000 /* a filename without its suffix */
|
#define FILELINK 0x1000 /* a filename without its suffix */
|
||||||
struct idf *sy_idf; /* reference back to its idf structure */
|
struct idf *sy_idf; /* reference back to its idf structure */
|
||||||
|
@ -42,12 +42,14 @@ typedef struct symbol {
|
||||||
/* struct outname syv_onam; /* for non-dbx entries */
|
/* struct outname syv_onam; /* for non-dbx entries */
|
||||||
struct file *syv_file; /* for FILESYM */
|
struct file *syv_file; /* for FILESYM */
|
||||||
struct symbol *syv_fllink; /* for FILELINK */
|
struct symbol *syv_fllink; /* for FILELINK */
|
||||||
|
struct fields *syv_field;
|
||||||
} sy_v;
|
} sy_v;
|
||||||
#define sy_const sy_v.syv_const
|
#define sy_const sy_v.syv_const
|
||||||
#define sy_name sy_v.syv_name
|
#define sy_name sy_v.syv_name
|
||||||
#define sy_onam sy_v.syv_onam
|
#define sy_onam sy_v.syv_onam
|
||||||
#define sy_file sy_v.syv_file
|
#define sy_file sy_v.syv_file
|
||||||
#define sy_filelink sy_v.syv_fllink
|
#define sy_filelink sy_v.syv_fllink
|
||||||
|
#define sy_field sy_v.syv_field
|
||||||
} t_symbol, *p_symbol;
|
} t_symbol, *p_symbol;
|
||||||
|
|
||||||
/* ALLOCDEF "symbol" 50 */
|
/* ALLOCDEF "symbol" 50 */
|
||||||
|
|
16
util/grind/token.h
Normal file
16
util/grind/token.h
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
/* $Header$ */
|
||||||
|
|
||||||
|
/* token structure for lexical analyzer */
|
||||||
|
|
||||||
|
struct token {
|
||||||
|
int tokno;
|
||||||
|
long ival;
|
||||||
|
char *str;
|
||||||
|
double fval;
|
||||||
|
struct idf *idf;
|
||||||
|
};
|
||||||
|
|
||||||
|
extern struct token tok, aside;
|
||||||
|
|
||||||
|
#define TOK tok.tokno
|
||||||
|
#define ASIDE aside.tokno
|
|
@ -29,6 +29,11 @@ struct tokenname tkspec[] = { /* the names of the special tokens */
|
||||||
{INTEGER, "number"},
|
{INTEGER, "number"},
|
||||||
{REAL, "real"},
|
{REAL, "real"},
|
||||||
{CHAR, "char"},
|
{CHAR, "char"},
|
||||||
|
{BIN_OP, "<operator>"},
|
||||||
|
{PREF_OR_BIN_OP, "<operator>"},
|
||||||
|
{PREF_OP, "<operator>"},
|
||||||
|
{POST_OP, "<operator>"},
|
||||||
|
{SEL_OP, "<operator>"},
|
||||||
{0, ""}
|
{0, ""}
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -44,6 +44,12 @@ mknode(va_alist)
|
||||||
case OP_INTEGER:
|
case OP_INTEGER:
|
||||||
p->t_ival = va_arg(ap, long);
|
p->t_ival = va_arg(ap, long);
|
||||||
break;
|
break;
|
||||||
|
case OP_STRING:
|
||||||
|
p->t_sval = va_arg(ap, char *);
|
||||||
|
break;
|
||||||
|
case OP_REAL:
|
||||||
|
p->t_fval = va_arg(ap, double);
|
||||||
|
break;
|
||||||
case OP_AT:
|
case OP_AT:
|
||||||
p->t_lino = va_arg(ap, long);
|
p->t_lino = va_arg(ap, long);
|
||||||
p->t_filename = va_arg(ap, char *);
|
p->t_filename = va_arg(ap, char *);
|
||||||
|
@ -74,23 +80,10 @@ freenode(p)
|
||||||
register int na, i;
|
register int na, i;
|
||||||
|
|
||||||
if (! p) return;
|
if (! p) return;
|
||||||
switch(p->t_oper) {
|
na = nargs(p->t_oper);
|
||||||
case OP_NAME:
|
assert(na <= MAXARGS);
|
||||||
case OP_INTEGER:
|
for (i = 0; i < na; i++) {
|
||||||
case OP_AT:
|
freenode(p->t_args[i]);
|
||||||
case OP_CONT:
|
|
||||||
case OP_NEXT:
|
|
||||||
case OP_STEP:
|
|
||||||
case OP_REGS:
|
|
||||||
case OP_DELETE:
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
na = nargs(p->t_oper);
|
|
||||||
assert(na <= MAXARGS);
|
|
||||||
for (i = 0; i < na; i++) {
|
|
||||||
freenode(p->t_args[i]);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
free_tree(p);
|
free_tree(p);
|
||||||
}
|
}
|
||||||
|
@ -219,6 +212,12 @@ print_node(p, top_level)
|
||||||
case OP_INTEGER:
|
case OP_INTEGER:
|
||||||
fprintf(db_out, "%d", p->t_ival);
|
fprintf(db_out, "%d", p->t_ival);
|
||||||
break;
|
break;
|
||||||
|
case OP_STRING:
|
||||||
|
fprintf(db_out, "%s", p->t_sval);
|
||||||
|
break;
|
||||||
|
case OP_REAL:
|
||||||
|
fprintf(db_out, "%.14g", p->t_fval);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
if (top_level) fputs("\n", db_out);
|
if (top_level) fputs("\n", db_out);
|
||||||
}
|
}
|
||||||
|
@ -548,7 +547,7 @@ do_print(p)
|
||||||
break;
|
break;
|
||||||
case OP_NAME:
|
case OP_NAME:
|
||||||
case OP_SELECT:
|
case OP_SELECT:
|
||||||
sym = identify(p, VAR|REGVAR|LOCVAR|VARPAR);
|
sym = identify(p, VAR|REGVAR|LOCVAR|VARPAR|CONST);
|
||||||
if (! sym) return;
|
if (! sym) return;
|
||||||
print_node(p, 0);
|
print_node(p, 0);
|
||||||
if (! print_sym(sym)) {
|
if (! print_sym(sym)) {
|
||||||
|
|
|
@ -3,11 +3,14 @@
|
||||||
#define MAXARGS 3
|
#define MAXARGS 3
|
||||||
|
|
||||||
typedef struct tree {
|
typedef struct tree {
|
||||||
int t_oper; /* operator */
|
short t_oper; /* tree operator */
|
||||||
|
short t_whichoper; /* expression operator */
|
||||||
t_addr t_address; /* some operators use an address */
|
t_addr t_address; /* some operators use an address */
|
||||||
int t_itemno; /* item number in status list */
|
int t_itemno; /* item number in status list */
|
||||||
union {
|
union {
|
||||||
long tt_ival;
|
long tt_ival;
|
||||||
|
char *tt_sval;
|
||||||
|
double tt_fval;
|
||||||
struct {
|
struct {
|
||||||
struct idf *tt_idf;
|
struct idf *tt_idf;
|
||||||
char *tt_str;
|
char *tt_str;
|
||||||
|
@ -17,6 +20,8 @@ typedef struct tree {
|
||||||
t_position tt_pos;
|
t_position tt_pos;
|
||||||
} t_xxxx;
|
} t_xxxx;
|
||||||
#define t_ival t_xxxx.tt_ival
|
#define t_ival t_xxxx.tt_ival
|
||||||
|
#define t_sval t_xxxx.tt_sval
|
||||||
|
#define t_fval t_xxxx.tt_fval
|
||||||
#define t_idf t_xxxx.tt_x.tt_idf
|
#define t_idf t_xxxx.tt_x.tt_idf
|
||||||
#define t_str t_xxxx.tt_x.tt_str
|
#define t_str t_xxxx.tt_x.tt_str
|
||||||
#define t_sc t_xxxx.tt_x.tt_scope
|
#define t_sc t_xxxx.tt_x.tt_scope
|
||||||
|
|
|
@ -12,20 +12,21 @@ int stack_offset; /* for up and down commands */
|
||||||
|
|
||||||
extern long pointer_size;
|
extern long pointer_size;
|
||||||
extern t_addr *get_EM_regs();
|
extern t_addr *get_EM_regs();
|
||||||
|
extern char *memcpy();
|
||||||
|
|
||||||
/* Get the value of the symbol indicated by sym.
|
/* Get the value of the symbol indicated by sym.
|
||||||
Return 0 on failure,
|
Return 0 on failure,
|
||||||
1 on success.
|
1 on success.
|
||||||
On success, 'buf' contains the value, and 'AB' may contain the parameters
|
On success, 'buf' contains the value, and 'size' contains the size.
|
||||||
of the procedure invocation containing sym.
|
For 'buf', storage is allocated by Malloc; this storage must
|
||||||
For both of these, storage is allocated by Malloc; this storage must
|
|
||||||
be freed by caller (I don't like this any more than you do, but caller
|
be freed by caller (I don't like this any more than you do, but caller
|
||||||
does not know sizes).
|
does not know sizes).
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
get_value(sym, buf, AB)
|
get_value(sym, buf, psize)
|
||||||
register p_symbol sym;
|
register p_symbol sym;
|
||||||
char **buf, **AB;
|
char **buf;
|
||||||
|
long *psize;
|
||||||
{
|
{
|
||||||
p_type tp = sym->sy_type;
|
p_type tp = sym->sy_type;
|
||||||
long size = tp->ty_size;
|
long size = tp->ty_size;
|
||||||
|
@ -33,9 +34,9 @@ get_value(sym, buf, AB)
|
||||||
t_addr *EM_regs;
|
t_addr *EM_regs;
|
||||||
int i;
|
int i;
|
||||||
p_scope sc, symsc;
|
p_scope sc, symsc;
|
||||||
|
char *AB;
|
||||||
|
|
||||||
*buf = 0;
|
*buf = 0;
|
||||||
*AB = 0;
|
|
||||||
switch(sym->sy_class) {
|
switch(sym->sy_class) {
|
||||||
case VAR:
|
case VAR:
|
||||||
/* exists if child exists; nm_value contains addres */
|
/* exists if child exists; nm_value contains addres */
|
||||||
|
@ -44,7 +45,40 @@ get_value(sym, buf, AB)
|
||||||
retval = 1;
|
retval = 1;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case CONST:
|
||||||
|
*buf = Malloc((unsigned) tp->ty_size);
|
||||||
|
switch(tp->ty_class) {
|
||||||
|
case T_REAL:
|
||||||
|
if (tp->ty_size != sizeof(double)) {
|
||||||
|
*((float *) *buf) = sym->sy_const.co_rval;
|
||||||
|
}
|
||||||
|
else *((double *) *buf) = sym->sy_const.co_rval;
|
||||||
|
break;
|
||||||
|
case T_INTEGER:
|
||||||
|
case T_SUBRANGE:
|
||||||
|
case T_UNSIGNED:
|
||||||
|
case T_ENUM:
|
||||||
|
if (tp->ty_size == 1) {
|
||||||
|
*((char *) *buf) = sym->sy_const.co_ival;
|
||||||
|
}
|
||||||
|
else if (tp->ty_size == 2) {
|
||||||
|
*((short *) *buf) = sym->sy_const.co_ival;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
*((long *) *buf) = sym->sy_const.co_ival;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case T_SET:
|
||||||
|
memcpy(*buf, sym->sy_const.co_setval, (int) tp->ty_size);
|
||||||
|
break;
|
||||||
|
case T_STRING:
|
||||||
|
memcpy(*buf, sym->sy_const.co_sval, (int) tp->ty_size);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
fatal("strange constant");
|
||||||
|
}
|
||||||
|
retval = 1;
|
||||||
|
break;
|
||||||
case VARPAR:
|
case VARPAR:
|
||||||
case LOCVAR:
|
case LOCVAR:
|
||||||
/* first find the stack frame in which it resides */
|
/* first find the stack frame in which it resides */
|
||||||
|
@ -97,28 +131,29 @@ get_value(sym, buf, AB)
|
||||||
|
|
||||||
size = proctype->ty_nbparams;
|
size = proctype->ty_nbparams;
|
||||||
if (has_static_link(sc)) size += pointer_size;
|
if (has_static_link(sc)) size += pointer_size;
|
||||||
*AB = Malloc((unsigned) size);
|
AB = Malloc((unsigned) size);
|
||||||
if (! get_bytes(size, EM_regs[AB_OFF], *AB)) {
|
if (! get_bytes(size, EM_regs[AB_OFF], AB)) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if ((size = tp->ty_size) == 0) {
|
if ((size = tp->ty_size) == 0) {
|
||||||
size = compute_size(tp, *AB);
|
size = compute_size(tp, AB);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*buf = Malloc((unsigned) size);
|
*buf = Malloc((unsigned) size);
|
||||||
|
*psize = size;
|
||||||
if (get_bytes(size,
|
if (get_bytes(size,
|
||||||
(t_addr) BUFTOA(*AB+sym->sy_name.nm_value),
|
(t_addr) BUFTOA(AB+sym->sy_name.nm_value),
|
||||||
*buf)) {
|
*buf)) {
|
||||||
retval = 1;
|
retval = 1;
|
||||||
}
|
}
|
||||||
|
free(AB);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (retval == 0) {
|
if (retval == 0) {
|
||||||
if (*buf) free(*buf);
|
if (*buf) free(*buf);
|
||||||
if (*AB) free(*AB);
|
|
||||||
*buf = 0;
|
*buf = 0;
|
||||||
*AB = 0;
|
*psize = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return retval;
|
return retval;
|
||||||
|
|
Loading…
Reference in a new issue