15470Slinton /* Copyright (c) 1982 Regents of the University of California */
25470Slinton 
3*5760Slinton static char sccsid[] = "@(#)trinfo.c 1.2 02/11/82";
45470Slinton 
55470Slinton /*
65470Slinton  * Trace information management.
75470Slinton  *
85470Slinton  * The trace information is a list of variables that are being
95470Slinton  * traced or whose value changing should cause a stop.
105470Slinton  */
115470Slinton 
125470Slinton #include "defs.h"
135470Slinton #include "breakpoint.h"
145470Slinton #include "process.h"
155470Slinton #include "machine.h"
165470Slinton #include "sym.h"
175470Slinton #include "tree.h"
185470Slinton #include "source.h"
195470Slinton #include "object.h"
205470Slinton #include "tree/tree.rep"
215470Slinton 
225470Slinton /*
235470Slinton  * When tracing variables we keep a copy of their most recent value
245470Slinton  * and compare it to the current one each time a breakpoint occurs.
255470Slinton  * MAXTRSIZE is the maximum size variable we allow.
265470Slinton  */
275470Slinton 
285470Slinton #define MAXTRSIZE 512
295470Slinton 
305470Slinton /*
315470Slinton  * The tracing structure is a list of information about all the
325470Slinton  * variables that are being traced.
335470Slinton  */
345470Slinton 
355470Slinton typedef struct trinfo {
36*5760Slinton     TRTYPE trtype;
37*5760Slinton     ADDRESS traddr;
38*5760Slinton     SYM *trblock;
39*5760Slinton     NODE *trvar;
40*5760Slinton     NODE *trcond;
41*5760Slinton     char *trvalue;
42*5760Slinton     struct trinfo *trnext;
435470Slinton } TRINFO;
445470Slinton 
455470Slinton LOCAL TRINFO *trhead;
465470Slinton 
475470Slinton /*
485470Slinton  * add a variable to be traced
495470Slinton  */
505470Slinton 
515470Slinton addvar(trtype, node, cond)
525470Slinton TRTYPE trtype;
535470Slinton NODE *node;
545470Slinton NODE *cond;
555470Slinton {
56*5760Slinton     register TRINFO *tp;
575470Slinton 
58*5760Slinton     tp = alloc(1, TRINFO);
59*5760Slinton     tp->trtype = trtype;
60*5760Slinton     tp->traddr = (ADDRESS) -1;
61*5760Slinton     tp->trblock = curfunc;
62*5760Slinton     tp->trvar = node;
63*5760Slinton     tp->trcond = cond;
64*5760Slinton     tp->trvalue = NIL;
65*5760Slinton     tp->trnext = trhead;
66*5760Slinton     trhead = tp;
675470Slinton }
685470Slinton 
695470Slinton /*
705470Slinton  * remove a variable from the trace list
715470Slinton  */
725470Slinton 
735470Slinton delvar(trtype, node, cond)
745470Slinton TRTYPE trtype;
755470Slinton NODE *node;
765470Slinton NODE *cond;
775470Slinton {
78*5760Slinton     register TRINFO *tp, *last;
795470Slinton 
80*5760Slinton     last = NIL;
81*5760Slinton     for (tp = trhead; tp != NIL; tp = tp->trnext) {
82*5760Slinton 	if (tp->trtype == trtype &&
83*5760Slinton 	    tr_equal(tp->trvar, node) &&
84*5760Slinton 	    tr_equal(tp->trcond, cond)) {
85*5760Slinton 	    break;
865470Slinton 	}
87*5760Slinton     }
88*5760Slinton     if (tp == NIL) {
89*5760Slinton 	trerror("can't delete term %t", node);
90*5760Slinton     }
91*5760Slinton     if (last == NIL) {
92*5760Slinton 	trhead = tp->trnext;
93*5760Slinton     } else {
94*5760Slinton 	last->trnext = tp->trnext;
95*5760Slinton     }
96*5760Slinton     if (tp->trvalue != NIL) {
97*5760Slinton 	free(tp->trvalue);
98*5760Slinton     }
99*5760Slinton     free(tp);
1005470Slinton }
1015470Slinton 
1025470Slinton /*
1035470Slinton  * Print out any news about variables in the list whose
1045470Slinton  * values have changed.
1055470Slinton  */
1065470Slinton 
1075470Slinton prvarnews()
1085470Slinton {
109*5760Slinton     register TRINFO *tp;
110*5760Slinton     register NODE *p;
111*5760Slinton     register int n;
112*5760Slinton     SYM *s;
113*5760Slinton     char buff[MAXTRSIZE];
114*5760Slinton     static LINENO prevline;
1155470Slinton 
116*5760Slinton     for (tp = trhead; tp != NIL; tp = tp->trnext) {
117*5760Slinton 	if (tp->trcond != NIL && !cond(tp->trcond)) {
118*5760Slinton 	    continue;
1195470Slinton 	}
120*5760Slinton 	s = curfunc;
121*5760Slinton 	while (s != NIL && s != tp->trblock) {
122*5760Slinton 	    s = container(s);
123*5760Slinton 	}
124*5760Slinton 	if (s == NIL) {
125*5760Slinton 	    continue;
126*5760Slinton 	}
127*5760Slinton 	p = tp->trvar;
128*5760Slinton 	if (tp->traddr == (ADDRESS) -1) {
129*5760Slinton 	    tp->traddr = lval(p->left);
130*5760Slinton 	}
131*5760Slinton 	n = size(p->nodetype);
132*5760Slinton 	dread(buff, tp->traddr, n);
133*5760Slinton 	if (tp->trvalue == NIL) {
134*5760Slinton 	    tp->trvalue = alloc(n, char);
135*5760Slinton 	    mov(buff, tp->trvalue, n);
136*5760Slinton 	    mov(buff, sp, n);
137*5760Slinton 	    sp += n;
138*5760Slinton 	    if (tp->trtype == TRPRINT) {
139*5760Slinton 		printf("initially (at ");
140*5760Slinton 		printwhere(curline, srcfilename(pc));
141*5760Slinton 		printf("):\t");
142*5760Slinton 		prtree(p);
143*5760Slinton 		printf(" = ");
144*5760Slinton 		printval(p->nodetype);
145*5760Slinton 		putchar('\n');
146*5760Slinton 	    }
147*5760Slinton 	} else if (cmp(tp->trvalue, buff, n) != 0) {
148*5760Slinton 	    mov(buff, tp->trvalue, n);
149*5760Slinton 	    mov(buff, sp, n);
150*5760Slinton 	    sp += n;
151*5760Slinton 	    printf("after ");
152*5760Slinton 	    printwhere(prevline, srcfilename(pc));
153*5760Slinton 	    printf(":\t");
154*5760Slinton 	    prtree(p);
155*5760Slinton 	    printf(" = ");
156*5760Slinton 	    printval(p->nodetype);
157*5760Slinton 	    putchar('\n');
158*5760Slinton 	    if (tp->trtype == TRSTOP) {
159*5760Slinton 		isstopped = TRUE;
160*5760Slinton 		curline = srcline(pc);
161*5760Slinton 		printstatus();
162*5760Slinton 	    }
163*5760Slinton 	}
164*5760Slinton     }
165*5760Slinton     prevline = curline;
1665470Slinton }
1675470Slinton 
1685470Slinton /*
1695470Slinton  * Free the table.  Note that trvar and trcond fields are not freed,
1705470Slinton  * this is because they are the same as in the breakpoint table and
1715470Slinton  * are freed by the bpfree routine.
1725470Slinton  */
1735470Slinton 
1745470Slinton trfree()
1755470Slinton {
176*5760Slinton     register TRINFO *tp, *next;
1775470Slinton 
178*5760Slinton     for (tp = trhead; tp != NIL; tp = next) {
179*5760Slinton 	next = tp->trnext;
180*5760Slinton 	if (tp->trvalue != NIL) {
181*5760Slinton 	    free(tp->trvalue);
1825470Slinton 	}
183*5760Slinton 	free(tp);
184*5760Slinton     }
185*5760Slinton     trhead = NIL;
1865470Slinton }
187