|
|
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.