|
|
1.1 root 1: #include "univ.h"
2: #include "core.pub"
3: #include "bpts.pri"
4: #include "symbol.h"
5: #include "expr.pub"
6: #include "format.pub"
7: #include "process.pub"
8: #include "symtab.pub"
9: #include "parse.h"
10: SRCFILE("bpts.c")
11:
12: char *BptReq::setline(Process *p)
13: {
14: trace("%d.set(%d)", this, p); OK("BptReq::setline");
15: for( Source *s = p->symtab()->root(); s; s = (Source*)s->rsib )
16: if( !strcmp(s->text(), file)
17: || !strcmp(basename(s->text()), file) )
18: break;
19: if( !s )
20: return sf("source file not found: %s", file);
21: Stmt *stmt = s->stmtafter(line);
22: if( !stmt )
23: return sf("statement not found: line %d", line);
24: if( p->bpts()->isbpt(stmt) )
25: return sf("may not set bpt more than once: %s:%d", file, line);
26: stmt->conditional(expr);
27: stmt->dobpt(1);
28: return 0;
29: }
30:
31: char *BptReq::setfunc(Process *p)
32: {
33: trace("%d.setfunc(%d)", this, p); OK("BptReq::setfunc");
34: SymTab *symtab = p->symtab();
35: if( !symtab ) return "symbol table error";
36: Func *f = (Func*)p->symtab()->idtosym(U_FUNC, func);
37: if( !f || !f->source() )
38: return sf("source function not found: %s", func);
39: file = f->source()->text();
40: if( be & BEGIN ){
41: line = f->lines.lo;
42: setline(p);
43: }
44: if( be & END ){
45: line = f->lines.hi;
46: setline(p);
47: }
48: }
49:
50: char *BptReq::set(Process *p)
51: {
52: trace("%d.set(%d)", this, p); OK("BptReq::set");
53: if( error) return error;
54: if( file ) return setline(p);
55: else if( func ) return setfunc(p);
56: else return "BptReq::set";
57: }
58:
59: void BptReq::parse(char *e)
60: {
61: Parse y(G_EXPR);
62: error = 0;
63: expr = 0;
64: if( e ){
65: expr = (Expr*) y.parse(e);
66: if( !expr )
67: error = y.error;
68: }
69: }
70:
71: BptReq::BptReq(char *f, char *curly, char *e)
72: {
73: file = 0;
74: func = f;
75: for( be = 0; *curly; ++curly ) switch(*curly){
76: case '{': be |= BEGIN; break;
77: case '}': be |= END; break;
78: }
79: parse(e);
80: }
81:
82: BptReq::BptReq(char *f, long l, char *e)
83: {
84: file = f;
85: func = 0;
86: line = l;
87: parse(e);
88: }
89:
90: Trap::Trap(Stmt *s, Trap *t)
91: {
92: static long uniq = 0;
93: trace( "%d.Trap( %d, %d, %d )", this, s, t ); VOK;
94: key = ++uniq; // won't catch up with trace
95: stmt = s;
96: sib = t;
97: }
98:
99: char *Trap::liftorlay(LiftLay lol, Core *core)
100: {
101: trace( "%d.liftorlay(%d)", this, lol ); OK("Trap::liftorlay");
102: if( !stmt ) return 0;
103: if( error = lol==LIFT ? core->liftbpt(this) : core->laybpt(this) ){
104: Stmt *s = stmt;
105: stmt = 0;
106: s->select();
107: }
108: return error;
109: }
110:
111: void Bpts::banner()
112: {
113: trace( "%d.banner()", this ); VOK;
114: if( pad ){
115: pad->banner("Breakpoint List: %s", core->procpath());
116: pad->name("BptList %s", basename(core->procpath()));
117: }
118: }
119:
120: Bpts::Bpts(Core *c)
121: {
122: Menu m;
123:
124: trace( "%d.Bpts(%d)", this, c ); VOK;
125: core = c;
126: pad = new Pad( (PadRcv*) this );
127: m.last( "clear all?", (Action) &Bpts::clearall );
128: m.last( "clean list", (Action) &Bpts::refresh );
129: pad->menu(m);
130: banner();
131: }
132:
133: void Bpts::hostclose()
134: {
135: trace( "%d.hostclose()", this ); VOK;
136: lift();
137: delete pad;
138: pad = 0;
139: }
140:
141: Trap *Bpts::istrap(Stmt *s)
142: {
143: Trap *t;
144:
145: trace( "%d.istrap(%d)%s", this, s, s->text() ); OK(0);
146: IF_LIVE(!s || !s->range.lo) return 0;
147: for( t = trap; t; t = t->sib )
148: if( t->stmt && t->stmt->range.lo == s->range.lo ) return t;
149: return 0;
150: }
151:
152: int Bpts::isasmbpt(long pc)
153: {
154: Trap *t;
155:
156: trace( "%d.isasmbpt(%d)", this, pc ); OK(0);
157: for( t = trap; t; t = t->sib )
158: if( t->stmt && !t->stmt->parent && t->stmt->range.lo==pc ) return 1;
159: return 0;
160: }
161:
162:
163: void Bpts::set(Stmt *s)
164: {
165: Trap *t;
166:
167: trace( "%d.set(%d)%s", this, s, s->text() ); VOK;
168: IF_LIVE( !s || !s->range.lo ) return;
169: if( t = istrap(s) ){
170: if( s != t->stmt ) t->error = sf(" same location as %s", s->text());
171: select(t);
172: t->stmt->select();
173: } else {
174: t = trap = new Trap(s, trap);
175: if( layed ) t->liftorlay(LAY, core);
176: select(t);
177: s->select();
178: }
179: }
180:
181: void Bpts::clr(Stmt *s)
182: {
183: Trap *t;
184:
185: trace( "%d.clr(%d)%s", this, s, s->text() ); VOK;
186: IF_LIVE( !s || !s->range.lo ) return;
187: if( t = istrap(s) ){
188: if( layed ) t->liftorlay(LIFT, core);
189: t->stmt = 0;
190: select(t);
191: s->select(SVP);
192: } else
193: pad->error( "no breakpoint at %s", s->text() );
194: }
195:
196: int Bpts::isbpt(Stmt *s)
197: {
198: Trap *t;
199:
200: trace( "%d.isbpt(%d) %s", this, s, s->text() ); OK(0);
201: IF_LIVE(!s) return 0;
202: for( t = trap; t; t = t->sib )
203: if( t->stmt == s ) return 1;
204: return 0;
205: }
206:
207: Stmt *Bpts::bptstmt(long pc)
208: {
209: Trap *t;
210:
211: trace( "%d.bptstmt(%d)", this, pc ); OK(0);
212: IF_LIVE(!pc) return 0;
213: for( t = trap; t; t = t->sib )
214: if( t->stmt && t->stmt->range.lo == pc ) return t->stmt;
215: return 0;
216: }
217:
218: void Bpts::lay()
219: {
220: Trap *t;
221:
222: trace( "%d.lay()", this ); VOK;
223: Process *s = core->process()->slave();
224: if( s ) s->bpts()->lay();
225: if( layed ) return;
226: for( t = trap; t; t = t->sib )
227: if( t->liftorlay(LAY, core) ) select(t);
228: layed = 1;
229:
230: }
231:
232: void Bpts::lift()
233: {
234: Trap *t;
235:
236: trace( "%d.lift()", this ); VOK;
237: Process *s = core->process()->slave();
238: if( s ) s->bpts()->lift();
239: if( !layed ) return;
240: for( t = trap; t; t = t->sib )
241: if( t->liftorlay(LIFT, core) ) select(t);
242: layed = 0;
243: }
244:
245: void Bpts::liftparents(Bpts *parent_bpts)
246: {
247: Trap *savet;
248: int savel;
249:
250: trace( "%d.liftparents(%d)", this, parent_bpts ); VOK;
251: savet = trap;
252: savel = layed;
253: trap = parent_bpts->trap;
254: layed = 1;
255: lift();
256: trap = savet;
257: layed = savel;
258: }
259:
260: void Bpts::select(Trap *t)
261: {
262: Menu m;
263: Bls buf;
264: Attrib a = DONT_CUT;
265:
266: trace( "%d.select(%d)", this, t ); VOK;
267: IF_LIVE(!t) return;
268: if( t->stmt ){
269: buf.af( "%s", t->stmt->text() );
270: if( t->stmt->condition && t->stmt->condition!=Q_BPT ) /* ? */
271: buf.af( " if(%s)", t->stmt->condition->text() );
272: }
273: if( t->error ){
274: a |= SELECTLINE;
275: buf.af( "%s", t->error );
276: }
277: if( t->stmt ){
278: m.last( "clear bpt", (Action)&Stmt::dobpt, 0 );
279: if( t->stmt->source() )
280: m.last( "src text", (Action)&Stmt::select );
281: m.last( "assembler", (Action)&Stmt::asmblr );
282: }
283: t->error = 0;
284: if( !buf.text[0] ) /* messy */
285: pad->removeline(t->key);
286: else
287: pad->insert(t->key, a, (PadRcv*)t->stmt, m, buf.text );
288: }
289:
290: void Bpts::clearall()
291: {
292: Trap *t;
293:
294: trace( "%d.clearall()", this ); VOK;
295: for( t = trap; t; t = t->sib )
296: if( t->stmt ) clr(t->stmt);
297: trap = 0; /* leaves garbage */
298: }
299:
300: void Bpts::refresh()
301: {
302: Trap *t;
303:
304: pad->clear();
305: trace( "%d.refresh()", this ); VOK;
306: for( t = trap; t; t = t->sib )
307: if( t->stmt ) select(t);
308: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.