Files
TempleOS-Rijn/LT/Utils/IDE.APZ
T
2018-09-08 21:45:20 +02:00

364 lines
8.2 KiB
Plaintext

#help_index "Debugging"
ClassStruct *DbgFindFun(Ltf *l,I8 line_offset=0)
{
I1 st[256],*filename=l->filename.name;
I8 line=l->cur_entry->y+1+line_offset;
U8 i;
SysHashEntry *temph;
SysHashTable *h=Fs->hash_table;
ClassStruct *tempc;
DbgInfo *tempd;
while (h) {
for (i=0;i<=h->mask;i++) {
temph=h->body[i];
while (temph) {
if (temph->type&HTT_FUNCTION) {
tempc=temph;
if (tempd=tempc->debug) {
StrCpy(st,tempc->source_link);
RemoveFirstSeg(st,":");
RemoveLastSeg(st,",");
if (!StrCmp(st,filename)) {
if (line>=tempd->min_line && line<=tempd->max_line)
return tempc;
}
}
}
temph=temph->next;
}
}
h=h->next;
}
return NULL;
}
void WatchLocals()
{
BoolU4 old_preempt=Preempt(OFF);
TssStruct *tss=Fs->parent_tss,*dbg_tss=tss->dbg_tss;
Ltf *swap,*l;
ClassStruct *tempc,*tempc1;
U8 j,sc,ch;
void **rbp,**ptr;
I8 offset,ip;
Fs->double_buf_cur_ltf=LtfNew;
while (TRUE) {
if (!(dbg_tss=tss->dbg_tss))
Exit;
if (ScanKey(&ch,&sc,TRUE)) {
j=Jiffies+JIFFY_FREQ*5;
LtfDel(Fs->double_buf_cur_ltf);
Fs->double_buf_cur_ltf=NULL;
do {
if (ch==CH_CTRLQ || ch==CH_ESC)
Exit;
if (ScanKey(&ch,&sc,TRUE))
j=Jiffies+JIFFY_FREQ*5;
WinSync;
} while (Jiffies<j);
Fs->double_buf_cur_ltf=LtfNew;
} else {
LtfDel(Fs->cur_ltf);
Fs->cur_ltf=LtfNew;
if (l=dbg_tss->cur_ltf) {
if (tempc=DbgFindFun(l,0)) {
PutS("$$WW,1$$");
rbp=tss->rbp;
ip=tss->rip;
do {
tempc1=FindPSect(ip,&offset);
break; //TODO: load reg variables for higher level subroutines
if (tempc==tempc1)
break;
else {
if (rbp>=*rbp)
break;
ptr=rbp+8;
rbp=*rbp;
ip=*ptr;
if (!CheckOnStk(rbp,tss))
break;
}
} while (TRUE);
if (tempc==tempc1)
FunRep(tempc->str,rbp,2,tss);
}
}
swap=Fs->double_buf_cur_ltf;
Fs->double_buf_cur_ltf=Fs->cur_ltf;
Fs->cur_ltf=swap;
WinSync;
}
}
LtfDel(Fs->double_buf_cur_ltf);
Fs->double_buf_cur_ltf=NULL;
Preempt(old_preempt);
}
public void IDE(I1 *filename)
//Spawns a child process which has
//access to parents symbols. Can be used
//to debug parent.
{
TssStruct *tss;
I1 *fn1=DefaultExtension(filename,"CPZ"),
*fn2=AbsoluteFileName(fn1);
if (PopUpCancelOk("$$BK,1$$$$FG,RED$$LoseThos IDE Debugger$$FG$$$$BK,0$$\r\n"
"Do not use this on files that run when included.\r\n"
"\r\nTo use:\r\n"
" 1) Set a break-point in the editor window.\r\n"
" 2) Run program from command line.\r\n\r\n"
"$$FG,GREEN$$F5$$FG$$\t\tGo\r\n"
"$$FG,GREEN$$SHIFT-F5$$FG$$\tStep\r\n"
"$$FG,GREEN$$F9$$FG$$\t\tToggle Break Point\r\n"
"$$FG,GREEN$$SHIFT-F9$$FG$$\tClear All Break Points\r\n"
)) {
if (!Fs->dbg_tss) {
Fs->win_top=2;
Fs->win_bottom=TEXT_ROWS-2;
Fs->win_left=1;
Fs->win_right=TEXT_COLS>>1-1;
tss=Spawn(&UserCmdLine,"Debug Task",Fs);
WaitTskIdle(tss);
tss->win_top=12;
tss->win_bottom=TEXT_ROWS-2;
tss->win_left=TEXT_COLS>>1+1;
tss->win_right=TEXT_COLS-2;
XTalk(tss,"Edit(\"%s\");\r",fn2);
Fs->dbg_tss=tss;
tss=Spawn(&UserCmdLine,"Watch Task",Fs);
WaitTskIdle(tss);
tss->win_top=2;
tss->win_bottom=10;
tss->win_left=TEXT_COLS>>1+1;
tss->win_right=TEXT_COLS-2;
XTalk(tss,"WatchLocals;\r");
ExecuteFile(fn2);
}
Free(fn1);
Free(fn2);
}
}
#help_index "Debugging/Breakpoints"
I8 IDELineAdd(DbgInfo *tempd,I8 line)
{
I8 max=tempd->max_line-tempd->min_line;
line-=tempd->min_line;
if (line<0)
return IDELineAdd(tempd,tempd->min_line);
while (!tempd->body[line] && line<max)
line++;
return tempd->body[line];
}
I8 IDERIPLineNum(Ltf *l,void *rip)
{
I1 st[256],*filename=l->filename.name;
I8 line;
SysHashEntry *temph;
SysHashTable *h=Fs->hash_table;
ClassStruct *tempc;
I8 i;
DbgInfo *tempd;
while (h) {
for (i=0;i<=h->mask;i++) {
temph=h->body[i];
while (temph) {
if (temph->type&HTT_FUNCTION) {
tempc=temph;
if (tempd=tempc->debug) {
StrCpy(st,tempc->source_link);
RemoveFirstSeg(st,":");
RemoveLastSeg(st,",");
if (!StrCmp(st,filename)) {
for (line=tempd->min_line;line<=tempd->max_line;line++)
if (rip>=IDELineAdd(tempd,line) &&
rip<IDELineAdd(tempd,line+1))
return line;
}
}
}
temph=temph->next;
}
}
h=h->next;
}
return -1;
}
void IDESetStepRange(Ltf *l)
{
I1 st[256],*filename=l->filename.name;
I8 line=l->cur_entry->y+1;
SysHashEntry *temph;
SysHashTable *h=Fs->hash_table;
ClassStruct *tempc;
I8 i;
DbgInfo *tempd;
while (h) {
for (i=0;i<=h->mask;i++) {
temph=h->body[i];
while (temph) {
if (temph->type&HTT_FUNCTION) {
tempc=temph;
if (tempd=tempc->debug) {
StrCpy(st,tempc->source_link);
RemoveFirstSeg(st,":");
RemoveLastSeg(st,",");
if (!StrCmp(st,filename)) {
if (line>=tempd->min_line && line<=tempd->max_line) {
Fs->user_data0=IDELineAdd(tempd,line);
Fs->user_data1=IDELineAdd(tempd,line+1);
return;
}
}
}
}
temph=temph->next;
}
}
h=h->next;
}
}
void IDEToggleBpt(Ltf *l)
{ //F9
I1 st[256],*filename=l->filename.name;
I8 line=l->cur_entry->y+1;
SysHashEntry *temph;
SysHashTable *h=Fs->hash_table;
ClassStruct *tempc;
I8 i,a;
DbgInfo *tempd;
LtfEntry *ll;
while (h) {
for (i=0;i<=h->mask;i++) {
temph=h->body[i];
while (temph) {
if (temph->type&HTT_FUNCTION) {
tempc=temph;
if (tempd=tempc->debug) {
StrCpy(st,tempc->source_link);
RemoveFirstSeg(st,":");
RemoveLastSeg(st,",");
if (!StrCmp(st,filename)) {
if (line>=tempd->min_line && line<=tempd->max_line) {
a=IDELineAdd(tempd,line);
ll=l->cur_entry;
while (ll->last->btype!=LTFT_CR &&
ll->last->btype!=LTFT_SOFT_CR &&
ll->last!=l)
ll=ll->last;
l->cur_entry=ll;
l->cur_data_col=ll->min_col;
if (!RBpt(Fs->parent_tss,a)) {
SBpt(Fs->parent_tss,a,SBPTF_BPT);
Auto("$$BP$$");
} else {
if (ll->btype==LTFT_BPT) {
l->cur_entry=ll->next;
l->cur_data_col=l->cur_entry->min_col;
LtfDelEntry(l,ll);
}
}
LtfGotoLineNum(l,line);
return;
}
}
}
}
temph=temph->next;
}
}
h=h->next;
}
}
void IDEClearAllBpts(Ltf *l)
{ //SHIFT-F9
LtfEntry *ll,*ll2;
CBpt(Fs->parent_tss);
ll=l->dummy.next;
while (ll!=l) {
ll2=ll->next;
if (ll->btype==LTFT_BPT) {
if (l->cur_entry==ll) {
l->cur_entry=ll->next;
l->cur_data_col=l->cur_entry->min_col;
}
LtfDelEntry(l,ll);
}
ll=ll2;
}
}
void IDEGo() //Continue after breakpoint
{ //F5
TssStruct *tss=Fs->parent_tss;
void *rip=&tss->rip;
if (!Btr(&tss->task_flags,TSSf_DISABLE_BPTS)) {
*rip-=1;
if (!DBpt(tss,*rip))
*rip+=1;
}
Fs->user_data0=0;
Fs->user_data1=0;
Btr(&tss->rflags,8);
Btr(&tss->task_flags,TSSf_SUSPENDED);
}
void IDEStep(Ltf *l) //Single step
{ //SHIFT-F5
TssStruct *tss=Fs->parent_tss;
void *rip=&tss->rip;
I8 line=IDERIPLineNum(l,*rip);
if (!Bts(&tss->task_flags,TSSf_DISABLE_BPTS)) {
*rip-=1;
if (!DBpt(tss,*rip))
*rip+=1;
}
if (line>0) {
LtfGotoLineNum(l,line);
IDESetStepRange(l);
} else {
Fs->user_data0=0;
Fs->user_data1=0;
}
Bts(&tss->rflags,8);
Btr(&tss->task_flags,TSSf_SUSPENDED);
}
void IDESetLineNum(Ltf *l)
{ //SHIFT-F8
TssStruct *tss=Fs->parent_tss;
I8 line=IDERIPLineNum(l,tss->rip);
if (line>0)
LtfGotoLineNum(l,line);
}
void IDEResumeDbg()
{
TssStruct *dbg=Fs->dbg_tss;
I8 u0=dbg->user_data0,u1=dbg->user_data1;
if (!u0 || (Fs->rip<u0 || Fs->rip>u1) ||
Fs->rip==u1 && u1!=u0) {
WinToTop(dbg);
QueueMsg(dbg,NULL,MSG_KEY_DOWN,0,SCF_SHIFT+SC_F8,0);
} else
Btr(&Fs->task_flags,TSSf_SUSPENDED);
}
ext[EXT_RESUME_DBG]=&IDEResumeDbg;
#help_index ""