run.c,
symbol.c,
print.c,
- value.c,
type.c,
rd.c,
do_comm.c,
%cluster {
%targets lint.out[type = lint-output];
- %sources $CMD_LLSRC + $CSRC + $DBS_LLTARGETS + $HHSRC + char.ct + operators.ot ;
+ %sources $CSRC + $CMD_LLSRC + $DBS_LLTARGETS + $HHSRC + char.ct + operators.ot ;
%use lint(realdest => lint.out) ;
} ;
struct avl_tree *tree; /* tree to be added to */
char *n; /* information */
{
- balance_add(&(tree->root), n, tree->cmp);
+ (void) balance_add(&(tree->root), n, tree->cmp);
}
/* extern char *find_ngt(struct avl_tree *tree, char *n);
print_string(),
print_char(),
get_number(),
- get_string(),
+ getstring(),
get_token(),
print_op(),
unop_prio(),
static long
array_elsize();
-static struct langdep c = {
+static struct langdep c_lang = {
0,
"%ld",
array_elsize,
binop_prio,
unop_prio,
- get_string,
+ getstring,
get_name,
get_number,
get_token,
fix_bin_to_pref
};
-struct langdep *c_dep = &c;
+struct langdep *c_dep = &c_lang;
-static int
+static void
printchar(f, c, esc)
FILE *f;
int c;
}
}
-static int
+static
print_char(c)
int c;
{
putc('\'', db_out);
}
-static int
+static
print_string(f, s, len)
FILE *f;
char *s;
}
static int
-get_string(c)
+getstring(c)
int c;
{
register int ch;
return STRING;
}
-static int
+static
print_op(f, p)
FILE *f;
p_tree p;
}
}
-static int
+static
fix_bin_to_pref(p)
p_tree p;
{
extern char *Salloc();
extern char *strindex();
extern char *strcpy();
+extern void signal_child();
extern FILE *db_in;
extern int disable_intr;
extern p_tree run_command, print_command;
+struct token tok, aside;
int errorgiven = 0;
int child_interrupted = 0;
int interrupted = 0;
int eof_seen = 0;
+
+static int shellescape();
+
static int extended_charset = 0;
static int in_expression = 0;
-struct token tok, aside;
-
#define binprio(op) ((*(currlang->binop_prio))(op))
#define unprio(op) ((*(currlang->unop_prio))(op))
}
com = 0;
}
else {
- log(com);
+ enterlog(com);
eval(com);
if (repeatable(com)) {
lastcom = com;
}
}
} else if (lastcom && ! errorgiven) {
- log(lastcom);
+ enterlog(lastcom);
eval(lastcom);
}
if (give_prompt) {
| where_command(p)
| STATUS { *p = mknode(OP_STATUS); }
| DUMP { *p = mknode(OP_DUMP); }
-| RESTORE count(p)? { *p = mknode(OP_RESTORE, *p); }
+| RESTORE opt_num(p) { *p = mknode(OP_RESTORE, *p); }
| delete_command(p)
| print_command(p)
| display_command(p)
| FIND qualified_name(p){ *p = mknode(OP_FIND, *p); }
| WHICH qualified_name(p){ *p = mknode(OP_WHICH, *p); }
| able_command(p)
-| '!' { shellescape();
+| '!' { (void) shellescape();
*p = mknode(OP_SHELL);
}
| source_command(p)
{ p_tree whr = 0, cond = 0, exp = 0; }
:
TRACE
- [ ON expression(&exp, 0) ]?
+ [ ON format_expression(&exp) ]?
where(&whr)?
condition(&cond)? { *p = mknode(OP_TRACE, whr, cond, exp); }
;
delete_command(p_tree *p;)
:
- DELETE count_list(p)? { *p = mknode(OP_DELETE, *p); }
+ DELETE num_list(p)? { *p = mknode(OP_DELETE, *p); }
;
print_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])?
+ num_list(&(*p)->t_args[0])?
;
-count_list(p_tree *p;)
+num_list(p_tree *p;)
:
- count(p)
+ num(p)
[ ',' { *p = mknode(OP_LINK, *p, (p_tree) 0); }
- count(&(*p)->t_args[1])
+ num(&(*p)->t_args[1])
]*
;
;
opt_num(p_tree *p;)
+:
+ num(p)
+|
+ { *p = 0; }
+;
+
+num(p_tree *p;)
:
count(p)
|
'-' count(p) { (*p)->t_ival = - (*p)->t_ival; }
-|
- { *p = 0; }
;
qualified_name(p_tree *p;)
return id->id_reserved ? id->id_reserved : NAME;
}
-extern char * symbol2str();
+extern char *symbol2str();
LLmessage(t)
{
errorgiven = 1;
}
-static int
+static void
catch_del()
{
signal(SIGINT, catch_del);
interrupted = 1;
}
-int
+void
init_del()
{
signal(SIGINT, catch_del);
}
-static int
+static void
ctch()
{
/* Only for shell escapes ... */
#define SHBUFSIZ 512
-int
+static int
shellescape()
{
register char *p; /* walks through command */
extern long str2long();
extern double atof();
-extern long pointer_size;
-
-static char *DbPtr; /* current pointer in DBX string */
+static char *DbPtr; /* current pointer in db string */
static int AllowName; /* set if NAME legal at this point */
static long ival;
static double fval;
static struct outname *EndAckNames; /* &AckNames[NAckNames] */
/* Read the symbol table from file 'f', which is supposed to be an
- ACK a.out format file. Offer DBX strings to the DBX string parser.
+ ACK a.out format file. Offer db strings to the db string parser.
*/
int
DbRead(f)
else n->on_mptr = 0;
}
- /* Offer strings to the DBX string parser if they contain a ':'.
+ /* Offer strings to the db string parser if they contain a ':'.
Also offer filename-line number information to add_position_addr().
Here, the order may be important.
*/
#include "symbol.h"
#include "scope.h"
#include "file.h"
-#include "message.h"
extern FILE *db_out;
extern t_lineno listline, currline;
-extern int stop_reason;
extern int interrupted;
+extern int stack_offset;
p_tree print_command;
+extern void set_bytes();
+
/*ARGSUSED*/
do_noop(p)
p_tree p;
struct dump {
char *globals, *stack;
- struct message_hdr mglobal, mstack;
struct dump *next;
};
error("could not allocate enough memory");
return;
}
- p->t_address = get_dump(&d->mglobal, &d->globals, &d->mstack, &d->stack);
+ p->t_address = get_dump(&d->globals, &d->stack);
if (! p->t_address) {
free((char *) d);
return;
return;
}
- if (! put_dump(&d->mglobal, d->globals, &d->mstack, d->stack)) {
+ if (! put_dump(d->globals, d->stack)) {
+ error("restoring failed");
}
perform_items();
}
do_stop(p)
p_tree p;
{
- if (! setstop(p, M_SETBP)) {
+ if (! setstop(p, 1)) {
return;
}
add_to_item_list(p);
p_tree p;
{
p->t_address = NO_ADDR;
- if (! settrace(p, M_SETTRACE)) {
+ if (! settrace(p, 1)) {
return;
}
add_to_item_list(p);
int kind;
{
if (!p) {
- if (stop_reason) {
- able_item(stop_reason, kind);
- }
- else {
- error("no current stopping point");
- }
+ able_item(0, kind);
return;
}
switch(p->t_oper) {
}
}
if (count > 0) {
- fprintf(db_out, "Only %d breakpoints skipped\n",
+ fprintf(db_out, "Only %ld breakpoints skipped\n",
p->t_args[0]->t_ival - count);
}
}
p_tree p;
{
p = p->t_args[0];
- if (! singlestep(M_SETSS, p ? p->t_ival : 1L)) {
+ if (! singlestep(0, p ? p->t_ival : 1L)) {
}
}
p_tree p;
{
p = p->t_args[0];
- if (! singlestep(M_SETSSF, p? p->t_ival : 1L)) {
+ if (! singlestep(1, p? p->t_ival : 1L)) {
}
}
fprintf(db_out, "%s(", sc->sc_definedby->sy_idf->id_text);
print_params(sc->sc_definedby->sy_type, AB, has_static_link(sc));
fputs(") ", db_out);
- print_position(where_PC, 0);
+ (void) print_position(where_PC, 0);
fputs("\n", db_out);
return 1;
}
/* implementation of the delete command */
-extern p_tree remove_from_item_list();
-
do_delete(p)
p_tree p;
{
switch(p->t_oper) {
case OP_DELETE:
if (! p->t_args[0]) {
- if (stop_reason) {
- remove_from_item_list(stop_reason);
- stop_reason = 0;
- }
- else {
- error("no current stopping point");
- }
+ remove_from_item_list(0);
}
else do_delete(p->t_args[0]);
break;
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, M_CLRBP);
- break;
- case OP_TRACE:
- settrace(p, M_CLRTRACE);
- break;
- case OP_DUMP:
- free_dump(p);
- }
- freenode(p);
+ remove_from_item_list((int) p->t_ival);
break;
default:
assert(0);
extern int item_count;
extern int in_wheninvoked;
-log(p)
+enterlog(p)
p_tree p;
{
register p_tree p1;
case OP_DELETE:
case OP_ENABLE:
case OP_DISABLE:
+ case OP_RESTORE:
/* Change absolute item numbers into relative ones
for safer replay
*/
p1 = p->t_args[0];
while (p1 && p1->t_oper == OP_LINK) {
register p_tree p2 = p1->t_args[0];
- if (p2->t_ival > 0) {
- p2->t_ival = item_count - p2->t_ival;
+ if (p2->t_ival > 0 && p2->t_ival <= item_count) {
+ p2->t_ival = p2->t_ival - item_count - 1;
}
p1 = p1->t_args[1];
}
- if (p1 && p1->t_ival > 0) {
- p1->t_ival = item_count - p1->t_ival;
+ if (p1 && p1->t_ival > 0 && p1->t_ival <= item_count) {
+ p1->t_ival = p1->t_ival - item_count - 1;
}
/* Fall through */
default:
and returns 1 if it evaluates to TRUE, or 0 if it could not be
evaluated for some reason or if it evalutes to FALSE.
If the expression cannot be evaluated, an error message is given.
- - int eval_desig(p_tree p, t_addr *pbuf, long **psize, p_type *ptp)
+ - int eval_desig(p_tree p, t_addr *paddr, long **psize, p_type *ptp)
This routine evaluates the expression indicated by p, which should
result in a designator. The result of the expression is an address
- which is to be found in *pbuf. *psize will contain the size of the
+ which is to be found in *paddr. *psize will contain the size of the
designated object, and *ptp its type.
If the expression cannot be evaluated or does not result in a
designator, 0 is returned and an error message is given.
#include "symbol.h"
#include "type.h"
#include "langdep.h"
+#include "scope.h"
+#include "idf.h"
extern FILE *db_out;
+extern int stack_offset;
extern char *strcpy();
+extern t_addr *get_EM_regs();
+extern char *memcpy();
#define malloc_succeeded(p) if (! (p)) {\
error("could not allocate enough memory");\
return 0;\
}
+/* static t_addr get_addr(p_symbol sym; long *psize);
+ Get the address of the object indicated by sym. Returns 0 on failure,
+ address on success. *psize will contain size of object.
+ For local variables or parameters, the 'stack_offset' variable is
+ used to determine from which stack frame the search must start.
+*/
+static t_addr
+get_addr(sym, psize)
+ register p_symbol sym;
+ long *psize;
+{
+ p_type tp = sym->sy_type;
+ long size = tp->ty_size;
+ t_addr *EM_regs;
+ int i;
+ p_scope sc, symsc;
+
+ *psize = size;
+ switch(sym->sy_class) {
+ case VAR:
+ /* exists if child exists; nm_value contains addres */
+ return (t_addr) sym->sy_name.nm_value;
+ case VARPAR:
+ case LOCVAR:
+ /* first find the stack frame in which it resides */
+ symsc = base_scope(sym->sy_scope);
+
+ /* now symsc contains the scope where the storage for sym is
+ allocated. Now find it on the stack of child.
+ */
+ i = stack_offset;
+ for (;;) {
+ sc = 0;
+ if (! (EM_regs = get_EM_regs(i++))) {
+ return 0;
+ }
+ if (! EM_regs[1]) {
+ error("%s not available", sym->sy_idf->id_text);
+ return 0;
+ }
+ sc = base_scope(get_scope_from_addr(EM_regs[2]));
+ if (! sc || sc->sc_start > EM_regs[2]) {
+ error("%s not available", sym->sy_idf->id_text);
+ sc = 0;
+ return 0;
+ }
+ if (sc == symsc) break; /* found it */
+ }
+
+ if (sym->sy_class == LOCVAR) {
+ /* Either local variable or value parameter */
+ return EM_regs[sym->sy_name.nm_value < 0 ? 0 : 1] +
+ (t_addr) sym->sy_name.nm_value;
+ }
+
+ /* If we get here, we have a var parameter. Get the parameters
+ of the current procedure invocation.
+ */
+ {
+ p_type proctype = sc->sc_definedby->sy_type;
+ t_addr a;
+ char *AB;
+
+ size = proctype->ty_nbparams;
+ if (has_static_link(sc)) size += pointer_size;
+ AB = malloc((unsigned) size);
+ if (! AB) {
+ error("could not allocate enough memory");
+ break;
+ }
+ if (! get_bytes(size, EM_regs[1], AB)) {
+ break;
+ }
+ if ((size = tp->ty_size) == 0) {
+ size = compute_size(tp, AB);
+ *psize = size;
+ }
+ a = (t_addr) get_int(AB+sym->sy_name.nm_value, pointer_size, T_UNSIGNED);
+ free(AB);
+ return a;
+ }
+ default:
+ error("%s is not a variable", sym->sy_idf->id_text);
+ break;
+ }
+ return 0;
+}
+
+/* static int get_value(p_symbol sym; char **pbuf; long *psize);
+ Get the value of the symbol indicated by sym. Return 0 on failure,
+ 1 on success. On success, 'pbuf' contains the value, and 'psize' contains
+ the size. For 'pbuf', storage is allocated by malloc; this storage must
+ be freed by caller (I don't like this any more than you do, but caller
+ does not know sizes).
+ For local variables or parameters, the 'stack_offset' variable is
+ used to determine from which stack frame the search must start.
+*/
+static int
+get_value(sym, pbuf, psize)
+ register p_symbol sym;
+ char **pbuf;
+ long *psize;
+{
+ p_type tp = sym->sy_type;
+ int retval = 0;
+ t_addr a;
+ long size = tp->ty_size;
+
+ *pbuf = 0;
+ switch(sym->sy_class) {
+ case CONST:
+ *pbuf = malloc((unsigned) size);
+ if (! *pbuf) {
+ error("could not allocate enough memory");
+ break;
+ }
+ switch(tp->ty_class) {
+ case T_REAL:
+ put_real(*pbuf, size, sym->sy_const.co_rval);
+ break;
+ case T_INTEGER:
+ case T_SUBRANGE:
+ case T_UNSIGNED:
+ case T_ENUM:
+ put_int(*pbuf, size, sym->sy_const.co_ival);
+ break;
+ case T_SET:
+ memcpy(*pbuf, sym->sy_const.co_setval, (int) size);
+ break;
+ case T_STRING:
+ memcpy(*pbuf, sym->sy_const.co_sval, (int) size);
+ break;
+ default:
+ fatal("strange constant");
+ }
+ retval = 1;
+ break;
+ case VAR:
+ case VARPAR:
+ case LOCVAR:
+ a = get_addr(sym, psize);
+ if (a) {
+ size = *psize;
+ *pbuf = malloc((unsigned) size);
+ if (! *pbuf) {
+ error("could not allocate enough memory");
+ break;
+ }
+ if (get_bytes(size, a, *pbuf)) {
+ retval = 1;
+ }
+ }
+ break;
+ }
+
+ if (retval == 0) {
+ if (*pbuf) free(*pbuf);
+ *pbuf = 0;
+ *psize = 0;
+ }
+ else *psize = size;
+
+ return retval;
+}
+
/* buffer to integer and vice versa routines */
long
else l1 = (unsigned long) l1 >
(unsigned long) l2;
break;
+ default:
+ l1 = 0;
+ assert(0);
+ break;
}
break;
case T_REAL:
case E_GT:
l1 = d1 > d2;
break;
+ default:
+ l1 = 0;
+ assert(0);
+ break;
}
break;
default:
return retval;
}
-extern t_addr get_addr();
-
int
eval_desig(p, paddr, psize, ptp)
p_tree p;
using conversion routines. In
.BR grind ,
the conversions needed are performed automatically.
+.LP
+Expressions whose value is to be printed can be given a "format" by appending
+a `\e', followed by a format. A format consists of a string of letters.
+The following letters are available:
+.LP
+.nf
+c print all integer values as a char
+d print all integer values in signed decimal format
+o print all integer values in octal format
+x print all integer values in hexadecimal format
+h print all integer values in hexadecimal format
+u print all integer values in unsigned decimal format
+s for "pointer to char" types, make an attempt to print
+ the indicated string
+.fi
.SS Operators
.LP
.B Grind
remainder, bitwise or, bitwise xor, bitwise and, boolean or,
boolean and, left-shift, right-shift, address-of, dereference, less than,
less than or equal, equal, not equal, greater than, greater than or equal,
-selection.
+selection, array subscripting.
.LP
The syntax and priority of these operators depends on the source language.
Parentheses can be used for grouping.
the trace command discussed later).
The following way is also accepted:
.RS
-\fBat\fP [ "\fIfilename\fP": ] \fIlinenumber\fP \fBin \fIfunction\fP
+\fBin\fP \fIfunction\fP \fBat\fP [ "\fIfilename\fP": ] \fIlinenumber\fP
.RE
In this case, consistency of the information given is checked. This last
form is useful for "stuffing" output from the status command described later.
+.SS "Command numbers"
+.LP
+Some command numbers have a command number associated with them. Other commands
+refer to these command numbers. These command numbers can either be given as
+an absolute number, or as a negative number. In the last case, the number
+is interpreted relative to the last number assigned. This feature is normally
+only used for commands that are put in a log file, so that "sourceing" these
+log files is safer (see also the description of the \fBsource\fP and \fBlog\fP
+commands).
+
.SS "Commands"
.TP
.B ^C
.br
Continue execution from where it stopped, or, if \fIsourceline\fP is
given, at that source line. If \fIcount\fP is given, pass \fIcount\fP-1
-breakpoints.
+breakpoints. \fIsourceline\fP must be in the same function.
.TP
\fBtrace\fP [ \fBon\fP \fIexpression\fP ] [ \fIposition\fP ] [ \fBif\fP \fIcondition\fP ]
.ti -0.5i
is reached.
Either a position or a condition (or both) must be given.
.TP
-\fBwhen\fP [ \fIposition\fP ] [ \fBif\fP \fIcondition\fP ] { \fIcommand\fP [ ; \fIcommand ] ... }
+\fBwhen\fP [ \fIposition\fP ] [ \fBif\fP \fIcondition\fP ] { \fIcommand\fP [ ; \fIcommand\fP ] ... }
Execute the
.B grind
.IR command (s)
.br
Start logging the \fBgrind\fP commands given on file \fIfilename\fP, or
stop logging. If no argument is given, the current log file is printed.
+In logged commands, an absolute command number is replaced by a relative one.
.TP
\fBdisable\fP [ \fIcommandnumber\fP [ , \fIcommandnumber\fP ... ] ]
.br
Invoke the shell with \fIshellcommand\fP. \fIshellcommand\fP extends to the
end of the line. In the command, the characters `%' and `!' are replaced
with the current file name and the previous shell command respectively.
-The sequences `\%' and `\!' are replaced by `%' and `!' respectively.
+The sequences `\e%' and `\e!' are replaced by `%' and `!' respectively.
.TP
\fBframe\fP [ \fIcount\fP | + \fIcount\fP | - \fIcount\fP ]
.br
#include "position.h"
#include "tree.h"
#include "operator.h"
-#include "message.h"
extern FILE *db_out;
extern int db_ss;
-int stop_reason;
typedef struct item {
struct item *i_next;
};
static struct itemlist item_list;
+static int stop_reason;
int item_count;
static int
int mess_type;
int may_stop;
{
- /* Perform actions associated with position 'a', and return 1 if we must stop
- there, and 0 if not.
+ /* Perform actions associated with position 'a', and return stop_reason
+ if we must stop there, and 0 if not.
*/
register p_item i = item_list.il_first;
- int stopping = 0;
stop_reason = 0;
for (i = item_list.il_first; i != 0; i = i->i_next) {
&& (p->t_address == a || p->t_address == NO_ADDR)) {
switch(p->t_oper) {
case OP_STOP:
- if (mess_type != M_DB_SS && mess_type != M_OK) break;
+ if (mess_type != 1) break;
if (! p->t_args[1] || eval_cond(p->t_args[1])) {
if (! stop_reason) stop_reason = i->i_itemno;
- stopping = 1;
}
break;
case OP_TRACE:
&& (p->t_address == a || p->t_address == NO_ADDR)) {
switch(p->t_oper) {
case OP_TRACE:
- if ((! stopping && mess_type != M_END_SS)
+ if ((! stop_reason && mess_type != 0)
|| p->t_args[2] || ! may_stop) {
perform(p, a);
}
}
}
}
- return stopping;
+ return stop_reason;
}
handle_displays()
{
p_item i;
- if (in_item_list(p)) return 1;
+ if (in_item_list(p)) return;
i = new_item();
i->i_node = p;
i->i_itemno = ++item_count;
item_list.il_last = i;
pr_item(i);
- return 1;
}
-p_tree
remove_from_item_list(n)
int n;
{
register p_item i = item_list.il_first, prev = 0;
p_tree p;
- if (n <= 0) n = item_count - n;
+ if (n == 0) {
+ n = stop_reason;
+ if (n == 0) {
+ error("no current stopping point");
+ return;
+ }
+ stop_reason = 0;
+ }
+ if (n < 0) n = item_count + n + 1;
while (i) {
if (i->i_itemno == n) break;
prev = i;
}
if (! i) {
error("no item %d in current status", n);
- return 0;
+ return;
}
if (i->i_itemno == stop_reason) stop_reason = 0;
if (prev) {
if (p->t_address == NO_ADDR
&& (p->t_oper != OP_TRACE || ! p->t_args[0])) db_ss--;
free_item(i);
- return p;
+ switch(p->t_oper) {
+ case OP_STOP:
+ case OP_WHEN:
+ (void) setstop(p, 0);
+ break;
+ case OP_TRACE:
+ (void) settrace(p, 0);
+ break;
+ case OP_DUMP:
+ free_dump(p);
+ break;
+ }
+ freenode(p);
}
p_tree
{
register p_item i = item_list.il_first;
- if (n <= 0) n = item_count - n;
+ if (n == 0) {
+ n = stop_reason;
+ if (n == 0) return 0;
+ }
+ if (n < 0) n = item_count + n + 1;
while (i) {
if (i->i_itemno == n) return i->i_node;
i = i->i_next;
register p_item i = item_list.il_first;
register p_tree p;
- if (n <= 0) n = item_count - n;
+ if (n == 0) {
+ n = stop_reason;
+ if (n == 0) {
+ error("no current stopping point");
+ return;
+ }
+ }
+ if (n < 0) n = item_count + n + 1;
while (i) {
if (i->i_itemno == n) break;
i = i->i_next;
switch(p->t_oper) {
case OP_STOP:
case OP_WHEN:
- setstop(p, kind ? M_CLRBP : M_SETBP);
+ (void) setstop(p, ! kind);
break;
case OP_TRACE:
- settrace(p, kind ? M_CLRTRACE : M_SETTRACE);
+ (void) settrace(p, ! kind);
break;
}
}
struct langdep *currlang;
-static int
+static void
add_language(suff, lang)
char *suff;
struct langdep *lang;
list = p;
}
-int
init_languages()
{
add_language(".mod", m2_dep);
add_language(".c", c_dep);
}
-int
find_language(suff)
char *suff;
{
extern t_lineno currline;
extern int interrupted;
-static int
+static void
mk_filnm(dir, file, newname)
char *dir;
char *file;
int debug;
extern struct tokenname tkidf[];
extern char *strindex();
+extern void signal_child();
+extern void init_del();
+extern void init_run();
extern int eof_seen;
extern int interrupted;
else if (AObj == 0) AObj = "a.out";
reserve(tkidf);
reserve(shorts);
- if (! init_run()) {
- fatal("something wrong with file descriptors");
- }
+ init_run();
prompt();
Commands();
signal_child(SIGKILL);
print_string(),
print_char(),
get_number(),
- get_name(),
+ getname(),
get_token(),
- get_string(),
+ getstring(),
print_op(),
binop_prio(),
unop_prio(),
array_elsize,
binop_prio,
unop_prio,
- get_string,
- get_name,
+ getstring,
+ getname,
get_number,
get_token,
print_op,
struct langdep *m2_dep = &m2;
-static int
+static
print_char(c)
int c;
{
fprintf(db_out, (c >= 040 && c < 0177) ? "'%c'" : "%oC", c);
}
-static int
+static
print_string(f, s, len)
FILE *f;
char *s;
}
static int
-get_name(c)
+getname(c)
register int c;
{
char buf[512+1];
}
static int
-get_string(c)
+getstring(c)
int c;
{
register int ch;
return STRING;
}
-static int
+static
print_op(f, p)
FILE *f;
p_tree p;
}
}
-static int
+static
fix_bin_to_pref()
{
/* No problems of this kind in Modula-2 */
t_addr a;
int print_function;
{
- register p_scope sc = base_scope(get_scope_from_addr(a));
register p_position pos = get_position_from_addr(a);
- if (sc && print_function) {
- fprintf(db_out, "in %s ", sc->sc_definedby->sy_idf->id_text);
+ if (print_function) {
+ register p_scope sc = base_scope(get_scope_from_addr(a));
+ if (sc) fprintf(db_out, "in %s ", sc->sc_definedby->sy_idf->id_text);
}
if (pos) fprintf(db_out, "at \"%s\":%u", pos->filename, pos->lineno);
return pos;
#include <stdio.h>
#include "type.h"
-#include "message.h"
#include "langdep.h"
#include "scope.h"
#include "symbol.h"
format++;
}
switch(format == 0 ? 0 : *format) {
+ case 'u':
+ fprintf(db_out, currlang->uns_fmt, v);
+ break;
default:
if (tp != uchar_type) {
fprintf(db_out, currlang->uns_fmt, v);
case 'h':
fprintf(db_out, currlang->hexint_fmt, v);
break;
+ case 'u':
+ fprintf(db_out, currlang->uns_fmt, v);
+ break;
}
}
if (fld->fld_bitsize < (sz << 3)) {
/* apparently a bit field */
/* ??? */
- fprintf(db_out, "<bitfield, %d, %ld>", fld->fld_bitsize, sz);
+ fprintf(db_out, "<bitfield, %ld, %ld>", fld->fld_bitsize, sz);
}
else print_val(fld->fld_type, sz, addr+(fld->fld_pos>>3), compressed, indent, format);
if (compressed && i > 1) {
extern char *AObj;
extern FILE *db_out;
extern int debug;
-extern long pointer_size;
extern char *progname;
extern int child_interrupted;
extern int interrupted;
-extern int stop_reason;
-extern int stack_offset;
extern t_lineno currline;
static int child_pid; /* process id of child */
static int child_status;
static int restoring;
static int fild1[2], fild2[2]; /* pipe file descriptors */
-int disable_intr = 1;
+int disable_intr = 1;
int db_ss;
+int stack_offset;
+
+void signal_child();
-static int catch_sigpipe();
+static void catch_sigpipe();
static int stopped();
static int uputm(), ugetm();
static t_addr curr_stop;
p_tree run_command;
-static
+static void
ITOBUF(p, l, sz)
register char *p;
long l;
return l;
}
-int
+void
init_run()
{
/* take file descriptors so that listing cannot take them */
pipe(fild2) < 0 ||
fild1[0] != 3 ||
fild2[1] != 6) {
- return 0;
+ fatal("something wrong with file descriptors");
}
to_child = fild1[1];
from_child = fild2[0];
child_pid = 0;
if (currfile) CurrentScope = currfile->sy_file->f_scope;
currline = 0;
- return 1;
}
extern int errno;
-int
start_child(p)
p_tree p;
{
/* start up the process to be debugged and set up communication */
char *argp[MAXARG]; /* argument list */
- register p_tree pt = p->t_args[0], pt1;
+ register p_tree pt = p->t_args[0], pt1 = 0;
unsigned int nargs = 1; /* #args */
char *in_redirect = 0; /* standard input redirected */
char *out_redirect = 0; /* standard output redirected */
}
else {
error("too many arguments");
- return 0;
+ return;
}
break;
case OP_INPUT:
if (in_redirect) {
error("input redirected twice?");
- return 0;
+ return;
}
in_redirect = pt->t_str;
break;
case OP_OUTPUT:
if (out_redirect) {
error("output redirected twice?");
- return 0;
+ return;
}
out_redirect = pt->t_str;
break;
child_pid = fork();
if (child_pid < 0) {
error("could not create child");
- return 0;
+ return;
}
if (child_pid == 0) {
/* this is the child process */
exit(1);
}
- /* debugger */
- close(fild1[0]);
- close(fild2[1]);
+ /* debugger; don't close fild1[0] and fild2[1]; we want those file
+ descriptors occupied!
+ */
- pipe(fild1); /* to occupy file descriptors */
signal(SIGPIPE, catch_sigpipe);
{
struct message_hdr m;
if (! ugetm(&m)) {
error("child not responding");
init_run();
- return 0;
+ return;
}
curr_stop = BUFTOI(m.m_buf+1, (int) PS);
CurrentScope = get_scope_from_addr(curr_stop);
}
perform_items();
- if (! restoring && ! item_addr_actions(curr_stop, M_OK, 1)) {
- send_cont(1);
- }
- else if (! restoring) {
- stopped("stopped", curr_stop);
+ if (! restoring) {
+ int stop_reason = item_addr_actions(curr_stop, 1, 1);
+ if (! stop_reason) (void) send_cont(1);
+ else (void) stopped("stopped", curr_stop, stop_reason);
}
- return 1;
}
+void
signal_child(sig)
{
if (child_pid) {
}
}
-static int
+static void
catch_sigpipe()
{
child_pid = 0;
static int single_stepping;
static int
-stopped(s, a)
- char *s; /* stop message */
- t_addr a; /* address where stopped */
+stopped(s, a, stop_reason)
+ char *s; /* stop message */
+ t_addr a; /* address where stopped */
+ int stop_reason; /* status entry causing the stop */
{
p_position pos;
t_addr a;
static int level = 0;
int child_dead = 0;
+ int stop_reason;
level++;
for (;;) {
+ stop_reason = 0;
if (! child_pid) {
error("no process");
return 0;
}
if (m->m_type & M_DB_RUN) {
disable_intr = 0;
- stop_reason = 0;
stack_offset = 0;
}
if (!child_interrupted && (! uputm(m) || ! ugetm(&answer))) {
if (! level) {
child_interrupted = 0;
interrupted = 0;
- stopped("interrupted", (t_addr) BUFTOI(answer.m_buf+1, (int)PS));
+ return stopped("interrupted", (t_addr) BUFTOI(answer.m_buf+1, (int)PS), 0);
}
return 1;
}
}
a = BUFTOI(answer.m_buf+1, (int)PS);
type = answer.m_type & 0377;
+ if (type == M_END_SS) type = 0;
+ else if (type == M_OK || type == M_DB_SS) type = 1;
+ else type = 2;
if (m->m_type & M_DB_RUN) {
/* run command */
CurrentScope = get_scope_from_addr((t_addr) a);
- if (! item_addr_actions(a, type, stop_message) &&
- ( type == M_DB_SS || type == M_OK)) {
+ if (!(stop_reason = item_addr_actions(a, type, stop_message))
+ && (type == 1)) {
/* no explicit breakpoints at this position.
Also, child did not stop because of
SETSS or SETSSF, otherwise we would
}
continue;
}
- if (type != M_END_SS && single_stepping) {
+ if (type != 0 && single_stepping) {
m->m_type = M_CLRSS;
if (! uputm(m) || ! ugetm(&answer)) return 0;
}
single_stepping = 0;
}
+ level--;
if (stop_message) {
- stopped("stopped", a);
+ return stopped("stopped", a, stop_reason);
}
- level--;
return 1;
}
/*NOTREACHED*/
return retval;
}
+void
set_bytes(size, from, to)
long size;
char *from;
}
t_addr
-get_dump(globmessage, globbuf, stackmessage, stackbuf)
- struct message_hdr *globmessage, *stackmessage;
+get_dump(globbuf, stackbuf)
char **globbuf, **stackbuf;
{
struct message_hdr m;
+ struct message_hdr *globm, *stackm;
long sz;
m.m_type = M_DUMP;
assert(0);
}
- *globmessage = answer;
sz = BUFTOI(answer.m_buf+1, (int)LS);
- *globbuf = malloc((unsigned) sz);
- if (! ureceive(*globbuf, sz) || ! ugetm(stackmessage)) {
+ *globbuf = malloc((unsigned) (sz+sizeof(struct message_hdr)));
+ if (! *globbuf
+ || ! ureceive(*globbuf+sizeof(struct message_hdr), sz)
+ || ! ugetm(&m)) {
if (*globbuf) free(*globbuf);
+ else error("could not allocate enougn memory");
return 0;
}
- assert(stackmessage->m_type == M_DSTACK);
- sz = BUFTOI(stackmessage->m_buf+1, (int)LS);
- *stackbuf = malloc((unsigned) sz);
- if (! ureceive(*stackbuf, sz)) {
- if (*globbuf) free(*globbuf);
- if (*stackbuf) free(*stackbuf);
- return 0;
- }
- ITOBUF(globmessage->m_buf+SP_OFF, BUFTOI(stackmessage->m_buf+SP_OFF, (int)PS), (int) PS);
- if (! *globbuf || ! *stackbuf) {
- error("could not allocate enough memory");
- if (*globbuf) free(*globbuf);
+ globm = (struct message_hdr *) *globbuf;
+ *globm = answer;
+
+ assert(m.m_type == M_DSTACK);
+ sz = BUFTOI(m.m_buf+1, (int)LS);
+ *stackbuf = malloc((unsigned) sz+sizeof(struct message_hdr));
+ if (! *stackbuf || ! ureceive(*stackbuf+sizeof(struct message_hdr), sz)) {
+ free(*globbuf);
if (*stackbuf) free(*stackbuf);
+ else error("could not allocate enougn memory");
return 0;
}
- return BUFTOI(globmessage->m_buf+PC_OFF, (int)PS);
+ stackm = (struct message_hdr *) *stackbuf;
+ *stackm = m;
+ ITOBUF(globm->m_buf+SP_OFF, BUFTOI(stackm->m_buf+SP_OFF, (int)PS), (int) PS);
+ return BUFTOI(globm->m_buf+PC_OFF, (int)PS);
}
int
-put_dump(globmessage, globbuf, stackmessage, stackbuf)
- struct message_hdr *globmessage, *stackmessage;
+put_dump(globbuf, stackbuf)
char *globbuf, *stackbuf;
{
struct message_hdr m;
- int retval;
+ struct message_hdr *globm = (struct message_hdr *) globbuf,
+ *stackm = (struct message_hdr *) stackbuf;
+ stackbuf += sizeof(struct message_hdr);
+ globbuf += sizeof(struct message_hdr);
if (! child_pid) {
restoring = 1;
start_child(run_command);
restoring = 0;
}
- retval = uputm(globmessage)
- && usend(globbuf, BUFTOI(globmessage->m_buf+1, (int) LS))
- && uputm(stackmessage)
- && usend(stackbuf, BUFTOI(stackmessage->m_buf+1, (int) LS))
+ return uputm(globm)
+ && usend(globbuf, BUFTOI(globm->m_buf+1, (int) LS))
+ && uputm(stackm)
+ && usend(stackbuf, BUFTOI(stackm->m_buf+1, (int) LS))
&& ugetm(&m)
- && stopped("restored", BUFTOI(m.m_buf+1, (int) PS));
- return retval;
+ && stopped("restored", BUFTOI(m.m_buf+1, (int) PS), 0);
}
t_addr *
{
struct message_hdr m;
- m.m_type = type | (db_ss ? M_DB_SS : 0);
+ m.m_type = (type ? M_SETSSF : M_SETSS) | (db_ss ? M_DB_SS : 0);
ITOBUF(m.m_buf+1, count, (int) LS);
single_stepping = 1;
if (could_send(&m, 1) && child_pid) return 1;
{
struct message_hdr m;
- m.m_type = type;
+ m.m_type = type ? M_SETBP : M_CLRBP;
ITOBUF(m.m_buf+1, (long) a, (int) PS);
- if (debug) printf("%s breakpoint at 0x%lx\n", type == M_SETBP ? "setting" : "clearing", (long) a);
+ if (debug) printf("%s breakpoint at 0x%lx\n", type ? "setting" : "clearing", (long) a);
if (child_pid && ! could_send(&m, 0)) {
}
{
struct message_hdr m;
- m.m_type = type;
+ m.m_type = type ? M_SETTRACE : M_CLRTRACE;
ITOBUF(m.m_buf+1, (long)start, (int) PS);
ITOBUF(m.m_buf+PS+1, (long)end, (int) PS);
- if (debug) printf("%s trace at [0x%lx,0x%lx]\n", type == M_SETTRACE ? "setting" : "clearing", (long) start, (long) end);
+ if (debug) printf("%s trace at [0x%lx,0x%lx]\n", type ? "setting" : "clearing", (long) start, (long) end);
if (child_pid && ! could_send(&m, 0)) {
return 0;
}
#include "file.h"
#include "idf.h"
#include "tree.h"
-#include "message.h"
#include "scope.h"
#include "symbol.h"
#include "langdep.h"
break;
case OP_DUMP:
fputs("dump ", f);
- print_position(p->t_address, 1);
+ (void) print_position(p->t_address, 1);
break;
case OP_RESTORE:
fputs("restore ", f);
case OP_WHEN:
fputs("when ", f);
if (p->t_address != NO_ADDR) {
- print_position(p->t_address, 1);
+ (void) print_position(p->t_address, 1);
}
else print_node(f, p->t_args[0], 0);
if (p->t_args[1]) {
case OP_STOP:
fputs("stop ", f);
if (p->t_address != NO_ADDR) {
- print_position(p->t_address, 1);
+ (void) print_position(p->t_address, 1);
}
else print_node(f, p->t_args[0], 0);
if (p->t_args[1]) {
fputs(" ", f);
}
if (p->t_address != NO_ADDR) {
- print_position(p->t_address, 1);
+ (void) print_position(p->t_address, 1);
}
else print_node(f, p->t_args[0], 0);
if (p->t_args[1]) {
}
break;
case OP_AT:
- fprintf(f, "at \"%s\":%ld", p->t_filename, p->t_lino);
+ fprintf(f, "at \"%s\":%d", p->t_filename, (int) p->t_lino);
break;
case OP_IN:
fputs("in ", f);
#include "sizes.h"
#include "symbol.h"
#include "scope.h"
-#include "message.h"
#include "langdep.h"
#include "expr.h"
p = &list_row[type_index[0]];
while (type_index[1] >= p->len) {
int indx = p->len/NINCR;
- p->len += NINCR;
if (p->len) {
p->row = (p_type **) Realloc((char *) p->row,
(unsigned) (indx + 1) * sizeof(p_type *));
}
else p->row = (p_type **) Malloc(sizeof(p_type *));
+ p->len += NINCR;
p->row[indx] = (p_type *) Malloc(NINCR * sizeof(p_type));
for (i = NINCR-1; i >= 0; i--) {
p->row[indx][i] = 0;