From 3672f835fef3fc985bb7e59948266fcf042c7427 Mon Sep 17 00:00:00 2001 From: ceriel Date: Thu, 11 Oct 1990 08:42:07 +0000 Subject: [PATCH] Too many changes and fixes to mention them all here --- util/grind/Amakefile | 3 +- util/grind/c.c | 91 +++++++++-- util/grind/char.ct | 4 +- util/grind/commands.g | 254 +++++++++++++++++++----------- util/grind/dbx_string.g | 27 +++- util/grind/dbxread.c | 4 +- util/grind/expr.c | 94 +++++++++-- util/grind/grind.1 | 27 ++-- util/grind/itemlist.cc | 82 +++++++--- util/grind/list.c | 11 +- util/grind/main.c | 29 ++-- util/grind/message.h | 1 + util/grind/modula-2.c | 14 +- util/grind/operators.ot | 8 +- util/grind/position.c | 8 +- util/grind/print.c | 133 ++++++++++++---- util/grind/run.c | 162 ++++++++++++------- util/grind/symbol.c | 39 +++-- util/grind/tokenname.c | 4 + util/grind/tree.c | 339 ++++++++++++++++++++++++++-------------- util/grind/tree.hh | 2 - util/grind/type.c | 3 +- util/grind/type.hh | 5 +- 23 files changed, 930 insertions(+), 414 deletions(-) diff --git a/util/grind/Amakefile b/util/grind/Amakefile index f1e5df0bf..bd1efc4b5 100644 --- a/util/grind/Amakefile +++ b/util/grind/Amakefile @@ -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 = { diff --git a/util/grind/c.c b/util/grind/c.c index 894eecd9d..88f57dbf0 100644 --- a/util/grind/c.c +++ b/util/grind/c.c @@ -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; diff --git a/util/grind/char.ct b/util/grind/char.ct index 9682c3349..e5363cf63 100644 --- a/util/grind/char.ct +++ b/util/grind/char.ct @@ -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 diff --git a/util/grind/commands.g b/util/grind/commands.g index 628ed0dbc..771b2e34f 100644 --- a/util/grind/commands.g +++ b/util/grind/commands.g @@ -4,7 +4,6 @@ { #include #include -#include #include #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"); -} } diff --git a/util/grind/dbx_string.g b/util/grind/dbx_string.g index ccbee0a8f..26c3ac617 100644 --- a/util/grind/dbx_string.g +++ b/util/grind/dbx_string.g @@ -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); } diff --git a/util/grind/dbxread.c b/util/grind/dbxread.c index 17bc7f277..82d8478c6 100644 --- a/util/grind/dbxread.c +++ b/util/grind/dbxread.c @@ -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 */ diff --git a/util/grind/expr.c b/util/grind/expr.c index 59c3c5a9c..b2d4f96fc 100644 --- a/util/grind/expr.c +++ b/util/grind/expr.c @@ -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) { diff --git a/util/grind/grind.1 b/util/grind/grind.1 index c670db158..5c0164518 100644 --- a/util/grind/grind.1 +++ b/util/grind/grind.1 @@ -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 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 diff --git a/util/grind/itemlist.cc b/util/grind/itemlist.cc index 873e545de..adef72fc8 100644 --- a/util/grind/itemlist.cc +++ b/util/grind/itemlist.cc @@ -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,26 +154,54 @@ 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; } -print_items() +able_item(n, kind) + int n; { register p_item i = item_list.il_first; + register p_tree p; - for (; i; i = i->i_next) { - pr_item(i->i_node); + 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; } } -pr_item(p) - p_tree p; +print_items() { - fprintf(db_out, "(%d)\t", p->t_itemno); - print_node(p, 1); + register p_item i = item_list.il_first; + + for (; i; i = i->i_next) { + pr_item(i); + } } do_items() @@ -171,6 +209,6 @@ 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); } } diff --git a/util/grind/list.c b/util/grind/list.c index 66a1cbe91..4406b0f9c 100644 --- a/util/grind/list.c +++ b/util/grind/list.c @@ -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); diff --git a/util/grind/main.c b/util/grind/main.c index 3840e3c22..0b5ed3a95 100644 --- a/util/grind/main.c +++ b/util/grind/main.c @@ -9,7 +9,7 @@ #include "Lpars.h" static char *usage = "Usage: %s [] []"; -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); } diff --git a/util/grind/message.h b/util/grind/message.h index 3abdf811a..719c899b7 100644 --- a/util/grind/message.h +++ b/util/grind/message.h @@ -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 */ }; diff --git a/util/grind/modula-2.c b/util/grind/modula-2.c index e614c61f2..219c6d603 100644 --- a/util/grind/modula-2.c +++ b/util/grind/modula-2.c @@ -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; diff --git a/util/grind/operators.ot b/util/grind/operators.ot index f190fac38..d1030a1ed 100644 --- a/util/grind/operators.ot +++ b/util/grind/operators.ot @@ -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 diff --git a/util/grind/position.c b/util/grind/position.c index 916a46d6b..a8882bbdc 100644 --- a/util/grind/position.c +++ b/util/grind/position.c @@ -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); diff --git a/util/grind/print.c b/util/grind/print.c index ecc95419f..66895766f 100644 --- a/util/grind/print.c +++ b/util/grind/print.c @@ -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, "", 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, ""); 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); diff --git a/util/grind/run.c b/util/grind/run.c index 060d44a86..88c0d6797 100644 --- a/util/grind/run.c +++ b/util/grind/run.c @@ -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,40 +392,63 @@ could_send(m, stop_message) } if (stop_message) { stopped("stopped", a); - handle_displays(); } - return 1; + level--; + return type; } + level--; return 0; } /*NOTREACHED*/ } -int -get_bytes(size, from, to) +static int +getbytes(size, from, to, kind) long size; t_addr from; char *to; { struct message_hdr m; - m.m_type = GETBYTES; + 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) { + if (answer.m_type == FAIL || answer.m_type == INTR) { return 0; } - assert(answer.m_type == DATA && answer.m_size == m.m_size); + assert(answer.m_type == DATA); return ureceive(to, answer.m_size); } +int +get_bytes(size, from, to) + long size; + t_addr from; + char *to; +{ + return getbytes(size, from, to, GETBYTES); +} + +int +get_string(size, from, to) + long size; + t_addr from; + char *to; +{ + int retval = getbytes(size, from, to, GETSTR); + + to[(int)answer.m_size] = 0; + return retval; +} + int set_bytes(size, from, to) long size; @@ -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; } diff --git a/util/grind/symbol.c b/util/grind/symbol.c index 2592e7c3c..ab98f33b2 100644 --- a/util/grind/symbol.c +++ b/util/grind/symbol.c @@ -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; diff --git a/util/grind/tokenname.c b/util/grind/tokenname.c index 7634093c0..e3d70998c 100644 --- a/util/grind/tokenname.c +++ b/util/grind/tokenname.c @@ -27,6 +27,7 @@ struct tokenname tkspec[] = { /* the names of the special tokens */ {NAME, "name"}, {STRING, "string"}, {INTEGER, "number"}, + {EXPRESSION, ""}, {REAL, "real"}, {CHAR, "char"}, {BIN_OP, ""}, @@ -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, ""} }; diff --git a/util/grind/tree.c b/util/grind/tree.c index af76c08b6..c4be88bf9 100644 --- a/util/grind/tree.c +++ b/util/grind/tree.c @@ -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_trace(p) +do_stop(p) p_tree p; { - t_addr a; - t_addr e; + if (! setstop(p, SETBP)) { + return; + } + add_to_item_list(p); +} - 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); +settrace(p, kind) + p_tree p; + int kind; +{ + t_addr a, e; - if (sc) e = sc->sc_start - 1; - else e = 0xffffffff; - } - if (! set_or_clear_trace(a, e, SETTRACE)) { - error("could not set trace"); - } + 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; +{ + p->t_address = NO_ADDR; + 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; - - for (cnt = p->t_ival; cnt != 0; cnt--) { + unsigned int maxcnt = p->t_ival; + p_scope sc; + t_addr *buf; + t_addr PC; + + 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; - t_addr PC; - p_scope sc; - t_addr *buf; - if (! (buf = get_EM_regs(i++))) { - error("no debuggee"); - return; - } + 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); + 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 (sc) e = sc->sc_start - 1; - else e = 0xffffffff; - } - set_or_clear_trace(a, e, CLRTRACE); - } + 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; } diff --git a/util/grind/tree.hh b/util/grind/tree.hh index ae06adf93..cb715c56a 100644 --- a/util/grind/tree.hh +++ b/util/grind/tree.hh @@ -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; diff --git a/util/grind/type.c b/util/grind/type.c index fb75682cd..f9d35bbb7 100644 --- a/util/grind/type.c +++ b/util/grind/type.c @@ -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); diff --git a/util/grind/type.hh b/util/grind/type.hh index 281761dc9..185903331 100644 --- a/util/grind/type.hh +++ b/util/grind/type.hh @@ -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; -- 2.34.1