File:  [Research Unix] / researchv9 / jtools / src / pi / bpts.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs
Tue Apr 24 17:21:59 2018 UTC (8 years, 1 month ago) by root
Branches: belllabs, MAIN
CVS tags: researchv9-SUN3_old, researchv9-SUN3, HEAD
researchv9-SUN3(old)

#include "univ.h"
#include "core.pub"
#include "bpts.pri"
#include "symbol.h"
#include "expr.pub"
#include "format.pub"
#include "process.pub"
#include "symtab.pub"
#include "parse.h"
SRCFILE("bpts.c")

char *BptReq::setline(Process *p)
{
	trace("%d.set(%d)", this, p); OK("BptReq::setline");
	for( Source *s = p->symtab()->root(); s; s = (Source*)s->rsib )
		if( !strcmp(s->text(), file)
		 || !strcmp(basename(s->text()), file) )
			break;
	if( !s )
		return sf("source file not found: %s", file);
	Stmt *stmt = s->stmtafter(line);
	if( !stmt )
		return sf("statement not found: line %d", line);
	if( p->bpts()->isbpt(stmt) )
		return sf("may not set bpt more than once: %s:%d", file, line);
	stmt->conditional(expr);
	stmt->dobpt(1);
	return 0;
}

char *BptReq::setfunc(Process *p)
{
	trace("%d.setfunc(%d)", this, p); OK("BptReq::setfunc");
	SymTab *symtab = p->symtab();
	if( !symtab ) return "symbol table error";
	Func *f = (Func*)p->symtab()->idtosym(U_FUNC, func);
	if( !f || !f->source() )
		return sf("source function not found: %s", func);
	file = f->source()->text();
	if( be & BEGIN ){
		line = f->lines.lo;
		setline(p);
	}
	if( be & END ){
		line = f->lines.hi;
		setline(p);
	}
}

char *BptReq::set(Process *p)
{
	trace("%d.set(%d)", this, p); OK("BptReq::set");
	if( error) return error;
	if( file ) return setline(p);
	else if( func ) return setfunc(p);
	else return "BptReq::set";
}

void BptReq::parse(char *e)
{
	Parse y(G_EXPR);
	error = 0;
	expr = 0;
	if( e ){
		expr = (Expr*) y.parse(e);
		if( !expr )
			error = y.error;
	}
}

BptReq::BptReq(char *f, char *curly, char *e)
{
	file = 0;
	func = f;
	for( be = 0; *curly; ++curly ) switch(*curly){
		case '{': be |= BEGIN; break;
		case '}': be |= END;   break;
	}
	parse(e);
}

BptReq::BptReq(char *f, long l, char *e)
{
	file = f;
	func = 0;
	line = l;
	parse(e);
}

Trap::Trap(Stmt *s, Trap *t)
{
	static long uniq = 0;
	trace( "%d.Trap( %d, %d, %d )", this, s, t );	VOK;
	key = ++uniq;		// won't catch up with trace
	stmt = s;
	sib = t;
}

char *Trap::liftorlay(LiftLay lol, Core *core)
{
	trace( "%d.liftorlay(%d)", this, lol ); OK("Trap::liftorlay");
	if( !stmt ) return 0;
	if( error = lol==LIFT ? core->liftbpt(this) : core->laybpt(this) ){
		Stmt *s = stmt;
		stmt = 0;
		s->select();
	}
	return error;
}

void Bpts::banner()
{
	trace( "%d.banner()", this ); 	VOK;
	if( pad ){
		pad->banner("Breakpoint List: %s", core->procpath());
		pad->name("BptList %s", basename(core->procpath()));
	}
}

Bpts::Bpts(Core *c)
{
	Menu m;

	trace( "%d.Bpts(%d)", this, c ); 	VOK;
	core = c;
	pad = new Pad( (PadRcv*) this );
	m.last( "clear all?", (Action) &Bpts::clearall );
	m.last( "clean list", (Action) &Bpts::refresh );
	pad->menu(m);
	banner();
}

void Bpts::hostclose()
{
	trace( "%d.hostclose()", this ); 	VOK;
	lift();
	delete pad;
	pad = 0;
}

Trap *Bpts::istrap(Stmt *s)
{
	Trap *t;

	trace( "%d.istrap(%d)%s", this, s, s->text() );	OK(0);
	IF_LIVE(!s || !s->range.lo) return 0;
	for( t = trap; t; t = t->sib )
		if( t->stmt && t->stmt->range.lo == s->range.lo ) return t;
	return 0;
}

