templeos-info/public/Wb/Adam/DolDoc/DocCodeTools.HC

659 lines
15 KiB
HolyC
Raw Normal View History

2024-03-16 10:26:19 +00:00
#help_index "DolDoc/Misc"
U0 EdReplaceTroubleOne(CDoc *doc,U8 *st_original,U8 *st_safe,I64 num,
Bool to_safe,Bool sel)
{
U8 buf[STR_LEN];
StrPrint(buf,st_safe,num);
if (to_safe)
EdReplace(doc,st_original,buf,sel);
else
EdReplace(doc,buf,st_original,sel);
}
U0 EdReplaceTroubleAll(CDoc *doc,Bool to_safe,Bool sel)
{
I64 i=0;
EdReplaceTroubleOne(doc,"#assert" ,"//<@%d@>" ,i++,to_safe,sel);
EdReplaceTroubleOne(doc,"#define" ,"//<@%d@>" ,i++,to_safe,sel);
EdReplaceTroubleOne(doc,"#include","//<@%d@>" ,i++,to_safe,sel);
//#if will match #if,#ifdef,#ifndef,#ifaot and #ifjit
EdReplaceTroubleOne(doc,"#if" ,"//<@%d@>" ,i++,to_safe,sel);
EdReplaceTroubleOne(doc,"#endif" ,"//<@%d@>" ,i++,to_safe,sel);
//Convert #exe to union because we want that indent pattern.
EdReplaceTroubleOne(doc,"#exe" ,"union@%d@",i++,to_safe,sel);
EdReplaceTroubleOne(doc,"'{'" ,"'<@%d@>'" ,i++,to_safe,sel);
EdReplaceTroubleOne(doc,"'}'" ,"'<@%d@>'" ,i++,to_safe,sel);
}
#define C_INDENT_SPACES 2
#define ASM_RENUM_SPACING 5
#define EF_REINDENT 0
#define EF_CMP_CHK 1
#define EF_RENUM_ASM 2
#define EF_CTRL_SLIDER 3
#define EF_CH_SC 4
I64 PopUpEdFmt()
{
I64 i;
CDoc *doc=DocNew;
DocPrint(doc,"$$LTBLUE$$$$MU,\"Compile Check\",LE=EF_CMP_CHK$$\n"
"$$MU,\"Reindent HolyC Fun (Beware braces in strings.)\","
"LE=EF_REINDENT$$\n"
"$$MU,\"Renum Asm Local @@ Labels for Fun\",LE=EF_RENUM_ASM$$\n"
"$$MU,\"Insert Template Code: Ctrl Slider\",LE=EF_CTRL_SLIDER$$\n"
"$$MU,\"Insert ASCII/Scan Code Hex Codes for key pressed\","
"LE=EF_CH_SC$$\n\n"
"$$MU,\"CANCEL\",LE=DOCM_CANCEL$$\n\n"
"$$GREEN$$<ALT-BACKSPACE>$$FG$$ to undo if not happy\n"
"with the ress.\n");
i=PopUpMenu(doc);
DocDel(doc);
return i;
}
class CRILex
{
CCmpCtrl *cc1,*cc2;
CQueVectU8 *indent;
I64 depth,exp_depth,one_shot;
Bool was_new_line,is_not_cont;
};
I64 EdRILex(CRILex *rx)
{
rx->is_not_cont=FALSE;
I64 i;
CLexFile *tmpf;
do {
Lex(rx->cc1);
Lex(rx->cc2);
i=PrsKeyWord(rx->cc2);
if (rx->cc1->token=='\n' && rx->cc2->token==';' || rx->cc2->token=='{' ||
rx->cc2->token=='}' || rx->cc2->token==':' || rx->cc2->token==')' &&
!rx->exp_depth || i==KW_ELSE || i==KW_CATCH || i==KW_DO)
rx->is_not_cont=TRUE;
if (rx->was_new_line && (rx->cc1->token!=':' || i==KW_CASE ||
i==KW_DFT || i==KW_START || i==KW_END)) {
tmpf=rx->cc2->lex_include_stk;
while (tmpf->next)
tmpf=tmpf->next;
QueVectU8Put(rx->indent,tmpf->cur_entry->y,rx->depth+rx->one_shot);
rx->one_shot=0;
}
if (rx->cc2->token=='\n')
rx->was_new_line=TRUE;
else
rx->was_new_line=FALSE;
} while (rx->cc1->token=='\n');
return rx->cc1->token;
}
U0 EdRIExp(CRILex *rx)
{
if (rx->cc1->token=='(') {
if (!rx->exp_depth++)
rx->depth+=3;
EdRILex(rx);
while (rx->cc1->token && rx->cc1->token!=')')
EdRIExp(rx);
if (!--rx->exp_depth) {
rx->depth-=3;
if (rx->depth<0) rx->depth=0;
}
} else if (rx->cc1->token=='[') {
if (!rx->exp_depth++)
rx->depth+=3;
EdRILex(rx);
while (rx->cc1->token && rx->cc1->token!=']')
EdRIExp(rx);
if (!--rx->exp_depth) {
rx->depth-=3;
if (rx->depth<0) rx->depth=0;
}
}
EdRILex(rx);
}
U0 EdRIStmt(CRILex *rx,Bool indent)
{
I64 i;
Bool cont;
if (rx->cc1->token=='{') {
rx->depth++;
EdRILex(rx);
while (rx->cc1->token && rx->cc1->token!='}')
EdRIStmt(rx,FALSE);
if (--rx->depth<0) rx->depth=0;
EdRILex(rx);
} else {
if (indent) rx->depth++;
do {
cont=FALSE;
switch (PrsKeyWord(rx->cc1)) {
case KW_IF:
EdRILex(rx);
EdRIExp(rx);
EdRIStmt(rx,TRUE);
if (PrsKeyWord(rx->cc1)==KW_ELSE) {
EdRILex(rx);
if (PrsKeyWord(rx->cc1)==KW_IF && rx->cc2->token!='\n')
EdRIStmt(rx,FALSE);
else
EdRIStmt(rx,TRUE);
}
break;
case KW_TRY:
EdRILex(rx);
EdRIStmt(rx,TRUE);
if (PrsKeyWord(rx->cc1)==KW_CATCH) {
EdRILex(rx);
EdRIStmt(rx,TRUE);
}
break;
case KW_LOCK:
EdRILex(rx);
EdRIStmt(rx,TRUE);
break;
case KW_FOR:
case KW_WHILE:
EdRILex(rx);
EdRIExp(rx);
EdRIStmt(rx,TRUE);
break;
case KW_ASM:
case KW_CLASS:
case KW_UNION:
if (EdRILex(rx)==TK_IDENT)
EdRILex(rx);
EdRIStmt(rx,TRUE);
break;
case KW_DO:
EdRILex(rx);
EdRIStmt(rx,TRUE);
if (PrsKeyWord(rx->cc1)==KW_WHILE) {
EdRILex(rx);
EdRIExp(rx);
}
if (rx->cc1->token==';')
EdRILex(rx);
break;
case KW_SWITCH:
EdRILex(rx);
EdRIExp(rx);
if (rx->cc1->token=='{') {
rx->depth++;
EdRILex(rx);
i=0;
while (rx->cc1->token && rx->cc1->token!='}') {
switch (PrsKeyWord(rx->cc1)) {
case KW_START:
rx->depth+=i; i=0;
while (EdRILex(rx) && rx->cc1->token!=':');
EdRILex(rx);
i++;
break;
case KW_END:
rx->depth+=i; i=0;
if (--rx->depth<0) rx->depth=0;
while (EdRILex(rx) && rx->cc1->token!=':');
EdRILex(rx);
break;
case KW_CASE:
case KW_DFT:
rx->depth+=i; i=0;
while (EdRILex(rx) && rx->cc1->token!=':');
EdRILex(rx);
break;
default:
if (rx->cc1->token)
EdRIStmt(rx,TRUE);
}
}
if (--rx->depth<0) rx->depth=0;
EdRILex(rx);
}
break;
default:
if (rx->cc1->token==TK_IDENT && rx->cc1->hash_entry &&
rx->cc1->hash_entry->type&(HTT_OPCODE|HTT_ASM_KEYWORD)) {
// rx->one_shot=4-rx->depth;
do EdRILex(rx);
while (rx->cc2->token && rx->cc2->token!='\n');
rx->is_not_cont=TRUE;
} else {
while (rx->cc1->token && rx->cc1->token!=';' &&
rx->cc1->token!=':') {
if (rx->cc2->token=='\n' && !rx->is_not_cont)
rx->one_shot=3;
EdRILex(rx);
}
if (rx->cc1->token==':')
cont=TRUE;
EdRILex(rx);
}
}
} while (cont && rx->cc1->token!='}');
if (indent && --rx->depth<0)
rx->depth=0;
}
}
CQueVectU8 *EdRICode(CDoc *doc)
{
CQueVectU8 *res;
CRILex *rx=CAlloc(sizeof(CRILex));
rx->cc1=CmpCtrlNew(,CCF_KEEP_NEW_LINES|CCF_DONT_FREE_BUF,doc->filename.name);
Free(rx->cc1->lex_include_stk->full_name);
LexAttachDoc(rx->cc1,rx->cc1->lex_include_stk,doc,,
doc->cur_entry,doc->cur_col);
rx->cc2=CmpCtrlNew(,CCF_KEEP_NEW_LINES|CCF_DONT_FREE_BUF,doc->filename.name);
Free(rx->cc2->lex_include_stk->full_name);
LexAttachDoc(rx->cc2,rx->cc2->lex_include_stk,doc,,
doc->cur_entry,doc->cur_col);
rx->indent=QueVectU8New(doc->cur_entry->y);
Lex(rx->cc1);
EdRIStmt(rx,FALSE);
CmpCtrlDel(rx->cc1);
CmpCtrlDel(rx->cc2);
res=rx->indent;
Free(rx);
return res;
}
U0 EdRemFunLeadingSpace(CDoc *doc)
{
Bool unlock=DocLock(doc),
start_of_line=TRUE;
U8 *ptr;
I64 ch,levels=1;
CDocEntry *doc_e,*doc_e2;
EdGoToFun(doc,FALSE,FALSE);
doc_e=doc->cur_entry->next;
do {
doc_e2=doc_e->next;
if (doc_e!=doc && doc_e!=doc->cur_entry &&
!(doc_e->de_flags&(DOCEG_DONT_EDIT-DOCEF_SCROLLING_X)))
switch (doc_e->type_u8) {
case DOCT_TEXT:
ptr=doc_e->tag;
if (start_of_line) {
while (*ptr==CH_SPACE)
ptr++;
if (*ptr)
start_of_line=FALSE;
ptr=StrNew(ptr,doc->mem_task);
Free(doc_e->tag);
doc_e->tag=ptr;
}
if (!*ptr)
DocEntryDel(doc,doc_e);
else {
while (ch=*ptr++)
if (ch=='{')
levels++;
else if (ch=='}') {
if (!--levels)
break;
}
if (!levels) goto ls_done;
}
break;
case DOCT_TAB:
if (start_of_line)
DocEntryDel(doc,doc_e);
break;
case DOCT_NEW_LINE:
start_of_line=TRUE;
break;
default:
start_of_line=FALSE;
}
doc_e=doc_e2;
} while (doc_e!=doc->cur_entry);
ls_done:
DocRecalc(doc);
DocCenter(doc);
if (unlock)
DocUnlock(doc);
}
class CRenum
{
CRenum *next,*last;
U8 label[sizeof(CEdFindText.find_text)];
};
I64 EdRAGetU8(CDoc *doc)
{
I64 res=-1;
while (doc->cur_entry!=doc &&
doc->cur_entry->type&DOCET_SEL && res<0) {
res=EdCurU8(doc);
EdCursorRight(doc);
}
return res;
}
U0 EdRACollect(CDoc *doc,CRenum *head)
{
I64 ch,i;
CRenum *tmpr;
U8 buf[sizeof(CEdFindText.find_text)];
ch=EdRAGetU8(doc);
while (ch>=0) {
if (ch!='@')
ch=EdRAGetU8(doc);
else {
ch=EdRAGetU8(doc);
if (ch=='@') {
ch=EdRAGetU8(doc);
StrCpy(buf,"@@");
i=2;
while (ch>=0 && i<sizeof(CEdFindText.find_text)) {
if (Bt(char_bmp_alpha_numeric,ch))
buf[i++]=ch;
else
break;
ch=EdRAGetU8(doc);
}
if (i<sizeof(CEdFindText.find_text)) {
buf[i++]=0;
while (ch>=0 && Bt(char_bmp_white_space,ch))
ch=EdRAGetU8(doc);
if (ch==':') {
ch=EdRAGetU8(doc);
tmpr=MAlloc(sizeof(CRenum));
StrCpy(tmpr->label,buf);
QueIns(tmpr,head->last);
}
}
}
}
}
//This is needed because we moved the
//cursor and it didn't recalc.
DocRecalc(doc);
}
U0 EdRenumAsm(CDoc *doc)
{
Bool unlock=DocLock(doc);
I64 num=0;
CRenum head,*tmpr,*tmpr1;
U8 buf[sizeof(CEdFindText.find_text)],
buf2[sizeof(CEdFindText.find_text)];
QueInit(&head);
EdSelFun(doc,TRUE);
EdRACollect(doc,&head);
tmpr=head.next;
while (tmpr!=&head) {
tmpr1=tmpr->next;
num+=ASM_RENUM_SPACING;
StrPrint(buf,"@#%02d",num);
EdReplace(doc,tmpr->label,buf,TRUE,TRUE,TRUE);
Free(tmpr);
tmpr=tmpr1;
}
while (num) {
StrPrint(buf, "@#%02d",num);
StrPrint(buf2,"@@%02d",num);
EdReplace(doc,buf,buf2,TRUE,TRUE,TRUE);
num-=ASM_RENUM_SPACING;
}
EdSelAll(doc,FALSE);
DocRecalc(doc);
DocCenter(doc);
if (unlock)
DocUnlock(doc);
}
U0 EdCodeTools2(CDoc *doc,I64 tool_action,Bool beep=TRUE)
{
Bool okay,unlock=DocLock(doc),start_of_line=TRUE;
CDocEntry *doc_e,*doc_ne;
I64 i,start_y,end_y,x,r,goto_line_num;
U8 *b,*st,*st2,*prj_file;
CTask *task=NULL;
CJob *tmpc;
CQueVectU8 *indent;
DocRecalc(doc);
goto_line_num=doc->cur_entry->y+1;
DocCaptureUndo(doc,TRUE);
switch (tool_action) {
case EF_CMP_CHK:
okay=FALSE;
if (doc->flags&DOCF_PLAIN_TEXT)
DocFlagsToggle(doc,DOCF_PLAIN_TEXT);
DocWrite(doc);
task=Spawn(&SrvCmdLine,NULL,"Srv",,Fs);
st2=DirCur;
st=MStrPrint("Cd(\"%s\");",st2);
tmpc=TaskExe(task,Fs,st,1<<JOBf_WAKE_MASTER|1<<JOBf_FOCUS_MASTER);
Free(st2);
Free(st);
WinHorz(Fs->win_left,Fs->win_right, task);
WinVert(Fs->win_top, Fs->win_bottom,task);
if (JobResScan(tmpc,&r)) {
st=DirFile(doc->filename.name,,"PRJ.Z");
prj_file=FileNameAbs(st,FUF_Z_OR_NOT_Z);
Free(st);
if (FileFind(prj_file)) {
st2=DirFile(prj_file),
st=MStrPrint("Cd(\"%s\");",st2);
Free(st2);
tmpc=TaskExe(task,Fs,st,1<<JOBf_WAKE_MASTER|
1<<JOBf_FOCUS_MASTER|1<<JOBf_FREE_ON_COMPLETE);
Free(st);
st=MStrPrint("\"$$WW,1$$\";Cmp(\"%s\",\"SysTmp\",\"SysTmp\");",
prj_file);
tmpc=TaskExe(task,Fs,st,1<<JOBf_WAKE_MASTER|1<<JOBf_FOCUS_MASTER);
Free(st);
if (JobResScan(tmpc,&r))
if (!r) {
tmpc=TaskExe(task,Fs,
"Load(\"SysTmp\",LDF_JUST_LOAD);",
1<<JOBf_WAKE_MASTER|1<<JOBf_FOCUS_MASTER);
if (JobResScan(tmpc,&r))
okay=TRUE;
}
tmpc=TaskExe(task,Fs,"Del(\"SysTmp.*\");",
1<<JOBf_WAKE_MASTER|1<<JOBf_FOCUS_MASTER);
JobResScan(tmpc,&r);
} else {
Free(prj_file);
st=DirFile(doc->filename.name,"Load","HC.Z");
prj_file=FileNameAbs(st,FUF_Z_OR_NOT_Z);
Free(st);
if (FileFind(prj_file))
st=MStrPrint("\"$$WW,1$$\";ExeFile(\"%s\",CCF_JUST_LOAD);",prj_file);
else
st=MStrPrint("\"$$WW,1$$\";ExeFile(\"%s\",CCF_JUST_LOAD);",
doc->filename.name);
tmpc=TaskExe(task,Fs,st,1<<JOBf_WAKE_MASTER|1<<JOBf_FOCUS_MASTER);
Free(st);
if (JobResScan(tmpc,&r) && r)
okay=TRUE;
}
Free(prj_file);
}
if (!okay) {
PopUpOk("Has Errors");
while (LBts(&sys_semas[SEMA_FIX],0))
Yield;
ToFileLine(dbg.fix_file_line,&st,&i);
LBtr(&sys_semas[SEMA_FIX],0);
if (!StrCmp(st,doc->filename.name))
goto_line_num=i;
Free(st);
}
break;
case EF_REINDENT:
start_y=doc->cur_entry->y;
EdReplaceTroubleAll(doc,TRUE,FALSE);
DocGoToLine(doc,start_y+1);
if (EdGoToFun(doc,FALSE,FALSE)) {
start_y=doc->cur_entry->y;
indent=EdRICode(doc);
DocUnlock(doc);
if (beep) {
Snd(86); Sleep(150); Snd;
Sleep(100);
Snd(86); Sleep(150); Snd;
}
DocLock(doc);
EdRemFunLeadingSpace(doc);
DocGoToLine(doc,start_y+1);
doc_e=doc->cur_entry;
end_y=start_y+indent->total_cnt;
while (start_y<=doc_e->y<end_y) {
if (doc_e!=doc && doc_e!=doc->cur_entry &&
!(doc_e->de_flags&(DOCEG_DONT_EDIT-DOCEF_SCROLLING_X))) {
if (doc_e->type_u8==DOCT_NEW_LINE||
doc_e->type_u8==DOCT_SOFT_NEW_LINE)
start_of_line=TRUE;
else {
if (start_of_line) {
i=QueVectU8Get(indent,doc_e->y)*C_INDENT_SPACES;
x=doc_e->x+1;
while (i>8) {
doc_ne=DocEntryNewBase(doc,
DOCT_TAB|doc->settings_head.dft_text_attr<<8,,
x,doc_e->y,doc_e->page_line_num);
MemCpy(&doc_ne->settings,
&doc_e->settings,sizeof(CDocSettings));
QueIns(doc_ne,doc_e->last);
i-=8;
x+=8;
}
if (i>0) {
b=MAlloc(i+1,doc->mem_task);
MemSet(b,CH_SPACE,i);
b[i]=0;
doc_ne=DocEntryNewBase(doc,
DOCT_TEXT|doc->settings_head.dft_text_attr<<8,,
x,doc_e->y,doc_e->page_line_num);
doc_ne->tag=b;
doc_ne->max_col=1;
MemCpy(&doc_ne->settings,
&doc_e->settings,sizeof(CDocSettings));
QueIns(doc_ne,doc_e->last);
}
}
start_of_line=FALSE;
}
}
doc_e=doc_e->next;
}
QueVectU8Del(indent);
}
start_y=doc->cur_entry->y;
EdReplaceTroubleAll(doc,FALSE,FALSE);
DocGoToLine(doc,start_y+1);
break;
case EF_RENUM_ASM:
if (EdGoToFun(doc,FALSE,TRUE)) {
if (EdCurU8(doc)=='{') {
EdCursorRight(doc);
DocRecalc(doc);
} else if (EdCurU8(doc)==':') {
EdCursorRight(doc);
if (EdCurU8(doc)==':')
EdCursorRight(doc);
DocRecalc(doc);
}
DocUnlock(doc);
if (beep) {
Snd(86); Sleep(150); Snd;
Sleep(100);
Snd(86); Sleep(150); Snd;
}
DocLock(doc);
EdRenumAsm(doc);
}
break;
}
DocRecalc(doc);
DocGoToLine(doc,goto_line_num);
DocUnlock(doc);
if (!unlock)
DocLock(doc);
if (task)
Kill(task,FALSE);
}
U0 EdPopUpChSC(I64 *_ch,I64 *_sc)
{
I64 sc;
"Press A Key\n";
DocPut->flags|=DOCF_SIZE_MIN;
do GetMsg(_ch,&sc,1<<MSG_KEY_DOWN);
while (sc.u8[0]==SC_SHIFT || sc.u8[0]==SC_CTRL || sc.u8[0]==SC_ALT);
*_sc=sc;
}
U0 EdChSC(CDoc *doc)
{
I64 ch,sc;
U8 buf[STR_LEN];
StrPrint(buf,"EdPopUpChSC(%d,%d);",&ch,&sc);
PopUp(buf,Fs);
if (ch==CH_BACKSPACE)
DocPrint(doc,"CH_BACKSPACE,0x%X",sc);
else if (ch=='\n')
DocPrint(doc,"'\n',0x%X",sc);
else if (CH_CTRLA<=ch<=CH_CTRLZ)
DocPrint(doc,"CH_CTRL%C,0x%X",ch+'@',sc);
else if (ch=='$$')
DocPrint(doc,"'$$$$',0x%X",sc);
else if (ch=='\\')
DocPrint(doc,"'\\\\',0x%X",sc);
else if (ch=='\'')
DocPrint(doc,"'\\\'',0x%X",sc);
else if (ch==CH_ESC)
DocPrint(doc,"CH_ESC,0x%X",sc);
else if (ch==CH_SHIFT_ESC)
DocPrint(doc,"CH_SHIFT_ESC,0x%X",sc);
else if (ch==CH_SPACE)
DocPrint(doc,"CH_SPACE,0x%X",sc);
else if (ch==CH_SHIFT_SPACE)
DocPrint(doc,"CH_SHIFT_SPACE,0x%X",sc);
else if (Bt(char_bmp_displayable,ch))
DocPrint(doc,"'%c',0x%X",ch,sc);
else
DocPrint(doc,"0x%X,0x%X",ch,sc);
}
U0 EdCodeTools(CDoc *doc)
{
I64 tool_action=PopUpEdFmt;
switch (tool_action) {
case EF_CMP_CHK:
case EF_REINDENT:
case EF_RENUM_ASM:
EdCodeTools2(doc,tool_action);
break;
case EF_CTRL_SLIDER:
TemplateCtrlSlider(doc);
break;
case EF_CH_SC:
EdChSC(doc);
break;
}
}