Added 'file ?' and shell escape, and some re-organization
This commit is contained in:
@@ -20,15 +20,9 @@
|
||||
|
||||
extern FILE *db_out;
|
||||
t_lineno currline;
|
||||
static t_lineno listline;
|
||||
extern long pointer_size;
|
||||
t_lineno listline;
|
||||
extern char *strrindex();
|
||||
extern int interrupted;
|
||||
extern int stop_reason;
|
||||
|
||||
p_tree print_command;
|
||||
|
||||
static int wsize = 10;
|
||||
|
||||
/*VARARGS1*/
|
||||
p_tree
|
||||
@@ -89,7 +83,7 @@ freenode(p)
|
||||
free_tree(p);
|
||||
}
|
||||
|
||||
static t_addr
|
||||
t_addr
|
||||
get_addr_from_node(p)
|
||||
p_tree p;
|
||||
{
|
||||
@@ -399,73 +393,6 @@ eval(p)
|
||||
if (p && operators[p->t_oper].op_fun) (*operators[p->t_oper].op_fun)(p);
|
||||
}
|
||||
|
||||
do_list(p)
|
||||
p_tree 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;
|
||||
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;
|
||||
}
|
||||
else {
|
||||
t_addr a = get_addr_from_node(p->t_args[0]);
|
||||
p_position pos;
|
||||
|
||||
if (a == ILL_ADDR) {
|
||||
return;
|
||||
}
|
||||
pos = get_position_from_addr(a);
|
||||
newfile(str2idf(pos->filename, 1));
|
||||
l1 = pos->lineno - (l2 > 0 ? l2 : wsize)/2;
|
||||
if (l1 < 1) l1 = 1;
|
||||
}
|
||||
}
|
||||
if (listfile) {
|
||||
if (l2 < 0) {
|
||||
l2 = -l2;
|
||||
if (l1 > l2) l2 = 1;
|
||||
else l2 -= l1 - 1;
|
||||
}
|
||||
lines(listfile->sy_file, l1, l2);
|
||||
listline = l1 + l2;
|
||||
}
|
||||
else error("no current file");
|
||||
}
|
||||
|
||||
do_file(p)
|
||||
p_tree p;
|
||||
{
|
||||
FILE *f;
|
||||
|
||||
if (p->t_args[0]) {
|
||||
if ((f = fopen(p->t_args[0]->t_str, "r")) == NULL) {
|
||||
error("could not open %s", p->t_args[0]->t_str);
|
||||
return;
|
||||
}
|
||||
fclose(f);
|
||||
newfile(p->t_args[0]->t_idf);
|
||||
}
|
||||
else if (listfile) fprintf(db_out, "%s\n", listfile->sy_idf->id_text);
|
||||
else error("no current file");
|
||||
}
|
||||
|
||||
newfile(id)
|
||||
register struct idf *id;
|
||||
{
|
||||
@@ -481,328 +408,6 @@ newfile(id)
|
||||
find_language(strrindex(id->id_text, '.'));
|
||||
}
|
||||
|
||||
setstop(p, kind)
|
||||
p_tree p;
|
||||
int kind;
|
||||
{
|
||||
t_addr a = get_addr_from_node(p->t_args[0]);
|
||||
|
||||
if (a == ILL_ADDR) return 0;
|
||||
|
||||
p->t_address = a;
|
||||
if (a != NO_ADDR) {
|
||||
if (! set_or_clear_breakpoint(a, kind)) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
do_stop(p)
|
||||
p_tree p;
|
||||
{
|
||||
if (! setstop(p, SETBP)) {
|
||||
return;
|
||||
}
|
||||
add_to_item_list(p);
|
||||
}
|
||||
|
||||
settrace(p, kind)
|
||||
p_tree p;
|
||||
int kind;
|
||||
{
|
||||
t_addr a, e;
|
||||
|
||||
a = get_addr_from_node(p->t_args[0]);
|
||||
if (a == NO_ADDR) return 1;
|
||||
if (a == ILL_ADDR) return 0;
|
||||
if (p->t_args[0]->t_oper == OP_AT) {
|
||||
e = a;
|
||||
p->t_address = a;
|
||||
}
|
||||
else {
|
||||
p_scope sc = get_next_scope_from_addr(a+1);
|
||||
|
||||
if (sc) e = sc->sc_start - 1;
|
||||
else e = 0xffffffff;
|
||||
}
|
||||
return set_or_clear_trace(a, e, kind);
|
||||
}
|
||||
|
||||
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;
|
||||
{
|
||||
if (!p) {
|
||||
if (stop_reason) {
|
||||
able_item(stop_reason, kind);
|
||||
}
|
||||
else {
|
||||
error("no current stopping point");
|
||||
}
|
||||
return;
|
||||
}
|
||||
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;
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
if (p) {
|
||||
count = p->t_args[0]->t_ival;
|
||||
if (p->t_args[1]) {
|
||||
t_addr a = get_addr_from_position(&(p->t_args[1]->t_pos));
|
||||
p_scope sc = get_scope_from_addr(a);
|
||||
|
||||
if (a == ILL_ADDR || base_scope(sc) != base_scope(CurrentScope)) {
|
||||
error("cannot continue at line %d",
|
||||
p->t_args[1]->t_lino);
|
||||
return;
|
||||
}
|
||||
if (! set_pc(a)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
else count = 1;
|
||||
while (count--) {
|
||||
if (! send_cont(count==0)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (count > 0) {
|
||||
fprintf(db_out, "Only %d breakpoints skipped\n",
|
||||
p->t_args[0]->t_ival - count);
|
||||
}
|
||||
}
|
||||
|
||||
do_step(p)
|
||||
p_tree p;
|
||||
{
|
||||
p = p->t_args[0];
|
||||
if (! do_single_step(SETSS, p ? p->t_ival : 1L)) {
|
||||
}
|
||||
}
|
||||
|
||||
do_next(p)
|
||||
p_tree p;
|
||||
{
|
||||
p = p->t_args[0];
|
||||
if (! do_single_step(SETSSF, p? p->t_ival : 1L)) {
|
||||
}
|
||||
}
|
||||
|
||||
extern t_addr *get_EM_regs();
|
||||
|
||||
do_regs(p)
|
||||
p_tree p;
|
||||
{
|
||||
t_addr *buf;
|
||||
int n = 0;
|
||||
|
||||
p = p->t_args[0];
|
||||
if (p) n = p->t_ival;
|
||||
if (! (buf = get_EM_regs(n))) {
|
||||
return;
|
||||
}
|
||||
fprintf(db_out, "EM registers %d levels back:\n", n);
|
||||
fprintf(db_out, "\tLocalBase =\t0x%lx\n\tArgumentBase =\t0x%lx\n",
|
||||
(long) buf[LB_OFF], (long) buf[AB_OFF]);
|
||||
fprintf(db_out, "\tProgramCounter=\t0x%lx\n\tHeapPointer = \t0x%lx\n",
|
||||
(long) buf[PC_OFF],
|
||||
(long) buf[HP_OFF]);
|
||||
fprintf(db_out, "\tStackPointer =\t0x%lx\n", (long) buf[SP_OFF]);
|
||||
}
|
||||
|
||||
/*ARGSUSED*/
|
||||
do_where(p)
|
||||
p_tree p;
|
||||
{
|
||||
int i = 0;
|
||||
unsigned int cnt;
|
||||
unsigned int maxcnt = 0xffff;
|
||||
p_scope sc;
|
||||
t_addr *buf;
|
||||
t_addr PC;
|
||||
|
||||
p = p->t_args[0];
|
||||
if (p && 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;
|
||||
}
|
||||
else if (p) maxcnt = p->t_ival;
|
||||
for (cnt = maxcnt; cnt != 0; cnt--) {
|
||||
t_addr AB;
|
||||
|
||||
if (interrupted) return;
|
||||
if (! (buf = get_EM_regs(i++))) break;
|
||||
AB = buf[AB_OFF];
|
||||
PC = buf[PC_OFF];
|
||||
if (! AB) break;
|
||||
sc = base_scope(get_scope_from_addr(PC));
|
||||
if (! sc || sc->sc_start > PC) break;
|
||||
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(PC, 0);
|
||||
fputs("\n", db_out);
|
||||
}
|
||||
}
|
||||
|
||||
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");
|
||||
}
|
||||
}
|
||||
else do_delete(p->t_args[0]);
|
||||
break;
|
||||
case OP_LINK:
|
||||
do_delete(p->t_args[0]);
|
||||
do_delete(p->t_args[1]);
|
||||
break;
|
||||
case OP_INTEGER:
|
||||
p = remove_from_item_list((int) p->t_ival);
|
||||
|
||||
if (p) switch(p->t_oper) {
|
||||
case OP_WHEN:
|
||||
case OP_STOP:
|
||||
setstop(p, CLRBP);
|
||||
break;
|
||||
case OP_TRACE:
|
||||
settrace(p, CLRTRACE);
|
||||
break;
|
||||
case OP_DUMP:
|
||||
free_dump(p);
|
||||
}
|
||||
freenode(p);
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
}
|
||||
|
||||
do_print(p)
|
||||
p_tree p;
|
||||
{
|
||||
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); No, could be in when-list */
|
||||
print_command = p;
|
||||
}
|
||||
/* fall through */
|
||||
case OP_DISPLAY:
|
||||
do_print(p->t_args[0]);
|
||||
break;
|
||||
case OP_LINK:
|
||||
do_print(p->t_args[0]);
|
||||
do_print(p->t_args[1]);
|
||||
break;
|
||||
default:
|
||||
if (interrupted || ! eval_expr(p, &buf, &size, &tp)) return;
|
||||
print_node(p, 0);
|
||||
fputs(" = ", db_out);
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
do_set(p)
|
||||
p_tree p;
|
||||
{
|
||||
char *buf = 0;
|
||||
long size, size2;
|
||||
p_type tp, tp2;
|
||||
t_addr a;
|
||||
|
||||
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;
|
||||
}
|
||||
set_bytes(size, buf, a);
|
||||
free(buf);
|
||||
}
|
||||
|
||||
perform(p, a)
|
||||
register p_tree p;
|
||||
t_addr a;
|
||||
|
||||
Reference in New Issue
Block a user