Too many changes and fixes to mention them all here

This commit is contained in:
ceriel 1990-10-11 08:42:07 +00:00
parent 7f8a099a15
commit 3672f835fe
23 changed files with 942 additions and 426 deletions

View file

@ -61,6 +61,7 @@ CSRC = {
value.c,
type.c,
rd.c,
help.c,
modula-2.c,
c.c
} ;
@ -101,7 +102,7 @@ LIBRARIES = {
$EMHOME/modules/lib/libsystem.a
} ;
DBFLAGS = { -g, -DDEBUG } ;
DBFLAGS = { -O, -DDEBUG } ;
PROFFLAGS = { } ;
LDFLAGS = {

View file

@ -57,8 +57,8 @@ static struct langdep c = {
print_string,
print_char,
array_elsize,
unop_prio,
binop_prio,
unop_prio,
get_string,
get_name,
get_number,
@ -69,11 +69,46 @@ static struct langdep c = {
struct langdep *c_dep = &c;
static int
printchar(c, esc)
int c;
{
switch(c) {
case '\n':
fputs("\\n", db_out);
break;
case '\t':
fputs("\\t", db_out);
break;
case '\b':
fputs("\\b", db_out);
break;
case '\r':
fputs("\\r", db_out);
break;
case '\f':
fputs("\\f", db_out);
break;
case '\\':
fputs("\\\\", db_out);
break;
case '\'':
case '"':
fprintf(db_out, c == esc ? "\\%c" : "%c", c);
break;
default:
fprintf(db_out, (c >= 040 && c < 0177) ? "%c" : "\\%03o", c);
break;
}
}
static int
print_char(c)
int c;
{
fprintf(db_out, (c >= 040 && c < 0177) ? "'%c'" : "'\\0%o'", c);
fputc('\'', db_out);
printchar(c, '\'');
fputc('\'', db_out);
}
static int
@ -82,12 +117,10 @@ print_string(s, len)
int len;
{
register char *str = s;
int delim = '\'';
while (*str) {
if (*str++ == '\'') delim = '"';
}
fprintf(db_out, "%c%.*s%c", delim, len, s, delim);
fputc('"', db_out);
while (*str && len-- > 0) printchar(*str++, '"');
fputc('"', db_out);
}
extern long int_size;
@ -110,7 +143,6 @@ unop_prio(op)
case E_BNOT:
case E_MIN:
case E_DEREF:
case E_SELECT:
case E_PLUS:
case E_ADDR:
return 12;
@ -153,6 +185,11 @@ binop_prio(op)
case E_MOD:
case E_ZMOD:
return 11;
case E_ARRAY:
case E_SELECT:
return 12;
case E_DERSELECT:
return 13;
}
return 1;
}
@ -236,15 +273,19 @@ get_token(c)
register int c;
{
switch(c) {
case '[':
tok.ival = E_ARRAY;
/* fall through */
case '(':
case ')':
case '[':
case ']':
case '`':
case ':':
case ',':
case '}':
case '{':
case '\\':
return c;
case '.':
tok.ival = E_SELECT;
return SEL_OP;
@ -340,7 +381,7 @@ get_token(c)
tok.ival = E_BNOT;
return PREF_OP;
default:
error("illegal character 0%o", c);
error((c >= 040 && c < 0177) ? "%s'%c'" : "%s'\\0%o'", "illegal character ", c);
return LLlex();
}
}
@ -397,6 +438,7 @@ get_string(c)
while (ch = getc(db_in), ch != c) {
if (ch == '\n') {
error("newline in string");
ungetc(ch, db_in);
break;
}
if (ch == '\\') {
@ -406,6 +448,15 @@ get_string(c)
buf[len++] = ch;
}
buf[len++] = 0;
if (c == '\'') {
long val = 0;
ch = 0;
while (buf[ch] != 0) {
val = (val << 8) + (buf[ch++] & 0377);
}
tok.ival = val;
return INTEGER;
}
tok.str = Salloc(buf, (unsigned) len);
return STRING;
}
@ -418,28 +469,34 @@ print_op(p)
case OP_UNOP:
switch(p->t_whichoper) {
case E_MIN:
fputs("-", db_out);
fputs("-(", db_out);
print_node(p->t_args[0], 0);
fputc(')', db_out);
break;
case E_PLUS:
fputs("+", db_out);
fputs("+(", db_out);
print_node(p->t_args[0], 0);
fputc(')', db_out);
break;
case E_NOT:
fputs("!", db_out);
fputs("!(", db_out);
print_node(p->t_args[0], 0);
fputc(')', db_out);
break;
case E_DEREF:
fputs("*", db_out);
fputs("*(", db_out);
print_node(p->t_args[0], 0);
fputc(')', db_out);
break;
case E_BNOT:
fputs("~", db_out);
fputs("~(", db_out);
print_node(p->t_args[0], 0);
fputc(')', db_out);
break;
case E_ADDR:
fputs("&", db_out);
fputs("&(", db_out);
print_node(p->t_args[0], 0);
fputc(')', db_out);
break;
}
break;

View file

@ -8,11 +8,11 @@
%iSTGARB
STSKIP: \t\013\014\015
STNL:;\012
STIDF:a-zA-Z_$
STIDF:a-zA-Z_
STSTR:"'
STDOT:.
STNUM:0-9
STSIMP:,<>{}:`
STSIMP:-,<>{}:`?\\
%T#include "class.h"
%Tchar tkclass[] = {
%p

View file

@ -4,7 +4,6 @@
{
#include <stdio.h>
#include <alloc.h>
#include <setjmp.h>
#include <signal.h>
#include "ops.h"
@ -19,15 +18,17 @@
#include "expr.h"
extern char *Salloc();
extern char *strindex();
extern FILE *db_in;
extern int disable_intr;
extern p_tree run_command, print_command;
int errorgiven;
int errorgiven = 0;
int child_interrupted = 0;
int interrupted = 0;
int eof_seen = 0;
static int extended_charset = 0;
static int in_expression = 0;
jmp_buf jmpbuf;
static int init_del();
static int skip_to_eol();
struct token tok, aside;
@ -40,50 +41,51 @@ struct token tok, aside;
commands
{ p_tree com, lastcom = 0;
int give_prompt;
}
:
{ if (! setjmp(jmpbuf)) {
init_del();
}
else {
skip_to_eol();
goto prmpt;
}
}
[ %persistent command_line(&com)
[ '\n' { give_prompt = 1; }
| %default ';' { give_prompt = 0; }
]
{ if (com) {
if (errorgiven) {
freenode(com);
com = 0;
}
if (lastcom && !in_status(lastcom) &&
lastcom != run_command) {
if (lastcom) {
freenode(lastcom);
lastcom = 0;
}
if (com) {
eval(com);
if (repeatable(com)) {
lastcom = com;
}
eval(com);
if (! repeatable(com) &&
! in_status(com) &&
com != run_command) {
else if (! in_status(com) &&
com != run_command &&
com != print_command) {
freenode(com);
}
}
} else if (lastcom && ! errorgiven) eval(lastcom);
} else if (lastcom && ! errorgiven) {
eval(lastcom);
}
if (give_prompt) {
errorgiven = 0;
interrupted = 0;
prompt();
}
}
[ '\n' { prmpt: prompt(); }
| ';'
] { errorgiven = 0; }
]*
{ signal_child(SIGKILL); }
;
command_line(p_tree *p;)
:
{ *p = 0; }
[
list_command(p)
| file_command(p)
| run_command(p)
@ -102,9 +104,12 @@ command_line(p_tree *p;)
| display_command(p)
| trace_command(p)
| set_command(p)
| help_command(p)
| FIND qualified_name(p){ *p = mknode(OP_FIND, *p); }
| WHICH qualified_name(p){ *p = mknode(OP_WHICH, *p); }
| { *p = 0; }
| able_command(p)
|
]
;
where_command(p_tree *p;)
@ -112,6 +117,7 @@ where_command(p_tree *p;)
:
WHERE
[ INTEGER { l = tok.ival; }
| '-' INTEGER { l = - tok.ival; }
| { l = 0x7fffffff; }
] { *p = mknode(OP_WHERE, l); }
;
@ -121,12 +127,17 @@ list_command(p_tree *p;)
:
LIST
[
| lin_num(&t1)
[ ',' lin_num(&t2)
| { t2 = mknode(OP_INTEGER, t1->t_ival); }
]
| count(&t1)
| qualified_name(&t1)
] { *p = mknode(OP_LIST, t1, t2); }
]
[ ',' count(&t2)
| '-'
[ count(&t2) { t2->t_ival = - t2->t_ival; }
| { t2 = mknode(OP_INTEGER, -100000000L); }
]
|
]
{ *p = mknode(OP_LIST, t1, t2); }
;
file_command(p_tree *p;)
@ -139,13 +150,20 @@ file_command(p_tree *p;)
}
;
help_command(p_tree *p;)
:
[ HELP | '?' ]
[ { *p = mknode(OP_HELP, (struct idf *) 0, (char *) 0); }
| name(p) { (*p)->t_oper = OP_HELP; }
| '?' { *p = mknode(OP_HELP, str2idf("help",0), (char *) 0); }
]
;
run_command(p_tree *p;)
:
RUN { extended_charset = 1; *p = 0; }
RUN { extended_charset = 1; }
args(p) { *p = mknode(OP_RUN, *p);
extended_charset = 0;
freenode(run_command);
run_command = *p;
}
| RERUN { if (! run_command) {
error("no run command given yet");
@ -171,7 +189,7 @@ trace_command(p_tree *p;)
{ p_tree whr = 0, cond = 0, exp = 0; }
:
TRACE
[ ON expression(&exp, 1) ]?
[ ON expression(&exp, 0) ]?
where(&whr)?
condition(&cond)? { *p = mknode(OP_TRACE, whr, cond, exp); }
;
@ -195,8 +213,10 @@ when_command(p_tree *p;)
condition(&cond)?
'{'
command_line(p)
[ ';' { *p = mknode(OP_LINK, *p, (p_tree) 0);
p = &((*p)->t_args[1]);
[ ';' { if (*p) {
*p = mknode(OP_LINK, *p, (p_tree) 0);
p = &((*p)->t_args[1]);
}
}
command_line(p)
]*
@ -206,6 +226,9 @@ when_command(p_tree *p;)
freenode(*p);
*p = 0;
}
else if (! *p) {
error("no commands given");
}
else *p = mknode(OP_WHEN, whr, cond, *p);
}
;
@ -239,41 +262,81 @@ regs_command(p_tree *p;)
delete_command(p_tree *p;)
:
DELETE
INTEGER { *p = mknode(OP_DELETE, tok.ival); }
DELETE count_list(p) { *p = mknode(OP_DELETE, *p); }
;
print_command(p_tree *p;)
:
PRINT expression_list(p)
PRINT
[ format_expression_list(p)
{ *p = mknode(OP_PRINT, *p); }
|
{ *p = mknode(OP_PRINT, (p_tree) 0); }
]
;
display_command(p_tree *p;)
:
DISPLAY expression_list(p)
DISPLAY format_expression_list(p)
{ *p = mknode(OP_DISPLAY, *p); }
;
expression_list(p_tree *p;)
format_expression_list(p_tree *p;)
:
expression(p, 1)
format_expression(p)
[ ',' { *p = mknode(OP_LINK, *p, (p_tree) 0);
p = &((*p)->t_args[1]);
}
expression(p, 1)
format_expression(p)
]*
;
format_expression(p_tree *p;)
{ p_tree p1; }
:
expression(p, 0)
[ '\\'
[ name(&p1) { register char *c = p1->t_str;
while (*c) {
if (! strindex("doshcax", *c)) {
error("illegal format: %c", *c);
break;
}
c++;
}
*p = mknode(OP_FORMAT, *p, p1);
}
|
]
|
]
;
set_command(p_tree *p;)
:
SET expression(p, 1) { *p = mknode(OP_SET, *p, (p_tree) 0); }
TO expression(&((*p)->t_args[1]), 1)
SET expression(p, 0) { *p = mknode(OP_SET, *p, (p_tree) 0); }
TO expression(&((*p)->t_args[1]), 0)
;
able_command(p_tree *p;)
:
[ ENABLE { *p = mknode(OP_ENABLE, (p_tree) 0); }
| DISABLE { *p = mknode(OP_DISABLE, (p_tree) 0); }
]
count_list(&(*p)->t_args[0])
;
count_list(p_tree *p;)
:
count(p)
[ ',' { *p = mknode(OP_LIST, *p, (p_tree) 0); }
count(&(*p)->t_args[1])
]*
;
condition(p_tree *p;)
:
IF expression(p, 1)
IF expression(p, 0)
;
where(p_tree *p;)
@ -293,36 +356,7 @@ expression(p_tree *p; int level;)
(*p)->t_whichoper = currop;
}
expression(&((*p)->t_args[1]), currprio)
{ adjust_oper(p); }
]*
{ in_expression--; }
;
factor(p_tree *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)
|
{ *p = mknode(OP_UNOP, (p_tree) 0);
(*p)->t_whichoper = (int) tok.ival;
}
[ PREF_OP
| PREF_OR_BIN_OP { (*currlang->fix_bin_to_pref)(*p); }
]
expression(&(*p)->t_args[0], unprio((*p)->t_whichoper))
;
designator(p_tree *p;)
:
qualified_name(p)
[
|
SEL_OP { *p = mknode(OP_BINOP, *p, (p_tree) 0);
(*p)->t_whichoper = (int) tok.ival;
}
@ -331,9 +365,43 @@ designator(p_tree *p;)
'[' { *p = mknode(OP_BINOP, *p, (p_tree) 0);
(*p)->t_whichoper = E_ARRAY;
}
expression(&(*p)->t_args[1], 1)
expression(&(*p)->t_args[1], 0)
[ ',' { *p = mknode(OP_BINOP, *p, (p_tree) 0);
(*p)->t_whichoper = E_ARRAY;
}
expression(&(*p)->t_args[1], 0)
]*
']'
]*
{ in_expression--; }
;
factor(p_tree *p;)
:
[
%default EXPRESSION /* lexical analyzer will never return this token */
{ *p = mknode(OP_INTEGER, 0L); }
|
'(' expression(p, 0) ')'
|
INTEGER { *p = mknode(OP_INTEGER, tok.ival); }
|
REAL { *p = mknode(OP_REAL, tok.fval); }
|
STRING { *p = mknode(OP_STRING, tok.str); }
|
qualified_name(p)
|
{ *p = mknode(OP_UNOP, (p_tree) 0);
(*p)->t_whichoper = (int) tok.ival;
}
[ PREF_OP
| PREF_OR_BIN_OP
{ (*currlang->fix_bin_to_pref)(*p); }
]
expression(&(*p)->t_args[0], unprio((*p)->t_whichoper))
]
[ %while(1)
POST_OP { *p = mknode(OP_UNOP, *p);
(*p)->t_whichoper = (int) tok.ival;
}
@ -352,7 +420,7 @@ position(p_tree *p;)
else str = listfile->sy_idf->id_text;
}
]
lin_num(&lin) { *p = mknode(OP_AT, lin->t_ival, str);
count(&lin) { *p = mknode(OP_AT, lin->t_ival, str);
freenode(lin);
}
;
@ -379,7 +447,7 @@ arg(p_tree *p;)
'<' name(p) { (*p)->t_oper = OP_INPUT; }
;
lin_num(p_tree *p;)
count(p_tree *p;)
:
INTEGER { *p = mknode(OP_INTEGER, tok.ival); }
;
@ -403,7 +471,7 @@ name(p_tree *p;)
| AT
| IN
| IF
| NAME
| %default NAME
| CONT
| STEP
| NEXT
@ -421,6 +489,9 @@ name(p_tree *p;)
| FIND
| DISPLAY
| WHICH
| HELP
| DISABLE
| ENABLE
] { *p = mknode(OP_NAME, tok.idf, tok.str); }
;
@ -438,7 +509,10 @@ LLlex()
do {
c = getc(db_in);
} while (c != EOF && class(c) == STSKIP);
if (c == EOF) return c;
if (c == EOF) {
eof_seen = 1;
return c;
}
if (extended_charset && in_ext(c)) {
TOK = get_name(c);
return TOK;
@ -483,7 +557,7 @@ get_name(c)
c = getc(db_in);
} while ((extended_charset && in_ext(c)) || in_idf(c));
ungetc(c, db_in);
*p = 0;
*p++ = 0;
if (extended_charset) {
tok.idf = 0;
tok.str = Salloc(buf, (unsigned) (p - buf));
@ -520,20 +594,16 @@ static int
catch_del()
{
signal(SIGINT, catch_del);
signal_child(SIGEMT);
longjmp(jmpbuf, 1);
if (! disable_intr) {
signal_child(SIGEMT);
child_interrupted = 1;
}
interrupted = 1;
}
static int
int
init_del()
{
signal(SIGINT, catch_del);
}
static int
skip_to_eol()
{
while (TOK != '\n' && TOK > 0) LLlex();
wait_for_child("interrupted");
}
}

View file

@ -56,8 +56,13 @@ debugger_string
| /* type name */
{ s = NewSymbol(str, CurrentScope, TYPE, currnam); }
't' type_name(&(s->sy_type), s)
{ if (! s->sy_type->ty_sym) s->sy_type->ty_sym = s; }
{ if (! s->sy_type->ty_sym) s->sy_type->ty_sym = s;
if ((s->sy_type->ty_class == T_ENUM ||
s->sy_type->ty_class == T_SUBRANGE) &&
currnam->on_desc != 0) {
s->sy_type->ty_size = currnam->on_desc;
}
}
| /* tag name (only C?) */
{ s = NewSymbol(str, CurrentScope, TAG, currnam); }
'T' tag_name(s)
@ -225,7 +230,7 @@ type_name(p_type *t; p_symbol sy;)
type(t, type_index, sy)
{ p = tp_lookup(type_index);
if (*p && *p != incomplete_type) {
if (!((*p)->ty_flags & T_CROSS))
if ((*p)->ty_class != T_CROSS)
error("Redefining (%d,%d) %d",
type_index[0],
type_index[1],
@ -264,7 +269,7 @@ tag_name(p_symbol t;)
type(&(t->sy_type), type_index, t)
{ p = tp_lookup(type_index);
if (*p && *p != incomplete_type) {
if (!((*p)->ty_flags & T_CROSS))
if ((*p)->ty_class != T_CROSS)
error("Redefining (%d,%d) %d",
type_index[0],
type_index[1],
@ -275,6 +280,11 @@ tag_name(p_symbol t;)
}
if (t->sy_type) *p = t->sy_type;
if (*p == 0) *p = incomplete_type;
if (t->sy_type &&
t->sy_type->ty_class == T_ENUM &&
currnam->on_desc != 0) {
t->sy_type->ty_size = currnam->on_desc;
}
}
;
@ -348,14 +358,15 @@ type(p_type *ptp; int *type_index; p_symbol sy;)
]
{ AllowName = 1; }
name(&str)
{ sy = Lookfromscope(str2idf(str,0),CurrentScope,TAG);
if (sy && sy->sy_type->ty_class == tclass) {
{ sy = Lookfromscope(str2idf(str,0),TAG,CurrentScope);
if (sy &&
(sy->sy_type->ty_class == tclass ||
sy->sy_type->ty_class == T_CROSS)) {
tp = sy->sy_type;
}
else {
tp = new_type();
tp->ty_flags = T_CROSS;
tp->ty_class = tclass;
tp->ty_class = T_CROSS;
tp->ty_tag = str;
sy = NewSymbol(str, CurrentScope, TAG, (struct outname *) 0);
}

View file

@ -38,11 +38,11 @@ DbxRead(f)
/* Open file, read header, and check magic word */
if (! rd_open(f)) {
fatal("%s: not an ACK object file", f);
fatal("%s: could not open", f);
}
rd_ohead(&h);
if (BADMAGIC(h) && h.oh_magic != O_CONVERTED) {
fatal("%s: not an ACK object file", f);
fatal("%s: not an object file", f);
}
/* Allocate space for name table and read it */

View file

@ -229,10 +229,10 @@ eval_cond(p)
if (eval_expr(p, &buf, &size, &tp)) {
if (convert(&buf, &size, &tp, target_tp, target_tp->ty_size)) {
val = get_int(buf, size, T_UNSIGNED);
if (buf) free(buf);
free(buf);
return (int) (val != 0);
}
if (buf) free(buf);
free(buf);
}
return 0;
}
@ -298,6 +298,7 @@ ptr_addr(p, paddr, psize, ptp)
return 1;
default:
error("illegal operand of DEREF");
free(buf);
break;
}
}
@ -318,6 +319,9 @@ do_deref(p, pbuf, psize, ptp)
malloc_succeeded(*pbuf);
if (! get_bytes(*psize, addr, *pbuf)) {
error("could not get value");
free(*pbuf);
*pbuf = 0;
return 0;
}
return 1;
}
@ -337,6 +341,8 @@ do_addr(p, pbuf, psize, ptp)
*pbuf = malloc((unsigned) pointer_size);
malloc_succeeded(*pbuf);
put_int(*pbuf, pointer_size, (long) addr);
address_type->ty_ptrto = *ptp;
*ptp = address_type;
return 1;
}
return 0;
@ -505,7 +511,7 @@ do_andor(p, pbuf, psize, ptp)
p_type *ptp;
{
long l1, l2;
char *buf;
char *buf = 0;
long size;
p_type tp;
p_type target_tp = currlang->has_bool_type ? bool_type : int_type;
@ -524,7 +530,7 @@ do_andor(p, pbuf, psize, ptp)
free(buf);
return 1;
}
free(buf);
if (buf) free(buf);
return 0;
}
@ -541,9 +547,44 @@ do_arith(p, pbuf, psize, ptp)
long size;
p_type tp, balance_tp;
if (eval_expr(p->t_args[0], pbuf, psize, ptp) &&
eval_expr(p->t_args[1], &buf, &size, &tp) &&
(balance_tp = balance(*ptp, tp)) &&
if (!(eval_expr(p->t_args[0], pbuf, psize, ptp) &&
eval_expr(p->t_args[1], &buf, &size, &tp))) {
return 0;
}
if ((*ptp)->ty_class == T_POINTER) {
if (currlang != c_dep ||
(p->t_whichoper != E_PLUS && p->t_whichoper != E_MIN)) {
error("illegal operand type(s)");
free(buf);
return 0;
}
l1 = get_int(*pbuf, *psize, T_UNSIGNED);
if (tp->ty_class == T_POINTER) {
if (p->t_whichoper != E_MIN) {
error("illegal operand type(s)");
free(buf);
return 0;
}
l2 = get_int(buf, size, T_UNSIGNED);
free(buf);
*pbuf = Realloc(*pbuf, (unsigned) long_size);
put_int(*pbuf, long_size, (l1 - l2)/(*ptp)->ty_ptrto->ty_size);
*ptp = long_type;
return 1;
}
if (! convert(&buf, &size, &tp, long_type, long_size)) {
free(buf);
return 0;
}
l2 = get_int(buf, size, T_INTEGER) * (*ptp)->ty_ptrto->ty_size;
free(buf);
buf = 0;
if (p->t_whichoper == E_PLUS) l1 += l2;
else l1 -= l2;
put_int(*pbuf, *psize, l1);
return 1;
}
if ((balance_tp = balance(*ptp, tp)) &&
convert(pbuf, psize, ptp, balance_tp, balance_tp->ty_size) &&
convert(&buf, &size, &tp, balance_tp, balance_tp->ty_size)) {
switch(balance_tp->ty_class) {
@ -795,6 +836,10 @@ do_cmp(p, pbuf, psize, ptp)
break;
}
break;
default:
error("illegal operand type(s)");
free(buf);
return 0;
}
if (*psize < int_size) {
*psize = int_size;
@ -976,6 +1021,9 @@ do_select(p, pbuf, psize, ptp)
*pbuf = malloc((unsigned int) *psize);
malloc_succeeded(*pbuf);
if (! get_bytes(*psize, a, *pbuf)) {
error("could not get value");
free(*pbuf);
*pbuf = 0;
return 0;
}
return 1;
@ -983,6 +1031,27 @@ do_select(p, pbuf, psize, ptp)
return 0;
}
static int
do_derselect(p, pbuf, psize, ptp)
p_tree p;
char **pbuf;
long *psize;
p_type *ptp;
{
int retval;
t_tree t;
t.t_oper = OP_UNOP;
t.t_whichoper = E_DEREF;
t.t_args[0] = p->t_args[0];
p->t_args[0] = &t;
p->t_whichoper = E_SELECT;
retval = eval_expr(p, pbuf, psize, ptp);
p->t_args[0] = t.t_args[0];
p->t_whichoper = E_DERSELECT;
return retval;
}
static int (*bin_op[])() = {
0,
0,
@ -1009,7 +1078,7 @@ static int (*bin_op[])() = {
do_arith,
do_arith,
0,
0,
do_derselect,
do_sft,
do_sft,
0
@ -1023,9 +1092,14 @@ eval_expr(p, pbuf, psize, ptp)
p_type *ptp;
{
register p_symbol sym;
int retval = 0;
int retval = 0;
*pbuf = 0;
switch(p->t_oper) {
case OP_FORMAT:
if (eval_expr(p->t_args[0], pbuf, psize, ptp)) retval = 1;
break;
case OP_NAME:
case OP_SELECT:
sym = identify(p, VAR|REGVAR|LOCVAR|VARPAR|CONST);
@ -1148,7 +1222,7 @@ eval_desig(p, paddr, psize, ptp)
}
break;
default:
assert(0);
error("illegal designator");
break;
}
if (! retval) {

View file

@ -1,5 +1,5 @@
.\" $Header$
.TH GRIND 1ACK
.TH GRIND 1
.SH NAME
grind \- source-level debugger for ACK
.SH SYNOPSIS
@ -21,15 +21,15 @@ available on many Unix systems. However, some
.B grind
commands are not available in
.IR dbx ,
some more
some
.I dbx
commands are not available in
.BR grind ,
and some things are just plain different.
and some things are just different.
.LP
.I <object file>
is an object file, produced by
.IR ack (1ACK)
.IR ack (1)
with the
.B \-g
option to include a symbol table.
@ -40,7 +40,7 @@ is specified, "a.out" is used.
.LP
For some machines, the debugger does not recognize the object file
format. For these machines, the result of the
.IR led (6ACK)
.IR led (6)
program must be saved and offered to
.BR grind .
.SH USAGE
@ -164,10 +164,10 @@ when the
is reached, and then when
.I condition
becomes true.
If no position is given, stop when
If no position is given, do this when
.I condition
becomes true.
If no condition is given, stop when
If no condition is given, do this when
.I position
is reached.
Either a position or a condition (or both) must be given.
@ -273,6 +273,9 @@ If the types do not match,
tries to apply conversions.
.TP
\fBwhere\fP [ \fIn\fP ]
.ti -0.5i
\fBw\fP [ \fIn\fP ]
.br
List all, or the top
.IR n ,
active functions on the stack.
@ -302,13 +305,11 @@ the first statement of
Exit
.BR grind .
.LP
Some commands can be repeated by entering an empty command line: step,
next, print, list, status, cont.
.SH ENVIRONMENT
P.M.
Some commands can be repeated without arguments by entering an empty command line:
step, next, list, cont.
.SH SEE ALSO
.IR ack (1ACK).
.IR led (6ACK).
.IR ack (1).
.IR led (6).
.SH REMARKS
.LP
.B Grind

View file

@ -7,13 +7,16 @@
#include "position.h"
#include "tree.h"
#include "operator.h"
#include "message.h"
extern FILE *db_out;
extern int db_ss;
typedef struct item {
struct item *i_next;
struct tree *i_node;
struct item *i_next;
struct tree *i_node;
int i_disabled;
int i_itemno;
} t_item, *p_item;
/* STATICALLOCDEF "item" 10 */
@ -25,7 +28,7 @@ struct itemlist {
static struct itemlist item_list;
int
static int
in_item_list(p)
p_tree p;
{
@ -38,8 +41,17 @@ in_item_list(p)
return 0;
}
static
pr_item(i)
p_item i;
{
fprintf(db_out, "(%d)\t", i->i_itemno);
print_node(i->i_node, 0);
fputs(i->i_disabled ? " (disabled)\n": "\n", db_out);
}
int
item_addr_actions(a)
item_addr_actions(a, mess_type)
t_addr a;
{
/* Perform actions associated with position 'a', and return 1 if we must stop
@ -51,16 +63,14 @@ item_addr_actions(a)
while (i) {
register p_tree p = i->i_node;
if (p->t_address == a || p->t_address == NO_ADDR) {
if (! i->i_disabled && (p->t_address == a || p->t_address == NO_ADDR)) {
switch(p->t_oper) {
case OP_TRACE:
case OP_WHEN:
if (! p->t_args[1] ||
eval_cond(p->t_args[1])) {
perform(p, a);
}
perform(p, a);
break;
case OP_STOP:
if (mess_type != DB_SS && mess_type != OK) break;
if (! p->t_args[1] ||
eval_cond(p->t_args[1])) stopping = 1;
break;
@ -83,7 +93,7 @@ handle_displays()
while (i) {
register p_tree p = i->i_node;
if (p->t_oper == OP_DISPLAY) do_print(p);
if (! i->i_disabled && p->t_oper == OP_DISPLAY) do_print(p);
i = i->i_next;
}
}
@ -105,9 +115,9 @@ add_to_item_list(p)
else {
item_list.il_last->i_next = i;
}
p->t_itemno = ++item_list.il_count;
i->i_itemno = ++item_list.il_count;
item_list.il_last = i;
pr_item(p);
pr_item(i);
return 1;
}
@ -119,7 +129,7 @@ remove_from_item_list(n)
p_tree p = 0;
while (i) {
if (i->i_node->t_itemno == n) break;
if (i->i_itemno == n) break;
prev = i;
i = i->i_next;
}
@ -144,33 +154,61 @@ get_from_item_list(n)
register p_item i = item_list.il_first;
while (i) {
if (i->i_node->t_itemno == n) return i->i_node;
if (i->i_itemno == n) return i->i_node;
i = i->i_next;
}
return 0;
}
able_item(n, kind)
int n;
{
register p_item i = item_list.il_first;
register p_tree p;
while (i) {
if (i->i_itemno == n) break;
i = i->i_next;
}
if (! i) {
error("no item %d in current status", n);
return;
}
p = i->i_node;
if (i->i_disabled == kind) {
warning("item %d already %sabled", n, kind ? "dis" : "en");
return;
}
if (p->t_address == NO_ADDR &&
(p->t_oper != OP_TRACE || ! p->t_args[0])) {
db_ss += kind == 1 ? (-1) : 1;
}
i->i_disabled = kind;
switch(p->t_oper) {
case OP_STOP:
case OP_WHEN:
setstop(p, kind ? CLRBP : SETBP);
break;
case OP_TRACE:
settrace(p, kind ? CLRTRACE : SETTRACE);
break;
}
}
print_items()
{
register p_item i = item_list.il_first;
for (; i; i = i->i_next) {
pr_item(i->i_node);
pr_item(i);
}
}
pr_item(p)
p_tree p;
{
fprintf(db_out, "(%d)\t", p->t_itemno);
print_node(p, 1);
}
do_items()
{
register p_item i = item_list.il_first;
for (; i; i = i->i_next) {
if (i->i_node->t_oper != OP_DUMP) eval(i->i_node);
if (! i->i_disabled && i->i_node->t_oper != OP_DUMP) eval(i->i_node);
}
}

View file

@ -13,6 +13,7 @@ extern char *dirs[];
extern FILE *fopen();
extern FILE *db_out;
extern t_lineno currline;
extern int interrupted;
static int
mk_filnm(dir, file, newname)
@ -81,16 +82,14 @@ lines(file, l1, l2)
else f = last_f;
if (l1 < 1) l1 = 1;
if (l2 > file->f_nlines) l2 = file->f_nlines;
if (l1 > l2) {
error("%s has only %d lines", file->f_sym->sy_idf->id_text, file->f_nlines);
return;
}
if (l1 > file->f_nlines) l1 = file->f_nlines;
if (l1+l2-1 > file->f_nlines) l2 = file->f_nlines - l1 + 1;
fseek(f, *(file->f_linepos+(l1-1)), 0);
for (n = l1; n <= l2; n++) {
for (n = l1; n < l1 + l2; n++) {
register int c;
if (interrupted) return;
fprintf(db_out, "%c%5d\t", currfile && file == currfile->sy_file && n == currline ? '>' : ' ', n);
do {
c = getc(f);

View file

@ -9,7 +9,7 @@
#include "Lpars.h"
static char *usage = "Usage: %s [<ack.out>] [<a.out>]";
static char *progname;
char *progname;
char *AckObj;
char *AObj;
char *dirs[] = { "", 0 };
@ -18,6 +18,7 @@ FILE *db_in;
int debug;
extern struct tokenname tkidf[];
extern char *strindex();
extern int eof_seen;
static struct tokenname shorts[] = {
{LIST, "l"},
@ -28,6 +29,7 @@ static struct tokenname shorts[] = {
{PRINT, "p"},
{RESTORE, "r"},
{TRACE, "t"},
{WHERE, "w"},
{ 0, 0}
};
@ -39,6 +41,7 @@ main(argc, argv)
db_out = stdout;
db_in = stdin;
progname = argv[0];
init_del();
while (p = strindex(progname, '/')) {
progname = p + 1;
}
@ -66,20 +69,19 @@ main(argc, argv)
else if (AObj == 0) AObj = "a.out";
reserve(tkidf);
reserve(shorts);
if (currfile) CurrentScope = currfile->sy_file->f_scope;
if (! init_run()) {
fatal("something wrong with file descriptors");
}
prompt();
Commands();
fputc( '\n', db_out);
if (eof_seen) fputc('\n', db_out);
exit(0);
}
prompt()
{
if (isatty(fileno(db_in))) {
fprintf(db_out, "%s -> ", progname);
fprintf(db_out, "-> ");
fflush(db_out);
}
}
@ -94,12 +96,11 @@ fatal(va_alist)
va_start(ap);
{
fmt = va_arg(ap, char *);
fprintf(stderr, "%s: ", progname);
vfprintf(stderr, fmt, ap);
fprintf(stderr, "\n");
fprintf(db_out, "%s: ", progname);
vfprintf(db_out, fmt, ap);
fprintf(db_out, "\n");
}
va_end(ap);
abort();
exit(1);
}
@ -115,9 +116,9 @@ error(va_alist)
va_start(ap);
{
fmt = va_arg(ap, char *);
fprintf(stderr, "%s: ", progname);
vfprintf(stderr, fmt, ap);
fprintf(stderr, "\n");
fprintf(db_out, "%s: ", progname);
vfprintf(db_out, fmt, ap);
fprintf(db_out, "\n");
}
va_end(ap);
errorgiven = 1;
@ -133,9 +134,9 @@ warning(va_alist)
va_start(ap);
{
fmt = va_arg(ap, char *);
fprintf(stderr, "%s: ", progname);
vfprintf(stderr, fmt, ap);
fprintf(stderr, "\n");
fprintf(db_out, "%s: ", progname);
vfprintf(db_out, fmt, ap);
fprintf(db_out, "\n");
}
va_end(ap);
}

View file

@ -36,6 +36,7 @@ struct message_hdr {
#define FAIL 51 /* answer of child when something goes wrong */
#define DATA 52 /* answer of child when data requested */
#define END_SS 53 /* when stopped because of user single stepping */
#define INTR 54 /* sent on interrupt */
long m_size; /* size */
char m_buf[BUFLEN]; /* some of the data required included in message */
};

View file

@ -110,8 +110,6 @@ unop_prio(op)
case E_MIN:
case E_PLUS:
return 3;
case E_SELECT:
return 9;
}
return 1;
}
@ -121,6 +119,10 @@ binop_prio(op)
int op;
{
switch(op) {
case E_SELECT:
return 9;
case E_ARRAY:
return 5;
case E_AND:
case E_MUL:
case E_DIV:
@ -357,15 +359,18 @@ get_token(c)
register int c;
{
switch(c) {
case '[':
tok.ival = E_ARRAY;
/* fall through */
case '(':
case ')':
case '[':
case ']':
case '`':
case '{':
case '}':
case ':':
case ',':
case '\\':
return c;
case '.':
@ -424,7 +429,7 @@ get_token(c)
tok.ival = E_NOT;
return PREF_OP;
default:
error("illegal character 0%o", c);
error((c >= 040 && c < 0177) ? "%s'%c'" : "%s'\\0%o'", "illegal character ", c);
return LLlex();
}
}
@ -440,6 +445,7 @@ get_string(c)
while (ch = getc(db_in), ch != c) {
if (ch == '\n') {
error("newline in string");
ungetc(ch, db_in);
break;
}
buf[len++] = ch;

View file

@ -10,6 +10,7 @@ OP_STRING 0 0
OP_NAME 0 0
OP_AT 0 0
OP_IN 1 0
OP_HELP 0 do_help
OP_STOP 2 do_stop
OP_WHEN 3 do_stop
OP_CONT 2 do_continue
@ -17,8 +18,8 @@ OP_STEP 0 do_step
OP_NEXT 0 do_next
OP_REGS 0 do_regs
OP_WHERE 0 do_where
OP_STATUS 0 do_status
OP_DELETE 0 do_delete
OP_STATUS 0 print_items
OP_DELETE 1 do_delete
OP_SELECT 2 0
OP_SET 2 do_set
OP_PRINT 1 do_print
@ -30,3 +31,6 @@ OP_DISPLAY 1 add_to_item_list
OP_WHICH 1 do_which
OP_UNOP 1 0
OP_BINOP 2 0
OP_FORMAT 2 0
OP_DISABLE 1 do_disable
OP_ENABLE 1 do_enable

View file

@ -127,9 +127,11 @@ add_position_addr(filename, n)
map->f_start = n;
}
else map = lastmap;
map->f_end = n;
setnext_outname(n, map->f_line_addr[HASH(n->on_desc)]);
map->f_line_addr[HASH(n->on_desc)] = n;
if (map) {
map->f_end = n;
setnext_outname(n, map->f_line_addr[HASH(n->on_desc)]);
map->f_line_addr[HASH(n->on_desc)] = n;
}
}
/* extern p_position print_position(t_addr a, int print_function);

View file

@ -15,46 +15,99 @@
extern FILE *db_out;
extern long float_size, pointer_size, int_size;
extern char *strindex();
static
print_literal(tp, v)
print_unsigned(tp, v, format)
p_type tp;
long v;
register char *format;
{
while (format && *format) {
if (strindex("cdohx", *format)) break;
format++;
}
switch(format == 0 ? 0 : *format) {
default:
if (tp != uchar_type) {
fprintf(db_out, currlang->uns_fmt, v);
break;
}
/* fall through */
case 'c':
(*currlang->printchar)((int) v);
break;
case 'd':
fprintf(db_out, currlang->decint_fmt, v);
break;
case 'o':
fprintf(db_out, currlang->octint_fmt, v);
break;
case 'x':
case 'h':
fprintf(db_out, currlang->hexint_fmt, v);
break;
}
}
static
print_literal(tp, v, compressed, format)
p_type tp;
long v;
int compressed;
char *format;
{
register struct literal *lit = tp->ty_literals;
register int i;
if (format) {
print_unsigned(tp, v, format);
return;
}
for (i = tp->ty_nenums; i; i--, lit++) {
if (lit->lit_val == v) {
fprintf(db_out, lit->lit_name);
fputs(lit->lit_name, db_out);
break;
}
}
if (! i) {
fprintf(db_out, "unknown enumeration value %d", v);
fprintf(db_out,
compressed ? "?%ld?" : "unknown enumeration value %ld",
v);
}
}
static
print_unsigned(tp, v)
print_integer(tp, v, format)
p_type tp;
long v;
register char *format;
{
if (tp == uchar_type) {
(*currlang->printchar)((int) v);
while (format && *format) {
if (strindex("cdohx", *format)) break;
format++;
}
else fprintf(db_out, currlang->uns_fmt, v);
}
static
print_integer(tp, v)
p_type tp;
long v;
{
if (tp == char_type) {
switch(format == 0 ? 0 : *format) {
default:
if (tp != char_type) {
fprintf(db_out, currlang->decint_fmt, v);
break;
}
/* fall through */
case 'c':
(*currlang->printchar)((int) v);
break;
case 'd':
fprintf(db_out, currlang->decint_fmt, v);
break;
case 'o':
fprintf(db_out, currlang->octint_fmt, v);
break;
case 'x':
case 'h':
fprintf(db_out, currlang->hexint_fmt, v);
break;
}
else fprintf(db_out, currlang->decint_fmt, v);
}
print_params(tp, AB, static_link)
@ -83,7 +136,6 @@ print_params(tp, AB, static_link)
}
if (static_link) p += pointer_size;
if (! get_bytes(size, AB, param_bytes)) {
error("no debuggee");
free(param_bytes);
return;
}
@ -110,11 +162,11 @@ print_params(tp, AB, static_link)
fprintf(db_out, currlang->addr_fmt, (long) addr);
}
else {
print_val(par->par_type, size, q, 1, 0);
print_val(par->par_type, size, q, 1, 0, (char *)0);
}
free(q);
}
else print_val(par->par_type, par->par_type->ty_size, p, 1, 0);
else print_val(par->par_type, par->par_type->ty_size, p, 1, 0, (char *)0);
if (i) fputs(", ", db_out);
p += param_size(par->par_type, par->par_kind);
par++;
@ -122,12 +174,13 @@ print_params(tp, AB, static_link)
free(param_bytes);
}
print_val(tp, tp_sz, addr, compressed, indent)
print_val(tp, tp_sz, addr, compressed, indent, format)
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 */
int compressed; /* for parameter lists */
int indent; /* indentation */
register char *format; /* format given or 0 */
{
register int i;
long elsize;
@ -135,12 +188,13 @@ print_val(tp, tp_sz, addr, compressed, indent)
if (indent == 0) indent = 4;
switch(tp->ty_class) {
case T_SUBRANGE:
print_val(tp->ty_base, tp_sz, addr, compressed, indent);
print_val(tp->ty_base, tp_sz, addr, compressed, indent, format);
break;
case T_ARRAY:
if (tp->ty_elements == char_type ||
tp->ty_elements == uchar_type) {
print_val(string_type, tp_sz, addr, compressed, indent);
if ((!format || strindex(format, 'a') == 0) &&
(tp->ty_elements == char_type ||
tp->ty_elements == uchar_type)) {
print_val(string_type, tp_sz, addr, compressed, indent, format);
break;
}
if (compressed) {
@ -156,7 +210,7 @@ print_val(tp, tp_sz, addr, compressed, indent)
indent += 4;
elsize = (*currlang->arrayelsize)(tp->ty_elements->ty_size);
for (i = tp_sz/elsize; i; i--) {
print_val(tp->ty_elements, tp->ty_elements->ty_size, addr, compressed, indent);
print_val(tp->ty_elements, tp->ty_elements->ty_size, addr, compressed, indent, format);
addr += elsize;
if (compressed && i > 1) {
fprintf(db_out, ", ...");
@ -192,7 +246,7 @@ print_val(tp, tp_sz, addr, compressed, indent)
/* ??? */
fprintf(db_out, "<bitfield, %d, %ld>", fld->fld_bitsize, sz);
}
else print_val(fld->fld_type, sz, addr+(fld->fld_pos>>3), compressed, indent);
else print_val(fld->fld_type, sz, addr+(fld->fld_pos>>3), compressed, indent, format);
if (compressed && i > 1) {
fprintf(db_out, ", ...");
break;
@ -210,7 +264,7 @@ print_val(tp, tp_sz, addr, compressed, indent)
fprintf(db_out, "<union>");
break;
case T_ENUM:
print_literal(tp, get_int(addr, tp_sz, T_ENUM));
print_literal(tp, get_int(addr, tp_sz, T_ENUM), compressed, format);
break;
case T_PROCEDURE: {
register p_scope sc = get_scope_from_addr((t_addr) get_int(addr, pointer_size, T_UNSIGNED));
@ -220,8 +274,21 @@ print_val(tp, tp_sz, addr, compressed, indent)
break;
}
}
/* Fall through */
fprintf(db_out, currlang->addr_fmt, get_int(addr, pointer_size, T_UNSIGNED));
break;
case T_POINTER:
if (format && strindex(format,'s') &&
(tp->ty_ptrto == char_type || tp->ty_ptrto == uchar_type)) {
t_addr a = get_int(addr, tp_sz, T_UNSIGNED);
char *naddr = malloc(512);
if (naddr && get_string(511L, a, naddr)) {
print_val(string_type, 512L, naddr, 0, indent, format);
free(naddr);
break;
}
if (naddr) free(naddr);
}
fprintf(db_out, currlang->addr_fmt, get_int(addr, pointer_size, T_UNSIGNED));
break;
case T_FILE:
@ -259,13 +326,13 @@ print_val(tp, tp_sz, addr, compressed, indent)
}
switch(base->ty_class) {
case T_INTEGER:
print_integer(base, val+i);
print_integer(base, val+i, format);
break;
case T_UNSIGNED:
print_unsigned(base, val+i);
print_unsigned(base, val+i, format);
break;
case T_ENUM:
print_literal(base, val+i);
print_literal(base, val+i, compressed, format);
break;
default:
assert(0);
@ -283,10 +350,10 @@ print_val(tp, tp_sz, addr, compressed, indent)
fprintf(db_out, currlang->real_fmt, get_real(addr, tp->ty_size));
break;
case T_UNSIGNED:
print_unsigned(tp, get_int(addr, tp_sz, T_UNSIGNED));
print_unsigned(tp, get_int(addr, tp_sz, T_UNSIGNED), format);
break;
case T_INTEGER:
print_integer(tp, get_int(addr, tp_sz, T_INTEGER));
print_integer(tp, get_int(addr, tp_sz, T_INTEGER), format);
break;
case T_STRING:
(*currlang->printstring)(addr, (int) tp_sz);

View file

@ -27,20 +27,25 @@ extern char *AObj;
extern FILE *db_out;
extern int debug;
extern long pointer_size;
extern char *progname;
extern int child_interrupted;
extern int interrupted;
static int child_pid; /* process id of child */
static int to_child, from_child; /* file descriptors for communication */
static int child_status;
static int restoring;
static int fild1[2], fild2[2]; /* pipe file descriptors */
int disable_intr = 1;
int db_ss;
t_lineno currline, listline;
t_lineno currline;
static int catch_sigpipe();
static int stopped();
static int uputm(), ugetm();
static t_addr curr_stop;
p_tree run_command;
int
init_run()
@ -57,9 +62,13 @@ init_run()
}
to_child = fild1[1];
from_child = fild2[0];
child_pid = 0;
if (currfile) CurrentScope = currfile->sy_file->f_scope;
return 1;
}
extern int errno;
int
start_child(p)
p_tree p;
@ -76,6 +85,10 @@ start_child(p)
allowed one child
*/
if (p != run_command) {
freenode(run_command);
run_command = p;
}
/* first check arguments and redirections and build argument list */
while (pt) {
switch(pt->t_oper) {
@ -133,7 +146,7 @@ start_child(p)
close(0);
if ((fd = open(in_redirect, 0)) < 0 ||
(fd != 0 && dup2(fd, 0) < 0)) {
error("could not open input file");
perror(progname);
exit(1);
}
if (fd != 0) {
@ -142,10 +155,11 @@ start_child(p)
}
if (out_redirect) {
int fd;
close(1);
if ((fd = creat(in_redirect, 0666)) < 0 ||
if ((fd = creat(out_redirect, 0666)) < 0 ||
(fd != 1 && dup2(fd, 1) < 0)) {
error("could not open output file");
perror(progname);
exit(1);
}
if (fd != 1) {
@ -165,32 +179,23 @@ start_child(p)
pipe(fild1); /* to occupy file descriptors */
signal(SIGPIPE, catch_sigpipe);
if (! wait_for_child((char *) 0)) {
error("child not responding");
return 0;
{
struct message_hdr m;
if (! ugetm(&m)) {
error("child not responding");
init_run();
return 0;
}
curr_stop = m.m_size;
CurrentScope = get_scope_from_addr(curr_stop);
}
do_items();
if (! restoring && ! item_addr_actions(curr_stop)) {
if (! restoring && ! item_addr_actions(curr_stop, OK)) {
send_cont(1);
}
else if (! restoring) {
stopped("stopped", curr_stop);
handle_displays();
}
return 1;
}
int
wait_for_child(s)
char *s; /* to pass on to 'stopped' */
{
struct message_hdr m;
if (child_pid) {
if (ugetm(&m)) {
return stopped(s, (t_addr) m.m_size);
}
return 0;
}
return 1;
}
@ -212,7 +217,6 @@ catch_sigpipe()
child_pid = 0;
}
static int
ureceive(p, c)
char *p;
@ -252,6 +256,7 @@ usend(p, c)
{
int i;
if (! child_pid) return 0;
while (c >= 0x1000) {
i = write(to_child, p, 0x1000);
if (i < 0) return 0;
@ -299,11 +304,12 @@ stopped(s, a)
{
p_position pos;
if (s) {
if (s && a) {
fprintf(db_out, "%s ", s);
pos = print_position(a, 1);
fputs("\n", db_out);
list_position(pos);
handle_displays();
}
curr_stop = a;
return 1;
@ -315,16 +321,37 @@ could_send(m, stop_message)
{
int type;
t_addr a;
static int level = 0;
level++;
for (;;) {
if (child_pid) {
if (! uputm(m) ||
! ugetm(&answer)) {
if (child_pid) {
error("something wrong!");
int child_dead = 0;
if (m->m_type & DB_RUN) disable_intr = 0;
if (!child_interrupted && (! uputm(m) || ! ugetm(&answer))) {
child_dead = 1;
}
disable_intr = 1;
if ((interrupted || child_interrupted) && ! child_dead) {
while (child_interrupted && answer.m_type != INTR) {
if (! ugetm(&answer)) {
child_dead = 1;
break;
}
}
if (interrupted && ! child_dead) {
level--;
if (! level) {
child_interrupted = 0;
CurrentScope = get_scope_from_addr((t_addr) answer.m_size);
interrupted = 0;
stopped("interrupted", (t_addr) answer.m_size);
}
return 1;
}
}
if (child_dead) {
wait(&child_status);
init_run();
if (child_status & 0177) {
fprintf(db_out,
"child died with signal %d\n",
@ -335,6 +362,8 @@ could_send(m, stop_message)
"child terminated, exit status %d\n",
child_status >> 8);
}
init_run();
level--;
return 1;
}
a = answer.m_size;
@ -342,7 +371,7 @@ could_send(m, stop_message)
if (m->m_type & DB_RUN) {
/* run command */
CurrentScope = get_scope_from_addr((t_addr) a);
if (! item_addr_actions(a) &&
if (! item_addr_actions(a, type) &&
( type == DB_SS || type == OK)) {
/* no explicit breakpoints at this position.
Also, child did not stop because of
@ -363,38 +392,61 @@ could_send(m, stop_message)
}
if (stop_message) {
stopped("stopped", a);
handle_displays();
}
return 1;
level--;
return type;
}
level--;
return 0;
}
/*NOTREACHED*/
}
static int
getbytes(size, from, to, kind)
long size;
t_addr from;
char *to;
{
struct message_hdr m;
m.m_type = kind;
m.m_size = size;
put_int(m.m_buf, pointer_size, (long)from);
if (! could_send(&m, 0)) {
error("no process");
return 0;
}
if (answer.m_type == FAIL || answer.m_type == INTR) {
return 0;
}
assert(answer.m_type == DATA);
return ureceive(to, answer.m_size);
}
int
get_bytes(size, from, to)
long size;
t_addr from;
char *to;
{
struct message_hdr m;
return getbytes(size, from, to, GETBYTES);
}
m.m_type = GETBYTES;
m.m_size = size;
put_int(m.m_buf, pointer_size, (long)from);
int
get_string(size, from, to)
long size;
t_addr from;
char *to;
{
int retval = getbytes(size, from, to, GETSTR);
if (! could_send(&m, 0)) {
return 0;
}
if (answer.m_type == FAIL) {
return 0;
}
assert(answer.m_type == DATA && answer.m_size == m.m_size);
return ureceive(to, answer.m_size);
to[(int)answer.m_size] = 0;
return retval;
}
int
@ -409,8 +461,7 @@ set_bytes(size, from, to)
m.m_size = size;
put_int(m.m_buf, pointer_size, (long) to);
return uputm(&m)
&& usend(from, size)
return uputm(&m) && usend(from, size)
&& ugetm(&m)
&& m.m_type != FAIL;
}
@ -424,16 +475,16 @@ get_dump(globmessage, globbuf, stackmessage, stackbuf)
m.m_type = DUMP;
if (! could_send(&m, 0)) {
error("no debuggee");
error("no process");
return 0;
}
if (answer.m_type == FAIL) return 0;
if (answer.m_type == FAIL || answer.m_type == INTR) return 0;
assert(answer.m_type == DGLOB);
*globmessage = answer;
*globbuf = malloc((unsigned) answer.m_size);
if (! ureceive(*globbuf, answer.m_size) || ! ugetm(stackmessage)) {
if (*globbuf) free(*globbuf);
error("no debuggee");
error("no process");
return 0;
}
assert(stackmessage->m_type == DSTACK);
@ -441,7 +492,7 @@ get_dump(globmessage, globbuf, stackmessage, stackbuf)
if (! ureceive(*stackbuf, stackmessage->m_size)) {
if (*globbuf) free(*globbuf);
if (*stackbuf) free(*stackbuf);
error("no debuggee");
error("no process");
return 0;
}
put_int(globmessage->m_buf+SP_OFF*pointer_size, pointer_size,
@ -461,17 +512,17 @@ put_dump(globmessage, globbuf, stackmessage, stackbuf)
char *globbuf, *stackbuf;
{
struct message_hdr m;
int retval;
if (! child_pid) {
restoring = 1;
start_child(run_command);
restoring = 0;
}
return uputm(globmessage) &&
usend(globbuf, globmessage->m_size) &&
uputm(stackmessage) &&
usend(stackbuf, stackmessage->m_size) &&
retval = uputm(globmessage) && usend(globbuf, globmessage->m_size) &&
uputm(stackmessage) && usend(stackbuf, stackmessage->m_size) &&
ugetm(&m) && stopped("restored", m.m_size);
return retval;
}
t_addr *
@ -486,9 +537,10 @@ get_EM_regs(level)
m.m_size = level;
if (! could_send(&m, 0)) {
error("no process");
return 0;
}
if (answer.m_type == FAIL) return 0;
if (answer.m_type == FAIL || answer.m_type == INTR) return 0;
*to++ = (t_addr) get_int(answer.m_buf, pointer_size, T_UNSIGNED);
*to++ = (t_addr) get_int(answer.m_buf+pointer_size, pointer_size, T_UNSIGNED);
*to++ = (t_addr) get_int(answer.m_buf+2*pointer_size, pointer_size, T_UNSIGNED);
@ -506,7 +558,7 @@ set_pc(PC)
m.m_type = SETEMREGS;
m.m_size = 0;
put_int(m.m_buf+PC_OFF*pointer_size, pointer_size, (long)PC);
return could_send(&m, 0) && answer.m_type != FAIL;
return could_send(&m, 0) && answer.m_type != FAIL && answer.m_type != INTR;
}
int
@ -530,7 +582,7 @@ do_single_step(type, count)
m.m_type = type | (db_ss ? DB_SS : 0);
m.m_size = count;
single_stepping = 1;
if (could_send(&m, 1) && answer.m_type != FAIL) {
if (could_send(&m, 1) && answer.m_type != FAIL && answer.m_type != INTR) {
return 1;
}
single_stepping = 0;
@ -549,7 +601,8 @@ set_or_clear_breakpoint(a, type)
m.m_type = type;
m.m_size = a;
if (debug) printf("%s breakpoint at 0x%lx\n", type == SETBP ? "setting" : "clearing", (long) a);
if (! could_send(&m, 0)) { }
if (! could_send(&m, 0)) {
}
return 1;
}
@ -565,7 +618,8 @@ set_or_clear_trace(start, end, type)
put_int(m.m_buf, pointer_size, (long)start);
put_int(m.m_buf+pointer_size, pointer_size, (long)end);
if (debug) printf("%s trace at [0x%lx,0x%lx]\n", type == SETTRACE ? "setting" : "clearing", (long) start, (long) end);
if (! could_send(&m, 0)) { }
if (! could_send(&m, 0)) {
}
return 1;
}

View file

@ -117,11 +117,12 @@ add_file(s)
p_symbol sym1;
*p = 0;
sym1 = NewSymbol(Salloc(s, (unsigned) strlen(s)+1),
s = Salloc(s, (unsigned) strlen(s)+1);
*p = c;
sym1 = NewSymbol(s,
PervasiveScope,
FILELINK,
(struct outname *) 0);
*p = c;
sym1->sy_filelink = sym;
sym->sy_file->f_base = sym1;
}
@ -171,11 +172,14 @@ consistent(p, sc)
#define CLASS (FILELINK|FILESYM|PROC|FUNCTION|MODULE|TYPE|VAR|REGVAR|LOCVAR|VARPAR)
sym = Lookfromscope(p->t_idf, CLASS, sc->sc_static_encl);
if (sym) {
int precise = 1;
target_sc = def_scope(sym);
while (sc && sc != target_sc) {
precise = 0;
sc = sc->sc_static_encl;
}
return sc != 0;
return sc == 0 ? 0 : precise + 1 ;
}
return 0;
@ -183,11 +187,16 @@ consistent(p, sc)
arg = p->t_args[1];
sym = Lookfromscope(arg->t_idf, CLASS, sc->sc_static_encl);
if (sym) {
int precise = 1;
target_sc = def_scope(sym);
while (sc && sc != target_sc) {
precise = 0;
sc = sc->sc_static_encl;
}
return sc != 0 && consistent(p, sym->sy_scope);
if (sc == 0) return 0;
if (precise) return consistent(p, sym->sy_scope);
return consistent(p, sym->sy_scope) != 0;
}
return 0;
@ -205,9 +214,10 @@ identify(p, class_set)
p_tree p;
int class_set;
{
p_symbol sym = 0;
p_symbol sym = 0, sym1 = 0;
register p_symbol s;
p_tree arg;
int precise = 0;
switch(p->t_oper) {
case OP_NAME:
@ -243,19 +253,26 @@ identify(p, class_set)
arg = p->t_args[1];
assert(arg->t_oper == OP_NAME);
s = arg->t_idf->id_def;
sym = 0;
while (s) {
if ((s->sy_class & class_set) && consistent(p, s->sy_scope)) {
if (sym) {
error("could not identify \"%s\"", arg->t_str);
sym = 0;
int temp;
if ((s->sy_class & class_set) &&
(temp = consistent(p, s->sy_scope))) {
if (temp > precise) {
sym = s;
precise = temp;
sym1 = 0;
}
sym = s;
else if (sym && temp == precise) sym1 = s;
}
s = s->sy_next;
}
if (sym && sym1) {
error("could not identify \"%s\"", arg->t_str);
return 0;
}
if (!sym && !s) {
error("could not find \"%s\"", arg->t_str);
return 0;
}
break;

View file

@ -27,6 +27,7 @@ struct tokenname tkspec[] = { /* the names of the special tokens */
{NAME, "name"},
{STRING, "string"},
{INTEGER, "number"},
{EXPRESSION, "<expression>"},
{REAL, "real"},
{CHAR, "char"},
{BIN_OP, "<operator>"},
@ -65,6 +66,9 @@ struct tokenname tkidf[] = { /* names of the identifier tokens */
{FIND, "find"},
{DISPLAY, "display"},
{WHICH, "which"},
{HELP, "help"},
{DISABLE,"disable"},
{ENABLE,"enable"},
{-1, "quit"},
{0, ""}
};

View file

@ -19,12 +19,15 @@
#include "expr.h"
extern FILE *db_out;
extern t_lineno currline, listline;
extern t_lineno currline;
static t_lineno listline;
extern long pointer_size;
extern char *strrindex();
extern int interrupted;
p_tree run_command;
p_tree print_command;
static int wsize = 10;
/*VARARGS1*/
p_tree
@ -41,6 +44,7 @@ mknode(va_alist)
p->t_oper = va_arg(ap, int);
switch(p->t_oper) {
case OP_NAME:
case OP_HELP:
p->t_idf = va_arg(ap, struct idf *);
p->t_str = va_arg(ap, char *);
break;
@ -58,7 +62,6 @@ mknode(va_alist)
case OP_NEXT:
case OP_STEP:
case OP_REGS:
case OP_DELETE:
case OP_RESTORE:
case OP_WHERE:
p->t_ival = va_arg(ap, long);
@ -76,21 +79,6 @@ mknode(va_alist)
return p;
}
adjust_oper(pp)
p_tree *pp;
{
register p_tree p = *pp, p1;
switch(p->t_whichoper) {
case E_DERSELECT:
p1 = mknode(OP_UNOP, p->t_args[0]);
p1->t_whichoper = E_DEREF;
p->t_args[0] = p1;
p->t_whichoper = E_SELECT;
break;
}
}
freenode(p)
register p_tree p;
{
@ -164,8 +152,16 @@ print_node(p, top_level)
if (p->t_args[0]) {
print_node(p->t_args[0], 0);
if (p->t_args[1]) {
fputs(", ", db_out);
print_node(p->t_args[1], 0);
if (p->t_args[1]->t_ival >= 0) {
fputs(", ", db_out);
print_node(p->t_args[1], 0);
}
else {
if (p->t_args[1]->t_ival < -100000000) {
fputs("-", db_out);
}
else print_node(p->t_args[1], 0);
}
}
}
break;
@ -173,10 +169,23 @@ print_node(p, top_level)
fputs("print ", db_out);
print_node(p->t_args[0], 0);
break;
case OP_ENABLE:
fputs("enable ", db_out);
print_node(p->t_args[0], 0);
break;
case OP_DISABLE:
fputs("disable ", db_out);
print_node(p->t_args[0], 0);
break;
case OP_DISPLAY:
fputs("display ", db_out);
print_node(p->t_args[0], 0);
break;
case OP_LINK:
print_node(p->t_args[0], 0);
fputs(", ", db_out);
print_node(p->t_args[1], 0);
break;
case OP_FILE:
fputs("file ", db_out);
print_node(p->t_args[0], 0);
@ -196,7 +205,8 @@ print_node(p, top_level)
print_node(p->t_args[0], 0);
break;
case OP_DELETE:
fprintf(db_out, "delete %ld", p->t_ival);
fputs("delete ", db_out);
print_node(p->t_args[0], 0);
break;
case OP_REGS:
fprintf(db_out, "regs %ld", p->t_ival);
@ -221,6 +231,10 @@ print_node(p, top_level)
fputs("where", db_out);
if (p->t_ival != 0x7fffffff) fprintf(db_out, " %ld", p->t_ival);
break;
case OP_HELP:
fputs("help", db_out);
if (p->t_str != 0) fprintf(db_out, " %s", p->t_str);
break;
case OP_CONT:
fputs("cont", db_out);
if (p->t_args[0]) {
@ -303,6 +317,11 @@ print_node(p, top_level)
case OP_REAL:
fprintf(db_out, currlang->real_fmt, p->t_fval);
break;
case OP_FORMAT:
print_node(p->t_args[0], 0);
fputs("\\", db_out);
print_node(p->t_args[1], 0);
break;
case OP_UNOP:
case OP_BINOP:
(*currlang->printop)(p);
@ -317,11 +336,19 @@ repeatable(com)
{
switch(com->t_oper) {
case OP_CONT:
com->t_args[0]->t_ival = 1;
freenode(com->t_args[1]);
com->t_args[1] = 0;
return 1;
case OP_NEXT:
case OP_STEP:
com->t_ival = 1;
return 1;
case OP_LIST:
case OP_STATUS:
case OP_PRINT:
freenode(com->t_args[0]);
com->t_args[0] = 0;
freenode(com->t_args[1]);
com->t_args[1] = 0;
return 1;
}
return 0;
@ -345,7 +372,7 @@ in_status(com)
eval(p)
p_tree p;
{
if (p) (*operators[p->t_oper].op_fun)(p);
if (p && operators[p->t_oper].op_fun) (*operators[p->t_oper].op_fun)(p);
}
do_list(p)
@ -353,15 +380,25 @@ do_list(p)
{
int l1, l2;
if (p->t_args[1]) {
l2 = p->t_args[1]->t_ival;
if (l2 >= 0) {
if (l2 == 0) l2 = 1;
wsize = l2;
}
}
else l2 = wsize;
if (! p->t_args[0]) {
l1 = listline;
l2 = listline + 9;
if (! l1) {
listline = currline - (wsize/2);
l1 = listline;
}
}
else {
if (p->t_args[0]->t_oper == OP_INTEGER) {
l1 = p->t_args[0]->t_ival;
assert(p->t_args[1] != 0);
l2 = p->t_args[1]->t_ival;
}
else {
t_addr a = get_addr_from_node(p->t_args[0]);
@ -372,16 +409,20 @@ do_list(p)
}
pos = get_position_from_addr(a);
newfile(str2idf(pos->filename, 1));
l1 = pos->lineno - 5;
l1 = pos->lineno - (l2 > 0 ? l2 : wsize)/2;
if (l1 < 1) l1 = 1;
l2 = l1+9;
}
}
if (listfile) {
if (l2 < 0) {
l2 = -l2;
if (l1 > l2) l2 = 1;
else l2 -= l1 - 1;
}
lines(listfile->sy_file, l1, l2);
listline = l2+1;
listline = l1 + l2;
}
else fprintf(db_out, "no current file\n");
else error("no current file");
}
do_file(p)
@ -391,7 +432,7 @@ do_file(p)
newfile(p->t_args[0]->t_idf);
}
else if (listfile) fprintf(db_out, "%s\n", listfile->sy_idf->id_text);
else fprintf(db_out, "no current file\n");
else error("no current file");
}
newfile(id)
@ -409,55 +450,102 @@ newfile(id)
find_language(strrindex(id->id_text, '.'));
}
do_stop(p)
setstop(p, kind)
p_tree p;
int kind;
{
t_addr a = get_addr_from_node(p->t_args[0]);
if (a == ILL_ADDR) {
return;
}
if (a == ILL_ADDR) return 0;
p->t_address = a;
add_to_item_list(p);
if (a != NO_ADDR) {
if (! set_or_clear_breakpoint(a, SETBP)) {
error("could not set breakpoint");
if (! set_or_clear_breakpoint(a, kind)) {
error("could not %s breakpoint", kind == SETBP ? "set" : "clear");
return 0;
}
}
return 1;
}
do_stop(p)
p_tree p;
{
if (! setstop(p, SETBP)) {
return;
}
add_to_item_list(p);
}
settrace(p, kind)
p_tree p;
int kind;
{
t_addr a, e;
a = get_addr_from_node(p->t_args[0]);
if (a == NO_ADDR) return 1;
if (a == ILL_ADDR) return 0;
if (p->t_args[0]->t_oper == OP_AT) {
e = a;
p->t_address = a;
}
else {
p_scope sc = get_next_scope_from_addr(a+1);
if (sc) e = sc->sc_start - 1;
else e = 0xffffffff;
}
if (! set_or_clear_trace(a, e, kind)) {
error("could not %s trace", kind == SETTRACE ? "set" : "clear");
return 0;
}
return 1;
}
do_trace(p)
p_tree p;
{
t_addr a;
t_addr e;
p->t_address = NO_ADDR;
if (p->t_args[0]) {
a = get_addr_from_node(p->t_args[0]);
if (a == ILL_ADDR) return;
if (p->t_args[0]->t_oper == OP_AT) {
e = a;
p->t_address = a;
}
else {
p_scope sc = get_next_scope_from_addr(a+1);
if (sc) e = sc->sc_start - 1;
else e = 0xffffffff;
}
if (! set_or_clear_trace(a, e, SETTRACE)) {
error("could not set trace");
}
if (! settrace(p, SETTRACE)) {
return;
}
add_to_item_list(p);
}
static
able(p, kind)
p_tree p;
int kind;
{
switch(p->t_oper) {
case OP_LINK:
able(p->t_args[0], kind);
able(p->t_args[1], kind);
break;
case OP_INTEGER:
able_item((int)p->t_ival, kind);
break;
}
}
do_enable(p)
p_tree p;
{
able(p->t_args[0], 0);
}
do_disable(p)
p_tree p;
{
able(p->t_args[0], 1);
}
do_continue(p)
p_tree p;
{
int count;
int first_time = 1;
if (p) {
count = p->t_args[0]->t_ival;
@ -476,9 +564,10 @@ do_continue(p)
else count = 1;
while (count--) {
if (! send_cont(count==0)) {
error("no debuggee");
if (first_time) error("no process");
break;
}
first_time = 0;
}
}
@ -486,7 +575,7 @@ do_step(p)
p_tree p;
{
if (! do_single_step(SETSS, p->t_ival)) {
error("no debuggee");
if (! interrupted) error("no process");
}
}
@ -495,7 +584,7 @@ do_next(p)
{
if (! do_single_step(SETSSF, p->t_ival)) {
error("no debuggee");
if (! interrupted) error("no process");
}
}
@ -508,7 +597,7 @@ do_regs(p)
int n = p->t_ival;
if (! (buf = get_EM_regs(n))) {
error("no debuggee");
if (! interrupted) error("no process");
return;
}
fprintf(db_out, "EM registers %d levels back:\n", n);
@ -526,17 +615,30 @@ do_where(p)
{
int i = 0;
unsigned int cnt;
unsigned int maxcnt = p->t_ival;
p_scope sc;
t_addr *buf;
t_addr PC;
for (cnt = p->t_ival; cnt != 0; cnt--) {
t_addr AB;
t_addr PC;
p_scope sc;
t_addr *buf;
if (! (buf = get_EM_regs(i++))) {
error("no debuggee");
return;
if (p->t_ival < 0) {
for (;;) {
buf = get_EM_regs(i++);
if (! buf || ! buf[AB_OFF]) break;
PC = buf[PC_OFF];
sc = base_scope(get_scope_from_addr(PC));
if (! sc || sc->sc_start > PC) break;
if (interrupted) return;
}
i--;
maxcnt = - p->t_ival;
i -= maxcnt;
if (i < 0) i = 0;
}
for (cnt = maxcnt; cnt != 0; cnt--) {
t_addr AB;
if (interrupted) return;
if (! (buf = get_EM_regs(i++))) break;
AB = buf[AB_OFF];
PC = buf[PC_OFF];
if (! AB) break;
@ -550,63 +652,60 @@ do_where(p)
}
}
/*ARGSUSED*/
do_status(p)
p_tree p;
{
print_items();
}
extern p_tree remove_from_item_list();
do_delete(p)
p_tree p;
{
p = remove_from_item_list((int) p->t_ival);
if (p) switch(p->t_oper) {
case OP_WHEN:
case OP_STOP: {
t_addr a = get_addr_from_node(p->t_args[0]);
if (a != ILL_ADDR && a != NO_ADDR) {
set_or_clear_breakpoint(a, CLRBP);
}
switch(p->t_oper) {
case OP_DELETE:
do_delete(p->t_args[0]);
break;
}
case OP_TRACE: {
t_addr a = get_addr_from_node(p->t_args[0]);
if (a != ILL_ADDR && a != NO_ADDR) {
t_addr e;
if (p->t_args[0]->t_oper == OP_AT) {
e = a;
}
else {
p_scope sc = get_next_scope_from_addr(a+1);
if (sc) e = sc->sc_start - 1;
else e = 0xffffffff;
}
set_or_clear_trace(a, e, CLRTRACE);
}
case OP_LINK:
do_delete(p->t_args[0]);
do_delete(p->t_args[1]);
break;
case OP_INTEGER:
p = remove_from_item_list((int) p->t_ival);
if (p) switch(p->t_oper) {
case OP_WHEN:
case OP_STOP:
setstop(p, CLRBP);
break;
case OP_TRACE:
settrace(p, CLRTRACE);
break;
case OP_DUMP:
free_dump(p);
}
freenode(p);
break;
}
case OP_DUMP:
free_dump(p);
}
freenode(p);
}
do_print(p)
p_tree p;
{
char *buf;
char *buf = 0;
char *format = 0;
long size;
p_type tp;
switch(p->t_oper) {
case OP_PRINT:
if (p->t_args[0] == 0) {
p = print_command;
if (p == 0) {
error("no previous print command");
break;
}
}
else if (p != print_command) {
freenode(print_command);
print_command = p;
}
/* fall through */
case OP_DISPLAY:
do_print(p->t_args[0]);
break;
@ -615,10 +714,13 @@ do_print(p)
do_print(p->t_args[1]);
break;
default:
if (! eval_expr(p, &buf, &size, &tp)) return;
if (interrupted || ! eval_expr(p, &buf, &size, &tp)) return;
print_node(p, 0);
fputs(" = ", db_out);
print_val(tp, size, buf, 0, 0);
if (p->t_oper == OP_FORMAT) {
format = p->t_args[1]->t_str;
}
print_val(tp, size, buf, 0, 0, format);
if (buf) free(buf);
fputs("\n", db_out);
break;
@ -633,13 +735,17 @@ do_set(p)
p_type tp, tp2;
t_addr a;
if (! eval_desig(p->t_args[0], &a, &size, &tp) ||
if (interrupted || ! eval_desig(p->t_args[0], &a, &size, &tp) ||
! eval_expr(p->t_args[1], &buf, &size2, &tp2) ||
! convert(&buf, &size2, &tp2, tp, size)) {
if (buf) free(buf);
return;
}
if (interrupted) {
free(buf);
return;
}
if (! set_bytes(size, buf, a)) {
error("could not handle this SET request");
}
@ -652,11 +758,14 @@ perform(p, a)
{
switch(p->t_oper) {
case OP_WHEN:
if (p->t_args[1] && ! eval_cond(p->t_args[1])) break;
p = p->t_args[2];
while (p->t_oper == OP_LINK) {
if (interrupted) return;
eval(p->t_args[0]);
p = p->t_args[1];
}
if (interrupted) return;
eval(p);
break;
case OP_TRACE:
@ -667,6 +776,8 @@ perform(p, a)
break;
}
}
if (interrupted) return;
if (p->t_args[1] && ! eval_cond(p->t_args[1])) break;
list_position(get_position_from_addr(a));
if (p->t_args[2]) do_print(p->t_args[2]);
break;
@ -681,6 +792,6 @@ list_position(pos)
newfile(str2idf(pos->filename, 1));
currfile = listfile;
currline = pos->lineno;
listline = currline-5;
lines(currfile->sy_file, (int)currline, (int)currline);
lines(currfile->sy_file, (int)currline, (int)1);
listline = 0;
}

View file

@ -6,7 +6,6 @@ typedef struct tree {
short t_oper; /* tree operator */
short t_whichoper; /* expression operator */
t_addr t_address; /* some operators use an address */
int t_itemno; /* item number in status list */
union {
long tt_ival;
char *tt_sval;
@ -34,4 +33,3 @@ typedef struct tree {
/* ALLOCDEF "tree" 100 */
extern p_tree mknode();
extern p_tree run_command;

View file

@ -17,7 +17,7 @@ p_type int_type, char_type, short_type, long_type, bool_type;
p_type uint_type, uchar_type, ushort_type, ulong_type;
p_type void_type, incomplete_type;
p_type float_type, double_type;
p_type string_type;
p_type string_type, address_type;
long int_size = SZ_INT,
char_size = 1,
@ -255,6 +255,7 @@ init_types()
ushort_type = basic_type(T_UNSIGNED, short_size);
uchar_type = basic_type(T_UNSIGNED, char_size);
string_type = basic_type(T_STRING, 0L);
address_type = basic_type(T_POINTER, pointer_size);
void_type = basic_type(T_VOID, 0L);
incomplete_type = basic_type(T_INCOMPLETE, 0L);
float_type = basic_type(T_REAL, float_size);

View file

@ -38,9 +38,8 @@ typedef struct type {
#define T_VOID 12
#define T_UNSIGNED 13
#define T_STRING 14 /* only for string constants ... */
#define T_CROSS 15 /* cross reference to type */
#define T_INCOMPLETE 100
short ty_flags;
#define T_CROSS 0x0001
long ty_size;
struct symbol *ty_sym;
union {
@ -117,7 +116,7 @@ extern long
compute_size();
extern p_type char_type, uchar_type, bool_type, int_type,
long_type, double_type, string_type;
long_type, double_type, string_type, address_type;
extern p_type void_type, incomplete_type;
extern long int_size, pointer_size, long_size, double_size;