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

659 lines
15 KiB
HolyC
Executable File
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#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;
}
}