int Bpts::isasmbpt(long pc)
{
	Trap *t;

	trace( "%d.isasmbpt(%d)", this, pc );	OK(0);
	for( t = trap; t; t = t->sib )
		if( t->stmt && !t->stmt->parent && t->stmt->range.lo==pc ) return 1;
	return 0;
}
	

void Bpts::set(Stmt *s)
{
	Trap *t;

	trace( "%d.set(%d)%s", this, s, s->text() );	VOK;
	IF_LIVE( !s || !s->range.lo ) return;
	if( t = istrap(s) ){
		if( s != t->stmt ) t->error = sf(" same location as %s", s->text());
		select(t);
		t->stmt->select();
	} else {
		t = trap = new Trap(s, trap);
		if( layed ) t->liftorlay(LAY, core);
		select(t);
		s->select();
	}
}

void Bpts::clr(Stmt *s)
{
	Trap *t;

	trace( "%d.clr(%d)%s", this, s, s->text() );	VOK;
	IF_LIVE( !s || !s->range.lo ) return;
	if( t = istrap(s) ){
		if( layed ) t->liftorlay(LIFT, core);
		t->stmt = 0;
		select(t);
		s->select(SVP);
	} else
		pad->error( "no breakpoint at %s", s->text() );
}

int Bpts::isbpt(Stmt *s)
{
	Trap *t;

	trace( "%d.isbpt(%d) %s", this, s, s->text() );	OK(0);
	IF_LIVE(!s) return 0;
	for( t = trap; t; t = t->sib )
		if( t->stmt == s ) return 1;
	return 0;
}

Stmt *Bpts::bptstmt(long pc)
{
	Trap *t;

	trace( "%d.bptstmt(%d)", this, pc );	OK(0);
	IF_LIVE(!pc) return 0;
	for( t = trap; t; t = t->sib )
		if( t->stmt && t->stmt->range.lo == pc ) return t->stmt;
	return 0;
}

void Bpts::lay()
{
	Trap *t;

	trace( "%d.lay()", this );	VOK;
	Process *s = core->process()->slave();
	if( s ) s->bpts()->lay();
	if( layed ) return;
	for( t = trap; t; t = t->sib )
		if( t->liftorlay(LAY, core) ) select(t);
	layed = 1;
	
}

void Bpts::lift()
{
	Trap *t;

	trace( "%d.lift()", this );	VOK;
	Process *s = core->process()->slave();
	if( s ) s->bpts()->lift();
	if( !layed ) return;
	for( t = trap; t; t = t->sib )
		if( t->liftorlay(LIFT, core) ) select(t);
	layed = 0;
}

void Bpts::liftparents(Bpts *parent_bpts)
{
	Trap *savet;
	int savel;

	trace( "%d.liftparents(%d)", this, parent_bpts ); VOK;
	savet = trap;
	savel = layed;
	trap = parent_bpts->trap;
	layed = 1;
	lift();
	trap = savet;
	layed = savel;
}

void Bpts::select(Trap *t)
{
	Menu m;
	Bls buf;
	Attrib a = DONT_CUT;

	trace( "%d.select(%d)", this, t );	VOK;
	IF_LIVE(!t) return;
	if( t->stmt ){
		buf.af( "%s", t->stmt->text() );
		if( t->stmt->condition && t->stmt->condition!=Q_BPT )	/* ? */
			buf.af( " if(%s)", t->stmt->condition->text() );
	}
	if( t->error ){
		a |= SELECTLINE;
		buf.af( "%s", t->error );
	}
	if( t->stmt ){
		m.last( "clear bpt", (Action)&Stmt::dobpt, 0 );
		if( t->stmt->source() )
			m.last( "src  text", (Action)&Stmt::select );
		m.last( "assembler", (Action)&Stmt::asmblr );
	}
	t->error = 0;
	if( !buf.text[0] )		/* messy */
		pad->removeline(t->key);
	else
		pad->insert(t->key, a, (PadRcv*)t->stmt, m, buf.text );
}

void Bpts::clearall()
{
	Trap *t;

	trace( "%d.clearall()", this );	VOK;
	for( t = trap; t; t = t->sib )
		if( t->stmt ) clr(t->stmt);
	trap = 0; 				/* leaves garbage */
}

void Bpts::refresh()
{
	Trap *t;

	pad->clear();
	trace( "%d.refresh()", this );	VOK;
	for( t = trap; t; t = t->sib )
		if( t->stmt ) select(t);
}

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.