1 /* Copyright (c) 1982 Regents of the University of California */
2 
3 static char sccsid[] = "@(#)trinfo.c 1.2 02/11/82";
4 
5 /*
6  * Trace information management.
7  *
8  * The trace information is a list of variables that are being
9  * traced or whose value changing should cause a stop.
10  */
11 
12 #include "defs.h"
13 #include "breakpoint.h"
14 #include "process.h"
15 #include "machine.h"
16 #include "sym.h"
17 #include "tree.h"
18 #include "source.h"
19 #include "object.h"
20 #include "tree/tree.rep"
21 
22 /*
23  * When tracing variables we keep a copy of their most recent value
24  * and compare it to the current one each time a breakpoint occurs.
25  * MAXTRSIZE is the maximum size variable we allow.
26  */
27 
28 #define MAXTRSIZE 512
29 
30 /*
31  * The tracing structure is a list of information about all the
32  * variables that are being traced.
33  */
34 
35 typedef struct trinfo {
36     TRTYPE trtype;
37     ADDRESS traddr;
38     SYM *trblock;
39     NODE *trvar;
40     NODE *trcond;
41     char *trvalue;
42     struct trinfo *trnext;
43 } TRINFO;
44 
45 LOCAL TRINFO *trhead;
46 
47 /*
48  * add a variable to be traced
49  */
50 
51 addvar(trtype, node, cond)
52 TRTYPE trtype;
53 NODE *node;
54 NODE *cond;
55 {
56     register TRINFO *tp;
57 
58     tp = alloc(1, TRINFO);
59     tp->trtype = trtype;
60     tp->traddr = (ADDRESS) -1;
61     tp->trblock = curfunc;
62     tp->trvar = node;
63     tp->trcond = cond;
64     tp->trvalue = NIL;
65     tp->trnext = trhead;
66     trhead = tp;
67 }
68 
69 /*
70  * remove a variable from the trace list
71  */
72 
73 delvar(trtype, node, cond)
74 TRTYPE trtype;
75 NODE *node;
76 NODE *cond;
77 {
78     register TRINFO *tp, *last;
79 
80     last = NIL;
81     for (tp = trhead; tp != NIL; tp = tp->trnext) {
82 	if (tp->trtype == trtype &&
83 	    tr_equal(tp->trvar, node) &&
84 	    tr_equal(tp->trcond, cond)) {
85 	    break;
86 	}
87     }
88     if (tp == NIL) {
89 	trerror("can't delete term %t", node);
90     }
91     if (last == NIL) {
92 	trhead = tp->trnext;
93     } else {
94 	last->trnext = tp->trnext;
95     }
96     if (tp->trvalue != NIL) {
97 	free(tp->trvalue);
98     }
99     free(tp);
100 }
101 
102 /*
103  * Print out any news about variables in the list whose
104  * values have changed.
105  */
106 
107 prvarnews()
108 {
109     register TRINFO *tp;
110     register NODE *p;
111     register int n;
112     SYM *s;
113     char buff[MAXTRSIZE];
114     static LINENO prevline;
115 
116     for (tp = trhead; tp != NIL; tp = tp->trnext) {
117 	if (tp->trcond != NIL && !cond(tp->trcond)) {
118 	    continue;
119 	}
120 	s = curfunc;
121 	while (s != NIL && s != tp->trblock) {
122 	    s = container(s);
123 	}
124 	if (s == NIL) {
125 	    continue;
126 	}
127 	p = tp->trvar;
128 	if (tp->traddr == (ADDRESS) -1) {
129 	    tp->traddr = lval(p->left);
130 	}
131 	n = size(p->nodetype);
132 	dread(buff, tp->traddr, n);
133 	if (tp->trvalue == NIL) {
134 	    tp->trvalue = alloc(n, char);
135 	    mov(buff, tp->trvalue, n);
136 	    mov(buff, sp, n);
137 	    sp += n;
138 	    if (tp->trtype == TRPRINT) {
139 		printf("initially (at ");
140 		printwhere(curline, srcfilename(pc));
141 		printf("):\t");
142 		prtree(p);
143 		printf(" = ");
144 		printval(p->nodetype);
145 		putchar('\n');
146 	    }
147 	} else if (cmp(tp->trvalue, buff, n) != 0) {
148 	    mov(buff, tp->trvalue, n);
149 	    mov(buff, sp, n);
150 	    sp += n;
151 	    printf("after ");
152 	    printwhere(prevline, srcfilename(pc));
153 	    printf(":\t");
154 	    prtree(p);
155 	    printf(" = ");
156 	    printval(p->nodetype);
157 	    putchar('\n');
158 	    if (tp->trtype == TRSTOP) {
159 		isstopped = TRUE;
160 		curline = srcline(pc);
161 		printstatus();
162 	    }
163 	}
164     }
165     prevline = curline;
166 }
167 
168 /*
169  * Free the table.  Note that trvar and trcond fields are not freed,
170  * this is because they are the same as in the breakpoint table and
171  * are freed by the bpfree routine.
172  */
173 
174 trfree()
175 {
176     register TRINFO *tp, *next;
177 
178     for (tp = trhead; tp != NIL; tp = next) {
179 	next = tp->trnext;
180 	if (tp->trvalue != NIL) {
181 	    free(tp->trvalue);
182 	}
183 	free(tp);
184     }
185     trhead = NIL;
186 }
187