Files
sibo-playground/code/SIBOSDK/hwdemo/dump.c
2026-07-06 18:01:36 +01:00

661 lines
14 KiB
C

/*
DUMP.C
Written by DavidW
Started on 27/11/91
*/
#include <p_std.h>
#include <p_file.h>
#include <wlib.h>
#include <hwif.h>
GLREF_D UWORD DatLocked;
GLREF_D TEXT *DatUsedPathNamePtr;
LOCAL_D TEXT *cmds[]=
{
"oOpen",
"wWrite",
"fFind text",
"bFind bytes",
"aFind again",
"gGoto",
"xExit",
NULL
};
#define FILE_ITEMS 2
#define FIND_ITEMS 3
#define SPECIAL_ITEMS 2
#define ITEMS_BEFORE_FILE 0
#define ITEMS_BEFORE_FIND FILE_ITEMS
#define ITEMS_BEFORE_SPECIAL (ITEMS_BEFORE_FIND+FIND_ITEMS)
LOCAL_D H_MENU_DATA mdata[]=
{
"File",FILE_ITEMS,
"Find",FIND_ITEMS,
"Special",SPECIAL_ITEMS,
NULL
};
GLDEF_D TEXT ** _cmds=(&cmds[0]);
GLDEF_D H_MENU_DATA * _mdata=(&mdata[0]);
LOCAL_D TEXT filename[P_FNAMESIZE+2];
LOCAL_D VOID *fcb;
LOCAL_D LONG lpos;
LOCAL_D LONG last;
LOCAL_D UWORD DisplayPending;
LOCAL_D VOID *wfcb;
LOCAL_D TEXT findt[14]={0};
LOCAL_D UWORD caset=1;
LOCAL_D TEXT findb[14]={0};
LOCAL_D TEXT *pfind;
LOCAL_D UWORD casef;
LOCAL_D LONG fpos=(-1);
LOCAL_C VOID Check(INT val)
{
TEXT buf[64];
if (val<0)
{
wCancelBusyMsg();
uForceToFront();
DatLocked=TRUE;
p_errs(&buf[0],val);
wsAlertW(WS_ALERT_CLIENT,&buf[0],"Terminating application",0);
p_exit(0);
}
}
LOCAL_C VOID DoSeek(INT sense,LONG *ppos)
{
Check(p_seek(fcb,sense,ppos));
}
LOCAL_C INT WriteLine(INT ignore,TEXT *pb)
{
return(p_write(wfcb,pb,38));
}
LOCAL_C INT PrintLine(INT lineno,TEXT *pb)
{
P_RECT box;
box.tl.x=6;
box.tl.y=4+9*lineno;
box.br.x=234;
box.br.y=box.tl.y+9;
gPrintBoxText(&box,8,G_TEXT_ALIGN_LEFT,0,pb,38);
return(0);
}
LOCAL_C VOID Output(INT len,INT nlines,INT DoLine(INT,TEXT *))
{
TEXT inbuf[64];
TEXT outbuf[38];
INT i;
LONG loclpos;
INT linelen;
TEXT *pin;
TEXT *pout1;
TEXT *pout2;
INT val;
Check(p_read(fcb,&inbuf[0],len));
pin=(&inbuf[0]);
loclpos=lpos;
for (i=0; i<nlines; i++)
{
p_atos(&outbuf[0],"%05lx",loclpos);
loclpos+=8;
linelen=(len<8? len: 8);
len-=linelen;
pout1=(&outbuf[5]);
pout2=(&outbuf[30]);
p_bfil(pout1,33,32);
while (linelen--)
{
val=(*pin++);
p_atos(pout1," %02x",val);
pout1+=3;
*pout2++=(val<32? 8: val);
}
*pout1=32;
if (DoLine(i,&outbuf[0]))
break;
}
}
LOCAL_C VOID Display(VOID)
{
LONG ldiff;
DoSeek(P_FABS,&lpos);
ldiff=last-lpos;
Output((ldiff<64? (INT)ldiff: 64),8,PrintLine);
DisplayPending=FALSE;
}
LOCAL_C VOID ResetDisplay(VOID)
{
last=0;
DoSeek(P_FEND,&last);
lpos=0;
Display();
}
LOCAL_C INT TryOpenFile(TEXT *pb,VOID **newfcb)
{
return(uErrorValue(p_open(newfcb,pb,P_FOPEN|P_FRANDOM)));
}
LOCAL_C VOID ChangeOverTo(TEXT *newname,VOID *newfcb)
{
p_close(fcb);
fcb=newfcb;
p_scpy(&filename[0],newname);
hSetUpStatusNames(&filename[0]);
wsUpdate(WS_UPDATE_NAME);
ResetDisplay();
}
LOCAL_C VOID SetupFilename(TEXT *pb)
{
p_bcpy(pb+1,DatUsedPathNamePtr,*pb=p_slen(DatUsedPathNamePtr));
}
LOCAL_C VOID OpenFile(VOID)
{
H_DI_FSEL open;
TEXT openbuf[P_FNAMESIZE+2];
VOID *newfcb;
SetupFilename(&openbuf[0]);
do
{
if (uOpenDialog("Dump"))
return;
open.flags=H_FILE_PICK_SELECTOR;
open.fname=(&openbuf[0]);
if (uAddDialogItem(H_DIALOG_FSEL,"File:",&open))
return;
if (uRunDialog()<=0)
return;
openbuf[1+openbuf[0]]=0;
} while (TryOpenFile(&openbuf[1],&newfcb));
ChangeOverTo(&openbuf[1],newfcb);
}
LOCAL_C VOID WriteFile(VOID)
{
H_DI_FSEL write;
TEXT writebuf[P_FNAMESIZE+2];
LONG beg;
LONG end;
LONG diff;
H_DI_NUMBER numbeg;
H_DI_NUMBER numend;
INT len;
INT stop;
if (uErrorValue(p_fparse(".dmp",DatUsedPathNamePtr,&writebuf[1],NULL)))
return;
writebuf[0]=p_slen(&writebuf[1]);
write.fname=(&writebuf[0]);
write.flags=H_FILE_NEW_EDITOR;
beg=0;
end=last;
numbeg.value=(&beg);
numbeg.low=0;
numbeg.high=last;
numend.value=(&end);
numend.low=0;
numend.high=last;
FOREVER
{
if (uOpenDialog("Write dump to file"))
return;
if (uAddDialogItem(H_DIALOG_FSEL,"File:",&write))
return;
if (uAddDialogItem(H_DIALOG_NUMBER,"From offset",&numbeg))
return;
if (uAddDialogItem(H_DIALOG_NUMBER,"To offset",&numend))
return;
if (uRunDialog()<=0)
return;
diff=end-beg;
if (diff<=0)
{
wInfoMsg("`To' offset must exceed `From' offset");
continue;
}
writebuf[1+writebuf[0]]=0;
if (!uErrorValue(p_open(&wfcb,
&writebuf[1],P_FTEXT|P_FREPLACE|P_FUPDATE)))
break;
}
DoSeek(P_FABS,&beg);
stop=FALSE;
FOREVER
{
if (diff>64)
len=64;
else
{
len=(INT)diff;
stop=TRUE;
}
Output(len,len/8,WriteLine);
if (stop)
break;
diff-=64;
}
p_close(wfcb);
wInfoMsg("Dump written to file");
}
LOCAL_C VOID GotoLpos(VOID)
{
H_DI_NUMBER num;
if (last<=64)
{
wInfoMsg("Whole file is already visible");
return;
}
if (uOpenDialog(NULL))
return;
num.value=(&lpos);
num.low=0;
num.high=last-64;
if (uAddDialogItem(H_DIALOG_NUMBER,"Goto",&num))
return;
if (uRunDialog()<=0)
return;
Display();
}
LOCAL_C VOID HighlightBlock(INT x,INT y)
{
P_RECT box;
box.tl.y=4+9*y;
box.br.y=box.tl.y+9;
if (&findb[0]==pfind)
{
box.tl.x=41+18*x;
box.br.x=box.tl.x+13;
}
else
{
box.tl.x=185+6*x;
box.br.x=box.tl.x+7;
}
gClrRect(&box,G_TRMODE_INV);
wFlush();
p_sleep(10);
gClrRect(&box,G_TRMODE_INV);
}
LOCAL_C VOID HighlightFpos(VOID)
{
INT offset;
if (fpos<lpos)
lpos=fpos;
else if (fpos>lpos+63)
{
lpos=fpos;
if (lpos>last-64)
lpos=last-64;
}
Display();
offset=(INT)(fpos-lpos);
HighlightBlock(offset%8,offset/8);
}
LOCAL_C INT DoSearch(LONG *ptot)
{
TEXT buf[256];
INT toread;
TEXT *pb;
INT j;
INT offset;
INT len;
DoSeek(P_FABS,ptot);
toread=256;
pb=(&buf[0]);
offset=0;
wSetBusyMsg("Searching",W_CORNER_BOTTOM_LEFT|2);
FOREVER
{
len=p_read(fcb,pb,toread);
if (len==E_FILE_EOF)
break;
Check(len);
if (casef==2)
j=p_bsub(&buf[0],len+offset,pfind+1,*pfind);
else
j=p_bsubi(&buf[0],len+offset,pfind+1,*pfind);
if (j>=0)
{
fpos=(*ptot)+j;
wCancelBusyMsg();
HighlightFpos();
return(0);
}
if (len<toread)
break;
*ptot+=toread+offset-12;
pb=(TEXT *)p_bcpy(&buf[0],&buf[256-12],12);
offset=12;
toread=256-12;
}
wCancelBusyMsg();
return(-1);
}
LOCAL_C VOID SearchAll(VOID)
{
LONG tot;
tot=0;
if (DoSearch(&tot))
{
wInfoMsg("Not found");
fpos=(-1);
}
}
LOCAL_C VOID FindText(VOID)
{
H_DI_EDIT ed;
if (uOpenDialog("Find"))
return;
ed.str=(&findt[0]);
ed.len=12;
if (uAddDialogItem(H_DIALOG_EDIT,"Text",&ed))
return;
if (uAddChoiceList("Case sensitive",&caset,"No","Yes",NULL))
return;
if (uRunDialog()<=0)
return;
pfind=(&findt[0]);
casef=caset;
SearchAll();
}
LOCAL_C VOID LoadBytes(TEXT *pout)
{
INT len;
TEXT *pin;
len=findb[0];
*pout++=len*2;
pin=(&findb[1]);
while (len--)
{
p_atos(pout,"%02x",*pin++);
pout+=2;
}
}
LOCAL_C INT RecoverBytes(TEXT *pin)
{
TEXT buf[30];
INT len;
TEXT *pout;
TEXT *newpin;
UBYTE tmp;
if (p_bloc(pin+1,*pin,32)>=0)
{
wInfoMsg("Don't type any spaces");
return(-1);
}
if (*pin&1)
{
wInfoMsg("Type bytes as two characters each");
return(-1);
}
len=buf[0]=(*pin++)/2;
pout=(&buf[1]);
while (len--)
{
newpin=pin+2;
tmp=(*newpin);
*newpin=0;
if (p_stog(&pin,(UWORD *)pout,16) || pin!=newpin)
{
p_atos(&buf[0],"Conversion failure at %s",newpin-2);
wInfoMsg(&buf[0]);
*newpin=tmp;
return(-1);
}
*newpin=tmp;
pout++;
}
p_bcpy(&findb[0],&buf[0],buf[0]+1);
return(0);
}
LOCAL_C VOID FindBytes(VOID)
{
TEXT bytes[26];
H_DI_EDIT ed;
LoadBytes(&bytes[0]);
ed.str=(&bytes[0]);
ed.len=24;
do
{
if (uOpenDialog("Find"))
return;
if (uAddDialogItem(H_DIALOG_EDIT,"Bytes",&ed))
return;
if (uRunDialog()<=0)
return;
} while (RecoverBytes(&bytes[0]));
pfind=(&findb[0]);
casef=2;
SearchAll();
}
LOCAL_C VOID FindAgain(VOID)
{
LONG tot;
if (fpos<0)
{
wInfoMsg("Nothing to find again");
return;
}
tot=fpos+1;
if (tot==last || DoSearch(&tot))
wInfoMsg("No more found");
}
LOCAL_C VOID ManageCommand(INT index)
{
switch (index)
{
case ITEMS_BEFORE_FILE:
OpenFile();
break;
case ITEMS_BEFORE_FILE+1:
WriteFile();
break;
case ITEMS_BEFORE_FIND:
FindText();
break;
case ITEMS_BEFORE_FIND+1:
FindBytes();
break;
case ITEMS_BEFORE_FIND+2:
FindAgain();
break;
case ITEMS_BEFORE_SPECIAL:
GotoLpos();
break;
case ITEMS_BEFORE_SPECIAL+1:
p_exit(0);
}
}
LOCAL_C VOID MoveToTop(VOID)
{
lpos=0;
DisplayPending=TRUE;
}
LOCAL_C VOID CheckAndDisplay(VOID)
{
if (lpos<0)
lpos=0;
DisplayPending=TRUE;
}
LOCAL_C VOID MoveToBottom(VOID)
{
lpos=last-64;
CheckAndDisplay();
}
LOCAL_C VOID MoveBy(INT delta)
{
lpos+=delta;
if (lpos>last-64)
lpos=last-64;
CheckAndDisplay();
}
LOCAL_C VOID EnsureDisplay(VOID)
{
if (DisplayPending)
Display();
}
LOCAL_C VOID TryExecuteCommand(INT keycode)
{
keycode=uLocateCommand(keycode);
if (keycode>=0)
ManageCommand(keycode);
}
LOCAL_C VOID MainLoop(VOID)
{
INT ret;
WMSG_KEY key;
FOREVER
{
uGetKey(&key);
if (key.keycode&W_EVENT_KEY)
{
if (key.keycode==CONS_EVENT_COMMAND)
p_exit(0);
}
else if (key.keycode&W_SPECIAL_KEY)
{
EnsureDisplay();
TryExecuteCommand(key.keycode&(~W_SPECIAL_KEY));
}
else
{
switch (key.keycode)
{
case W_KEY_MENU:
if (!(key.modifiers&W_CTRL_MODIFIER))
{
EnsureDisplay();
ret=uPresentMenus();
if (ret>0)
TryExecuteCommand(ret);
}
break;
case W_KEY_LEFT:
MoveBy(-1);
break;
case W_KEY_RIGHT:
MoveBy(1);
break;
case W_KEY_UP:
if (key.modifiers&W_CTRL_MODIFIER)
MoveToTop();
else
MoveBy(-8);
break;
case W_KEY_DOWN:
if (key.modifiers&W_CTRL_MODIFIER)
MoveToBottom();
else
MoveBy(8);
break;
case W_KEY_HOME:
MoveBy(-4);
break;
case W_KEY_END:
MoveBy(4);
break;
case W_KEY_PAGE_UP:
if (key.modifiers&W_CTRL_MODIFIER)
MoveToTop();
else
MoveBy(-56);
break;
case W_KEY_PAGE_DOWN:
if (key.modifiers&W_CTRL_MODIFIER)
MoveToBottom();
else
MoveBy(56);
break;
}
}
if (DisplayPending && !uKeyPressOutstanding())
Display();
}
}
LOCAL_C VOID CreateGC(VOID)
{
INT hgc;
G_GC gc;
gc.style=G_STY_MONO;
hgc=gCreateGC(uFindMainWid(),G_GC_MASK_STYLE,&gc);
if (hgc<0)
p_exit(hgc);
}
LOCAL_C VOID SpecificInit(VOID)
{
CreateGC();
gBorder(W_BORD_CORNER_4);
hCrackCommandLine();
if (TryOpenFile(DatUsedPathNamePtr,&fcb))
p_exit(0);
ResetDisplay();
}
GLDEF_C VOID main(VOID)
{
uCommonInit();
SpecificInit();
MainLoop();
}