TempleOSCD_140715.ISO

This commit is contained in:
Terry A. Davis authored and minexew committed 2018-09-08 21:46:09 +02:00
1 parent 7ef616a20e
commit 64f679eeb9
1095 files changed
+24814 -221011

No files matched your search

+96
View File
@@ -0,0 +1,96 @@
#help_index "DolDoc"
#help_file "::/Doc/DolDoc"
/*$AN,"",A="Doc"$
TempleOS DolDoc's can have "cursor movement" cmds which can move the cursor up
the screen and layer on existing text. It can also have callback funs which
supply live, changing text. For these reasons, you can't assume you know
where the visible portion of the document is and must process much
of the document each time it is placed on the screen, becoming CPU
intensive on big documents.
See $LK,"::/Doc/DolDocOverview.TXT"$
*/
extern I64 EdLeftClickLink(CDoc *doc,CDocEntry *doc_e);
extern I64 TermRightClickLink(CDoc *doc,CDocEntry *doc_e);
extern U0 DocPrintPartial(CDoc *doc,U8 *fmt,...);
extern U0 DocFormBwd(CDoc *doc,Bool giveup=FALSE);
extern U0 EdUndoFilter(CDoc *doc);
extern U8 *PopUpPickLst(U8 *lst);
#define DHT_DOC_CMD 1
#define DHT_DOC_FLAG 2
#define DHT_COLOR 4
//--TEMPLEOS LINK TYPES--
// "filename"
// "FI:filename"
// "FA:haystack_filename,needle_anchor_str"
// "FF:haystack_filename,needle_str"
// "FF:haystack_filename,needle_str:occurnum"
// "FL:filename,linenum"
#define LK_FILE 0
#define LK_FILE_ANCHOR 1
#define LK_FILE_FIND 2
#define LK_FILE_LINE 3
// "MN:SymName"
#define LK_MAN_PAGE 4
// "PI:filename"
// "PF:haystack_filename,needle_str"
// "PF:haystack_filename,needle_str:occurnum"
// "PL:filename,linenum"
#define LK_PLAIN 5
#define LK_PLAIN_FIND 6
#define LK_PLAIN_LINE 7
// "BF:haystack_bible_book,needle_str"
#define LK_BIBLE_FIND 8
// "DF:word"
// "DF:word,defnum"
#define LK_DEF 9
// "HI:index"
#define LK_HELP_INDEX 10
// "AD:code_address_number"
#define LK_ADDR 11
//These are to edit a doc structure already in memory.
// "AI:doc_address"
// "AA:haystack_doc_address,needle_anchor_str"
// "AF:haystack_doc_address,needle_str"
// "AF:haystack_doc_address,needle_str:occurnum"
// "AL:doc_address,linenum"
#define LK_DOC 12 //See $LK,"SpriteEdText",A="MN:SpriteEdText"$()
#define LK_DOC_ANCHOR 13
#define LK_DOC_FIND 14
#define LK_DOC_LINE 15
#define LK_PLACE_ANCHOR 16
public class CDolDocGlbls
{
CHashTable *hash;
I64 dft_de_flags [DOCT_NUM_TYPES],
type_flags_nontag_invisible [(DOCT_NUM_TYPES+63)/64],
type_flags_form [(DOCT_NUM_TYPES+63)/64],
type_flags_data [(DOCT_NUM_TYPES+63)/64],
clean_scan_codes [4];
I32 dft_type_flags [DOCT_NUM_TYPES];
} doldoc;
MemSet(&doldoc,0,sizeof(CDolDocGlbls));
#include "DocNew"
#include "DocPlain"
#include "DocInit"
#include "DocHighlight"
#include "DocRecalc2a"
#include "DocRecalc2b"
sys_clipboard_doc=DocNew;
#include "DocFile"
#include "DocOpt"
#include "DocPopUp"
#include "DocCtrlL"
#include "DocMacro"
#include "DocFind"
#include "DocEd2a"
#include "DocEd2b"
#include "DocCodeTools"
#include "DocTree"
#include "DocMain"
+607
View File
@@ -0,0 +1,607 @@
#help_index "DolDoc/Misc"
#define C_INDENT_SPACES 2
#define ASM_RENUM_SPACING 5
#define EF_REINDENT 0
#define EF_CHK_COMPILE 1
#define EF_RENUM_ASM 2
#define EF_SLIDER_CTRL 3
#define EF_CH_SC 4
I64 PopUpEdFmt()
{
I64 i;
CDoc *doc=DocNew;
DocPrint(doc,"$$LTBLUE$$$$MU,\"Check Compile\",LE=EF_CHK_COMPILE$$\n"
"$$MU,\"Reindent CPP.Z Fun\",LE=EF_REINDENT$$\n"
"$$MU,\"Renum Asm Local @@ Labels for Fun\",LE=EF_RENUM_ASM$$\n"
"$$MU,\"Insert Template Code: Slider Ctrl\",LE=EF_SLIDER_CTRL$$\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 results.\n");
i=PopUpMenu(doc);
DocDel(doc);
return i;
}
class CRILex
{
CLex *lx1,*lx2;
CQueVectU8 *indent;
I64 depth,exp_depth;
Bool was_new_line,is_not_cont,one_shot;
};
I64 EdRILex(CRILex *rx)
{
Bool is_not_cont=FALSE;
I64 i,k;
do {
Lex(rx->lx1);
Lex(rx->lx2);
if (rx->lx1->token=='\n') {
if (rx->lx2->token==TK_IDENT)
i=PrsKeyWord(rx->lx2);
else
i=-1;
if (rx->lx2->token==';' || rx->lx2->token=='{' || rx->lx2->token=='}' ||
rx->lx2->token==':' || rx->lx2->token==')' && !rx->exp_depth ||
i==KW_ELSE || i==KW_CATCH || i==KW_DO)
is_not_cont=TRUE;
}
k=PrsKeyWord(rx->lx2);
if (rx->was_new_line && (rx->lx1->token!=':' ||
k==KW_DFT || k==KW_SUB_SWITCH_START || k==KW_SUB_SWITCH_END)) {
if (rx->one_shot) {
QueVectU8Put(rx->indent,rx->lx2->lfns[0].cur_entry->y,rx->depth+3);
rx->one_shot=FALSE;
} else
QueVectU8Put(rx->indent,rx->lx2->lfns[0].cur_entry->y,rx->depth);
}
if (rx->lx2->token=='\n')
rx->was_new_line=TRUE;
else
rx->was_new_line=FALSE;
} while (rx->lx1->token=='\n');
rx->is_not_cont=is_not_cont;
return rx->lx1->token;
}
U0 EdRIExp(CRILex *rx)
{
if (rx->lx1->token=='(') {
if (!rx->exp_depth++)
rx->depth+=3;
EdRILex(rx);
while (rx->lx1->token && rx->lx1->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->lx1->token=='{') {
rx->depth++;
EdRILex(rx);
while (rx->lx1->token && rx->lx1->token!='}')
EdRIStmt(rx,FALSE);
if (--rx->depth<0) rx->depth=0;
EdRILex(rx);
} else {
if (indent) rx->depth++;
do {
cont=FALSE;
switch (PrsKeyWord(rx->lx1)) {
case KW_IF:
EdRILex(rx);
EdRIExp(rx);
EdRIStmt(rx,TRUE);
if (PrsKeyWord(rx->lx1)==KW_ELSE) {
EdRILex(rx);
if (PrsKeyWord(rx->lx1)==KW_IF && rx->lx2->token!='\n')
EdRIStmt(rx,FALSE);
else
EdRIStmt(rx,TRUE);
}
break;
case KW_TRY:
EdRILex(rx);
EdRIStmt(rx,TRUE);
if (PrsKeyWord(rx->lx1)==KW_CATCH) {
EdRILex(rx);
EdRIStmt(rx,TRUE);
}
break;
case KW_FOR:
case KW_WHILE:
EdRILex(rx);
EdRIExp(rx);
EdRIStmt(rx,TRUE);
break;
case KW_ASM:
EdRILex(rx);
EdRIStmt(rx,TRUE);
break;
case KW_DO:
EdRILex(rx);
EdRIStmt(rx,TRUE);
if (PrsKeyWord(rx->lx1)==KW_WHILE) {
EdRILex(rx);
EdRIExp(rx);
}
if (rx->lx1->token==';')
EdRILex(rx);
break;
case KW_SWITCH:
case KW_NOBOUND_SWITCH:
EdRILex(rx);
EdRIExp(rx);
if (rx->lx1->token=='{') {
rx->depth++;
EdRILex(rx);
i=0;
while (rx->lx1->token && rx->lx1->token!='}') {
switch (PrsKeyWord(rx->lx1)) {
case KW_SUB_SWITCH_START:
rx->depth+=i; i=0;
while (EdRILex(rx) && rx->lx1->token!=':');
EdRILex(rx);
i++;
break;
case KW_SUB_SWITCH_END:
rx->depth+=i; i=0;
if (--rx->depth<0) rx->depth=0;
while (EdRILex(rx) && rx->lx1->token!=':');
EdRILex(rx);
break;
case KW_CASE:
case KW_DFT:
rx->depth+=i; i=0;
while (EdRILex(rx) && rx->lx1->token!=':');
EdRILex(rx);
break;
default:
if (rx->lx1->token)
EdRIStmt(rx,TRUE);
}
}
if (--rx->depth<0) rx->depth=0;
EdRILex(rx);
}
break;
default:
if (rx->lx1->token==TK_IDENT && rx->lx1->hash_entry &&
rx->lx1->hash_entry->type&(HTT_OPCODE|HTT_ASM_KEYWORD)) {
i=rx->depth;
rx->depth=4;
rx->one_shot=FALSE;
do EdRILex(rx);
while (rx->lx2->token && rx->lx2->token!='\n');
rx->depth=i;
} else {
while (rx->lx1->token && rx->lx1->token!=';' && rx->lx1->token!=':') {
if (rx->lx2->token=='\n' && !rx->is_not_cont)
rx->one_shot=TRUE;
EdRILex(rx);
}
if (rx->lx1->token==':')
cont=TRUE;
EdRILex(rx);
}
}
} while (cont && rx->lx1->token!='}');
if (indent && --rx->depth<0)
rx->depth=0;
}
}
CQueVectU8 *EdRICode(CDoc *doc)
{
CQueVectU8 *result;
CRILex *rx=CAlloc(sizeof(CRILex));
rx->lx1=LexNew(,LF_KEEP_NEW_LINES|LF_DONT_FREE_BUF,doc->filename.name);
Free(rx->lx1->lfns[0].name);
LexAttachDoc(rx->lx1,&rx->lx1->lfns[0],doc,,doc->cur_entry,doc->cur_data_col);
rx->lx2=LexNew(,LF_KEEP_NEW_LINES|LF_DONT_FREE_BUF,doc->filename.name);
Free(rx->lx2->lfns[0].name);
LexAttachDoc(rx->lx2,&rx->lx2->lfns[0],doc,,doc->cur_entry,doc->cur_data_col);
rx->indent=QueVectU8New(doc->cur_entry->y);
Lex(rx->lx1);
EdRIStmt(rx,FALSE);
LexDel(rx->lx1);
LexDel(rx->lx2);
result=rx->indent;
Free(rx);
return result;
}
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&(DOCEG1_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 result=-1;
while (doc->cur_entry!=doc && doc->cur_entry->type&DOCET_SELECTED && result<0) {
result=EdCurU8(doc);
EdCursorRight(doc);
}
return result;
}
U0 EdRACollect(CDoc *doc,CRenum *root)
{
I64 ch,i;
CRenum *tempr;
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(chars_bitmap_alpha_numeric,ch))
buf[i++]=ch;
else
break;
ch=EdRAGetU8(doc);
}
if (i<sizeof(CEdFindText.find_text)) {
buf[i++]=0;
while (ch>=0 && Bt(chars_bitmap_white_space,ch))
ch=EdRAGetU8(doc);
if (ch==':') {
ch=EdRAGetU8(doc);
tempr=MAlloc(sizeof(CRenum));
StrCpy(tempr->label,buf);
QueIns(tempr,root->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 root,*tempr,*tempr1;
U8 buf[sizeof(CEdFindText.find_text)],
buf2[sizeof(CEdFindText.find_text)];
QueInit(&root);
EdSelectFun(doc,TRUE);
EdRACollect(doc,&root);
tempr=root.next;
while (tempr!=&root) {
tempr1=tempr->next;
num+=ASM_RENUM_SPACING;
StrPrint(buf,"@#%02d",num);
EdReplace(doc,tempr->label,buf,TRUE,TRUE,TRUE);
Free(tempr);
tempr=tempr1;
}
while (num) {
StrPrint(buf, "@#%02d",num);
StrPrint(buf2,"@@%02d",num);
EdReplace(doc,buf,buf2,TRUE,TRUE,TRUE);
num-=ASM_RENUM_SPACING;
}
EdSelectAll(doc,FALSE);
DocRecalc(doc);
DocCenter(doc);
if (unlock)
DocUnlock(doc);
}
U0 EdCodeTools2(CDoc *doc,I64 tool_action)
{
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;
CSrvCmd *tempc;
CQueVectU8 *indent;
DocRecalc(doc);
goto_line_num=doc->cur_entry->y+1;
DocCaptureUndo(doc,TRUE);
switch (tool_action) {
case EF_CHK_COMPILE:
okay=FALSE;
if (doc->flags&DOCF_PLAIN_TEXT)
DocFlagsToggle(doc,DOCF_PLAIN_TEXT);
DocWrite(doc);
task=Spawn(&SrvUserCmdLine,NULL,"Srv",,Fs);
st2=CurDir;
st=MStrPrint("Cd(\"%s\");",st2);
tempc=TaskExe(task,Fs,st,1<<SVCf_WAKE_MASTER|1<<SVCf_FOCUS_MASTER);
Free(st2);
Free(st);
SetWinHorz(Fs->win_left,Fs->win_right, task);
SetWinVert(Fs->win_top, Fs->win_bottom,task);
if (ScanResult(tempc,&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);
tempc=TaskExe(task,Fs,st,1<<SVCf_WAKE_MASTER|1<<SVCf_FOCUS_MASTER|1<<SVCf_FREE_ON_COMPLETE);
Free(st);
st=MStrPrint("\"$$WW,1$$\";Cmp(\"%s\",\"SysTemp\",\"SysTemp\");",prj_file);
tempc=TaskExe(task,Fs,st,1<<SVCf_WAKE_MASTER|1<<SVCf_FOCUS_MASTER);
Free(st);
if (ScanResult(tempc,&r))
if (!r) {
tempc=TaskExe(task,Fs,
"Load(\"SysTemp\",LDF_JUST_LOAD);",1<<SVCf_WAKE_MASTER|1<<SVCf_FOCUS_MASTER);
if (ScanResult(tempc,&r))
okay=TRUE;
}
tempc=TaskExe(task,Fs,"Del(\"SysTemp.*\");",1<<SVCf_WAKE_MASTER|1<<SVCf_FOCUS_MASTER);
ScanResult(tempc,&r);
} else {
Free(prj_file);
st=DirFile(doc->filename.name,"Load","CPP.Z");
prj_file=FileNameAbs(st,FUF_Z_OR_NOT_Z);
Free(st);
if (FileFind(prj_file))
st=MStrPrint("\"$$WW,1$$\";ExeFile(\"%s\",TRUE);",prj_file);
else
st=MStrPrint("\"$$WW,1$$\";ExeFile(\"%s\",TRUE);",doc->filename.name);
tempc=TaskExe(task,Fs,st,1<<SVCf_WAKE_MASTER|1<<SVCf_FOCUS_MASTER);
Free(st);
if (ScanResult(tempc,&r) && r)
okay=TRUE;
}
Free(prj_file);
}
if (!okay) {
PopUpOk("Has Errors");
while (LBts(&sys_semas[SYS_SEMA_FIX],0))
Yield;
ToFileLine(dbg.fix_file_line,&st,&i);
LBtr(&sys_semas[SYS_SEMA_FIX],0);
if (!StrCmp(st,doc->filename.name))
goto_line_num=i;
Free(st);
}
break;
case EF_REINDENT:
if (EdGoToFun(doc,FALSE,FALSE)) {
start_y=doc->cur_entry->y;
indent=EdRICode(doc);
DocUnlock(doc);
Snd(2000); Sleep(150); Snd(0);
Sleep(100);
Snd(2000); Sleep(150); Snd(0);
DocLock(doc);
EdRemFunLeadingSpace(doc);
DocLineNumGoTo(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&(DOCEG1_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=CAlloc(sizeof(CDocEntryBase),doc->mem_task);
doc_ne->type=DOCT_TAB | doc->settings_root.dft_text_attr<<8;
doc_ne->de_flags=doldoc.dft_de_flags[DOCT_TAB];
doc_ne->x=x;
doc_ne->y=doc_e->y;
doc_ne->page_line_num=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=CAlloc(sizeof(CDocEntryBase),doc->mem_task);
doc_ne->type=DOCT_TEXT | doc->settings_root.dft_text_attr<<8;
doc_ne->de_flags=doldoc.dft_de_flags[DOCT_TEXT];
doc_ne->tag=b;
doc_ne->max_col=1;
doc_ne->x=x;
doc_ne->y=doc_e->y;
doc_ne->page_line_num=doc_e->page_line_num;
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);
}
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);
Snd(2000); Sleep(150); Snd(0);
Sleep(100);
Snd(2000); Sleep(150); Snd(0);
DocLock(doc);
EdRenumAsm(doc);
}
break;
}
DocRecalc(doc);
DocLineNumGoTo(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_MIN_SIZE;
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[136];
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(chars_bitmap_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_CHK_COMPILE:
case EF_REINDENT:
case EF_RENUM_ASM:
EdCodeTools2(doc,tool_action);
break;
case EF_SLIDER_CTRL:
TemplateSliderCtrl(doc);
break;
case EF_CH_SC:
EdChSC(doc);
break;
}
}
File diff suppressed because it is too large. Load diff
+759
View File
@@ -0,0 +1,759 @@
#help_index "DolDoc/Editor"
public I64 EdCurU8(CDoc *doc)
{//Return cur U8. See $LK,"EdRenumAsm",A="MN:EdRenumAsm"$ for an example.
Bool unlock=DocLock(doc);
CDocEntry *doc_ce=doc->cur_entry;
I64 result=-1;
if (doc_ce->type_u8==DOCT_TEXT && doc_ce->min_col<=doc->cur_data_col<doc_ce->max_col)
result=doc_ce->tag[doc->cur_data_col];
else if (doc_ce->type_u8==DOCT_TAB)
result='\t';
else if (doc_ce->type_u8==DOCT_NEW_LINE || doc_ce->type_u8==DOCT_SOFT_NEW_LINE)
result='\n';
if (unlock)
DocUnlock(doc);
return result;
}
public U0 EdCursorLeft(CDoc *doc,I64 sc=MIN_I64)
{//Move cursor left. Might need a call to $LK,"DocRecalc",A="MN:DocRecalc"$().
//See $LK,"EdRenumAsm",A="MN:EdRenumAsm"$ for an example.
U8 *dst;
Bool unlock=DocLock(doc);
CDocEntry *doc_ce=doc->cur_entry,*original_ce=doc_ce,*doc_ne;
I64 cc=doc->cur_data_col,y=doc_ce->y;
if (sc!=MIN_I64) sc=sc.u32[0];
if (sc>=0 && sc&SCF_CTRL) {
while (doc_ce->last!=doc && (doc_ce->last->y==y ||
doc_ce->de_flags & (DOCEF_SKIP|DOCEF_HARD_SKIP|DOCEF_FILTER_SKIP)))
doc_ce=doc_ce->last; //TODO: select? recurse?
cc=doc_ce->min_col;
} else {
if (cc>doc_ce->min_col) {
if (IsEditableText(doc_ce) && cc<doc_ce->max_col) {
dst=doc_ce->tag+cc;
doc_ne=DocEntryNew(doc,doc_ce,StrNew(dst,doc->mem_task));
*dst=0;
doc_ce->max_col=cc;
QueIns(doc_ne,doc_ce);
}
cc--;
if (IsEditableText(doc_ce) && cc>doc_ce->min_col) {
dst=doc_ce->tag+cc;
doc_ne=DocEntryNew(doc,doc_ce,StrNew(dst,doc->mem_task));
*dst=0;
doc_ce->max_col=cc;
QueIns(doc_ne,doc_ce);
doc_ce=doc_ne;
cc=doc_ce->min_col;
}
if (sc>=0)
BEqu(&doc_ce->type,DOCEt_SELECTED,sc&SCF_SHIFT);
} else {
cc=doc_ce->min_col;
while (doc_ce->last!=doc &&
(doc_ce->last->type_u8==DOCT_SOFT_NEW_LINE || doc_ce->last->type_u8==DOCT_INDENT ||
doc_ce->last->de_flags & (DOCEF_SKIP|DOCEF_HARD_SKIP|DOCEF_FILTER_SKIP))) {
doc_ce=doc_ce->last;
if (sc>=0)
BEqu(&doc_ce->type,DOCEt_SELECTED,sc&SCF_SHIFT);
}
if (doc_ce->last!=doc) {
doc_ce=doc_ce->last;
if (doc_ce->max_col>doc_ce->min_col) {
cc=doc_ce->max_col-1;
if (IsEditableText(doc_ce) && cc>doc_ce->min_col) {
dst=doc_ce->tag+cc;
doc_ne=DocEntryNew(doc,doc_ce,StrNew(dst,doc->mem_task));
*dst=0;
doc_ce->max_col=cc;
QueIns(doc_ne,doc_ce);
doc_ce=doc_ne;
cc=doc_ce->min_col;
}
} else
cc=doc_ce->max_col;
if (sc>=0)
BEqu(&doc_ce->type,DOCEt_SELECTED,sc&SCF_SHIFT);
}
}
}
doc->cur_data_col=cc;
doc->cur_entry=doc_ce;
if (doc_ce!=original_ce)
DocFormBwd(doc);
if (unlock)
DocUnlock(doc);
}
public U0 EdCursorRight(CDoc *doc,I64 sc=MIN_I64)
{//Move cursor right. Might need a call to $LK,"DocRecalc",A="MN:DocRecalc"$().
//See $LK,"EdRenumAsm",A="MN:EdRenumAsm"$ for an example.
Bool unlock=DocLock(doc);
U8 *dst;
CDocEntry *doc_ce=doc->cur_entry,*original_ce=doc_ce,*doc_ne;
I64 cc=doc->cur_data_col,y=doc_ce->y,old_de_flags,old_color;
if (sc!=MIN_I64) sc=sc.u32[0];
if (sc>=0 && sc&SCF_CTRL) {
while (doc_ce!=doc && doc_ce->next->y==y &&
doc_ce->next->type_u8!=DOCT_SOFT_NEW_LINE && doc_ce->next!=doc && (doc_ce->next->type_u8!=DOCT_NEW_LINE || !(doc->flags & DOCF_FORM)) ||
doc_ce->de_flags & (DOCEF_SKIP|DOCEF_HARD_SKIP|DOCEF_FILTER_SKIP))
doc_ce=doc_ce->next;
if (doc_ce->max_col>doc_ce->min_col)
cc=doc_ce->max_col-1;
else
cc=doc_ce->min_col;
} else {
if (cc<doc_ce->max_col) {
if (IsEditableText(doc_ce) && cc>doc_ce->min_col) {
dst=doc_ce->tag+cc;
doc_ne=DocEntryNew(doc,doc_ce,StrNew(dst,doc->mem_task));
*dst=0;
doc_ce->max_col=cc;
QueIns(doc_ne,doc_ce);
doc_ce=doc_ne;
cc=doc_ce->min_col;
}
cc++;
old_de_flags=doc_ce->de_flags;
old_color=doc_ce->type;
if (sc>=0)
BEqu(&doc_ce->type,DOCEt_SELECTED,sc&SCF_SHIFT);
if (IsEditableText(doc_ce) && cc<doc_ce->max_col) {
dst=doc_ce->tag+cc;
doc_ne=DocEntryNew(doc,doc_ce,StrNew(dst,doc->mem_task));
*dst=0;
doc_ne->type=DOCT_TEXT | old_color & -0x100;
doc_ne->de_flags=old_de_flags|doldoc.dft_de_flags[DOCT_TEXT];
doc_ce->max_col=cc;
QueIns(doc_ne,doc_ce);
doc_ce=doc_ne;
cc=doc_ce->min_col;
} else if (cc>=doc_ce->max_col) {
doc_ce=doc_ce->next;
cc=doc_ce->min_col;
}
} else {
if (doc_ce!=doc) {
if (cc<=doc_ce->min_col && sc>=0)
BEqu(&doc_ce->type,DOCEt_SELECTED,sc&SCF_SHIFT);
doc_ce=doc_ce->next;
while (doc_ce!=doc && doc_ce->de_flags & (DOCEF_SKIP|DOCEF_HARD_SKIP|DOCEF_FILTER_SKIP)) {
if (sc>=0)
BEqu(&doc_ce->type,DOCEt_SELECTED,sc&SCF_SHIFT);
doc_ce=doc_ce->next;
}
cc=doc_ce->min_col;
if (doc_ce->type_u8==DOCT_SOFT_NEW_LINE) {
if (sc>=0)
BEqu(&doc_ce->type,DOCEt_SELECTED,sc&SCF_SHIFT);
doc_ce=doc_ce->next;
cc=doc_ce->min_col;
}
}
}
}
doc->cur_data_col=cc;
doc->cur_entry=doc_ce;
if (doc_ce!=original_ce)
DocFormFwd(doc);
if (unlock)
DocUnlock(doc);
}
public U0 EdLineUp(CDoc *doc,I64 sc=MIN_I64)
{//Move cursor up. Might need a call to $LK,"DocRecalc",A="MN:DocRecalc"$().
//See $LK,"EdRenumAsm",A="MN:EdRenumAsm"$ for an example.
Bool unlock=DocLock(doc);
U8 *dst;
I64 y,x;
CDocEntry *doc_ce=doc->cur_entry,*doc_ne;
if (sc!=MIN_I64) sc=sc.u32[0];
if (doc_ce->type_u8==DOCT_HEX_ED) {
doc->cur_data_col=doc->cur_data_col-doc_ce->hex_ed_width*3;
if (doc->cur_data_col>=0) {
if (unlock)
DocUnlock(doc);
return;
} else
doc->cur_data_col=0;
}
x=doc->x; y=doc->y;
if (IsEditableText(doc_ce)) {
if (doc_ce->min_col<doc->cur_data_col<doc_ce->max_col-1) {
dst=doc_ce->tag+doc->cur_data_col;
doc_ne=DocEntryNew(doc,doc_ce,StrNew(dst,doc->mem_task));
*dst=0;
doc_ne->x=doc_ce->x+doc->cur_data_col;
doc_ce->max_col=doc->cur_data_col;
QueIns(doc_ne,doc_ce);
} else
if (doc->cur_data_col==doc_ce->min_col && doc_ce->last!=doc)
doc_ce=doc_ce->last;
} else
if (doc_ce->last!=doc)
doc_ce=doc_ce->last;
if (sc>=0)
BEqu(&doc_ce->type,DOCEt_SELECTED,sc&SCF_SHIFT);
doc->cur_entry=doc_ce;
DocFormBwd(doc);
doc_ce=doc->cur_entry;
while (doc_ce->last!=doc && (doc_ce->y>=y || doc_ce->de_flags & (DOCEF_SKIP|DOCEF_HARD_SKIP|DOCEF_FILTER_SKIP))) {
doc_ce=doc_ce->last;
if (sc>=0)
BEqu(&doc_ce->type,DOCEt_SELECTED,sc&SCF_SHIFT);
}
y=doc_ce->y;
doc->y=y;
while (doc_ce!=doc && (doc_ce->y>=y && doc_ce->x>=x || doc_ce->de_flags & (DOCEF_SKIP|DOCEF_HARD_SKIP|DOCEF_FILTER_SKIP))) {
if (sc>=0)
BEqu(&doc_ce->type,DOCEt_SELECTED,sc&SCF_SHIFT);
doc_ce=doc_ce->last;
}
if (doc_ce==doc || doc_ce->y<y)
doc_ce=doc_ce->next;
else {
if (!IsEditableText(doc_ce)) {
if (sc>=0)
BEqu(&doc_ce->type,DOCEt_SELECTED,sc&SCF_SHIFT);
} else {
if (doc_ce->next->x==x) {
doc_ce=doc_ce->next;
if (doc->flags & DOCF_FORM) {
while (doc_ce->next->x==x &&
(!Bt(doldoc.type_flags_form,doc_ce->type_u8) ||
doc_ce->de_flags&DOCEF_SKIP_IN_FORM))
doc_ce=doc_ce->next;
}
}
}
}
if (doc_ce->de_flags&DOCEF_TAG) {
doc->cur_data_col=x-doc_ce->x;
if (IsEditableText(doc_ce)) {
if (doc->cur_data_col>doc_ce->max_col)
doc->cur_data_col=doc_ce->max_col;
} else {
if (doc->cur_data_col>=doc_ce->max_col)
doc->cur_data_col=doc_ce->max_col-1;
}
if (doc->cur_data_col<doc_ce->min_col)
doc->cur_data_col=doc_ce->min_col;
} else {
if (doc_ce->type_u8==DOCT_HEX_ED) {
doc->cur_data_col=RoundI64((doc_ce->len-1)*3,doc_ce->hex_ed_width*3);
if (doc->cur_data_col<0)
doc->cur_data_col=0;
} else
doc->cur_data_col=doc_ce->min_col;
}
if (IsEditableText(doc_ce) && doc_ce->x<x) {
if (doc->cur_data_col<doc_ce->max_col-1) {
dst=doc_ce->tag+doc->cur_data_col;
doc_ne=DocEntryNew(doc,doc_ce,StrNew(dst,doc->mem_task));
*dst=0;
if (sc>=0) {
if (sc&SCF_SHIFT)
doc_ne->type=doc_ce->type | DOCET_SELECTED;
else
doc_ne->type=doc_ce->type & ~DOCET_SELECTED;
}
doc_ne->x=doc_ce->x+doc->cur_data_col;
doc_ce->max_col=doc->cur_data_col;
QueIns(doc_ne,doc_ce);
doc_ce=doc_ne;
doc->cur_data_col=doc_ce->min_col;
}
}
doc->cur_entry=doc_ce;
DocFormFwd(doc);
doc->x=doc->cur_entry->x+doc->cur_data_col;
if (unlock)
DocUnlock(doc);
}
public U0 EdLineDown(CDoc *doc,I64 sc=MIN_I64)
{//Move cursor down. Might need a call to $LK,"DocRecalc",A="MN:DocRecalc"$().
//See $LK,"EdRenumAsm",A="MN:EdRenumAsm"$ for an example.
Bool unlock=DocLock(doc);
U8 *dst;
I64 y,x,old_de_flags=0,old_color;
CDocEntry *doc_ce=doc->cur_entry,*doc_ne,*doc_ce2;
if (sc!=MIN_I64) sc=sc.u32[0];
if (doc_ce->type_u8==DOCT_HEX_ED) {
doc->cur_data_col=doc->cur_data_col+doc_ce->hex_ed_width*3;
if (doc->cur_data_col>=doc_ce->len*3) {
doc->cur_entry=doc_ce=doc_ce->next;
doc->cur_data_col=doc_ce->min_col;
doc->x=doc_ce->x+doc->cur_data_col;
doc->y=doc_ce->y;
}
if (unlock)
DocUnlock(doc);
return;
}
x=doc->x; y=doc->y;
if (IsEditableText(doc_ce)) {
if (doc->cur_data_col>doc_ce->min_col && doc->cur_data_col<doc_ce->max_col-1) {
dst=doc_ce->tag+doc->cur_data_col;
doc_ne=DocEntryNew(doc,doc_ce,StrNew(dst,doc->mem_task));
*dst=0;
if (sc>=0) {
if (sc&SCF_SHIFT)
doc_ne->type=doc_ce->type | DOCET_SELECTED;
else
doc_ne->type=doc_ce->type & ~DOCET_SELECTED;
}
doc_ne->x=doc_ce->x+doc->cur_data_col;
doc_ce->max_col=doc->cur_data_col;
QueIns(doc_ne,doc_ce);
doc_ce=doc_ne;
doc->cur_data_col=doc_ce->min_col;
}
}
doc_ce2=doc_ce;
while (doc_ce!=doc && (doc_ce->y<=y || doc_ce->de_flags & (DOCEF_SKIP|DOCEF_HARD_SKIP|DOCEF_FILTER_SKIP)))
doc_ce=doc_ce->next;
y=doc_ce->y;
doc->y=y;
while (doc_ce!=doc && (doc_ce->y<=y && doc_ce->x<=x || doc_ce->de_flags & (DOCEF_SKIP|DOCEF_HARD_SKIP|DOCEF_FILTER_SKIP))) {
old_de_flags=doc_ce->de_flags;
old_color=doc_ce->type;
doc_ce=doc_ce->next;
}
if (doc_ce->last!=doc && (doc_ce->x>x || doc_ce->y>y)) {
doc_ce=doc_ce->last;
doc->cur_entry=doc_ce;
if (!((doc_ce->type_u8==DOCT_NEW_LINE || doc_ce->type_u8==DOCT_SOFT_NEW_LINE || doc_ce->type_u8==DOCT_INDENT) &&
(doc_ce->last->type_u8==DOCT_NEW_LINE || doc_ce->last->type_u8==DOCT_SOFT_NEW_LINE || doc_ce->last->type_u8==DOCT_INDENT)))
DocFormBwd(doc);
doc_ce=doc->cur_entry;
}
while (doc_ce2!=doc && (doc_ce2!=doc_ce || IsEditableText(doc_ce))) {
if (doc_ce2->y<y || doc_ce2->x<x || doc_ce2->de_flags & (DOCEF_SKIP|DOCEF_HARD_SKIP|DOCEF_FILTER_SKIP) ||
doc_ce2->x==x && !doc_ce2->max_col &&
Bt(doldoc.type_flags_nontag_invisible,doc_ce2->type_u8)) {
if (sc>=0)
BEqu(&doc_ce2->type,DOCEt_SELECTED,sc&SCF_SHIFT);
}
if (doc_ce2==doc_ce) break;
doc_ce2=doc_ce2->next;
}
if (doc_ce->de_flags&DOCEF_TAG) {
doc->cur_data_col=x-doc_ce->x;
if (IsEditableText(doc_ce)) {
if (doc->cur_data_col>doc_ce->max_col)
doc->cur_data_col=doc_ce->max_col;
} else {
if (doc->cur_data_col>=doc_ce->max_col)
doc->cur_data_col=doc_ce->max_col-1;
}
if (doc->cur_data_col<doc_ce->min_col)
doc->cur_data_col=doc_ce->min_col;
} else
doc->cur_data_col=doc_ce->min_col;
if (IsEditableText(doc_ce)) {
if (doc_ce->min_col<doc->cur_data_col<doc_ce->max_col-1) {
dst=doc_ce->tag+doc->cur_data_col;
doc_ne=DocEntryNew(doc,doc_ce,StrNew(dst,doc->mem_task));
*dst=0;
doc_ne->type=DOCT_TEXT | old_color & -0x100;
doc_ne->de_flags=old_de_flags|doldoc.dft_de_flags[DOCT_TEXT];
doc_ce->max_col=doc->cur_data_col;
doc_ne->x=doc_ce->x+doc->cur_data_col;
QueIns(doc_ne,doc_ce);
doc_ce=doc_ne;
doc->cur_data_col=doc_ce->min_col;
}
}
doc->cur_entry=doc_ce;
DocFormFwd(doc);
if (!(doc->flags & DOCF_FORM))
while (doc_ce!=doc && doc_ce!=doc->cur_entry) {
if (sc>=0)
BEqu(&doc_ce->type,DOCEt_SELECTED,sc&SCF_SHIFT);
doc_ce=doc_ce->next;
}
doc->x=doc->cur_entry->x+doc->cur_data_col;
if (unlock)
DocUnlock(doc);
}
U0 EdDelChar(CDoc *doc)
{
Bool unlock=DocLock(doc);
CDocEntry *doc_ce=doc->cur_entry;
if (doc_ce==doc) {
if (unlock)
DocUnlock(doc);
return;
}
if (doc_ce->max_col!=0 && (IsEditableText(doc_ce)||doc_ce->type_u8==DOCT_DATA)) {
if (doc_ce->type_u8==DOCT_DATA) {
if (doc_ce->de_flags & DOCEF_HAS_TERMINATOR && doc->cur_data_col==doc_ce->max_col-1) {
if (unlock)
DocUnlock(doc);
return;
}
}
if (doc->cur_data_col<doc_ce->max_col)
StrCpy(doc_ce->tag+doc->cur_data_col,doc_ce->tag+doc->cur_data_col+1);
if (doc->cur_data_col>=doc_ce->max_col-1) {
doc->cur_entry=doc_ce->next;
doc->cur_data_col=doc->cur_entry->min_col;
}
DocRemSoftNewLines(doc,doc->cur_entry);
if (unlock)
DocUnlock(doc);
return;
}
doc->cur_entry=doc_ce->next;
doc->cur_data_col=doc->cur_entry->min_col;
if (!(doc_ce->de_flags&DOCEF_FILTER_SKIP))
DocEntryDel(doc,doc_ce);
DocRemSoftNewLines(doc,doc->cur_entry);
if (unlock)
DocUnlock(doc);
}
U0 ChkDollarBufSize(CDoc *doc)
{
U8 *b;
if (doc->dollar_buf_ptr>=doc->dollar_buf_size-2) {
doc->dollar_buf_size<<=1;
b=MAlloc(doc->dollar_buf_size,doc->mem_task);
MemCpy(b,doc->dollar_buf,doc->dollar_buf_ptr);
Free(doc->dollar_buf);
doc->dollar_buf=b;
}
}
U0 EdInsChar(I64 ch,I64 sc,CDoc *doc)
{
Bool unlock=DocLock(doc);
U8 *b,*src,*dst;
CDocEntry *doc_ce=doc->cur_entry,*doc_ne;
I64 i,j,m,y=doc_ce->y;
if (doc->flags & DOCF_IN_DOLLAR) {
if (!Bt(chars_bitmap_getkey,ch))
goto ic_done;
ChkDollarBufSize(doc);
doc->dollar_buf[doc->dollar_buf_ptr++]=ch;
if (ch=='$$') {
if (doc->dollar_buf_ptr==2) {
doc->flags&=~DOCF_IN_DOLLAR;
doc->dollar_buf_ptr=0;
goto ic_cont;
} else {
doc->dollar_buf[doc->dollar_buf_ptr]=0;
DocPrint(doc,doc->dollar_buf);
doc->flags&=~DOCF_IN_DOLLAR;
doc->dollar_buf_ptr=0;
goto ic_done;
}
} else
goto ic_done;
}
if (ch=='$$') {
if (!(doc->flags & (DOCF_PLAIN_TEXT | DOCF_PLAIN_TEXT_WITH_TABS))) {
doc->flags|=DOCF_IN_DOLLAR;
doc->dollar_buf_ptr=0;
doc->dollar_buf[doc->dollar_buf_ptr++]=ch;
goto ic_done;
}
}
if (ch=='\r') goto ic_done;
ic_cont:
if ((ch==CH_SPACE || ch=='\n') &&
!(sc & (SCF_CTRL|SCF_SHIFT)) &&
doc_ce->de_flags & (DOCEF_LINK|DOCEF_TREE|DOCEF_LST|DOCEF_CHECK_COLLAPSABLE|
DOCEF_LEFT_MACRO|DOCEF_LEFT_EXP|DOCEF_LEFT_CB|DOCEF_LEFT_AUTO |
DOCEF_RIGHT_MACRO|DOCEF_RIGHT_EXP|DOCEF_RIGHT_CB|DOCEF_RIGHT_AUTO)) {
doc->cmd_U8=ch;
DocEntryRun(doc,doc_ce,FALSE);
DocLock(doc);
goto ic_done;
}
if (doc_ce->type_u8==DOCT_HEX_ED) {
if (doc_ce->de_flags & DOCEF_DATA_IS_PTR)
b=doc_ce->data;
else
b=&doc_ce->data;
i=doc->cur_data_col;
j=i%(doc_ce->hex_ed_width*3);
m=i/(doc_ce->hex_ed_width*3)*doc_ce->hex_ed_width;
if (j>=doc_ce->hex_ed_width<<1)
b[j-doc_ce->hex_ed_width<<1+m]=ch;
else {
ch=ToUpper(ch)-'0';
if (ch>9) {
ch+='0'-'A'+10;
if (!(10<=ch<=15))
goto ic_done;
}
m=j>>1+m;
if (j & 1)
b[m]=b[m] & 0xF0| ch;
else
b[m]=b[m] & 0xF | ch<<4;
}
doc->cur_data_col++;
goto ic_done;
}
if (doc->flags & DOCF_OVERSTRIKE) {
if (Bt(chars_bitmap_displayable,ch)) {
ic_overstrike_char:
if (IsEditableText(doc_ce)) {
if (doc->cur_data_col<doc_ce->max_col) {
if (doc_ce->tag[doc->cur_data_col]) {
doc_ce->tag[doc->cur_data_col++]=ch;
goto ic_done;
}
} else {
doc_ce=doc_ce->next;
doc->cur_entry=doc_ce;
doc->cur_data_col=doc_ce->min_col;
goto ic_overstrike_char;
}
} else if (doc_ce->type_u8==DOCT_DATA) {
if (doc_ce->de_flags & DOCEF_HAS_TERMINATOR) {
if (doc_ce->tag[doc->cur_data_col] &&
doc->cur_data_col<doc_ce->min_col+doc_ce->len) {
doc_ce->tag[doc->cur_data_col++]=ch;
if ( ! doc_ce->tag[doc->cur_data_col]) {
doc_ce->tag[doc->cur_data_col]='_';
doc_ce->tag[doc->cur_data_col+1]=0;
}
}
} else {
if (doc_ce->tag[doc->cur_data_col])
doc_ce->tag[doc->cur_data_col++]=ch;
}
goto ic_done;
}
b=MAlloc(2,doc->mem_task);
*b=ch;
b[1]=0;
doc_ne=DocEntryNew(doc,doc_ce,b);
doc_ne->type=DOCT_TEXT | doc->settings_root.dft_text_attr<<8;
doc_ne->de_flags=doldoc.dft_de_flags[DOCT_TEXT];
QueIns(doc_ne,doc_ce->last);
} else if (ch=='\n') {
while (doc->cur_entry->next!=doc && doc->cur_entry->y==y)
doc->cur_entry=doc->cur_entry->next;
doc->cur_data_col=doc->cur_entry->min_col;
} else if (ch=='\t') {
if (doc->flags&DOCF_FORM)
goto ic_form_tab;
}
goto ic_done;
}
if (ch=='\n') {
doc_ne=CAlloc(sizeof(CDocEntryBase),doc->mem_task);
if (sc&SCF_CTRL && !(sc&SCF_SHIFT)) {
doc_ne->type=DOCT_PAGE_BREAK | doc->settings_root.dft_text_attr<<8;
doc_ne->de_flags=doldoc.dft_de_flags[DOCT_PAGE_BREAK];
} else {
doc_ne->type=DOCT_NEW_LINE | doc->settings_root.dft_text_attr<<8;
doc_ne->de_flags=doldoc.dft_de_flags[DOCT_NEW_LINE];
}
DocInsEntry(doc,doc_ne);
} else if (ch=='\t') {
if (doc->flags&DOCF_FORM &&
Bt(doldoc.type_flags_form,doc->cur_entry->type_u8) &&
!(doc->cur_entry->de_flags&DOCEF_SKIP_IN_FORM)) {
ic_form_tab:
doc->cur_entry=doc->cur_entry->next;
doc->cur_data_col=doc->cur_entry->min_col;
DocFormFwd(doc);
goto ic_done;
} else {
doc_ne=CAlloc(sizeof(CDocEntryBase),doc->mem_task);
doc_ne->type=DOCT_TAB | doc->settings_root.dft_text_attr<<8;
doc_ne->de_flags=doldoc.dft_de_flags[DOCT_TAB];
DocInsEntry(doc,doc_ne);
}
} else {
if (Bt(chars_bitmap_displayable,ch)) {
if (doc_ce->type_u8==DOCT_DATA) {
i=doc_ce->len+doc_ce->min_col;
if (doc_ce->de_flags & DOCEF_HAS_TERMINATOR)
i++;
if (i>doc_ce->max_col) {
b=doc_ce->tag;
doc_ce->max_col++;
for (i=doc_ce->max_col;i>doc->cur_data_col;i--)
b[i]=b[i-1];
b[doc->cur_data_col++]=ch;
}
} else if (IsEditableText(doc_ce)) {
dst=b=MAlloc(doc_ce->max_col+2,doc->mem_task);
src=doc_ce->tag;
i=doc->cur_data_col;
while (i-->0)
*dst++=*src++;
*dst++=ch;
while (*dst++=*src++);
Free(doc_ce->tag);
doc_ce->tag=b;
doc_ce->max_col++;
doc->cur_data_col++;
} else {
b=MAlloc(2,doc->mem_task);
*b=ch;
b[1]=0;
doc_ne=DocEntryNew(doc,doc_ce,b);
doc_ne->type=DOCT_TEXT | doc->settings_root.dft_text_attr<<8;
doc_ne->de_flags=doldoc.dft_de_flags[DOCT_TEXT];
doc_ne->x=doc_ce->x+1;
QueIns(doc_ne,doc_ce->last);
}
}
}
ic_done:
DocRemSoftNewLines(doc,doc->cur_entry);
if (doc->cur_entry->de_flags & DOCEF_UPDATE_DATA) {
if (doc->cur_entry->type_u8==DOCT_DATA ||
doc->cur_entry->type_u8==DOCT_CHECK_BOX)
DocDataScan(doc,doc->cur_entry);
}
if (unlock)
DocUnlock(doc);
}
U0 EdDelLine(CDoc *doc)
{
CDocEntry *doc_ce=doc->cur_entry,*doc_ce2;
I64 y;
y=doc->y;
while (doc_ce!=doc && doc_ce->y==y)
doc_ce=doc_ce->next;
doc->cur_entry=doc_ce;
doc->cur_data_col=doc_ce->min_col;
doc_ce=doc_ce->last;
while (doc_ce!=doc && doc_ce->y==y) {
doc_ce2=doc_ce->last;
if (!(doc_ce->de_flags&DOCEF_FILTER_SKIP))
DocEntryDel(doc,doc_ce);
doc_ce=doc_ce2;
}
}
U0 DocEntryToggle(CDoc *doc)
{
Bool unlock=DocLock(doc),old_color_names;
CDocEntry *doc_ce=doc->cur_entry,*cl1,*doc_ce2;
U8 ch,*st,*st2;
I64 i,j,k;
if (doc_ce!=doc && !(doc->flags&(DOCF_PLAIN_TEXT|DOCF_PLAIN_TEXT_WITH_TABS))) {
if (doc_ce->type_u8==DOCT_TEXT && !(doc_ce->de_flags & ~(DOCEF_TAG|DOCG_BL_IV_UL|DOCEF_WORD_WRAP|DOCEF_HIGHLIGHT|DOCEF_SKIP|DOCEF_HARD_SKIP|DOCEF_FILTER_SKIP))) {
doc_ce2=doc_ce->last;
for (k=0;k<20;k++) {
if (doc_ce2!=doc) {
cl1=doc_ce2->last;
if (doc_ce2->type_u8==DOCT_TEXT && doc_ce->de_flags==doc_ce2->de_flags && doc_ce->type==doc_ce2->type) {
i=StrLen(doc_ce2->tag);
j=StrLen(doc_ce->tag);
st=MAlloc(i+j+1,doc->mem_task);
MemCpy(st,doc_ce2->tag,i);
MemCpy(st+i,doc_ce->tag,j+1);
Free(doc_ce->tag);
doc_ce->tag=st;
doc_ce->max_col=i+j;
doc->cur_data_col+=i;
DocEntryDel(doc,doc_ce2);
} else if (doc_ce2->type_u8==DOCT_SOFT_NEW_LINE)
DocEntryDel(doc,doc_ce2);
else
break;
doc_ce2=cl1;
} else
break;
}
doc_ce2=doc_ce->next;
for (k=0;k<20;k++) {
if (doc_ce2!=doc) {
cl1=doc_ce2->next;
if (doc_ce2->type_u8==DOCT_TEXT && doc_ce->de_flags==doc_ce2->de_flags && doc_ce->type==doc_ce2->type) {
i=StrLen(doc_ce->tag);
j=StrLen(doc_ce2->tag);
st=MAlloc(i+j+1,doc->mem_task);
MemCpy(st,doc_ce->tag,i);
MemCpy(st+i,doc_ce2->tag,j+1);
Free(doc_ce->tag);
doc_ce->tag=st;
doc_ce->max_col=i+j;
DocEntryDel(doc,doc_ce2);
} else if (doc_ce2->type_u8==DOCT_SOFT_NEW_LINE)
DocEntryDel(doc,doc_ce2);
else
break;
doc_ce2=cl1;
} else
break;
}
i=doc->cur_data_col;
while (i>doc_ce->min_col && doc_ce->tag[i]!='$$')
i--;
j=doc->cur_data_col+1;
while (j<doc_ce->max_col && doc_ce->tag[j]!='$$')
j++;
if (i<j-1 && doc_ce->min_col<=i<j<doc_ce->max_col && doc_ce->tag[i]=='$$' && doc_ce->tag[j]=='$$') {
ch=doc_ce->tag[j+1];
doc_ce->tag[j+1]=0;
st=StrNew(doc_ce->tag+i);
doc_ce->tag[j+1]=ch;
StrCpy(doc_ce->tag+i,doc_ce->tag+j+1);
doc->cur_data_col=i;
st2=MStrPrint("%q",st);
if (doc_ce=DocPrint(doc,st2)) {
doc->cur_entry=doc_ce;
doc->cur_data_col=doc_ce->min_col;
}
Free(st);
Free(st2);
}
} else {
old_color_names=LBts(&doc->flags,DOCf_COLOR_NAMES);
st=Doc2PlainText(doc,doc_ce);
LBEqu(&doc->flags,DOCf_COLOR_NAMES,old_color_names);
DocEntryDel(doc,doc_ce);
DocPrint(doc,"$$$$%Q$$$$",st);
}
DocRecalc(doc);
}
if (unlock)
DocUnlock(doc);
}
U0 DocFlagsToggle(CDoc *doc,I64 tog_flags)
{
Bool unlock=DocLock(doc);
I64 size,flags=doc->flags^tog_flags;
U8 *st;
CDocUndo *u_next,*u_last;
doc->flags|=DOCF_COLOR_NAMES;
st=DocSave(doc,&size);
u_next=doc->undo_root.next;
u_last=doc->undo_root.last;
doc->undo_root.next=doc->undo_root.last=&doc->undo_root;
DocRst(doc,TRUE);
doc->undo_root.next=u_next;
doc->undo_root.last=u_last;
DocUndoCntSet(doc);
doc->flags=flags & ~(DOCG_BL_IV_UL|DOCF_WORD_WRAP);
DocLoad(doc,st,size);
DocCenter(doc);
if (unlock)
DocUnlock(doc);
Free(st);
}
+967
View File
@@ -0,0 +1,967 @@
#help_index "DolDoc/Output"
public U0 DocPutKey(CDoc *doc,I64 ch=0,I64 sc=0)
{//$LK,"PutKey",A="MN:PutKey"$(ch,sc) at doc insert pt, cur_entry.
I64 i,x,y,sc2,ext_ascii_cnt=0;
CDoc *m;
CDocEntry *doc_ce;
U8 *st,*st2;
Bool unlock;
if (!doc && !(doc=DocPut) || doc->doc_signature!=DOC_SIGNATURE_VAL)
return;
if (doc->user_put_key && (*doc->user_put_key)(doc,doc->user_put_data,ch,sc))
return;
unlock=DocLock(doc);
if (!Bt(doldoc.clean_scan_codes,sc.u8[0]))
doc->flags|=DOCF_UNDO_DIRTY;
DocCaptureUndo(doc);
if (Bt(chars_bitmap_getkey,ch) &&
!(sc&(SCF_CTRL|SCF_ALT))) {
if (sc&SCF_KEY_DESC) {
st=Char2KeyName(ch,FALSE);
SetKeyDesc("Char/'%s'",st);
Free(st);
} else
EdInsChar(ch,sc,doc);
} else {
doc_ce=doc->cur_entry;
x=doc->x; y=doc->y;
sc2=sc.u8[0];
switch (ch) {
case CH_CTRLA:
if (sc&SCF_KEY_DESC)
SetKeyDesc("Edit/Save As");
else
DocWrite(doc,TRUE);
break;
case CH_CTRLB:
if (sc&SCF_KEY_DESC)
SetKeyDesc("Win/Toggle Border");
else
WinBorder(Bt(&doc->win_task->display_flags,DISPLAYf_NO_BORDER),doc->win_task);
break;
case CH_CTRLC:
if (sc&SCF_KEY_DESC)
SetKeyDesc("Edit/Copy to Clipboard");
else
EdCopyToClipboard(doc);
break;
case CH_CTRLD:
if (sc&SCF_KEY_DESC)
SetKeyDesc("Cmd/Jump to File Manager");
else {
DocUnlock(doc);
FileMgr;
DocLock(doc);
}
break;
case CH_CTRLF:
if (sc&SCF_SHIFT) {
if (sc&SCF_KEY_DESC)
SetKeyDesc("Cmd/Grep Wizard");
else
GrepWiz;
} else {
if (sc&SCF_KEY_DESC)
SetKeyDesc("Edit/Find & Replace");
else
EdFindReplace(doc);
}
break;
case CH_CTRLG:
if (sc&SCF_KEY_DESC)
SetKeyDesc("Edit/GoTo Line Num");
else
EdGoToLine(doc);
break;
case CH_BACKSPACE: //<CTRL-H>
if (sc&SCF_ALT && !(sc&SCF_CTRL)) {
if (sc&SCF_KEY_DESC)
SetKeyDesc("Edit/Undo");
else
DocUndoRestore(doc);
} else {
if (sc&SCF_KEY_DESC)
SetKeyDesc("Char/Back Space");
else {
DocCaptureUndo(doc);
doc_ce=doc->cur_entry;
if (doc->cur_data_col<=doc_ce->min_col) {
doc_ce=doc->cur_entry=doc_ce->last;
if (doc_ce!=doc && doc_ce->type_u8==DOCT_SOFT_NEW_LINE)
doc_ce=doc->cur_entry=doc_ce->last;
if (doc_ce==doc || doc_ce->type_u8==DOCT_PMT) {
doc_ce=doc->cur_entry=doc_ce->next;
doc->cur_data_col=doc_ce->min_col;
} else {
doc->cur_data_col=doc_ce->max_col;
if (doc->cur_data_col>doc_ce->min_col)
doc->cur_data_col--;
EdDelChar(doc);
}
} else {
doc->cur_data_col--;
EdDelChar(doc);
}
}
}
break;
case CH_CTRLI:
if (sc&SCF_SHIFT) {
if (sc&SCF_KEY_DESC)
SetKeyDesc("Dollar/Indent Out");
else
DocPrint(doc,"$$ID,-2$$");
} else {
if (sc&SCF_KEY_DESC)
SetKeyDesc("Dollar/Indent In");
else
DocPrint(doc,"$$ID,2$$");
}
break;
case '\n':
if (sc&SCF_KEY_DESC) {
if (sc&SCF_SHIFT)
SetKeyDesc("Char/Return");
else
SetKeyDesc("Char/Page Break");
} else
EdInsChar(ch,sc,doc);
break;
case CH_CTRLK:
if (sc&SCF_KEY_DESC)
SetKeyDesc("Dollar/Toggle Blinking Text");
else if (sc&SCF_SHIFT)
DocPrint(doc,"$$BK,0$$");
else
DocPrint(doc,"$$BK,1$$");
break;
case CH_CTRLL:
if (sc&SCF_KEY_DESC) {
if (sc&SCF_SHIFT)
SetKeyDesc("Edit/Code Tools");
else
SetKeyDesc("Dollar/Wizard");
} else {
if (sc&SCF_SHIFT)
EdCodeTools(doc);
else {
DocUnlock(doc);
EdInsDollarCmd;
DocLock(doc);
}
}
break;
case CH_CTRLM:
if (sc&SCF_KEY_DESC) {
if (sc&SCF_SHIFT)
SetKeyDesc("Cmd/Jump to Notes File");
else
SetKeyDesc("Cmd/Jump to Menu");
} else {
if (sc&SCF_SHIFT)
Ed("HOME/PersonalNotes.TXT.Z");
else {
m=DocRead("HOME/PersonalMenu.TXT.Z");
DocMenuDo(m);
DocDel(m);
}
}
break;
case CH_CTRLO:
if (sc&SCF_KEY_DESC) {
if (sc&SCF_SHIFT)
SetKeyDesc("Edit/Collapse");
else
SetKeyDesc("Edit/Uncolapse");
} else {
if (sc&SCF_SHIFT)
DocCollapse(TRUE,doc);
else
DocCollapse(FALSE,doc);
}
break;
case CH_CTRLP:
if (doc->flags & (DOCF_SUPERSCRIPT_MODE | DOCF_SUBSCRIPT_MODE)) {
if (sc&SCF_KEY_DESC)
SetKeyDesc("Dollar/Toggle Super or Sub script");
else {
DocPrint(doc,"$$SY,0$$");
doc->flags&=~(DOCF_SUPERSCRIPT_MODE | DOCF_SUBSCRIPT_MODE);
}
} else if (sc&SCF_SHIFT) {
if (sc&SCF_KEY_DESC)
SetKeyDesc("Dollar/Toggle Subscript");
else {
DocPrint(doc,"$$SY,3$$");
doc->flags|=DOCF_SUBSCRIPT_MODE;
}
} else {
if (sc&SCF_KEY_DESC)
SetKeyDesc("Dollar/Toggle Superscript");
else {
DocPrint(doc,"$$SY,-3$$");
doc->flags|=DOCF_SUPERSCRIPT_MODE;
}
}
break;
case CH_CTRLQ:
break;
case CH_CTRLR:
if (sc&SCF_KEY_DESC)
SetKeyDesc("Dollar/Edit or Create Graphic");
else {
if (!(doc->flags&(DOCF_PLAIN_TEXT|DOCF_PLAIN_TEXT_WITH_TABS))) {
DocUnlock(doc);
if (doc_ce->type_u8==DOCT_SPRITE)
EdSpriteEd(doc,
(doc_ce->x-doc->line_start_col+doc_ce->max_col)*FONT_WIDTH,
(doc_ce->y-doc->cur_top_line_num)*FONT_HEIGHT);
else
EdSpriteIns(doc,
(doc_ce->x+doc->cur_data_col-doc->line_start_col)*FONT_WIDTH,
(doc_ce->y-doc->cur_top_line_num)*FONT_HEIGHT);
DocLock(doc);
}
}
break;
case CH_CTRLS:
if (sc&SCF_SHIFT) {
if (sc&SCF_KEY_DESC)
SetKeyDesc("Edit/Find Misspelled");
else
WSFindMisspelled(doc);
} else {
if (sc&SCF_KEY_DESC)
SetKeyDesc("Edit/Save");
else
DocWrite(doc);
}
break;
case CH_CTRLT:
if (sc&SCF_SHIFT) {
if (sc&SCF_KEY_DESC)
SetKeyDesc("Edit/Single Entry Toggle Plain Text");
else
DocEntryToggle(doc);
} else {
if (sc&SCF_KEY_DESC)
SetKeyDesc("Edit/Toggle Plain Text Display");
else
if (!(doc->flags&DOCF_FORM) || doc->flags&(DOCF_PLAIN_TEXT|DOCF_PLAIN_TEXT_WITH_TABS))
DocFlagsToggle(doc,DOCF_PLAIN_TEXT);
}
break;
case CH_CTRLU:
if (sc&SCF_KEY_DESC)
SetKeyDesc("Dollar/Toggle Underline");
else if (sc&SCF_SHIFT)
DocPrint(doc,"$$UL,0$$");
else
DocPrint(doc,"$$UL,1$$");
break;
case CH_CTRLV:
if (sc&SCF_KEY_DESC)
SetKeyDesc("Edit/Paste Clipboard");
else
EdPasteClipboard(doc);
break;
case CH_CTRLW:
if (sc&SCF_KEY_DESC)
SetKeyDesc("Dollar/Toggle Word Wrap");
else if (sc&SCF_SHIFT)
DocPrint(doc,"$$WW,0$$");
else
DocPrint(doc,"$$WW,1$$");
break;
case CH_CTRLX:
if (sc&SCF_KEY_DESC)
SetKeyDesc("Edit/Cut To Clipboard");
else
EdCutToClipboard(doc);
break;
case CH_CTRLY:
if (sc&SCF_KEY_DESC)
SetKeyDesc("Edit/Delete Line");
else
EdDelLine(doc);
break;
case CH_CTRLZ:
if (sc&SCF_KEY_DESC)
SetKeyDesc("Dollar/Toggle Inverted Text");
else if (sc&SCF_SHIFT)
DocPrint(doc,"$$IV,0$$");
else
DocPrint(doc,"$$IV,1$$");
break;
case '0'...'9':
if (!(sc&SCF_ALT)) {
if (sc&SCF_CTRL) {
if (sc&SCF_KEY_DESC) {
if (sc&SCF_SHIFT)
SetKeyDesc("Edit/Jump to Word Definition");
else
SetKeyDesc("Edit/Autocomplete Word");
} else {
if (WordStat(ON)) {
DocUnlock(doc);
if (sc&SCF_SHIFT)
WSDDef(ch-'0',Fs);
else
WSDFillin(ch-'0');
DocLock(doc);
}
}
}
} else {
if (sc&SCF_KEY_DESC)
SetKeyDesc("Edit/Enter extended-ASCII");
else {
if (++doc->ext_ascii_cnt==1)
doc->ext_ascii_val=ch-'0';
else
doc->ext_ascii_val=doc->ext_ascii_val*10+ch-'0';
if (doc->ext_ascii_cnt==3)
EdInsChar(doc->ext_ascii_val.u8[0],sc,doc);
else
ext_ascii_cnt=doc->ext_ascii_cnt;
}
}
break;
case '[':
if (!(sc&SCF_ALT) && sc&SCF_CTRL) {
if (sc&SCF_SHIFT) {
if (sc&SCF_KEY_DESC)
SetKeyDesc("Edit/GoTo matching brace");
else
EdFindPaired(doc,'}','{',FALSE);
} else {
if (sc&SCF_KEY_DESC)
SetKeyDesc("Edit/GoTo matching bracket");
else
EdFindPaired(doc,']','[',FALSE);
}
}
break;
case ']':
if (!(sc&SCF_ALT) && sc&SCF_CTRL) {
if (sc&SCF_SHIFT) {
if (sc&SCF_KEY_DESC)
SetKeyDesc("Edit/GoTo matching brace");
else
EdFindPaired(doc,'{','}',TRUE);
} else {
if (sc&SCF_KEY_DESC)
SetKeyDesc("Edit/GoTo matching bracket");
else
EdFindPaired(doc,'[',']',TRUE);
}
}
break;
default:
switch (sc2) {
case SC_F1...SC_F10:
if (!(sc&SCF_ALT)) {
if (sc&SCF_CTRL) {
if (sc&SCF_KEY_DESC) {
if (sc&SCF_SHIFT)
SetKeyDesc("Edit/Jump to Src of Sym");
else
SetKeyDesc("Edit/Autocomplete Sym");
} else {
DocUnlock(doc);
if (WordStat(ON)) {
if (sc&SCF_SHIFT)
WSMan(sc2-SC_F1+1,Fs);
else
WSFillIn(sc2-SC_F1+1);
}
DocLock(doc);
}
} else {
switch (sc2) {
case SC_F1:
if (sc&SCF_KEY_DESC) {
if (sc&SCF_SHIFT)
SetKeyDesc("About");
else
SetKeyDesc("Help");
} else {
if (sc&SCF_SHIFT)
Ed("::/Doc/Splash.TXT.Z");
else
Ed("::/Doc/HelpIndex.TXT.Z");
}
break;
case SC_F2:
if (sc&SCF_KEY_DESC) {
if (sc&SCF_SHIFT)
SetKeyDesc("Edit/Play Macro");
else
SetKeyDesc("Edit/Macro");
} else {
DocUnlock(doc);
if (sc&SCF_SHIFT) {
if (TaskValidate(sys_macro_util_task))
SendMsg(sys_macro_util_task,MSG_KEY_DOWN_UP,CH_SHIFT_ESC,0);
SysMacroStripKey(&sys_macro_root,ch,sc);
PlaySysMacro;
} else
EdMacroUtil;
DocLock(doc);
}
break;
case SC_F3:
if (sc&SCF_KEY_DESC) {
if (sc&SCF_SHIFT)
SetKeyDesc("Edit/Find Last");
else
SetKeyDesc("Edit/Find Next");
}else {
doc->find_replace->scan_fwd=!(sc&SCF_SHIFT);
EdFindNext(doc);
}
break;
case SC_F4:
if (sc&SCF_KEY_DESC) {
if (sc&SCF_SHIFT)
SetKeyDesc("Misc/Insert Directory Name");
else
SetKeyDesc("Misc/Insert FileName");
} else {
DocUnlock(doc);
if (sc&SCF_SHIFT)
st=PopUpPickDir;
else
st=PopUpPickFile;
DocLock(doc);
if (st) {
DocPrintPartial(doc,"%s",st);
Free(st);
}
}
break;
case SC_F5:
if (sc&SCF_KEY_DESC) {
if (sc&SCF_SHIFT)
SetKeyDesc("Cmd/Adam Include");
else
SetKeyDesc("Cmd/Run (Execute);Dbg/Go");
} else {
if (st2=DocEntryLink(doc,doc_ce)) {
st=DocLinkFile(st2);
Free(st2);
} else {
DocWrite(doc);
st=StrNew(doc->filename.name);
}
if (st2=DirFile(st,"Run","CPP.Z")) {
if (FileFind(st2)) {
Free(st);
st=st2;
} else
Free(st2);
}
if (st) {
if (sc&SCF_SHIFT)
AdamFile(st);
else
PopUpFile(st);
Free(st);
}
}
break;
case SC_F6:
if (sc&SCF_KEY_DESC) {
if (sc & SCF_SHIFT)
SetKeyDesc("God Doodle");
else
SetKeyDesc("God Song");
} else {
//$LK,"::/Adam/God/HSNotes.TXT"$
if (sc & SCF_SHIFT)
GodDoodle;
else
GodSong;
}
break;
case SC_F7:
if (sc&SCF_KEY_DESC) {
if (sc & SCF_SHIFT)
SetKeyDesc("God Passage");
else
SetKeyDesc("God Word");
} else {
//$LK,"::/Adam/God/HSNotes.TXT"$
FifoU8Flush(god.fifo);
GodBitsIns(GOD_GOOD_BITS,KbdMouseEvtTime>>GOD_BAD_BITS);
if (sc & SCF_SHIFT)
GodPassage;
else
GodWord;
}
break;
}
}
}
break;
case SC_CURSOR_DOWN:
case SC_END:
if (sc2==SC_END || sc&SCF_CTRL) {
if (sc&SCF_KEY_DESC) {
if (sc&SCF_SHIFT)
SetKeyDesc("Edit/GoTo Doc End, Select");
else
SetKeyDesc("Edit/GoTo Doc End");
} else {
while (doc_ce!=doc) {
BEqu(&doc_ce->type,DOCEt_SELECTED,sc&SCF_SHIFT);
doc_ce=doc->cur_entry=doc_ce->next;
}
doc->cur_data_col=doc_ce->min_col;
DocFormBwd(doc);
}
} else if (sc&SCF_KEY_DESC) {
if (sc&SCF_SHIFT)
SetKeyDesc("Edit/Cursor Down, Select");
else
SetKeyDesc("Edit/Cursor Down");
} else
EdLineDown(doc,sc);
break;
case SC_CURSOR_UP:
case SC_HOME:
if (sc2==SC_HOME || sc&SCF_CTRL) {
if (sc&SCF_KEY_DESC) {
if (sc&SCF_SHIFT)
SetKeyDesc("Edit/GoTo Top of Doc, Select");
else
SetKeyDesc("Edit/GoTo Top of Doc");
} else {
if (doc_ce==doc) doc_ce=doc_ce->last;
while (doc_ce!=doc) {
BEqu(&doc_ce->type,DOCEt_SELECTED,sc&SCF_SHIFT);
doc_ce=doc->cur_entry=doc_ce->last;
}
doc_ce=doc->cur_entry=doc->root.next;
doc->cur_data_col=doc_ce->min_col;
DocFormFwd(doc);
}
} else if (sc&SCF_KEY_DESC) {
if (sc&SCF_SHIFT)
SetKeyDesc("Edit/Cursor Up, Select");
else
SetKeyDesc("Edit/Cursor Up");
} else
EdLineUp(doc,sc);
break;
case SC_PAGE_DOWN:
if (sc&SCF_KEY_DESC) {
if (sc&SCF_SHIFT)
SetKeyDesc("Edit/Page Down, Select");
else
SetKeyDesc("Edit/Page Down");
} else {
i=doc_ce->y+doc->win_task->win_height-1;
if (doc_ce->type_u8==DOCT_HEX_ED)
i+=doc->cur_data_col/3/doc_ce->hex_ed_width;
while (doc_ce!=doc &&
(doc_ce->type_u8!=DOCT_HEX_ED && doc_ce->y<i ||
doc_ce->type_u8==DOCT_HEX_ED && doc_ce->y+doc->cur_data_col/3/doc_ce->hex_ed_width<i)) {
EdLineDown(doc,sc);
//paranoid check for stuck on same node
if (doc->cur_entry==doc_ce && doc_ce->type_u8!=DOCT_HEX_ED)
break;
doc_ce=doc->cur_entry;
}
}
break;
case SC_PAGE_UP:
if (sc&SCF_KEY_DESC) {
if (sc&SCF_SHIFT)
SetKeyDesc("Edit/Page Up, Select");
else
SetKeyDesc("Edit/Page Up");
}else {
i=doc_ce->y-(doc->win_task->win_height-1);
if (doc_ce->type_u8==DOCT_HEX_ED)
i+=doc->cur_data_col/3/doc_ce->hex_ed_width;
while (doc_ce->last!=doc &&
(doc_ce->type_u8!=DOCT_HEX_ED && doc_ce->y>i ||
doc_ce->type_u8==DOCT_HEX_ED && doc_ce->y+doc->cur_data_col/3/doc_ce->hex_ed_width>i) &&
doc_ce->y!=doc->root.next->y) {
EdLineUp(doc,sc);
//paranoid check for stuck on same node
if (doc->cur_entry==doc_ce && doc_ce->type_u8!=DOCT_HEX_ED)
break;
doc_ce=doc->cur_entry;
}
}
break;
case SC_CURSOR_LEFT:
if (sc&SCF_KEY_DESC) {
if (sc&SCF_CTRL)
SetKeyDesc("Edit/GoTo Start of Line");
else {
if (sc&SCF_SHIFT)
SetKeyDesc("Edit/Cursor Left, Select");
else
SetKeyDesc("Edit/Cursor Left");
}
} else
EdCursorLeft(doc,sc);
break;
case SC_CURSOR_RIGHT:
if (sc&SCF_KEY_DESC) {
if (sc&SCF_CTRL)
SetKeyDesc("Edit/GoTo End of Line");
else {
if (sc&SCF_SHIFT)
SetKeyDesc("Edit/Cursor Right, Select");
else
SetKeyDesc("Edit/Cursor Right");
}
} else
EdCursorRight(doc,sc);
break;
case SC_DELETE:
if (sc&SCF_KEY_DESC) {
if (sc&SCF_SHIFT)
SetKeyDesc("Edit/Cut To Clipboard");
else
SetKeyDesc("Char/Delete");
} else {
if (sc&SCF_SHIFT)
EdCutToClipboard(doc);
else
EdDelChar(doc);
}
break;
case SC_INS:
if (sc&SCF_KEY_DESC) {
if (sc&SCF_SHIFT)
SetKeyDesc("Edit/Paste Clipboard");
else if (sc&SCF_CTRL)
SetKeyDesc("Edit/Copy to Clipboard");
else
SetKeyDesc("Edit/Toggle Overstrike");
} else {
if (sc&SCF_SHIFT)
EdPasteClipboard(doc);
else if (sc&SCF_CTRL)
EdCopyToClipboard(doc);
else
doc->flags^=DOCF_OVERSTRIKE;
}
break;
} //switch (sc2)
}
}
doc->ext_ascii_cnt=ext_ascii_cnt;
if (unlock)
DocUnlock(doc);
if (!(doc->flags&DOCF_DONT_SWAP_OUT))
Yield;
}
Bool KDDocPutKey(I64 ch,I64 scan_code)
{
CDoc *doc;
if (doc=DocPut)
DocPutKey(doc,ch,scan_code);
return FALSE;
}
public U0 DocPrintPartial(CDoc *doc,U8 *fmt,...)
{//Lets you print half a doc cmd, if you like.
U8 *buf,*b,*src,*dst,*ptr,*ptr2;
Bool unlock;
CDocEntry *doc_ce,*doc_ne;
I64 ch,i,j;
if (!fmt)
return;
buf=StrPrintJoin(NULL,fmt,argc,argv);
ptr=buf;
if (doc->user_put_s && (*doc->user_put_s)(doc,doc->user_put_data,buf)) {
Free(buf);
return;
}
unlock=DocLock(doc);
if (doc->cur_entry->type_u8==DOCT_DATA)
while (ch=*ptr++)
DocPutKey(doc,ch,0);
else
while (ch=*ptr) {
if (!Bt(chars_bitmap_safe_dollar,ch) ||
doc->flags & (DOCF_OVERSTRIKE | DOCF_IN_DOLLAR)) {
DocPutKey(doc,ch,0);
ptr++;
} else {
ptr2=ptr++;
while (TRUE) {
ch=*ptr++;
if (!Bt(chars_bitmap_safe_dollar,ch))
break;
}
ptr--;
*ptr=0;
doc_ce=doc->cur_entry;
j=ptr-ptr2;
if (IsEditableText(doc_ce)) {
dst=b=MAlloc(doc_ce->max_col+j+1,doc->mem_task);
src=doc_ce->tag;
i=doc->cur_data_col;
doc->cur_data_col+=j;
doc_ce->max_col+=j;
while (i-->0)
*dst++=*src++;
while (j-->0)
*dst++=*ptr2++;
while (*dst++=*src++);
Free(doc_ce->tag);
doc_ce->tag=b;
} else {
dst=MAlloc(j+1,doc->mem_task);
MemCpy(dst,ptr2,j+1);
doc_ne=DocEntryNew(doc,doc_ce,dst);
doc_ne->type=DOCT_TEXT | doc->settings_root.dft_text_attr<<8;
doc_ne->de_flags=doldoc.dft_de_flags[DOCT_TEXT];
QueIns(doc_ne,doc_ce->last);
doc->cur_entry=doc_ne;
doc->cur_data_col=StrLen(ptr2);
}
*ptr=ch;
DocRemSoftNewLines(doc,doc->cur_entry);
}
}
if (unlock)
DocUnlock(doc);
if (!(doc->flags&DOCF_DONT_SWAP_OUT))
Yield;
Free(buf);
}
#help_index "DolDoc"
Bool DocFileEd(I64 _type,U8 *filename,
U8 *needle_str,I64 *_num,I64 edf_dof_flags)
{
I64 type=_type,flags=0,old_border_src=Fs->border_src;
CDocEntry *doc_e;
CDoc *doc;
Bool old_silent=Bt(&Fs->display_flags,DISPLAYf_SILENT),
result=FALSE,other_found=FALSE;
U8 *st1,*st2;
try {
switch (type) {
case LK_PLAIN:
flags=DOCF_PLAIN_TEXT;
case LK_DOC:
type=LK_FILE;
break;
case LK_DOC_ANCHOR:
type=LK_FILE_ANCHOR;
break;
case LK_PLAIN_FIND:
flags=DOCF_PLAIN_TEXT;
case LK_DOC_FIND:
type=LK_FILE_FIND;
break;
case LK_PLAIN_LINE:
flags=DOCF_PLAIN_TEXT;
case LK_DOC_LINE:
type=LK_FILE_LINE;
break;
case LK_BIBLE_FIND:
flags=DOCF_PLAIN_TEXT;
break;
}
flags|=DOCF_ALLOW_UNDO;
if (LK_DOC<=_type<=LK_DOC_LINE) {
doc=Str2I64(filename);//See $LK,"SpriteEdText",A="MN:SpriteEdText"$()
result=TRUE;
} else {
st1=StrNew(filename);
st2=StrNew(filename);
StrLastRem(st1,"/",st2); //st2 is name without dir
if (!FileNameChk(st2))
doc=NULL;
else {
Silent(ON);
if (Bt(&edf_dof_flags,EDf_BAIL)) //if bail, scan parents
result=FileFind(filename,,
FUF_JUST_FILES|FUF_Z_OR_NOT_Z|FUF_SCAN_PARENTS);
else if (!(result=FileFind(filename,,
FUF_JUST_FILES)))
other_found=FileFind(filename,,
FUF_JUST_FILES|FUF_Z_OR_NOT_Z|FUF_SCAN_PARENTS);
doc=DocRead(filename,flags);
doc->desc='Edit';
Silent(old_silent);
Fs->border_src=BDS_ED_FILENAME_PRT;
}
Free(st1);
Free(st2);
}
if (!doc||doc->doc_signature!=DOC_SIGNATURE_VAL)
result=FALSE;
else {
if (Bt(&edf_dof_flags,EDf_COLLAPSE))
DocCollapse(TRUE,doc);
else if (Bt(&edf_dof_flags,EDf_UNCOLLAPSE))
DocCollapse(FALSE,doc);
if (result || other_found)
switch (type) {
case LK_FILE_LINE:
result=DocLineNumGoTo(doc,*_num);
break;
case LK_FILE_ANCHOR:
result=DocAnchorFind(doc,needle_str);
break;
case LK_FILE_FIND:
result=DocFind(doc,,needle_str,*_num);
break;
case LK_BIBLE_FIND:
result=DocFind(doc,*_num,needle_str);
break;
default:
DocCenter(doc);
}
*_num=doc->cur_entry->y+1;
if (!(edf_dof_flags&EDF_BAIL) && DocDo(doc,edf_dof_flags|DOF_DONT_HOME)) {
DocLock(doc);
doc_e=doc->cur_entry;
if (doc_e!=doc)
DocEntryRun(doc,doc_e,TRUE);
DocUnlock(doc);
if (!(LK_DOC<=_type<=LK_DOC_LINE))
DocWrite(doc);
}
if (!(LK_DOC<=_type<=LK_DOC_LINE))
DocDel(doc);
}
} catch {
Silent(old_silent);
result=FALSE;
}
Fs->border_src=old_border_src;
return result;
}
public I64 EdLinkCvt(U8 *link_st,U8 **_filename=NULL,U8 **_needle_str=NULL,
I64 *_num=NULL,I64 edf_dof_flags=0)
{//$LK,"Editor Link",A="MN:LK_FILE"$ --> filename, needle_str and line number.
U8 *st,*ptr,*filename=NULL,*needle_str=NULL,*filename2;
I64 result,i,num=1;
CHashSrcSym *temph;
if (!link_st||!*link_st) {
if (edf_dof_flags&EDF_BAIL)
return -1;
link_st=dsk.temp_filename;
}
st=StrNew(link_st);
result=LK_FILE;
if (StrLen(st)>3 && st[2]==':') {
st[2]=0;
filename2=st+3;
switch (result=DefineMatch(st,"ST_LINK_TYPES",LMF_IGNORE_CASE)) {
case LK_MAN_PAGE:
if (temph=HashFind(filename2,Fs->hash_table,HTG_SRC_SYM))
result=EdLinkCvt(temph->src_link,&filename,&needle_str,&num,edf_dof_flags);
else
result=-1;
goto lc_done;
case LK_ADDR:
if (ptr=StrLastOcc(filename2,",")) {
*ptr=0;
i=Str2I64(ptr+1);
} else
i=DFT_ADDR_LINK_BIN_SIZE;
if (ptr=SrcEdLink(ExePrint("%s;",filename2),i)) {
result=EdLinkCvt(ptr,&filename,&needle_str,&num,edf_dof_flags);
Free(ptr);
} else
result=-1;
goto lc_done;
case LK_DEF:
if (ptr=StrLastOcc(filename2,",")) {
*ptr=0;
i=Str2I64(ptr+1);
} else
i=-1;
filename=StrNew(filename2);
num=i;
goto lc_done;
case LK_HELP_INDEX:
filename=StrNew(filename2);
goto lc_done;
case LK_BIBLE_FIND:
if (ptr=StrLastOcc(filename2,",")) {
*ptr=0;
needle_str=StrNew(ptr+1);
}
i=DefineMatch(filename2,"ST_BIBLE_BOOKS",LMF_IGNORE_CASE);
if (i<0)
result=-1;
else {
num=Str2I64(DefineSub(i,"ST_BIBLE_BOOK_LINES"));
filename2=Define("ST_BIBLE_FILE");
}
break;
case LK_FILE_LINE:
case LK_PLAIN_LINE:
case LK_DOC_LINE:
if (ptr=StrLastOcc(filename2,",")) {
*ptr=0;
num=Str2I64(ptr+1);
}
break;
case LK_FILE_ANCHOR:
case LK_DOC_ANCHOR:
if (ptr=StrLastOcc(filename2,",")) {
*ptr=0;
needle_str=StrNew(ptr+1);
}
break;
case LK_FILE_FIND:
case LK_PLAIN_FIND:
case LK_DOC_FIND:
if (ptr=StrLastOcc(filename2,",")) {
*ptr=0;
needle_str=StrNew(ptr+1);
if (ptr=StrLastOcc(needle_str,":")) {
*ptr=0;
num=Str2I64(ptr+1);
}
}
break;
}
} else
filename2=st;
if (result>=0) {
if (LK_DOC<=result<=LK_DOC_LINE)
filename=StrNew(filename2); //Holds document address as number.
else
filename=FileNameAbs(filename2,FUF_Z_OR_NOT_Z);
}
lc_done:
Free(st);
if (_filename)
*_filename=filename;
else
Free(filename);
if (_needle_str)
*_needle_str=needle_str;
else
Free(needle_str);
if (_num)
*_num=num;
return result;
}
+462
View File
@@ -0,0 +1,462 @@
#help_index "DolDoc/File"
public U0 DocLoad(CDoc *doc,U8 *src2,I64 size)
{//Fetch doc from raw mem buf.
I64 i;
U8 *src;
Bool unlock=DocLock(doc);
CDocBin *tempb;
doc->find_replace->filter_lines=0;
if (src2) {
DocPutS(doc,src2); //Too big $LK,"DocPrint",A="MN:DocPrint"$() is wasteful.
src=src2+StrLen(src2)+1;
i=size-(offset(CDocBin.end)-offset(CDocBin.start));
while (src<=src2+i) {
tempb=CAlloc(sizeof(CDocBin),doc->mem_task);
MemCpy(&tempb->start,src,offset(CDocBin.end)-offset(CDocBin.start));
src+=offset(CDocBin.end)-offset(CDocBin.start);
tempb->data=MAlloc(tempb->size,doc->mem_task);
if (tempb->size) {
MemCpy(tempb->data,src,tempb->size);
src+=tempb->size;
}
QueIns(tempb,doc->bin_root.last);
if (tempb->num>=doc->cur_bin_num)
doc->cur_bin_num=tempb->num+1;
}
}
if (!(doc->flags & (DOCF_PLAIN_TEXT|DOCF_PLAIN_TEXT_WITH_TABS)))
DocBinsValidate(doc);
DocTop(doc); //DOCT_CURSOR will set it in recalc
DocRecalc(doc);
if (unlock)
DocUnlock(doc);
}
public CDoc *DocRead(U8 *name=NULL,I64 flags=0)
{//Fetch doc from disk. See $LK,"flags",A="MN:DOCF_PLAIN_TEXT"$.
CDoc *doc=DocNew;
U8 *src,*name2;
I64 size=0;
if (!name) name=dsk.temp_filename;
doc->flags|=flags;
name2=FileNameAbs(name);
StrCpy(doc->filename.name,name2);
src=FileRead(name2,&size,&doc->file_attr);
Free(name2);
if (src) {
DocLoad(doc,src,size);
Free(src);
}
return doc;
}
public U8 *DocSave(CDoc *doc,I64 *_size=NULL)
{//Store doc to raw mem buf.
CDocEntry *doc_e;
CDocBin *b;
Bool unlock=DocLock(doc);
I64 ch,i,cnt;
U8 *st,*result,*dst,*src;
if (doc->flags&DOCF_NO_CURSOR || doc->root.next==doc)
cnt=1; //terminator
else
cnt=2; //cursor + terminator
if (!(doc->flags & (DOCF_PLAIN_TEXT|DOCF_PLAIN_TEXT_WITH_TABS)))
DocBinsValidate(doc);
DocRecalc(doc);
for (doc_e=doc->root.next;doc_e!=doc;doc_e=doc_e->next) {
if (!Bt(doldoc.type_flags_data,doc_e->type_u8)) {
switch (doc_e->type_u8) {
case DOCT_TAB:
case DOCT_PAGE_BREAK:
cnt++;
break;
case DOCT_NEW_LINE:
if (doc->flags&DOCF_CARRIAGE_RETURN)
cnt+=2;
else
cnt++;
break;
case DOCT_TEXT://$BK,1$Update $LK,"DOCT_TEXT",A="FF:D:/Compiler/Lex.CPP,DOCT_TEXT"$$BK,0$
if (!(doc_e->de_flags & ~(DOCEF_TAG|DOCG_BL_IV_UL|DOCEF_WORD_WRAP|DOCEF_HIGHLIGHT|DOCEF_SKIP|DOCEF_HARD_SKIP|DOCEF_FILTER_SKIP))) {
cnt+=StrLen(doc_e->tag);
if (!(doc->flags & (DOCF_PLAIN_TEXT | DOCF_PLAIN_TEXT_WITH_TABS)) ||
doc->flags&DOCF_DBL_DOLLARS)
cnt+=StrOcc(doc_e->tag,'$$');
} else {
st=Doc2PlainText(doc,doc_e);
cnt+=StrLen(st)+2;
Free(st);
}
break;
default:
if (doc_e->type_u8!=DOCT_SOFT_NEW_LINE &&
doc_e->type_u8!=DOCT_CURSOR) {
st=Doc2PlainText(doc,doc_e);
cnt+=StrLen(st)+2;
Free(st);
}
}
}
}
for (b=doc->bin_root.next;b!=&doc->bin_root;b=b->next) {
if (b->use_cnt>b->temp_use_cnt)
cnt+=offset(CDocBin.end)-
offset(CDocBin.start)+b->size;
}
result=MAlloc(cnt);
dst=result;
for (doc_e=doc->root.next;doc_e!=doc;doc_e=doc_e->next) {
if (!Bt(doldoc.type_flags_data,doc_e->type_u8)) {
if (doc_e->type_u8==DOCT_TEXT &&
!(doc_e->de_flags & ~(DOCEF_TAG|DOCG_BL_IV_UL|DOCEF_WORD_WRAP|DOCEF_HIGHLIGHT|DOCEF_SKIP|DOCEF_HARD_SKIP|DOCEF_FILTER_SKIP))) {
src=doc_e->tag;
i=0;
while (ch=*src++) {
if (doc_e==doc->cur_entry && i++==doc->cur_data_col && !(doc->flags&DOCF_NO_CURSOR))
*dst++=CH_CURSOR;
*dst++=ch;
if (ch=='$$') {
if (!(doc->flags & (DOCF_PLAIN_TEXT | DOCF_PLAIN_TEXT_WITH_TABS)) ||
doc->flags&DOCF_DBL_DOLLARS)
*dst++=ch;
}
}
if (doc_e==doc->cur_entry && i++==doc->cur_data_col && !(doc->flags&DOCF_NO_CURSOR))
*dst++=CH_CURSOR;
} else {
if (doc_e==doc->cur_entry && !(doc->flags&DOCF_NO_CURSOR))
*dst++=CH_CURSOR;
switch (doc_e->type_u8) {
case DOCT_TAB:
*dst++='\t';
break;
case DOCT_PAGE_BREAK:
*dst++=CH_FORM_FEED;
break;
case DOCT_NEW_LINE:
if (doc->flags&DOCF_CARRIAGE_RETURN)
*dst++='\r';
*dst++='\n';
break;
default:
if (doc_e->type_u8!=DOCT_SOFT_NEW_LINE &&
doc_e->type_u8!=DOCT_CURSOR) {//(Cursor is set by cur_entry)
*dst++='$$';
st=Doc2PlainText(doc,doc_e);
StrCpy(dst,st);
dst+=StrLen(st);
*dst++='$$';
Free(st);
}
}
}
}
}
if (doc->cur_entry==doc && doc->root.next!=doc && !(doc->flags&DOCF_NO_CURSOR))
*dst++=CH_CURSOR;
*dst++=0;
if (*result==CH_CURSOR) {
MemCpy(result,result+1,dst-result-1);
cnt--;
dst--;
}
b=doc->bin_root.next;
if (b!=&doc->bin_root) {
do {
if (b->use_cnt>b->temp_use_cnt) {
MemCpy(dst,&b->start,offset(CDocBin.end)-offset(CDocBin.start));
dst+=offset(CDocBin.end)-offset(CDocBin.start);
MemCpy(dst,b->data,b->size);
dst+=b->size;
}
b=b->next;
} while (b!=&doc->bin_root);
} else
cnt--; //No terminator
if (_size) *_size=cnt;
if (unlock)
DocUnlock(doc);
return result;
}
public Bool DocWrite(CDoc *doc,Bool prompt=FALSE)
{//Store doc to disk.
I64 size;
U8 *buf;
if (prompt && !DocFormDo(&doc->filename))
return FALSE;
if (doc->filename.name[0]=='A'&&doc->filename.name[2]==':')
return FALSE; //LK_DOC,LK_DOC_ANCHOR,LK_DOC_FIND,LK_DOC_LINE
buf=DocSave(doc,&size);
FileWrite(doc->filename.name,buf,size,0,doc->file_attr);
Free(buf);
return TRUE;
}
#help_index "DolDoc"
public U0 DocInsDoc(CDoc *doc=NULL,CDoc *doc2)
{//Insert copy of doc2 into doc at insert pt, cur_entry.
//TODO: $LK,"DocRst",A="MN:DocRst"$
U8 *dst;
Bool unlock_doc,unlock_doc2=DocLock(doc2);
CDocEntry *doc_ne,*doc_e=doc2->root.next,*doc_ce;
if (!doc) doc=DocPut;
unlock_doc=DocLock(doc),
DocRemSoftNewLines(doc,NULL);
doc_ce=doc->cur_entry;
if (doc_ce->type_u8==DOCT_TEXT && doc->cur_data_col>doc_ce->min_col) {
if (doc->cur_data_col<doc_ce->max_col) {
dst=doc_ce->tag+doc->cur_data_col;
doc_ne=DocEntryNew(doc,doc_ce,StrNew(dst,doc->mem_task));
*dst=0;
doc_ne->type=DOCT_TEXT | doc_ce->type & 0xFFFFFF00;
doc_ce->max_col=doc->cur_data_col;
QueIns(doc_ne,doc_ce);
doc->cur_entry=doc_ne;
doc->cur_data_col=doc_ne->min_col;
} else
if (doc_ce!=doc)
doc->cur_entry=doc_ce->next;
}
while (doc_e!=doc2) {
if (doc_e->type_u8!=DOCT_SOFT_NEW_LINE) {
doc_ne=DocEntryCopy(doc,doc_e);
QueIns(doc_ne,doc->cur_entry->last);
}
doc_e=doc_e->next;
}
DocRecalc(doc);
if (unlock_doc2)
DocUnlock(doc2);
if (unlock_doc)
DocUnlock(doc);
}
#help_index "DolDoc/Clipboard"
public U0 ClipboardDel()
{//Delete everything on clipboard.
DocRst(sys_clipboard_doc,TRUE);
}
public U0 EdCopyToClipboard(CDoc *doc)
{//Copy $LK,"DOCET_SELECTED",A="MN:DOCET_SELECTED"$ flagged entries to clipboard.
CDoc *doc2=sys_clipboard_doc;
Bool unlock_doc=DocLock(doc),
unlock_doc2=DocLock(doc2);
CDocEntry *doc_e=doc->root.next,*doc_ne;
ClipboardDel;
while (doc_e!=doc) {
if (doc_e->type & DOCET_SELECTED) {
doc_e->type&=~DOCET_SELECTED;
if (!Bt(doldoc.type_flags_data,doc_e->type_u8)) {
doc_ne=DocEntryCopy(doc2,doc_e);
QueIns(doc_ne,doc2->root.last);
}
}
doc_e=doc_e->next;
}
if (unlock_doc2)
DocUnlock(doc2);
if (unlock_doc)
DocUnlock(doc);
}
public U0 EdCutToClipboard(CDoc *doc)
{//Remove selected entries and place on clipboard.
CDoc *doc2=sys_clipboard_doc;
Bool unlock_doc=DocLock(doc),
unlock_doc2=DocLock(doc2);
CDocEntry *doc_e=doc->root.next,*doc_e1,*doc_ne,*doc_e2=NULL;
ClipboardDel;
while (doc_e!=doc) {
doc_e1=doc_e->next;
if (doc_e->type & DOCET_SELECTED) {
doc_e->type&=~DOCET_SELECTED;
if (!Bt(doldoc.type_flags_data,doc_e->type_u8)) {
doc_ne=DocEntryCopy(doc2,doc_e);
QueIns(doc_ne,doc2->root.last);
}
if (doc_e==doc->cur_entry || doc_e==doc_e2)
doc_e2=doc_e->next;
DocEntryDel(doc,doc_e);
}
doc_e=doc_e1;
}
if (doc_e2) {
doc->cur_entry=doc_e2;
doc->cur_data_col=doc_e2->min_col;
}
DocRemSoftNewLines(doc,NULL);
if (unlock_doc2)
DocUnlock(doc2);
if (unlock_doc)
DocUnlock(doc);
}
public U0 EdPasteClipboard(CDoc *doc)
{//Insert copy of clipboard at insert pt, cur_entry.
CDoc *doc2=sys_clipboard_doc;
Bool unlock_doc=DocLock(doc),
unlock_doc2=DocLock(doc2);
CDocEntry *doc_ce=doc->cur_entry,*doc_e;
if (doc_ce->type_u8==DOCT_DATA) {
doc_e=doc2->root.next;
while (doc_e!=doc2) {
if (doc_e->de_flags&DOCEF_TAG)
DocPrintPartial(doc,"%s",doc_e->tag);
doc_e=doc_e->next;
}
} else
DocInsDoc(doc,doc2);
if (unlock_doc2)
DocUnlock(doc2);
if (unlock_doc)
DocUnlock(doc);
}
public U0 DocCut(CDoc *doc,CDocEntry *start,CDocEntry *end)
{//Del start to end entry, including end points.
Bool unlock_doc=DocLock(doc);
CDocEntry *doc_e1;
while (start!=doc) {
doc_e1=start->next;
if (start==doc->cur_entry) {
doc->cur_entry=start->next;
doc->cur_data_col=doc->cur_entry->min_col;
}
DocEntryDel(doc,start);
if (start==end)
break;
start=doc_e1;
}
DocRemSoftNewLines(doc,NULL);
if (unlock_doc)
DocUnlock(doc);
}
public CDoc *DocCopy(CDoc *doc,CDocEntry *start,CDocEntry *end)
{//Copies start to end entry, including end points.
CDoc *doc2=DocNew;
Bool unlock_doc=DocLock(doc);
CDocEntry *doc_ne;
while (start!=doc) {
if (!Bt(doldoc.type_flags_data,start->type_u8)) {
doc_ne=DocEntryCopy(doc2,start);
QueIns(doc_ne,doc2->root.last);
}
if (start==end)
break;
start=start->next;
}
if (unlock_doc)
DocUnlock(doc);
return doc2;
}
#help_index "DolDoc/Compiler;Compiler/Directive"
public U0 StreamDoc(CDoc *doc)
{//Inject doc into compile stream. Use inside #exe{}.
//TODO: $LK,"DocRst",A="MN:DocRst"$
Bool unlock_doc=DocLock(doc);
CDocEntry *doc_e=doc->root.next;
while (doc_e!=doc) {
if (doc_e->type_u8==DOCT_TEXT)
StreamPrint("%s",doc_e->tag);
else if (doc_e->type_u8==DOCT_NEW_LINE)
StreamPrint("\n");
else if (doc_e->type_u8==DOCT_TAB)
StreamPrint("\t");
doc_e=doc_e->next;
}
if (unlock_doc)
DocUnlock(doc);
}
#help_index "DolDoc"
Bool DocCaptureUndo(CDoc *doc,Bool force=FALSE)
{
Bool result=FALSE,unlock;
I64 time_stamp;
CDocUndo *u;
if (doc->flags&DOCF_ALLOW_UNDO) {
unlock=DocLock(doc);
time_stamp=GetTSC;
if (doc->flags&DOCF_UNDO_DIRTY &&
time_stamp>doc->undo_root.last->time_stamp+cnts.time_stamp_freq<<4 || force) {
u=CAlloc(sizeof(CDocUndo),doc->mem_task);
u->time_stamp=time_stamp;
u->body=DocSave(doc,&u->size);
QueIns(u,doc->undo_root.last);
doc->flags&=~DOCF_UNDO_DIRTY;
doc->undo_cnt++;
u->doc_flags=doc->flags;
result=TRUE;
}
if (unlock)
DocUnlock(doc);
}
return result;
}
U0 DocUndoRestore(CDoc *doc)
{
Bool unlock=DocLock(doc);
CDocUndo *u=doc->undo_root.last,*u_next,*u_last;
if (u!=&doc->undo_root) {
QueRem(u);
u_next=doc->undo_root.next;
u_last=doc->undo_root.last;
QueInit(&doc->undo_root);
DocRst(doc,TRUE);
doc->flags=u->doc_flags;
DocLoad(doc,u->body,u->size);
DocUndoDel(doc,u);
doc->undo_root.next=u_next;
doc->undo_root.last=u_last;
}
DocUndoCntSet(doc);
doc->flags&=~DOCF_UNDO_DIRTY;
if (unlock)
DocUnlock(doc);
}
#help_index "Graphics/Windows BMP Files;Graphics/GRA Files;DolDoc/Output"
public Bool DocType(CDoc *doc=NULL,U8 *filename,I64 trailing_new_lines=1)
{//Output txt or graphic file to document.
Bool result=FALSE;
CDoc *doc2;
if (!doc && !(doc=DocPut) || doc->doc_signature!=DOC_SIGNATURE_VAL)
return FALSE;
if (FilesFindMatch(filename,FILEMASK_TXT)) {
doc2=DocRead(filename);
DocInsDoc(doc,doc2);
DocDel(doc2);
result=TRUE;
} else if (FilesFindMatch(filename,"*.BMP.Z")) {
DocBMPFile(doc,filename,FALSE);
result=TRUE;
} else if (FilesFindMatch(filename,"*.BMP;*.bmp")) {
DocBMPFile(doc,filename,TRUE);
result=TRUE;
} else if (FilesFindMatch(filename,"*.GRA*")) {
DocGRAFile(doc,filename);
result=TRUE;
}
if (result)
DocPrint(doc,"%h*c",trailing_new_lines,'\n');
return result;
}
#help_index "Graphics/Windows BMP Files;Graphics/GRA Files;File/Cmd Line (Typically);DolDoc/Cmd Line (Typically);Cmd Line (Typically)"
public Bool Type(U8 *filename,I64 trailing_new_lines=1)
{//Output txt or graphic file to command line.
return DocType(,filename,trailing_new_lines);
}
+570
View File
@@ -0,0 +1,570 @@
#help_index "DolDoc/Editor"
public Bool DocLineNumGoTo(CDoc *doc,I64 line_num) //one based
{//Nearest to specified line num. Move cur_entry & center.
Bool result=FALSE,unlock;
if (doc) {
unlock=DocLock(doc);
doc->x=0;
doc->y=line_num-1;
DocRecalc(doc,FALSE,DOC_RECALC_FIND_CURSOR);
DocCenter(doc);
if (doc->cur_entry->y==line_num-1)
result=TRUE;
if (unlock)
DocUnlock(doc);
}
return result;
}
public Bool DocFind(CDoc *haystack_doc,I64 start_line_num=MIN_I64,
U8 *needle,I64 match=1)
{//Find str by searching tags. Move cur_entry & center.
Bool result=FALSE,unlock;
CDocEntry *doc_e;
U8 *ptr;
I64 i;
if (haystack_doc) {
unlock=DocLock(haystack_doc);
if (start_line_num==MIN_I64) {
result=TRUE;
doc_e=haystack_doc->root.next;
} else {
result=DocLineNumGoTo(haystack_doc,start_line_num);
doc_e=haystack_doc->cur_entry;
}
if (result) {
if (needle) {
result=FALSE;
while (doc_e!=haystack_doc) {
if (doc_e->de_flags&DOCEF_TAG && doc_e->tag &&
(ptr=StrIMatch(needle,doc_e->tag))) {//TODO: handle multientry strings
i=ptr-doc_e->tag;
if (!--match) {
haystack_doc->cur_entry=doc_e;
if (i<doc_e->min_col) i=doc_e->min_col;
if (i>doc_e->max_col) i=doc_e->max_col;
haystack_doc->cur_data_col=i;
result=TRUE;
break;
}
}
doc_e=doc_e->next;
}
} else
result=FALSE;
}
if (!result) DocBottom(haystack_doc);
DocCenter(haystack_doc);
if (unlock)
DocUnlock(haystack_doc);
}
return result;
}
public Bool DocAnchorFind(CDoc *haystack_doc,U8 *needle_str)
{//Find named anchor. Move cur_entry & center.
Bool result=FALSE,unlock;
CDocEntry *doc_e;
if (haystack_doc) {
unlock=DocLock(haystack_doc);
doc_e=haystack_doc->root.next;
if (needle_str)
while (doc_e!=haystack_doc) {
if (doc_e->type_u8==DOCT_ANCHOR && doc_e->de_flags & DOCEF_AUX_STR) {
if (!StrCmp(needle_str,doc_e->aux_str)) {
haystack_doc->cur_entry=doc_e;
haystack_doc->cur_data_col=doc_e->min_col;
result=TRUE;
break;
}
}
doc_e=doc_e->next;
}
if (!result) DocBottom(haystack_doc);
DocCenter(haystack_doc);
if (unlock)
DocUnlock(haystack_doc);
}
return result;
}
public U0 EdFindNext(CDoc *doc)
{//Editor F3 find next, possibly doing replaces.
Bool unlock=DocLock(doc);
U8 *ptr,*ptr2,*ptr3;
CDocEntry *doc_ce=doc->cur_entry,*doc_e=doc_ce;
I64 sf_flags;
if (doc->find_replace->match_case)
sf_flags=0;
else
sf_flags=SFF_IGNORE_CASE;
if (doc->find_replace->whole_labels)
sf_flags|=SFG_WHOLE_LABELS;
do {
if (doc_e!=doc) {
if (doc_e->de_flags&DOCEF_TAG && doc_e->tag &&
!(doc_e->de_flags&(DOCEG1_DONT_EDIT|DOCEF_HARD_SKIP|DOCEF_FILTER_SKIP))) {
if (doc_e->type & DOCET_SELECTED || !doc->find_replace->scan_selected_text) {
if (doc->find_replace->scan_fwd) {
if (doc_e==doc_ce) {
ptr=doc_ce->tag+doc->cur_data_col+1;
if (ptr-doc_ce->tag>=doc_ce->max_col)
goto fn_skip;
if (ptr-doc_ce->tag<doc_ce->min_col)
ptr=doc_ce->tag+doc_ce->min_col;
} else
ptr=doc_e->tag;
if (ptr=StrFind(doc->find_replace->find_text,ptr,sf_flags)) {
doc->cur_entry=doc_e;
doc->cur_data_col=ptr-doc_e->tag;
if (doc->cur_data_col>=doc_e->max_col)
doc->cur_data_col=doc_e->max_col-1;
if (doc->cur_data_col<doc_e->min_col)
doc->cur_data_col=doc_e->min_col;
DocCenter(doc);
if (unlock)
DocUnlock(doc);
return;
}
} else {
ptr2=NULL;
ptr=doc_e->tag+doc_e->min_col;
if (doc_e==doc_ce)
ptr3=doc_ce->tag+doc->cur_data_col;
else
ptr3=doc_e->tag+doc_e->max_col;
while (ptr=StrFind(doc->find_replace->find_text,ptr,sf_flags)) {
if (ptr>=ptr3)
break;
ptr2=ptr++;
}
if (ptr2 && ptr2<ptr3) {
doc->cur_entry=doc_e;
doc->cur_data_col=ptr2-doc_e->tag;
if (doc->cur_data_col>=doc_e->max_col)
doc->cur_data_col=doc_e->max_col-1;
if (doc->cur_data_col<doc_e->min_col)
doc->cur_data_col=doc_e->min_col;
DocCenter(doc);
if (unlock)
DocUnlock(doc);
return;
}
}
}
}
}
fn_skip:
if (doc->find_replace->scan_fwd)
doc_e=doc_e->next;
else
doc_e=doc_e->last;
} while (doc_e!=doc_ce);
if (unlock)
DocUnlock(doc);
}
public U0 EdSelectAll(CDoc *doc,Bool select)
{//Set state of $LK,"DOCET_SELECTED",A="MN:DOCET_SELECTED"$ on all entries.
Bool unlock=DocLock(doc);
CDocEntry *doc_e=doc->root.next;
while (doc_e!=doc) {
BEqu(&doc_e->type,DOCEt_SELECTED,select);
doc_e=doc_e->next;
}
if (unlock)
DocUnlock(doc);
}
public Bool EdFindPaired(CDoc *doc,U8 plus,U8 minus,Bool fwd,Bool abort_on_dbl_colon=FALSE)
{//Find { } or ( ) pair. Move cur_entry & center.
Bool unlock=DocLock(doc),result=FALSE;
U8 *ptr;
I64 ch,levels=0,colons=0,original_col=doc->cur_data_col;
CDocEntry *doc_ce=doc->cur_entry,*doc_e=doc_ce,*original_ce=doc_ce;
if (abort_on_dbl_colon && EdCurU8(doc)==':')
colons=1;
else
colons=0;
do {
if (doc_e!=doc) {
if (doc_e->de_flags&DOCEF_TAG && doc_e->tag &&
!(doc_e->de_flags&(DOCEF_HARD_SKIP|DOCEF_FILTER_SKIP))) {
if (fwd) {
if (doc_e==doc_ce)
ptr=doc_e->tag+doc->cur_data_col+1;
else
ptr=doc_e->tag;
if (ptr-doc_e->tag<doc_e->min_col)
ptr=doc_e->tag+doc_e->min_col;
if (ptr-doc_e->tag>=doc_e->max_col)
goto pa_skip;
while (ch=*ptr++)
if (abort_on_dbl_colon && ch==':') {
if (++colons==2) {
doc->cur_entry=doc_e;
doc->cur_data_col=ptr-doc_e->tag-1;
EdCursorLeft(doc);
result=FALSE;
goto pa_done;
}
} else {
colons=0;
if (ch==plus)
levels++;
else if (ch==minus) {
if (!levels--) {
doc->cur_entry=doc_e;
doc->cur_data_col=ptr-doc_e->tag-1;
result=doc->cur_entry!=original_ce || doc->cur_data_col!=original_col;
goto pa_done;
}
}
}
} else {
if (doc_e==doc_ce) {
ptr=doc_e->tag+doc->cur_data_col-1;
if (ptr-doc_e->tag>=doc_e->max_col)
ptr=doc_e->tag+doc_e->max_col-1;
} else
ptr=doc_e->tag+doc_e->max_col-1;
if (ptr-doc_e->tag<doc_e->min_col)
goto pa_skip;
while (ptr>=doc_e->tag+doc_e->min_col) {
ch=*ptr--;
if (abort_on_dbl_colon && ch==':') {
if (++colons==2) {
doc->cur_entry=doc_e;
doc->cur_data_col=ptr-doc_e->tag+1;
result=FALSE;
goto pa_done;
}
} else {
colons=0;
if (ch==plus)
levels++;
else if (ch==minus) {
if (!levels--) {
doc->cur_entry=doc_e;
doc->cur_data_col=ptr-doc_e->tag+1;
result=doc->cur_entry!=original_ce || doc->cur_data_col!=original_col;
goto pa_done;
}
}
}
}
}
}
}
pa_skip:
if (fwd)
doc_e=doc_e->next;
else
doc_e=doc_e->last;
} while (doc_e!=doc_ce);
pa_done:
DocRecalc(doc);
DocCenter(doc);
if (unlock)
DocUnlock(doc);
return result;
}
public Bool EdGoToFun(CDoc *doc,Bool fwd,Bool abort_on_dbl_colon)
{//Move cur_entry to start of cur fun and center.(Shoddy)
Bool unlock=DocLock(doc),result=FALSE;
I64 ch,levels,colons;
if (fwd) {
levels=0;
colons=0;
while (doc->cur_entry!=doc) {
ch=EdCurU8(doc);
if (abort_on_dbl_colon && ch==':') {
if (++colons==2) {
EdCursorLeft(doc);
break;
}
} else {
colons=0;
if (ch=='{')
levels++;
else if (ch=='}' && !levels--)
break;
}
EdCursorRight(doc);
}
DocRecalc(doc);
if (doc->cur_entry!=doc)
result=TRUE;
} else {
while (EdFindPaired(doc,'}','{',FALSE,abort_on_dbl_colon));
if (doc->cur_entry!=doc) {
ch=EdCurU8(doc);
if (abort_on_dbl_colon && ch==':')
result=TRUE;
else {
if (ch=='{')
result=TRUE;
}
}
}
if (unlock)
DocUnlock(doc);
return result;
}
public U0 EdSelectFun(CDoc *doc,Bool abort_on_dbl_colon=FALSE)
{//Set $LK,"DOCET_SELECTED",A="MN:DOCET_SELECTED"$ on all entries in cur fun.
Bool unlock=DocLock(doc);
U8 *ptr;
I64 ch,levels=0,colons=0;
CDocEntry *doc_e;
EdSelectAll(doc,FALSE);
EdGoToFun(doc,FALSE,abort_on_dbl_colon);
if (EdCurU8(doc)=='{')
levels--;
else if (abort_on_dbl_colon && EdCurU8(doc)==':') {
EdCursorRight(doc);
if (EdCurU8(doc)==':')
EdCursorRight(doc);
}
doc_e=doc->cur_entry;
while (doc_e!=doc) {
doc_e->type|=DOCET_SELECTED;
if (doc_e->de_flags&DOCEF_TAG && doc_e->tag) {
ptr=doc_e->tag;
if (doc_e==doc->cur_entry)
ptr+=doc->cur_data_col;
while (ch=*ptr++)
if (abort_on_dbl_colon && ch==':') {
if (++colons==2)
goto sf_done;
} else {
colons=0;
if (ch=='{')
levels++;
else if (ch=='}' && !levels--)
goto sf_done;
}
}
doc_e=doc_e->next;
}
sf_done:
DocRecalc(doc);
if (unlock)
DocUnlock(doc);
}
U0 EdUndoFilter(CDoc *doc)
{
Bool unlock=DocLock(doc);
CDocEntry *doc_ce=doc->root.next;
while (doc_ce!=doc) {
doc_ce->de_flags&=~DOCEF_FILTER_SKIP;
doc_ce=doc_ce->next;
}
doc->find_replace->filter_lines=0;
if (unlock)
DocUnlock(doc);
}
I64 EdFindReplace(CDoc *doc)
{
Bool found,unlock;
I64 cmd,i,j,plen,rlen,dlen,result=-1,sf_flags;
U8 *src,*dst,*dst2;
CDocEntry *doc_ce=doc->cur_entry,*doc_e;
if (doc->find_replace->pmt)
cmd=RSAC_REPLACE;
else
cmd=RSAC_ALL;
if (!doc->find_replace->pmt || DocFormDo(doc->find_replace)) {
result=0;
unlock=DocLock(doc);
if (doc->find_replace->match_case || doc->find_replace->local_var)
sf_flags=0;
else
sf_flags=SFF_IGNORE_CASE;
if (doc->find_replace->whole_labels || doc->find_replace->local_var)
sf_flags|=SFG_WHOLE_LABELS;
if (i=doc->find_replace->filter_lines) {
doc_ce=doc->root.next;
while (doc_ce!=doc) {
if (doc_ce->de_flags&DOCEF_TAG && doc_ce->tag &&
!(doc_ce->de_flags&(DOCEF_HARD_SKIP|DOCEF_FILTER_SKIP)) &&
StrFind(doc->find_replace->find_text,doc_ce->tag,sf_flags)) {
doc_ce->type|=DOCET_SELECTED;
result++;
} else
doc_ce->type&=~DOCET_SELECTED;
doc_ce=doc_ce->next;
}
doc_ce=doc->root.next;
while (doc_ce!=doc) {
if (!(doc_ce->de_flags&(DOCEF_HARD_SKIP|DOCEF_FILTER_SKIP))) {
found=FALSE;
doc_e=doc_ce;
while (doc_e!=doc && doc_e->y>doc_ce->y-i) {
if (doc_e->type&DOCET_SELECTED) {
found=TRUE;
break;
} else
doc_e=doc_e->last;
}
if (!found) {
doc_e=doc_ce;
while (doc_e!=doc && doc_e->y<doc_ce->y+i) {
if (doc_e->type&DOCET_SELECTED) {
found=TRUE;
break;
} else
doc_e=doc_e->next;
}
}
if (!found)
doc_ce->de_flags|=DOCEF_FILTER_SKIP;
}
doc_ce=doc_ce->next;
}
EdSelectAll(doc,FALSE);
goto fr_unlock_done;
}
if (doc->find_replace->local_var) {
EdSelectFun(doc);
doc_ce=doc->cur_entry;
}
if (!doc->find_replace->replace && !doc->find_replace->local_var) {
EdFindNext(doc);
goto fr_unlock_done;
}
plen=StrLen(doc->find_replace->find_text);
if (!plen)
goto fr_unlock_done;
rlen=StrLen(doc->find_replace->replace_text);
if (doc->root.next!=doc) {
doc_e=doc_ce;
do {
if (doc_e==doc) {
if (doc->find_replace->scan_fwd)
doc_e=doc_e->next;
else
doc_e=doc_e->last;
if (doc_e==doc_ce)
break;
}
if (doc_e->type_u8==DOCT_TEXT &&
!(doc_e->de_flags&(DOCEG1_DONT_EDIT|DOCEF_HARD_SKIP|DOCEF_FILTER_SKIP)) &&
(doc_e->type & DOCET_SELECTED || !doc->find_replace->scan_selected_text&&!doc->find_replace->local_var)) {
src=doc_e->tag;
while (src) {
src=StrFind(doc->find_replace->find_text,src,sf_flags);
if (src) {
doc->cur_data_col=src-doc_e->tag;
doc->cur_entry=doc_e;
if (cmd!=RSAC_ALL)
DocCenter(doc);
doc_e=doc->cur_entry;
src=doc->cur_data_col+doc_e->tag;
if (cmd!=RSAC_ALL) {
DocUnlock(doc);
cmd=PopUpReplaceSkipAllCancel("");
DocLock(doc);
if (cmd<0)
goto fr_unlock_done;
}
if (cmd==RSAC_REPLACE || cmd==RSAC_ALL) {
dlen=StrLen(doc_e->tag);
doc_e->max_col=dlen+rlen-plen;
dst=MAlloc(doc_e->max_col+1,doc->mem_task);
dst2=dst;
j=src-doc_e->tag;
for (i=0;i<j;i++)
*dst++=doc_e->tag[i];
for (i=0;i<rlen;i++)
*dst++=doc->find_replace->replace_text[i];
src=dst;
for (i=j+plen;i<=dlen;i++)
*dst++=doc_e->tag[i];
Free(doc_e->tag);
doc_e->tag=dst2;
doc->cur_data_col=src-doc_e->tag;
doc->cur_entry=doc_e;
if (cmd!=RSAC_ALL) {
DocRemSoftNewLines(doc,doc->cur_entry);
DocRecalc(doc);
}
doc_e=doc->cur_entry;
src=doc->cur_data_col+doc_e->tag;
result++;
} else
src++;
}
}
}
if (doc->find_replace->scan_fwd)
doc_e=doc_e->next;
else
doc_e=doc_e->last;
} while (doc_e!=doc_ce);
}
fr_unlock_done:
DocRemSoftNewLines(doc,NULL);
DocRecalc(doc);
DocCenter(doc);
if (unlock)
DocUnlock(doc);
}
return result;
}
public I64 EdReplace(CDoc *doc,U8 *find,U8 *replace,
Bool selected=TRUE,Bool match_case=TRUE,Bool whole_labels=FALSE)
{//Find & replace using editor's cmd.
CEdFindText old_find_replace;
Bool unlock;
I64 i,result=-1;
if (!doc) return -1;
unlock=DocLock(doc);
MemCpy(&old_find_replace,doc->find_replace,sizeof(CEdFindText));
MemSet(doc->find_replace,0,sizeof(CEdFindText));
i=StrLen(find);
if (i<sizeof(CEdFindText.find_text)) {
MemCpy(doc->find_replace->find_text,find,i+1);
i=StrLen(replace);
if (i<sizeof(CEdFindText.replace_text)) {
MemCpy(doc->find_replace->replace_text,replace,i+1);
doc->find_replace->replace=TRUE;
doc->find_replace->scan_selected_text=selected;
doc->find_replace->match_case=match_case;
doc->find_replace->whole_labels=whole_labels;
doc->find_replace->pmt=FALSE;
result=EdFindReplace(doc);
}
}
MemCpy(doc->find_replace,&old_find_replace,sizeof(CEdFindText));
if (unlock)
DocUnlock(doc);
return result;
}
class CEdLineGoTo
{
I64 line fmtstr "$$DA,256,A=\"Go to Line:%d\"$$";
};
U0 EdGoToLine(CDoc *doc)
{//Prompt with form and go to line num.
CEdLineGoTo gtl;
gtl.line=1;
if (DocFormDo(&gtl))
DocLineNumGoTo(doc,gtl.line);
}
+154
View File
@@ -0,0 +1,154 @@
#help_index "DolDoc/Misc"
U32 *DocHighlight(CDocEntry *doc_e,U8 *src,I64 len,I64 _temp_u32_attr)
{//Be aware of $LK,"::/Adam/Utils/ToHtml.CPP"$.
U32 *result=MAlloc((len+1)*sizeof(U32)),*dst=result;
U8 *ptr;
CDocSettings *s=&doc_e->settings;
I64 ch,ch1,last_ch,temp_u32_attr,mask_temp_u32_attr=_temp_u32_attr&0xFFFFF000,
comment_depth,brace_depth=s->brace_depth,paren_depth=s->paren_depth;
CHash *temph;
nobound_switch (s->state) {
case DOCSS_NORMAL:
hl_normal:
while (len) {
while (len && !Bt(chars_bitmap_alpha_numeric,*src)) {
temp_u32_attr=_temp_u32_attr;
ch1=*src++;
switch (ch1) {
case '/':
if (len>=2) {
if (*src=='/') {
temp_u32_attr=DOC_COLOR_COMMENT<<8|mask_temp_u32_attr;
*dst++=ch1+temp_u32_attr;
*dst++=*src++ +temp_u32_attr;
len-=2;
goto hl_cpp_comment;
} else if (*src=='*') {
temp_u32_attr=DOC_COLOR_COMMENT<<8|mask_temp_u32_attr;
*dst++=ch1+temp_u32_attr;
*dst++=*src++ +temp_u32_attr;
len-=2;
comment_depth=1;
goto hl_comment;
}
}
break;
case '\'':
temp_u32_attr=DOC_COLOR_QUOTE<<8|mask_temp_u32_attr;
*dst++=ch1+temp_u32_attr;
len--;
goto hl_single_quote;
case '\"':
temp_u32_attr=DOC_COLOR_QUOTE<<8|mask_temp_u32_attr;
*dst++=ch1+temp_u32_attr;
len--;
goto hl_dbl_quote;
case '(':
if (paren_depth++&1)
temp_u32_attr=DOC_COLOR_ALT_TEXT<<8|mask_temp_u32_attr;
break;
case ')':
if (--paren_depth&1)
temp_u32_attr=DOC_COLOR_ALT_TEXT<<8|mask_temp_u32_attr;
break;
case '{':
if (brace_depth++&1)
temp_u32_attr=DOC_COLOR_ALT_TEXT<<8|mask_temp_u32_attr;
break;
case '}':
if (--brace_depth&1)
temp_u32_attr=DOC_COLOR_ALT_TEXT<<8|mask_temp_u32_attr;
break;
}
*dst++=ch1+temp_u32_attr;
if (!--len) goto hl_normal_done;
}
ptr=src;
while (len && Bt(chars_bitmap_alpha_numeric,*src)) {
src++;
len--;
}
ch=*src;
*src=0;
if (temph=HashFind(ptr,cmp.asm_hash,HTT_KEYWORD|HTT_ASM_KEYWORD|HTT_OPCODE|HTT_REG)) {
if (temph->type&(HTT_KEYWORD|HTT_ASM_KEYWORD|HTT_OPCODE))
temp_u32_attr=DOC_COLOR_KEYWORD<<8|mask_temp_u32_attr;
else
temp_u32_attr=DOC_COLOR_KEYWORD2<<8|mask_temp_u32_attr;
} else
temp_u32_attr=_temp_u32_attr;
while (ch1=*ptr++)
*dst++=ch1+temp_u32_attr;
*src=ch;
}
hl_normal_done:
s->state=DOCSS_NORMAL;
s->comment_depth=0;
break;
case DOCSS_SINGLE_QUOTE:
temp_u32_attr=DOC_COLOR_QUOTE<<8|mask_temp_u32_attr;
hl_single_quote:
last_ch=0;
while (len--) {
ch1=*src++;
*dst++=ch1+temp_u32_attr;
if (last_ch!='\\' && ch1=='\'')
goto hl_normal;
if (last_ch=='\\' && ch1=='\\')
last_ch=0;
else
last_ch=ch1;
}
s->state=DOCSS_SINGLE_QUOTE;
s->comment_depth=0;
break;
case DOCSS_DBL_QUOTE:
temp_u32_attr=DOC_COLOR_QUOTE<<8|mask_temp_u32_attr;
hl_dbl_quote:
last_ch=0;
while (len--) {
ch1=*src++;
*dst++=ch1+temp_u32_attr;
if (last_ch!='\\' && ch1=='\"')
goto hl_normal;
if (last_ch=='\\' && ch1=='\\')
last_ch=0;
else
last_ch=ch1;
}
s->state=DOCSS_DBL_QUOTE;
s->comment_depth=0;
break;
case DOCSS_COMMENT:
temp_u32_attr=DOC_COLOR_COMMENT<<8|mask_temp_u32_attr;
comment_depth=s->comment_depth;
hl_comment:
last_ch=0;
while (len--) {
ch1=*src++;
*dst++=ch1+temp_u32_attr;
if (last_ch=='*' && ch1=='/') {
if (!--comment_depth)
goto hl_normal;
} else if (last_ch=='/' && ch1=='*')
comment_depth++;
last_ch=ch1;
}
s->state=DOCSS_COMMENT;
s->comment_depth=comment_depth;
break;
case DOCSS_CPP_Z_COMMENT:
temp_u32_attr=DOC_COLOR_COMMENT<<8|mask_temp_u32_attr;
hl_cpp_comment:
while (len--)
*dst++=*src++ +temp_u32_attr;
s->state=DOCSS_CPP_Z_COMMENT;
s->comment_depth=0;
break;
}
s->paren_depth=paren_depth;
s->brace_depth=brace_depth;
*dst=0;
return result;
}
+95
View File
@@ -0,0 +1,95 @@
#help_index "DolDoc"
U0 DocInit()
{//$LK-UL,"CMD Defines",A="MN:DOCT_TEXT"$
CLex *lx;
I64 i;
CHashGeneric *temph;
DefineLstLoad("ST_DOC_CMDS",
"TX\0CR\0SR\0CU\0TB\0CL\0PB\0DA\0PL\0LM\0RM\0HD\0FO\0ID\0"
"FG\0BG\0FD\0BD\0PT\0WW\0UL\0IV\0BK\0SX\0SY\0CM\0AN\0LK\0BT\0"
"CB\0LS\0MA\0MU\0HX\0TR\0SP\0IB\0IS\0SO\0HL\0HC\0ER\0");
DefineLstLoad("ST_DOC_FLAGS",
"T\0A\0D\0HTML\0LE\0LM\0RE\0RM\0BI\0BP\0RT\0SX\0SY\0SCX\0U\0"
"LC\0LA\0RC\0RA\0TC\0LX\0CX\0RX\0TY\0CY\0BY\0"
"HL\0WW\0BK\0IV\0SEL\0UL\0"
"PRY\0MRX\0WR\0L\0X\0Q\0FST\0B\0S\0BD\0C\0CA\0RD\0P\0TRM\0Z\0H\0"
"TR\0LS\0SK\0PU\0SIF\0HS\0FS\0NC\0DD\0UD\0");
DefineLstLoad("ST_LINK_TYPES",
"FI\0FA\0FF\0FL\0MN\0PI\0PF\0PL\0BF\0DF\0HI\0AD\0AI\0AA\0AF\0AL\0");
doldoc.hash=HashTableNew(512);
HashDefineLstAdd("ST_DOC_CMDS",DHT_DOC_CMD,doldoc.hash);
HashDefineLstAdd("ST_DOC_FLAGS",DHT_DOC_FLAG,doldoc.hash);
HashDefineLstAdd("ST_COLORS",DHT_COLOR,doldoc.hash);
MemSet(doldoc.dft_de_flags, 0,sizeof(doldoc.dft_de_flags));
MemSet(doldoc.dft_type_flags, 0,sizeof(doldoc.dft_type_flags));
lx=LexNew("TX+T;DA+P+TRM+T;CM+LE+RE;AN+T;LK+L+UL+T;MA+X+UL+T;MU+X+UL+T;"
"BT+X+B+T;CB+CA+P+T;LS+LS+P+T;HX+P+Z;TR+TR+C+CA+UL+T;SP+T;IB+T;IS+T;"
"SO+T;HC+T;",LF_DONT_FREE_BUF);
lx->htc.hash_table_lst=NULL;
Lex(lx);
while (lx->token==TK_IDENT) {
if (temph=HashFind(lx->cur_str,doldoc.hash,DHT_DOC_CMD)) {
i=temph->user_data0;
Lex(lx);
PrsDocFlags(lx,&doldoc.dft_de_flags[i],&doldoc.dft_type_flags[i]);
}
if (lx->token==';')
Lex(lx);
}
LexDel(lx);
for (i=0;i<DOCT_NUM_TYPES;i++)
doldoc.dft_de_flags[i]&=~DOCG_BL_IV_UL;
doldoc.type_flags_form[0]=0;
for (i=0;i<DOCT_NUM_TYPES;i++)
if (Bt(&doldoc.dft_de_flags[i],DOCEf_TAG) && i!=DOCT_TEXT || i==DOCT_HEX_ED)
Bts(doldoc.type_flags_form,i);
//Don't forget $LK,"cmp_type_flags_src_code",A="MN:cmp_type_flags_src_code"$.
doldoc.type_flags_nontag_invisible[0]=
1<<DOCT_PAGE_LEN|
1<<DOCT_LEFT_MARGIN|
1<<DOCT_RIGHT_MARGIN|
1<<DOCT_HEADER|
1<<DOCT_FOOTER|
1<<DOCT_INDENT|
1<<DOCT_FOREGROUND|
1<<DOCT_BACKGROUND|
1<<DOCT_DFT_FOREGROUND|
1<<DOCT_DFT_BACKGROUND|
1<<DOCT_PMT|
1<<DOCT_WORD_WRAP|
1<<DOCT_UNDERLINE|
1<<DOCT_INVERT|
1<<DOCT_BLINK|
1<<DOCT_SHIFTED_X|
1<<DOCT_SHIFTED_Y|
1<<DOCT_SPRITE|
1<<DOCT_HIGHLIGHT;
doldoc.type_flags_data[0]=1<<DOCT_DATA|1<<DOCT_HEX_ED|1<<DOCT_CHECK_BOX;
Bts(doldoc.clean_scan_codes,SC_CURSOR_RIGHT);
Bts(doldoc.clean_scan_codes,SC_CURSOR_LEFT);
Bts(doldoc.clean_scan_codes,SC_CURSOR_UP);
Bts(doldoc.clean_scan_codes,SC_CURSOR_DOWN);
Bts(doldoc.clean_scan_codes,SC_PAGE_UP);
Bts(doldoc.clean_scan_codes,SC_PAGE_DOWN);
Bts(doldoc.clean_scan_codes,SC_ALT);
Bts(doldoc.clean_scan_codes,SC_CTRL);
Bts(doldoc.clean_scan_codes,SC_SHIFT);
Bts(doldoc.clean_scan_codes,SC_CAPS);
Bts(doldoc.clean_scan_codes,SC_NUM);
Bts(doldoc.clean_scan_codes,SC_SCROLL);
Bts(doldoc.clean_scan_codes,SC_HOME);
Bts(doldoc.clean_scan_codes,SC_END);
Bts(doldoc.clean_scan_codes,SC_GUI);
Bts(doldoc.clean_scan_codes,SC_BACKSPACE); //Handled specially
}
DocInit;
+220
View File
@@ -0,0 +1,220 @@
#help_index "DolDoc/Misc"
U8 captured_macro_name[136];
StrCpy(captured_macro_name,"Test");
I64 sys_macro_repeat_n=1;
U0 SysMacroStripKey(CSrvCmd *macro_root,I64 a1,I64 a2)
{
CSrvCmd *tempc,*tempc1;
tempc=macro_root->next;
while (tempc!=macro_root) {
tempc1=tempc->next;
if (tempc->cmd_code==SVCT_MSG &&
(tempc->msg_code==MSG_KEY_DOWN ||
tempc->msg_code==MSG_KEY_UP ||
tempc->msg_code==MSG_KEY_DOWN_UP) &&
a1 && tempc->aux1==a1 ||
!a1 && tempc->aux2==a2) {
QueRem(tempc);
SrvCmdDel(tempc);
}
tempc=tempc1;
}
}
#define MT_NULL 0
#define MT_MSG 1
#define MT_CHAR 2
class CMacroTemp
{
CMacroTemp *next,*last;
I64 type;
U8 buf[136];
};
CMacroTemp *Cmd2MT(CSrvCmd *tempc)
{
U8 buf[8];
CMacroTemp *tempmt=CAlloc(sizeof(CMacroTemp));
if (Bt(chars_bitmap_getkey,tempc->aux1) && tempc->msg_code==MSG_KEY_DOWN) {
tempmt->type=MT_CHAR;
buf[0]=tempc->aux1;
buf[1]=0;
StrPrint(tempmt->buf,"%Q",buf);
} else {
tempmt->type=MT_MSG;
StrPrint(tempmt->buf,"Msg(0x%X,0x%X,0x%X);",
tempc->msg_code,tempc->aux1,tempc->aux2);
}
return tempmt;
}
U8 *SysMacro2Str(CSrvCmd *macro_root)
{
CSrvCmd *tempc;
I64 cnt=1; //terminating zero
U8 *ptr,*m;
CMacroTemp *tempmt,*tempmt1,root;
Bool old_preempt=Preempt(OFF);
LBtr(&sys_semas[SYS_SEMA_RECORD_MACRO],0);
QueInit(&root);
root.type=MT_NULL;
tempc=macro_root->next;
while (tempc!=macro_root) {
tempmt=Cmd2MT(tempc);
QueIns(tempmt,root.last);
cnt+=StrLen(tempmt->buf);
if (tempmt->type==MT_CHAR) {
if (tempmt->last->type!=MT_CHAR)
cnt+=StrLen("\"");
if (tempmt->next->type!=MT_CHAR)
cnt+=StrLen("\";");
}
tempc=tempc->next;
}
m=MAlloc(cnt);
ptr=m;
tempmt=root.next;
while (tempmt!=&root) {
tempmt1=tempmt->next;
if (tempmt->type==MT_MSG) {
StrCpy(ptr, tempmt->buf);
ptr+=StrLen(tempmt->buf);
} else {
if (tempmt->last->type!=MT_CHAR) {
StrCpy(ptr, "\"");
ptr+=StrLen("\"");
}
StrCpy(ptr,tempmt->buf);
ptr+=StrLen(tempmt->buf);
if (tempmt->next->type!=MT_CHAR) {
StrCpy(ptr, "\";");
ptr+=StrLen("\";");
}
}
Free(tempmt);
tempmt=tempmt1;
}
*ptr=0;
Preempt(old_preempt);
return m;
}
U0 PlaySysMacro(I64 n=1)
{
CTask *task=sys_focus_task;
Bool old_preempt;
U8 *m;
if (TaskValidate(task)) {
LBtr(&sys_semas[SYS_SEMA_RECORD_MACRO],0);
old_preempt=Preempt(OFF);
m=SysMacro2Str(&sys_macro_root);
while (n-- && TaskValidate(task)) {
if (task==Fs)
AutoStr("%s",m);
else
XTalkStrWait(task,"%s",m);
}
Free(m);
Preempt(old_preempt);
}
}
U0 EdInsCapturedMacro()
{
Bool old_preempt=Preempt(OFF);
U8 *st=SysMacro2Str(&sys_macro_root);
if (sys_focus_task) {
XTalk(sys_focus_task,"$$MA+LA,T=\"%s\",LM=\"%Q\"$$",
captured_macro_name,st);
Free(st);
}
Preempt(old_preempt);
}
#define SM_RECORD 0
#define SM_INS 1
#define SM_PLAY 2
#define SM_REPEAT_N 3
#define SM_STOP 4
I64 PopUpMacroMenu()
{
I64 result=0;
U8 buf[136];
CSrvCmd *tempc;
CDoc *doc=DocNew;
CDocEntry *doc_e=DocPrint(doc,"$$DA-P,135,A=\"Name:%%s\"$$");
doc_e->data=captured_macro_name;
DocDataFmt(doc,doc_e);
doc_e=DocPrint(doc,"\n$$DA,32,A=\"Repeat N:%%d\"$$");
doc_e->data=&sys_macro_repeat_n;
DocDataFmt(doc,doc_e);
DocPrint(doc,"\n"
"$$CM+LX,1,3$$$$BT,\"RECORD\",LE=SM_RECORD$$"
"$$CM+LX,17,0$$$$BT,\"INSERT\",LE=SM_INS$$"
"$$CM+LX,1,3$$$$BT,\"PLAY\",LE=SM_PLAY$$"
"$$CM+LX,17,0$$$$BT,\"REPEAT N\",LE=SM_REPEAT_N$$"
"$$CM+LX,1,3$$$$BT,\"STOP\",LE=SM_STOP$$"
"$$CM+LX,17,0$$$$BT,\"CANCEL\",LE=DOCM_CANCEL$$"
"\n\n\n$$GREEN$$SHIFT-F2$$FG$$ will play macro.\n");
doc->flags|=DOCF_MIN_SIZE | DOCF_FORM;
StrPrint(buf,"DocMenuDo(%d);",doc);
sys_macro_util_task=Spawn(&SrvUserCmdLine,NULL,"Macro Popup",,Fs);
Fs->popup_task=sys_macro_util_task;
LBts(&sys_macro_util_task->display_flags,DISPLAYf_WIN_ON_TOP);
tempc=TaskExe(sys_macro_util_task,Fs,buf,
1<<SVCf_WAKE_MASTER|1<<SVCf_FOCUS_MASTER);
ScanResult(tempc,&result);
Fs->popup_task=NULL;
Kill(sys_macro_util_task);
sys_macro_util_task=NULL;
DocDataScan(doc,doc_e);
DocDel(doc);
return result;
}
U0 MacroTask(I64)
{
I64 i;
StrCpy(captured_macro_name,"Click Here");
sys_macro_repeat_n=1;
do {
i=PopUpMacroMenu;
WinRefocus;
switch (i) {
case SM_RECORD:
LBtr(&sys_semas[SYS_SEMA_RECORD_MACRO],0);
QueDel(&sys_macro_root,TRUE);
LBts(&sys_semas[SYS_SEMA_RECORD_MACRO],0);
break;
case SM_PLAY:
PlaySysMacro;
break;
case SM_REPEAT_N:
PlaySysMacro(sys_macro_repeat_n);
break;
case SM_STOP:
LBtr(&sys_semas[SYS_SEMA_RECORD_MACRO],0);
break;
case SM_INS:
LBtr(&sys_semas[SYS_SEMA_RECORD_MACRO],0);
EdInsCapturedMacro;
break;
}
} while (i>=0);
}
U0 EdMacroUtil()
{
if (!sys_macro_util_task)
Spawn(&MacroTask,NULL,"Macro");
}
+591
View File
@@ -0,0 +1,591 @@
#help_index "DolDoc/Cmd Line (Typically);Cmd Line (Typically)"
public Bool Ed(U8 *link_st,I64 edf_dof_flags=0)
{//Invoke document editor.
U8 *filename,*needle_str;
I64 i,num;
Bool cont,result=FALSE;
CDoc *doc;
switch (i=EdLinkCvt(link_st,&filename,&needle_str,&num,edf_dof_flags)) {
case -1:
break;
case LK_DEF:
doc=DocNew;
doc->desc='DictDef';
WSDDefsPut(doc,filename,num);
goto ej_doc;
case LK_HELP_INDEX:
doc=DocNew;
doc->desc='HelpIndx';
DocHelpIndex(doc,filename);
ej_doc:
if (!(edf_dof_flags&EDF_BAIL)) {
DocDo(doc);
DocDel(doc);
}
result=TRUE;
break;
default:
if (IsRaw)
EdLite(filename,num);
else {
cont=TRUE;
if (!(edf_dof_flags&EDF_BAIL) && !(LK_DOC<=i<=LK_DOC_LINE) &&
!FilesFindMatch(filename,FILEMASK_TXT) &&
!PopUpCancelOk(ST_WARN_ST "Not Text File\n\n"))
cont=FALSE;
if (cont)
result=DocFileEd(i,filename,needle_str,&num,edf_dof_flags);
}
}
Free(filename);
Free(needle_str);
return result;
}
public Bool Plain(U8 *filename)
{//Edit document in plain text mode, so dollar signs are not special.
Bool result;
U8 *st=MStrPrint("PI:%s",filename);
result=Ed(st);
Free(st);
return result;
}
#help_index "DolDoc"
public Bool DocLinkChk(U8 *link_st)
{//Check for bad $LK,"Editor Link",A="MN:LK_FILE"$.
U8 *filename;
Bool result=FALSE;
if (link_st) {
switch (EdLinkCvt(link_st,&filename)) {
case -1:
break;
case LK_FILE_LINE:
case LK_PLAIN_LINE:
case LK_FILE:
//We don't check line number
result=FileFind(filename,,FUF_JUST_FILES|FUF_Z_OR_NOT_Z|FUF_SCAN_PARENTS);
break;
case LK_BIBLE_FIND:
result=TRUE; //We don't check verse string
break;
default://TODO: Need to validate HI: and DF:
if (Ed(link_st,EDF_BAIL))
result=TRUE;
}
Free(filename);
}
return result;
}
public U8 *DocLinkFile(U8 *link_st,CTask *mem_task=NULL)
{//Return the file for an $LK,"Editor Link Types",A="MN:LK_FILE"$.
U8 *filename=NULL,*st,*result=NULL;
if (link_st) {
switch (EdLinkCvt(link_st,&filename)) {
case LK_FILE:
case LK_FILE_ANCHOR:
case LK_FILE_FIND:
case LK_FILE_LINE:
case LK_PLAIN:
case LK_PLAIN_FIND:
case LK_PLAIN_LINE:
st=FileNameAbs(filename,FUF_Z_OR_NOT_Z|FUF_SCAN_PARENTS);
result=StrNew(st);
Free(st);
break;
case LK_BIBLE_FIND:
result=StrNew(Define("ST_BIBLE_FILE"),mem_task);
break;
}
Free(filename);
}
return result;
}
#help_index "DolDoc/Task"
public CDoc *DocBorderNew(CDoc *pdoc)
{//Make new std border doc.
CDocEntry *doc_e;
CDoc *bdoc;
bdoc=DocNew;
bdoc->flags|=DOCF_BORDER_DOC;
if (pdoc) {
DocPrint(bdoc,"$$CM+H+BY+RX+NC,-7,1$$");
doc_e=DocPrint(bdoc,"$$TX+H+BD+TC,\" \"$$");
doc_e->user_data=pdoc;
doc_e->tag_cb=&EdFilterCB;
doc_e=DocPrint(bdoc,"$$TX+H+BD+TC,\" \"$$");
doc_e->user_data=pdoc;
doc_e->tag_cb=&EdOverStrikeCB;
doc_e=DocPrint(bdoc,"$$TX+H+BD+TC,\" \"$$");
doc_e->user_data=pdoc;
doc_e->tag_cb=&EdDollarCB;
DocPrint(bdoc,"$$CM+H+BY+RX+NC,-18,1$$");
doc_e=DocPrint(bdoc,"$$TX+BD+TC,\" \"$$");
doc_e->user_data=pdoc;
doc_e->tag_cb=&EdMoreCB;
doc_e=DocPrint(bdoc,"$$TX+H+BD+TC,\" \"$$");
doc_e->user_data=pdoc;
doc_e->tag_cb=&EdDollarTypeCB;
}
DocPrint(bdoc,"$$CM+H+TY+NC,0,-1$$");
doc_e=DocPrint(bdoc,"$$DA+H-TRM-P+BD+RD+CX+IV,140,A=\"%%s...\",SCX=15$$");
doc_e->data=&Fs->task_title;
DocDataFmt(bdoc,doc_e);
DocPrint(bdoc,"$$CM+H+NC,1,0$$$$TX+H+BD+IV,\"%X\"$$",Fs);
DocPrint(bdoc,"$$TX+H+RX+BD,\"[X]\"$$");
DocPrint(bdoc,"$$BK,1$$$$TX+H+LX+BD,\"MENU\"$$$$BK,0$$");
return bdoc;
}
public U0 DocTermNew()
{//Make into term win task with Put/Display/Border docs.
Bool old_preempt=Preempt(OFF);
CDoc *pdoc=DocNew;
pdoc->right_click_link=&TermRightClickLink;
pdoc->max_entries=4096;
Fs->border_src=BDS_CUR_PRT;
pdoc->desc='Term';
Fs->put_doc=Fs->display_doc=pdoc;
Fs->border_doc=DocBorderNew(pdoc);
Fs->cur_menu=MenuFile("::/Doc/EdPullDown.TXT");
WinScrollsInit(Fs);
Preempt(old_preempt);
Raw(OFF);
}
#help_index "DolDoc/Input"
public U8 *DocScanLine(CDoc *doc,CDocEntry *doc_e,I64 *cur_col=NULL,CDocEntry **_do_e_end=NULL)
{//Start at entry in doc,make and return one line as str.
CDocEntry *doc_e2=doc_e;
Bool unlock=DocLock(doc);
U8 *dst,*src,*start,*result;
I64 i=0;
if (cur_col)
*cur_col=-1;
while (doc_e2!=doc && doc_e2->type_u8!=DOCT_NEW_LINE) {
if (doc_e2->de_flags&DOCEF_TAG && doc_e2->tag) {
src=doc_e2->tag;
i+=StrLen(src);
} else if (doc_e2->type_u8==DOCT_TAB)
i++;
doc_e2=doc_e2->next;
}
result=MAlloc(i+1);
dst=result;
while (doc_e!=doc && doc_e->type_u8!=DOCT_NEW_LINE) {
start=dst;
if (doc_e->de_flags&DOCEF_TAG && doc_e->tag) {
src=doc_e->tag;
while (*src)
*dst++=*src++;
} else if (doc_e->type_u8==DOCT_TAB)
*dst++='\t';
if (doc_e==doc->cur_entry && cur_col)
*cur_col=start-result+doc->cur_data_col;
doc_e=doc_e->next;
}
if (_do_e_end) *_do_e_end=doc_e;
*dst=0;
if (doc_e==doc->cur_entry && cur_col && !doc->cur_data_col)
*cur_col=dst-result;
if (unlock)
DocUnlock(doc);
return result;
}
#help_index "DolDoc/Output"
U0 DocDump(CDoc *doc,I64 uS_delay=0)
{
U8 *st;
CDocEntry *doc_e,*doc_e2;
Bool unlock=DocLock(doc);
doc_e=doc->root.next;
while (doc_e!=doc) {
st=DocScanLine(doc,doc_e,NULL,&doc_e2);
"%s",st;
Free(st);
doc_e=doc_e2;
if (doc_e->type_u8==DOCT_NEW_LINE) {
'\n';
BusyWait(uS_delay);
doc_e=doc_e->next;
}
}
if (unlock)
DocUnlock(doc);
}
public CDocEntry *DocPutLine(CDoc *doc=NULL,CDocEntry *doc_e)
{//Send line from other doc to StdOut $LK,"DocPut",A="MN:DocPut"$.
I64 ch;
U8 *ptr,*ptr2;
Bool unlock;
if (!doc && !(doc=DocPut) || doc->doc_signature!=DOC_SIGNATURE_VAL)
return NULL;
unlock=DocLock(doc);
while (doc_e!=doc && doc_e->type_u8!=DOCT_NEW_LINE) {
if (doc_e->de_flags&DOCEF_TAG) {
ptr=doc_e->tag;
do {
ptr2=ptr;
while (ch=*ptr)
if (ch=='$$')
break;
else
ptr++;
*ptr=0;
"%s",ptr2;
*ptr=ch;
if (ch=='$$') {
"$$$$";
ptr++;
}
} while (ch);
} else if (doc_e->type_u8==DOCT_TAB)
'\t';
doc_e=doc_e->next;
}
'\n';
if (doc_e!=doc)
doc_e=doc_e->next;
if (unlock)
DocUnlock(doc);
return doc_e;
}
#help_index "DolDoc/Input"
U8 *DocGetStr2(I64 flags=0)
{//$LK,"Flags",A="MN:GSF_SHIFT_ESC_EXIT"$
CDoc *doc;
CDocEntry *doc_e,*doc_e_end;
Bool old_preempt=IsPreempt;
U8 *st,*st2,*result;
I64 ch,sc;
"$$PT$$";
do {
ch=DocGetKey(&sc);
if (ch==CH_ESC) {
if (doc=DocPut) {
DocLock(doc);
if (doc->doc_signature==DOC_SIGNATURE_VAL && doc->cur_entry!=doc) {
doc_e=DocEntryCopy(doc,doc->cur_entry);
DocBottom(doc);
DocEntryRun(doc,doc_e,TRUE);
DocEntryDel(doc,doc_e);
}
DocUnlock(doc);
}
if (flags&GSF_WITH_NEW_LINE)
break;
} if (ch==CH_SHIFT_ESC) {
if (flags&GSF_SHIFT_ESC_EXIT)
Exit;
else {
result=StrNew("");
goto gs_done;
}
}
//<CTRL-SHIFT-ENTER> is a blank line without entry
} while (flags&GSF_WITH_NEW_LINE || ch!='\n' || sc & SCF_CTRL && sc & SCF_SHIFT);
Preempt(OFF);
doc=DocPut;
DocLock(doc);
if (flags&GSF_WITH_NEW_LINE) {
doc_e=doc->cur_entry;
do doc_e=doc_e->last;
while (doc_e!=doc && doc_e->type_u8!=DOCT_PMT);
doc_e=doc_e->next;
if (result=DocScanLine(doc,doc_e,NULL,&doc_e_end)) {
while (doc_e_end!=doc && doc_e_end->type_u8==DOCT_NEW_LINE) {
st2=MStrPrint("%s\n",result);
Free(result);
result=st2;
if (st=DocScanLine(doc,doc_e_end->next,NULL,&doc_e_end)) {
st2=MStrPrint("%s%s",result,st);
Free(st);
Free(result);
result=st2;
}
}
}
} else {
doc_e=doc->cur_entry;
do doc_e=doc_e->last;
while (doc_e!=doc && doc_e->type_u8!=DOCT_NEW_LINE &&
doc_e->type_u8!=DOCT_PMT);
if (doc_e!=doc && doc_e->type_u8!=DOCT_PMT) {
do doc_e=doc_e->last;
while (doc_e!=doc && doc_e->type_u8!=DOCT_NEW_LINE &&
doc_e->type_u8!=DOCT_PMT);
}
doc_e=doc_e->next;
result=DocScanLine(doc,doc_e,NULL);
}
DocUnlock(doc);
gs_done:
"$$PT$$$$FG$$$$BG$$";
Preempt(old_preempt);
return result;
}
#help_index "Keyboard Devices;Char/Input"
public I64 GetI64(U8 *msg=NULL,I64 dft=0,I64 lo=MIN_I64,I64 hi=MAX_I64)
{//Prompt user for I64 expression.
Bool okay;
U8 *st;
I64 result;
while (TRUE) {
if (msg)
"" msg,dft;
st=GetStr;
if (!*st) {
Free(st);
return dft;
}
try {
result=ExePrint2("ToI64(%s);",st);
okay=TRUE;
} catch {
Fs->catch_except=TRUE;
okay=FALSE;
}
Free(st);
if (okay && lo<=result<=hi)
return result;
}
}
public F64 GetF64(U8 *msg=NULL,F64 dft=0,F64 lo=MIN_F64,F64 hi=MAX_F64)
{//Prompt user for F64 expression.
Bool okay;
U8 *st;
F64 result;
while (TRUE) {
if (msg)
"" msg,dft;
st=GetStr;
if (!*st) {
Free(st);
return dft;
}
try {
result=ExePrint2("ToF64(%s);",st)(F64);
okay=TRUE;
} catch {
Fs->catch_except=TRUE;
okay=FALSE;
}
Free(st);
if (okay && lo<=result<=hi)
return result;
}
}
public CDate GetDate(U8 *msg=NULL,CDate dft=MIN_I64,CDate lo=MIN_I64,CDate hi=MAX_I64)
{//Prompt user for date expression. (Use $LK,"Now",A="MN:Now"$() if you want current time.)
U8 *st;
CDate result;
if (dft==MIN_I64) dft=Now;
while (TRUE) {
if (msg)
"" msg,dft,dft;
st=GetStr;
if (!*st) {
Free(st);
return dft;
}
result=Str2Date(st);
Free(st);
if (result>=lo && result<=hi)
return result;
}
}
#help_index "DolDoc"
#define RIGHT_INCLUDE 0
#define RIGHT_AINCLUDE 1
#define RIGHT_COPY 2
#define RIGHT_MOVE 3
#define RIGHT_DELETE 4
#define RIGHT_TYPE 5
#define RIGHT_ED 6
#define RIGHT_PLAIN 7
#define RIGHT_AUTOFILE 8
I64 PopUpTermRight(U8 *header)
{
I64 i;
CDoc *doc=DocNew;
if (header) DocPrint(doc,"%s",header);
DocPrint(doc,"\n\n"
"TXT=%s\nJIT=%s\nGRA=%s"
"$$CM+LX,1,3 $$$$BT,\"INCLUDE JIT\",LE=RIGHT_INCLUDE$$"
"$$CM+LX,26,0$$$$BT,\"ADAM_INCLUDE JIT\",LE=RIGHT_AINCLUDE$$"
"$$CM+LX,1,3 $$$$BT,\"COPY \",LE=RIGHT_COPY$$"
"$$CM+LX,26,0$$$$BT,\"MOVE OR RENAME \",LE=RIGHT_MOVE$$"
"$$CM+LX,1,3 $$$$BT,\"DELETE \",LE=RIGHT_DELETE$$"
"$$CM+LX,26,0$$$$BT,\"TYPE TXT;GRA\",LE=RIGHT_TYPE$$"
"$$CM+LX,1,3 $$$$BT,\"ED TXT\",LE=RIGHT_ED$$"
"$$CM+LX,26,0$$$$BT,\"PLAIN ED TXT\",LE=RIGHT_PLAIN$$"
"$$CM+LX,1,3 $$$$BT,\"CANCEL \",LE=DOCM_CANCEL$$"
"$$CM+LX,26,0$$$$BT,\"AUTOFILE AUT\",LE=RIGHT_AUTOFILE$$\n",
FILEMASK_TXT,FILEMASK_JIT,FILEMASK_GRA);
i=PopUpMenu(doc);
DocDel(doc);
return i;
}
I64 EdLeftClickLink(CDoc *doc,CDocEntry *doc_e)
{//Called with doc locked, exit unlocked
Bool result;
U8 *st;
if (st=DocEntryLink(doc,doc_e)) {
DocUnlock(doc);
if (doc_e->de_flags & DOCEF_POPUP)
result=PopUpEd(st);
else
result=Ed(st);
Free(st);
return result;
}
}
I64 TermRightClickLink(CDoc *doc,CDocEntry *doc_e)
{//Called with doc locked, exit unlocked
Bool send_new_line=FALSE,result=FALSE;
U8 *st,*st2;
I64 i;
CEdFileName fn;
if (st2=DocEntryLink(doc,doc_e)) {
if (st=DocLinkFile(st2)) {
DocUnlock(doc);
if ((i=PopUpTermRight(st))>=0) {
DocBottom(doc);
switch (i) {
case RIGHT_INCLUDE:
if (FileExtDot(st) && !FilesFindMatch(st,FILEMASK_JIT)) {
if (!PopUpCancelOk(ST_WARN_ST "Not .CPP File\n\n")) {
send_new_line=TRUE;
break;
}
}
"#include \"%s\";\n$$PT$$$$FG$$$$BG$$",st;
WinZBufUpdate;
ExeFile(st);
result=TRUE;
break;
case RIGHT_AINCLUDE:
if (FileExtDot(st) && !FilesFindMatch(st,FILEMASK_JIT)) {
if (!PopUpCancelOk(ST_WARN_ST "Not .CPP File\n\n")) {
send_new_line=TRUE;
break;
}
}
"Adam(\"#include \\\"%s\\\"\" );\n$$PT$$$$FG$$$$BG$$",st;
WinZBufUpdate;
AdamFile(st,FALSE);
result=TRUE;
break;
case RIGHT_COPY:
StrCpy(fn.name,st);
if (DocFormDo(&fn)) {
result=ToBool(Copy(st,fn.name));
} else
send_new_line=TRUE;
break;
case RIGHT_MOVE:
StrCpy(fn.name,st);
if (DocFormDo(&fn))
result=Move(st,fn.name);
else
send_new_line=TRUE;
break;
case RIGHT_DELETE:
result=ToBool(Del(st));
break;
case RIGHT_TYPE:
result=Type(st);
break;
case RIGHT_ED:
"Ed(\"%s\");\n$$PT$$$$FG$$$$BG$$",st;
result=Ed(st);
break;
case RIGHT_PLAIN:
"Plain(\"%s\");\n$$PT$$$$FG$$$$BG$$",st;
result=Plain(st);
break;
case RIGHT_AUTOFILE:
if (FileExtDot(st) && !FilesFindMatch(st,"*.AUT*")) {
if (!PopUpCancelOk(ST_WARN_ST "Not .AUT File\n\n")) {
send_new_line=TRUE;
break;
}
}
"AutoFile(\"%s\");\n$$PT$$$$FG$$$$BG$$",st;
WinZBufUpdate;
AutoStr("%F\n",st);
result=TRUE;
break;
}
} else
send_new_line=TRUE;
Free(st);
} else
send_new_line=TRUE;
Free(st2);
} else
send_new_line=TRUE;
DocBottom(doc);
"$$PT$$$$FG$$$$BG$$";
if (send_new_line)
'\n';
return result;
}
#help_index "Debugging/Dump;DolDoc/Cmd Line (Typically);Cmd Line (Typically);DolDoc/Output"
public U0 DocDm(U8 *buf,I64 cnt=0x80)
{//Dump live chunk of mem showing addresses. Can be edited.
CDocEntry *doc_e;
CDoc *doc=DocPut;
Bool unlock=DocLock(doc);
doc_e=DocPrint(doc,"$$HX-Z,%d,16$$",cnt);
doc_e->data=buf;
doc->cur_entry=doc_e->next;
DocRecalc(doc);
if (unlock)
DocUnlock(doc);
}
public U0 DocD(U8 *buf,I64 cnt=0x80)
{//Dump live chunk of mem showing offsets. Can be edited.
CDocEntry *doc_e;
CDoc *doc=DocPut;
Bool unlock=DocLock(doc);
doc_e=DocPrint(doc,"$$HX,%d,16$$",cnt);
doc_e->data=buf;
doc->cur_entry=doc_e->next;
DocRecalc(doc);
if (unlock)
DocUnlock(doc);
}
#help_index "DolDoc/Output"
Bool KDDocPutS(U8 *st)
{
CDoc *doc;
if (doc=DocPut)
DocPrintPartial(doc,"%s",st);
return FALSE;
}
KeyDevAdd(&KDDocPutKey,&KDDocPutS,0x80000000,TRUE);
fp_getstr2=&DocGetStr2;
fp_doc_put=&DocPut;
+760
View File
@@ -0,0 +1,760 @@
#help_index "DolDoc"
public Bool DocLock(CDoc *doc)
{//Make this task have exclusive access to this doc.
if (!Bt(&doc->locked_flags,DOClf_LOCKED) || doc->owning_task!=Fs) {
while (LBts(&doc->locked_flags,DOClf_LOCKED))
Yield;
if (doc->owning_task!=Fs)
LBEqu(&doc->flags,DOCf_BREAK_UNLOCKED,BreakLock(Fs));
doc->owning_task=Fs;
return TRUE;
} else
return FALSE;
}
public Bool DocUnlock(CDoc *doc)
{//Release exclusive lock on access to doc.
Bool unlock_break;
if (Bt(&doc->locked_flags,DOClf_LOCKED) && doc->owning_task==Fs) {
doc->owning_task=0;
unlock_break=Bt(&doc->flags,DOCf_BREAK_UNLOCKED);
LBtr(&doc->locked_flags,DOClf_LOCKED);
if (unlock_break)
BreakUnlock(Fs);
return TRUE;
} else
return FALSE;
}
CDocBin *DocBinFindNum(CDoc *haystack_doc,I64 needle_num)
{
CDocBin *b=haystack_doc->bin_root.next;
while (b!=&haystack_doc->bin_root) {
if (b->num==needle_num)
return b;
b=b->next;
}
return NULL;
}
CDocBin *DocBinFindTag(CDoc *haystack_doc,U8 *needle_tag)
{
CDocBin *b;
if (needle_tag) {
b=haystack_doc->bin_root.next;
while (b!=&haystack_doc->bin_root) {
if (b->tag && !StrCmp(b->tag,needle_tag))
return b;
b=b->next;
}
}
return NULL;
}
U0 DocBinsValidate(CDoc *doc)
{
Bool unlock=DocLock(doc);
CDocBin *b,*b1;
CDocEntry *doc_e,*doc_e2;
I64 renum_num=0;
b=doc->bin_root.next;
while (b!=&doc->bin_root) {
b->use_cnt=0;
b->temp_use_cnt=0;
b->renum_num=-1;
Free(b->tag);
b->tag=NULL;
b=b->next;
}
doc_e=doc->root.next;
while (doc_e!=doc) {
doc_e2=doc_e->next;
if (doc_e->de_flags & DOCEF_HAS_BIN) {
if (b=doc_e->bin_data=DocBinFindNum(doc,doc_e->bin_num)) {
if (doc_e->de_flags & DOCEF_BIN_PTR_LINK)
b->temp_use_cnt=MAX_I32;
if (!b->use_cnt++)
b->renum_num=++renum_num;
doc_e->bin_num=b->renum_num;
if (!b->tag && doc_e->de_flags&DOCEF_TAG && doc_e->tag && *doc_e->tag)
b->tag=StrNew(doc_e->tag,doc->mem_task);
} else {
RawPrint(3000,"Bin Not Found");
doc_e->type=doc_e->de_flags=0;
doc_e->type_u8=DOCT_ERROR;
}
}
doc_e=doc_e2;
}
b=doc->bin_root.next;
doc->cur_bin_num=1;
while (b!=&doc->bin_root) {
b1=b->next;
if (!b->use_cnt) {
QueRem(b);
Free(b->data);
Free(b);
} else {
b->num=b->renum_num;
if (b->num>=doc->cur_bin_num)
doc->cur_bin_num=b->num+1;
}
b=b1;
}
if (unlock)
DocUnlock(doc);
}
U0 DocBinDel(CDoc *doc,CDocBin *b)
{
if (doc && b && b->use_cnt) {
b->use_cnt--;
if (!b->use_cnt) {
QueRem(b);
Free(b->tag);
Free(b->data);
Free(b);
}
} else
RawPrint(3000,"DocBinDel");
}
Bool IsEditableText(CDocEntry *doc_e)
{
if (doc_e->type_u8==DOCT_TEXT&&!(doc_e->de_flags&DOCEG1_DONT_EDIT))
return TRUE;
else
return FALSE;
}
CDocEntry *DocEntryNew(CDoc *doc,CDocEntry *doc_ce,U8 *tag)
{
CDocEntry *result=CAlloc(sizeof(CDocEntryBase),doc->mem_task);
result->type=doc_ce->type;
result->de_flags=doc_ce->de_flags;
result->tag=tag;
result->max_col=StrLen(tag);
result->x=doc_ce->x;
result->y=doc_ce->y;
result->page_line_num=doc_ce->page_line_num;
MemCpy(&result->settings,&doc_ce->settings,sizeof(CDocSettings));
return result;
}
public U0 DocEntryDel(CDoc *doc,CDocEntry *doc_e)
{//Free entry and all parts of entry.
if (!doc || doc==doc_e)
RawPrint(3000,"DocEntryDel");
else {
if (doc->cur_entry==doc_e)
doc->cur_entry=doc_e->next;
QueRem(doc_e);
if (doc_e->de_flags & DOCEF_TAG)
Free(doc_e->tag);
if (doc_e->de_flags & DOCEF_LEFT_MACRO)
Free(doc_e->left_macro);
if (doc_e->de_flags & DOCEF_RIGHT_MACRO)
Free(doc_e->right_macro);
if (doc_e->de_flags & DOCEF_AUX_STR)
Free(doc_e->aux_str);
if (doc_e->de_flags & DOCEF_DEFINE)
Free(doc_e->define_str);
if (doc_e->de_flags & DOCEF_HTML_LINK)
Free(doc_e->html_link);
if (doc_e->de_flags & DOCEF_BIN_PTR_LINK)
Free(doc_e->bin_ptr_link);
if (doc_e->de_flags & DOCEF_HAS_BIN)
DocBinDel(doc,doc_e->bin_data);
Free(doc_e);
}
}
public I64 DocEntrySize(CDoc *,CDocEntry *doc_e)
{//Mem size of entry and all parts.
I64 result;
if (!doc_e) return 0;
result=MSize2(doc_e);
if (doc_e->de_flags & DOCEF_TAG)
result+=MSize2(doc_e->tag);
if (doc_e->de_flags & DOCEF_AUX_STR)
result+=MSize2(doc_e->aux_str);
if (doc_e->de_flags & DOCEF_DEFINE)
result+=MSize2(doc_e->define_str);
if (doc_e->de_flags & DOCEF_HTML_LINK)
result+=MSize2(doc_e->html_link);
if (doc_e->de_flags & DOCEF_BIN_PTR_LINK)
result+=MSize2(doc_e->bin_ptr_link);
if (doc_e->de_flags & DOCEF_LEFT_MACRO)
result+=MSize2(doc_e->left_macro);
if (doc_e->de_flags & DOCEF_RIGHT_MACRO)
result+=MSize2(doc_e->right_macro);
return result;
}
U0 DocUndoDel(CDoc *,CDocUndo *u)
{
Free(u->body);
Free(u);
}
U0 DocUndoCntSet(CDoc *doc)
{
Bool unlock=DocLock(doc);
CDocUndo *u=doc->undo_root.next;
doc->undo_cnt=0;
while (u!=&doc->undo_root) {
doc->undo_cnt++;
u=u->next;
}
if (unlock)
DocUnlock(doc);
}
public CDocEntry *DocEntryCopy(CDoc *doc,CDocEntry *doc_e)
{//Make copy of entry and all parts of entry.
CDocEntry *doc_ne;
CDocBin *tempb;
CTask *task=doc->mem_task;
doc_ne=MAllocIdentical(doc_e,task);
doc_ne->next=doc_ne;
doc_ne->last=doc_ne;
if (doc_e->de_flags & DOCEF_TAG)
doc_ne->tag=MAllocIdentical(doc_e->tag,task);
if (doc_e->de_flags & DOCEF_AUX_STR)
doc_ne->aux_str=MAllocIdentical(doc_e->aux_str,task);
if (doc_e->de_flags & DOCEF_DEFINE)
doc_ne->define_str=MAllocIdentical(doc_e->define_str,task);
if (doc_e->de_flags & DOCEF_HTML_LINK)
doc_ne->html_link=MAllocIdentical(doc_e->html_link,task);
if (doc_e->de_flags & DOCEF_BIN_PTR_LINK)
doc_ne->bin_ptr_link=MAllocIdentical(doc_e->bin_ptr_link,task);
if (doc_e->de_flags & DOCEF_LEFT_MACRO)
doc_ne->left_macro=MAllocIdentical(doc_e->left_macro,task);
if (doc_e->de_flags & DOCEF_RIGHT_MACRO)
doc_ne->right_macro=MAllocIdentical(doc_e->right_macro,task);
if (doc_e->de_flags & DOCEF_HAS_BIN) {
tempb=MAllocIdentical(doc_e->bin_data,task);
tempb->data=MAllocIdentical(doc_e->bin_data->data,task);
doc_ne->bin_num=doc->cur_bin_num;
tempb->num=doc->cur_bin_num++;
doc_ne->bin_data=tempb;
if (doc_e->de_flags&DOCEF_TAG && doc_e->tag && *doc_e->tag)
tempb->tag=StrNew(doc_e->tag,task);
else
tempb->tag=NULL;
QueIns(tempb,doc->bin_root.last);
}
return doc_ne;
}
public U8 *DocEntryLink(CDoc *doc,CDocEntry *doc_e)
{//MAlloc new str, either tag or aux_str if link.
if (doc_e->de_flags&DOCEF_LINK) {
if (doc_e->de_flags & DOCEF_AUX_STR)
return StrNew(doc_e->aux_str,doc->mem_task);
else if (doc_e->de_flags & DOCEF_TAG)
return StrNew(doc_e->tag,doc->mem_task);
}
return NULL;
}
U0 DocFormFwd(CDoc *doc,Bool giveup=FALSE)
{
CDocEntry *doc_e=doc->cur_entry,*doc_e2=doc_e;
if (doc->flags & DOCF_FORM) {
if (doc_e==doc) goto ff_recover;
while (!Bt(doldoc.type_flags_form,doc_e->type_u8) ||
doc_e->de_flags&DOCEF_SKIP_IN_FORM) {
doc_e=doc_e->next;
if (doc_e==doc) {
ff_recover:
doc->cur_data_col=0;
if (!giveup) {
doc->cur_entry=doc_e->last;
DocFormBwd(doc,TRUE);
} else
doc->cur_entry=doc;
return;
}
}
}
while (doc_e->type_u8==DOCT_INDENT)
doc_e=doc_e->next;
if (doc_e!=doc_e2) {
doc->cur_data_col=doc_e->min_col;
doc->cur_entry=doc_e;
}
}
U0 DocFormBwd(CDoc *doc,Bool giveup=FALSE)
{
CDocEntry *doc_e=doc->cur_entry,*doc_e2=doc_e;
if (doc->flags & DOCF_FORM) {
while (!Bt(doldoc.type_flags_form,doc_e->type_u8) ||
doc_e->de_flags&DOCEF_SKIP_IN_FORM) {
doc_e=doc_e->last;
if (doc_e==doc) {
doc->cur_data_col=0;
if (!giveup) {
doc->cur_entry=doc_e->next;
DocFormFwd(doc,TRUE);
} else
doc->cur_entry=doc;
return;
}
}
}
while (doc_e->type_u8==DOCT_INDENT)
doc_e=doc_e->next;
if (doc_e!=doc_e2) {
doc->cur_data_col=doc_e->min_col;
doc->cur_entry=doc_e;
}
}
public U0 DocTop(CDoc *doc=NULL)
{//Move cursor, cur_entry, to top.
Bool unlock;
if (!doc && !(doc=DocPut))
return;
unlock=DocLock(doc);
doc->cur_entry=doc->root.next;
doc->cur_data_col=doc->cur_entry->min_col;
doc->x=0;
doc->y=0;
doc->line_start_col=0;
doc->cur_top_line_num=0;
DocFormFwd(doc);
DocRecalc(doc);
if (unlock)
DocUnlock(doc);
}
public U0 DocRst(CDoc *doc,Bool is_old)
{//Del all entries and set doc to dfts.
Bool unlock;
CDocEntry *doc_e,*doc_e2;
CDocUndo *u,*u8;
CDocSettings *s;
CDocBin *b,*b1;
if (!doc && !(doc=DocPut))
return;
unlock=DocLock(doc);
if (is_old) {
doc_e=doc->root.next;
while (doc_e!=doc) {
doc_e2=doc_e->next;
DocEntryDel(doc,doc_e);
doc_e=doc_e2;
}
u=doc->undo_root.next;
while (u!=&doc->undo_root) {
u8=u->next;
DocUndoDel(doc,u);
u=u8;
}
b=doc->bin_root.next;
while (b!=&doc->bin_root) {
b1=b->next;
QueRem(b);
Free(b->data);
Free(b);
b=b1;
}
}
//Check $LK,"DocInsDoc",A="MN:DocInsDoc"$
doc->flags&=DOCF_BREAK_UNLOCKED;
doc->root.next=doc->root.last=doc;
QueInit(&doc->bin_root);
QueInit(&doc->undo_root);
doc->undo_root.time_stamp=0;
doc->undo_cnt=0;
doc->cur_bin_num=1;
doc->dollar_buf_ptr=0;
doc->ext_ascii_cnt=doc->ext_ascii_val=0;
doc->cmd_U8=CH_SPACE;
doc->page_line_num=0;
doc->best_d=MAX_I64;
s=&doc->settings_root;
s->left_margin=DOC_DFT;
s->right_margin=DOC_DFT;
s->indent=0;
s->page_len=66;
s->header=DOC_DFT;
s->footer=DOC_DFT;
s->state=DOCSS_NORMAL;
s->comment_depth=0;
s->paren_depth=0;
s->brace_depth=0;
s->shifted_x=0;
s->shifted_y=0;
s->cur_text_attr=s->dft_text_attr=DOC_ATTR_DFT_TEXT;
doc_e=&doc->root;
doc_e->type=DOCT_ERROR;
doc_e->de_flags=0;
doc_e->x=0;
doc_e->y=0;
doc_e->min_col=0;
doc_e->max_col=0;
doc_e->page_line_num=doc->page_line_num;
MemCpy(&doc_e->settings,s,sizeof(CDocSettings));
DocTop(doc);
if (unlock)
DocUnlock(doc);
}
public U0 DocDel(CDoc *doc)
{//Free entire doc and entries.
if (!doc || doc->doc_signature!=DOC_SIGNATURE_VAL) return;
DocLock(doc);
doc->doc_signature=0;
DocRst(doc,TRUE);
Free(doc->find_replace);
Free(doc->dollar_buf);
DocUnlock(doc);
Free(doc);
}
public I64 DocSize(CDoc *doc)
{//Mem size of doc and all its entries.
Bool unlock;
CDocEntry *doc_e;
CDocUndo *u;
CDocBin *b;
I64 result=0;
if (!doc || doc->doc_signature!=DOC_SIGNATURE_VAL) return 0;
unlock=DocLock(doc);
doc_e=doc->root.next;
while (doc_e!=doc) {
result+=DocEntrySize(doc,doc_e);
doc_e=doc_e->next;
}
u=doc->undo_root.next;
while (u!=&doc->undo_root) {
result+=MSize2(u->body);
result+=MSize2(u);
u=u->next;
}
b=doc->bin_root.next;
while (b!=&doc->bin_root) {
result+=MSize2(b->data);
result+=MSize2(b);
b=b->next;
}
result+=MSize2(doc->find_replace);
result+=MSize2(doc->dollar_buf);
result+=MSize2(doc);
if (unlock)
DocUnlock(doc);
return result;
}
U0 DocDataFmt(CDoc *doc,CDocEntry *doc_e,I64 d=DOCM_CANCEL)
{
I64 i;
U8 *ptr;
CHashDefineStr *temph;
if (doc_e->type_u8==DOCT_DATA && doc_e->de_flags&DOCEF_AUX_STR ||
doc_e->type_u8==DOCT_CHECK_BOX || doc_e->de_flags & DOCEF_LST) {
if (d==DOCM_CANCEL) {
if (doc_e->de_flags & DOCEF_DATA_IS_PTR) {
if (!(ptr=doc_e->data)) return;
} else
ptr=&doc_e->data;
switch(doc_e->raw_type) {
case RT_I0:
case RT_U0: d=0; break;
case RT_I8: d=*ptr(I8 *); break;
case RT_U8: d=*ptr(U8 *); break;
case RT_I16: d=*ptr(I16 *); break;
case RT_U16: d=*ptr(U16 *); break;
case RT_I32: d=*ptr(I32 *); break;
case RT_U32: d=*ptr(U32 *); break;
default: d=*ptr(I64 *);
}
}
if (doc_e->type_u8==DOCT_DATA) {
StrPrint(doc_e->tag,doc_e->aux_str,d,doc_e->my_fmt_data);
if (doc_e->de_flags & DOCEF_HAS_TERMINATOR) {
i=StrLen(doc_e->tag);
doc_e->tag[i++]='_';
doc_e->tag[i]=0;
}
doc_e->max_col=StrLen(doc_e->tag);
} else if (doc_e->de_flags & DOCEF_LST) {
if (doc_e->de_flags & DOCEF_DEFINE &&
(temph=HashFind(doc_e->define_str,doc->win_task->hash_table,HTT_DEFINE_STR)) &&
0<=d<temph->cnt) {
ptr=MStrPrint("[%s]",temph->sub_lst[d]);
Free(doc_e->tag);
doc_e->tag=StrNew(ptr,doc->mem_task);
Free(ptr);
} else {
Free(doc_e->tag);
doc_e->tag=StrNew("[]",doc->mem_task);
}
} else {
if (d)
doc_e->de_flags|=DOCEF_CHECKED_COLLAPSED;
else
doc_e->de_flags&=~DOCEF_CHECKED_COLLAPSED;
}
}
}
U0 DocDataScan(CDoc *doc,CDocEntry *doc_e)
{
I64 i,d;
U8 *ptr,*ptr1,*ptr2;
CHashDefineStr *temph;
if (doc_e->type_u8==DOCT_DATA && doc_e->de_flags&DOCEF_AUX_STR ||
doc_e->type_u8==DOCT_CHECK_BOX || doc_e->de_flags & DOCEF_LST) {
if (doc_e->de_flags & DOCEF_DATA_IS_PTR) {
if (!(ptr=doc_e->data)) return;
} else
ptr=&doc_e->data;
if (doc_e->type_u8==DOCT_DATA) {
i=StrLen(doc_e->tag);
if (doc_e->de_flags & DOCEF_HAS_TERMINATOR)
doc_e->tag[--i]=0;
if (i>doc_e->len+doc_e->min_col)
doc_e->tag[doc_e->len+doc_e->min_col]=0;
if (RT_I8<=doc_e->raw_type<=RT_U32) {
StrScan(doc_e->tag,doc_e->aux_str,&d,doc_e->my_fmt_data);
if (doc_e->de_flags & DOCEF_HAS_TERMINATOR)
doc_e->tag[i]='_';
} else if (RT_I64<=doc_e->raw_type<=RT_UF64) {
StrScan(doc_e->tag,doc_e->aux_str,ptr,doc_e->my_fmt_data);
if (doc_e->de_flags & DOCEF_HAS_TERMINATOR)
doc_e->tag[i]='_';
return;
}
} else if (doc_e->de_flags & DOCEF_LST) {
d=0;
if (doc_e->tag && doc_e->de_flags & DOCEF_DEFINE &&
(temph=HashFind(doc_e->define_str,doc->win_task->hash_table,HTT_DEFINE_STR))) {
ptr1=ptr2=StrNew(doc_e->tag);
if (*ptr2=='[') {
ptr2++;
i=StrLen(ptr2);
if (ptr2[i-1]==']')
ptr2[i-1]=0;
}
d=LstMatch(ptr2,temph->data);
Free(ptr1);
}
} else {
if (doc_e->de_flags & DOCEF_CHECKED_COLLAPSED)
d=TRUE;
else
d=FALSE;
}
switch(doc_e->raw_type) {
case RT_I8:
case RT_U8:
*ptr(U8 *)=d;
case RT_I0:
case RT_U0:
break;
case RT_I16:
case RT_U16:
*ptr(U16 *)=d;
break;
case RT_I32:
case RT_U32:
*ptr(U32 *)=d;
break;
default:
*ptr(I64 *)=d;
}
}
}
U0 DocRemSoftNewLines(CDoc *doc=NULL,CDocEntry *doc_e=NULL)
{
CDocEntry *doc_e2,*saved_ll=doc_e;
Bool unlock;
if (!doc && !(doc=DocPut))
return;
unlock=DocLock(doc);
if (!doc_e) doc_e=doc->root.next;
while (doc_e!=doc) {
doc_e2=doc_e->next;
if (doc_e->type_u8==DOCT_SOFT_NEW_LINE) {
if (doc->cur_entry==doc_e) {
doc->cur_entry=doc_e2;
doc->cur_data_col=doc->cur_entry->min_col;
}
DocEntryDel(doc,doc_e);
} else if (saved_ll && doc_e->type_u8==DOCT_NEW_LINE)
break;
doc_e=doc_e2;
}
if (unlock)
DocUnlock(doc);
}
#help_index "DolDoc/Cmd Line (Typically);Cmd Line (Typically)"
public I64 DocMax(I64 i=MAX_I64)
{//Set max document entries. (Cmd line buffer.)
//Adjusts the size of the cmd line buf.
//Normally, the cmd line deletes entries
//when more are added and the old scroll up.
//See $LK,"max_entries",A="FF:::/Adam/DolDoc/DocMain.CPP,max_entries"$.
I64 result;
CDoc *doc;
if (doc=DocPut) {
result=doc->max_entries;
doc->max_entries=i;
return result;
} else
return 0;
}
#help_index "DolDoc"
public CDoc *DocNew(U8 *filename=NULL,CTask *task=NULL)
{//MAlloc new $LK,"DolDoc",A="FI:::/Doc/DolDocOverview.TXT"$. (Begin a new doc.)
CDoc *doc;
if (!task) task=Fs;
doc=CAlloc(sizeof(CDoc),task);
if (filename)
StrCpy(doc->filename.name,filename);
else
StrCpy(doc->filename.name,dsk.temp_filename);
doc->find_replace=CAlloc(sizeof(CEdFindText),task);
doc->find_replace->scan_fwd=TRUE;
doc->find_replace->match_case=TRUE;
doc->find_replace->pmt=TRUE;
doc->left_click_link=&EdLeftClickLink;
doc->dollar_buf_size=84;
doc->dollar_buf=MAlloc(doc->dollar_buf_size,task);
doc->max_entries=MAX_I64;
doc->win_task=task;
doc->mem_task=task;
DocRst(doc,FALSE);
doc->doc_signature=DOC_SIGNATURE_VAL;
return doc;
}
#help_index "DolDoc/Task"
public CDoc *DocPut(CTask *task=NULL)
{//Current document that StdOut Put() goes to.
//Basically, StdOut unless double buffering.
CDoc *result;
if (!task) task=Fs;
if ((result=task->put_doc) && result->doc_signature==DOC_SIGNATURE_VAL)
return result;
else
return NULL;
}
public CDoc *DocDisplay(CTask *task=NULL)
{//StdOut displayed unless double buffering.
CDoc *result;
if (!task) task=Fs;
if ((result=task->display_doc) && result->doc_signature==DOC_SIGNATURE_VAL)
return result;
else
return NULL;
}
public CDoc *DocBorder(CTask *task=NULL)
{//Doc holding border of window text.
CDoc *result;
if (!task) task=Fs;
if ((result=task->border_doc) && result->doc_signature==DOC_SIGNATURE_VAL)
return result;
else
return NULL;
}
public CDoc *DocDblBufStart(CTask *task=NULL)
{//See $LK,"::/Demo/Spy.CPP"$
Bool unlock_ddoc,old_preempt=Preempt(OFF);
CDoc *pdoc=DocPut(task),*ddoc=DocDisplay(task),*result;
if (!pdoc || !ddoc || pdoc!=ddoc)
result=NULL; //Already Double buffering
else {
if (!task) task=Fs;
unlock_ddoc=DocLock(ddoc); //dont want change during winupdate, so lock DocPut$WW,0$
result=DocNew(,task);
result->win_task =ddoc->win_task;
result->max_entries =ddoc->max_entries;
MemCpy(result->find_replace,ddoc->find_replace,sizeof(CEdFindText));
MemCpy(&result->filename,&ddoc->filename,sizeof(CEdFileName));
result->left_click_link =ddoc->left_click_link;
result->right_click_link =ddoc->right_click_link;
result->user_put_data =ddoc->user_put_data;
result->user_put_key =ddoc->user_put_key;
result->user_put_s =ddoc->user_put_s;
result->parent_doc =ddoc->parent_doc;
result->desc =ddoc->desc;
result->user_data =ddoc->user_data;
result->flags|=ddoc->flags&DOCG_DBL_BUF_FLAGS | DOCF_DONT_SHOW;
task->put_doc=result;
if (unlock_ddoc)
DocUnlock(ddoc);
}
Preempt(old_preempt);
return result;
}
public Bool DocDblBufEnd(CTask *task=NULL)
{//See $LK,"::/Demo/Spy.CPP"$
Bool result=FALSE,old_preempt=Preempt(OFF);
CDoc *pdoc=DocPut(task),*ddoc=DocDisplay(task);
if (pdoc && ddoc && pdoc!=ddoc) {//Double buffering?
if (!task) task=Fs;
ddoc->flags|=DOCF_DONT_SHOW;
pdoc->flags&=~DOCF_DONT_SHOW;
DocLock(ddoc);
task->display_doc=pdoc;
DocUnlock(ddoc);
DocDel(ddoc);
result=TRUE;
}
Preempt(old_preempt);
return result;
}
public Bool DocDblBufSwap(CTask *task=NULL)
{//See $LK,"::/Demo/Spy.CPP"$
Bool result=FALSE,old_preempt=Preempt(OFF);
CDoc *pdoc=DocPut(task),*ddoc=DocDisplay(task);
if (pdoc && ddoc && pdoc!=ddoc) {//Double buffering?
if (!task) task=Fs;
ddoc->flags|=DOCF_DONT_SHOW;
pdoc->flags&=~DOCF_DONT_SHOW;
DocLock(ddoc);
task->display_doc=pdoc;
DocUnlock(ddoc);
DocRst(ddoc,TRUE);
MemCpy(ddoc->find_replace,pdoc->find_replace,sizeof(CEdFindText));
MemCpy(&ddoc->filename,&pdoc->filename,sizeof(CEdFileName));
ddoc->max_entries =pdoc->max_entries;
ddoc->flags =pdoc->flags&DOCG_DBL_BUF_FLAGS | ddoc->flags&~DOCG_DBL_BUF_FLAGS;
ddoc->left_click_link =pdoc->left_click_link;
ddoc->right_click_link =pdoc->right_click_link;
ddoc->user_put_data =pdoc->user_put_data;
ddoc->user_put_key =pdoc->user_put_key;
ddoc->user_put_s =pdoc->user_put_s;
ddoc->desc =pdoc->desc;
ddoc->user_data =pdoc->user_data;
task->put_doc=ddoc;
result=TRUE;
}
Preempt(old_preempt);
return result;
}
+104
View File
@@ -0,0 +1,104 @@
#help_index "DolDoc"
I64 DocOptEntry(CDoc *,CDocEntry *doc_e)
{
U8 *st,*st2,**_dst;
I64 i,result=0;
if (doc_e->de_flags&DOCEF_LINK && doc_e->de_flags&(DOCEF_AUX_STR|DOCEF_TAG)) {
if (doc_e->de_flags & DOCEF_AUX_STR && doc_e->de_flags & DOCEF_TAG &&
!MemCmp(doc_e->aux_str,"FI:",3) && !StrCmp(doc_e->aux_str+3,doc_e->tag)) {
Free(doc_e->aux_str);
doc_e->aux_str=NULL;
doc_e->de_flags&=~DOCEF_AUX_STR;
result++;
}
if (doc_e->de_flags & DOCEF_AUX_STR)
_dst=&doc_e->aux_str;
else
_dst=&doc_e->tag;
if (StrMatch(".Z",*_dst)) {
st=DocLinkFile(*_dst);
if (FileFind(st)) {
if (IsDotZ(st))
st[StrLen(st)-2]=0;
i=StrLen(st);
if ((st2=StrMatch(st,*_dst)) && st2[i]=='.' && st2[i+1]=='Z') {
StrCpy(st2+i,st2+i+2);
result++;
}
}
Free(st);
}
/* !!! Dangerous, but handy !!!
if (doc_e->de_flags & DOCEF_AUX_STR) {
if (st=StrMatch(".Z",doc_e->aux_str)) {
StrCpy(st,st+2);
result++;
}
}
if (doc_e->de_flags&DOCEF_TAG) {
if (st=StrMatch(".Z",doc_e->tag)) {
StrCpy(st,st+2);
result++;
}
}
*/
}
return result;
}
I64 DocOptDoc(CDoc *doc)
{//Optimize Doc.
Bool unlock=DocLock(doc);
I64 result=0;
CDocEntry *doc_e;
DocRecalc(doc);
doc_e=doc->root.next;
while (doc_e!=doc) {
if (result+=DocOptEntry(doc,doc_e))
result+=DocOptEntry(doc,doc_e);
doc_e=doc_e->next;
}
DocRecalc(doc);
if (unlock)
DocUnlock(doc);
return result;
}
I64 DocOptFile(U8 *filename)
{//Optimize File.
I64 result;
CDoc *doc=DocRead(filename);
if (result=DocOptDoc(doc)) {
"-%d:%s\n",result,doc->filename.name;
DocWrite(doc);
}
DocDel(doc);
return result;
}
I64 DocOptLst(CDirEntry *tempde)
{
I64 result=0;
CDirEntry *tempde1;
while (tempde) {
tempde1=tempde->next;
if (tempde->attr & RS_ATTR_DIR) {
if (tempde->sub) {
"Scanning Directory: %s\n",tempde->full_name;
result+=DocOptLst(tempde->sub);
}
} else
result+=DocOptFile(tempde->full_name);
DirEntryDel(tempde);
tempde=tempde1;
}
return result;
}
public I64 DocOpt(U8 *files_find_mask="*",U8 *fu_flags=NULL)
{//Optimize $LK,"DolDoc",A="FI:::/Doc/DolDocOverview.TXT"$ Files, eliminating aux_str's and .Z's.
I64 f=0;
ScanFlags(&f,Define("ST_FILE_UTIL_FLAGS"),"+r+T");
ScanFlags(&f,Define("ST_FILE_UTIL_FLAGS"),fu_flags);
return DocOptLst(FilesFind(files_find_mask,f));
}
+739
View File
@@ -0,0 +1,739 @@
#help_index "DolDoc"
I64 PrsDocFlagSingle(CLex *lx,I64 *_de_flags,U32 *_type,Bool turn_on)
{
I64 result=-1;
CHashGeneric *temph;
if (lx->token==TK_IDENT && (temph=HashFind(lx->cur_str,doldoc.hash,DHT_DOC_FLAG))) {
result=temph->user_data0;
if (result<64) {
BEqu(_de_flags,result,turn_on);
switch (result) {
case DOCEf_SELECTED:
case DOCEf_UNDERLINE:
case DOCEf_INVERT:
case DOCEf_BLINK:
BEqu(_type,result,turn_on);
break;
}
}
Lex(lx); //skip flag
}
return result;
}
I64 PrsDocFlags(CLex *lx,I64 *_de_flags,U32 *_type)
{
I64 result=-1;
Bool turn_on;
while (TRUE) {
if (lx->token=='+')
turn_on=TRUE;
else if (lx->token=='-')
turn_on=FALSE;
else
break;
Lex(lx);
result=PrsDocFlagSingle(lx,_de_flags,_type,turn_on);
}
return result;
}
I64 DocBinPtrRst(CDoc *doc,CDocEntry *doc_e)
{
U8 *st,*st2;
CDoc *doc2;
CDocBin *tempb,*tempb2;
I64 i,bin_num=0;
if (doc_e->de_flags&DOCEF_HAS_BIN && doc_e->bin_ptr_link && StrLen(doc_e->bin_ptr_link)) {
bin_num=doc_e->bin_num;
st=StrNew(doc_e->bin_ptr_link);
st2=StrNew(st);
StrLastRem(st,",",st2);
i=Str2I64(st2);
if (i>0||*st2) {
doc2=DocRead(st);
if (i>0 && (tempb2=DocBinFindNum(doc2,i)) ||
i==0 && (tempb2=DocBinFindTag(doc2,st2))) {
i=1;
if (bin_num>0) {
if (tempb=DocBinFindNum(doc,bin_num)) {
i=tempb->use_cnt;
DocBinDel(doc,tempb);
}
} else
bin_num=doc->cur_bin_num++;
tempb=MAllocIdentical(tempb2,doc->mem_task);
tempb->use_cnt=i;
tempb->data=MAllocIdentical(tempb2->data,doc->mem_task);
tempb->num=bin_num;
doc_e->bin_data=tempb;
if (doc_e->de_flags&DOCEF_TAG && doc_e->tag && *doc_e->tag)
tempb->tag=StrNew(doc_e->tag,doc->mem_task);
else
tempb->tag=NULL;
QueIns(tempb,doc->bin_root.last);
} else
bin_num=0;
DocDel(doc2);
} else
bin_num=0;
Free(st2);
Free(st);
doc_e->bin_num=bin_num;
}
return bin_num;
}
U8 *Doc2PlainText(CDoc *doc,CDocEntry *doc_e)
{//TODO: break strs
I64 i,j,attr=doc_e->attr,
t1,f1,de_flags,type;
U8 *buf,*buf2;
if (doc_e->type_u8==DOCT_FOREGROUND && doc->flags&DOCF_COLOR_NAMES && 0<=attr<NUM_COLORS) {
buf=StrNew(DefineSub(attr,"ST_COLORS"));
attr=DOC_DFT;
} else
buf=StrNew(DefineSub(doc_e->type_u8,"ST_DOC_CMDS"));
if (doc_e->type_u8!=DOCT_ERROR) {
f1=doldoc.dft_de_flags[doc_e->type_u8];
t1=doc_e->type_u8|doldoc.dft_type_flags[doc_e->type_u8];
de_flags=doc_e->de_flags&~(DOCG_BL_IV_UL|DOCEF_SELECTED|DOCEF_HIGHLIGHT|DOCEF_WORD_WRAP|DOCEF_SKIP|DOCEF_FILTER_SKIP);
for (i=0;i<DOCEf_NUM_FLAGS;i++)
if (Bt(&f1,i)!=Bt(&de_flags,i)) {
if (Bt(&de_flags,i)) {
if (!(1<<i&DOCEG1_HAS_ARG)) {
buf2=MStrPrint("%s+%Z",buf,i,"ST_DOC_FLAGS");
Free(buf); buf=buf2;
}
} else {
buf2=MStrPrint("%s-%Z",buf,i,"ST_DOC_FLAGS");
Free(buf); buf=buf2;
}
}
type=doc_e->type&~DOCET_SELECTED;
for (i=DOCEt_BLINK;i<=DOCEt_UNDERLINE;i++)
if (Bt(&t1,i)!=Bt(&type,i)) {
if (Bt(&type,i))
buf2=MStrPrint("%s+%Z",buf,i,"ST_DOC_FLAGS");
else
buf2=MStrPrint("%s-%Z",buf,i,"ST_DOC_FLAGS");
Free(buf); buf=buf2;
}
buf2=MStrPrint("%s,",buf);
Free(buf); buf=buf2;
nobound_switch (doc_e->type_u8) {
sub_switch_start:
case DOCT_DATA:
buf2=MStrPrint("%s%d,",buf,doc_e->len);
break;
case DOCT_HEX_ED:
buf2=MStrPrint("%s%d,",buf,doc_e->len);
Free(buf); buf=buf2;
buf2=MStrPrint("%s%d,",buf,doc_e->hex_ed_width);
break;
sub_switch_end:
Free(buf); buf=buf2;
break;
case DOCT_FOREGROUND:
case DOCT_BACKGROUND:
case DOCT_DFT_FOREGROUND:
case DOCT_DFT_BACKGROUND:
if (doc->flags&DOCF_COLOR_NAMES && 0<=attr<NUM_COLORS) {
buf2=MStrPrint("%s%Z,",buf,doc_e->attr,"ST_COLORS");
Free(buf); buf=buf2;
break;
}
case DOCT_PAGE_LEN:
case DOCT_LEFT_MARGIN:
case DOCT_RIGHT_MARGIN:
case DOCT_HEADER:
case DOCT_FOOTER:
case DOCT_INDENT:
case DOCT_WORD_WRAP:
case DOCT_HIGHLIGHT:
case DOCT_UNDERLINE:
case DOCT_INVERT:
case DOCT_BLINK:
case DOCT_SHIFTED_X:
case DOCT_SHIFTED_Y:
if (attr!=DOC_DFT) {
buf2=MStrPrint("%s%d,",buf,doc_e->attr);
Free(buf); buf=buf2;
}
case DOCT_NUM_TYPES-1: //nobound_switch
break;
}
de_flags=doc_e->de_flags & DOCEG1_HAS_ARG;
while (de_flags) {
j=Bsf(de_flags);
Btr(&de_flags,j);
nobound_switch (j) {
case DOCEf_TAG:
if (doc_e->type_u8==DOCT_DATA || doc_e->type_u8==DOCT_MACRO &&
(doc_e->de_flags&DOCEF_LEFT_MACRO && !StrCmp(doc_e->tag,doc_e->left_macro) ||
doc_e->de_flags&DOCEF_RIGHT_MACRO && !StrCmp(doc_e->tag,doc_e->right_macro)) ||
doc_e->de_flags&DOCEF_LST && !StrCmp(doc_e->tag,"[]") && doc_e->de_flags&DOCEF_DEFINE) {
buf2=buf;
buf=NULL;
} else {
if (doc_e->type_u8==DOCT_CHECK_BOX) {
if (StrLen(doc_e->tag)>=4)
buf2=doc_e->tag+4;
else
buf2="";
} else if (doc_e->de_flags & DOCEF_TREE) {
if (StrLen(doc_e->tag)>=3)
buf2=doc_e->tag+3;
else
buf2="";
} else
buf2=doc_e->tag;
if (Bt(&doldoc.dft_de_flags[doc_e->type_u8],DOCEf_TAG))
buf2=MStrPrint("%s\"%$$Q\",",buf,buf2);
else
buf2=MStrPrint("%sT=\"%$$Q\",",buf,buf2);
}
break;
case DOCEf_AUX_STR:
buf2=MStrPrint("%sA=\"%$$Q\",",buf,doc_e->aux_str);
break;
case DOCEf_DEFINE:
buf2=MStrPrint("%sD=\"%$$Q\",",buf,doc_e->define_str);
break;
case DOCEf_HTML_LINK:
buf2=MStrPrint("%sHTML=\"%$$Q\",",buf,doc_e->html_link);
break;
case DOCEf_LEFT_EXP:
buf2=MStrPrint("%sLE=%d,",buf,doc_e->left_exp);
break;
case DOCEf_LEFT_MACRO:
buf2=MStrPrint("%sLM=\"%$$Q\",",buf,doc_e->left_macro);
break;
case DOCEf_RIGHT_EXP:
buf2=MStrPrint("%sRE=%d,",buf,doc_e->right_exp);
break;
case DOCEf_RIGHT_MACRO:
buf2=MStrPrint("%sRM=\"%$$Q\",",buf,doc_e->right_macro);
break;
case DOCEf_HAS_BIN:
buf2=MStrPrint("%sBI=%d,",buf,doc_e->bin_num);
break;
case DOCEf_BIN_PTR_LINK:
buf2=MStrPrint("%sBP=\"%$$Q\",",buf,doc_e->bin_ptr_link);
break;
case DOCEf_RAW_TYPE:
if (doc_e->type_u8==DOCT_CHECK_BOX&&doc_e->raw_type!=RT_I8 ||
doc_e->type_u8!=DOCT_CHECK_BOX&&doc_e->raw_type!=RT_I64)
buf2=MStrPrint("%sRT=%Z,",buf,doc_e->raw_type,"ST_RAW_TYPES");
break;
case DOCEf_SHIFTED_X:
j=doc_e->type.u16[1]&0x1F;
if (j&0x10) j|=0xFFFFFFF0;
buf2=MStrPrint("%sSX=%d,",buf,j);
break;
case DOCEf_SHIFTED_Y:
j=doc_e->type>>21 &0x1F;
if (j&0x10) j|=0xFFFFFFF0;
buf2=MStrPrint("%sSY=%d,",buf,j);
break;
case DOCEf_SCROLLING_X:
buf2=MStrPrint("%sSCX=%d,",buf,doc_e->scroll_len);
break;
case DOCEf_USER_DATA:
buf2=MStrPrint("%sU=0x%X,",buf,doc_e->user_data);
break;
case DOCEf_NUM_FLAGS-1: //nobound_switch
break;
}
Free(buf); buf=buf2;
}
buf[StrLen(buf)-1]=0; //Kill last comma
}
buf2=StrNew(buf,doc->mem_task); //exact allocation
Free(buf);
return buf2;
}
CDocEntry *PrsDollarCmd(CDoc *doc,U8 *st)
{//Uses $LK-UL,"Lex",A="MN:Lex"$() to parse a string and make Doc entries.
I64 i,j,de_flags,processed_flags,attr=DOC_DFT;
U8 *ptr,*st2;
CDocEntry *doc_e=NULL;
CHashGeneric *temph;
CLex *lx=LexNew(st,LF_DONT_FREE_BUF);
CHashTable *old_hash_table_lst=lx->htc.hash_table_lst;
try {
lx->htc.hash_table_lst=NULL;
if (Lex(lx)==TK_IDENT) {
if (temph=HashFind(lx->cur_str,doldoc.hash,DHT_DOC_CMD|DHT_COLOR)) {
if (temph->type&DHT_DOC_CMD)
i=temph->user_data0;
else {//DHT_COLOR
i=DOCT_FOREGROUND;
attr=temph->user_data0;
}
} else
goto pd_err;
Lex(lx); //skip cmd code
doc_e=CAlloc(sizeof(CDocEntry),doc->mem_task);
doc_e->type=i;
doc_e->de_flags=doldoc.dft_de_flags[i];
doc_e->type|=doldoc.dft_type_flags[i];
doc_e->raw_type=RT_I64;
j=PrsDocFlags(lx,&doc_e->de_flags,&doc_e->type);
lx->htc.hash_table_lst=old_hash_table_lst;
nobound_switch (i) {
case DOCT_DATA:
while (lx->token==',')
Lex(lx);
if (lx->token)
doc_e->len=LexExpressionI64(lx);
else
goto pd_err;
break;
case DOCT_CHECK_BOX:
doc_e->raw_type=RT_I8;
break;
case DOCT_HEX_ED:
while (lx->token==',')
Lex(lx);
if (lx->token)
doc_e->len=LexExpressionI64(lx);
else
goto pd_err;
while (lx->token==',')
Lex(lx);
if (lx->token)
doc_e->hex_ed_width=LexExpressionI64(lx);
else
goto pd_err;
break;
case DOCT_PAGE_LEN:
case DOCT_LEFT_MARGIN:
case DOCT_RIGHT_MARGIN:
case DOCT_HEADER:
case DOCT_FOOTER:
case DOCT_INDENT:
case DOCT_FOREGROUND:
case DOCT_BACKGROUND:
case DOCT_DFT_FOREGROUND:
case DOCT_DFT_BACKGROUND:
case DOCT_WORD_WRAP:
case DOCT_HIGHLIGHT:
case DOCT_UNDERLINE:
case DOCT_INVERT:
case DOCT_BLINK:
case DOCT_SHIFTED_X:
case DOCT_SHIFTED_Y:
while (lx->token==',')
Lex(lx);
if (lx->token)
doc_e->attr=LexExpressionI64(lx);
else
doc_e->attr=attr;
break;
#assert DOCT_ERROR==DOCT_NUM_TYPES-1
case DOCT_ERROR:
goto pd_err;
}
processed_flags=0;
while (TRUE) {
lx->htc.hash_table_lst=NULL;
while (lx->token==',')
Lex(lx);
lx->htc.hash_table_lst=old_hash_table_lst;
j=PrsDocFlagSingle(lx,&doc_e->de_flags,&doc_e->type,TRUE);
if (!(de_flags=~processed_flags & doc_e->de_flags & DOCEG1_HAS_ARG))
break;
if (lx->token=='=')
Lex(lx);
else
j=Bsf(de_flags);
if (j<0 || Bts(&processed_flags,j))
goto pd_err;
nobound_switch (j) {//TODO: Might check for expression errors
case DOCEf_TAG:
if (!doc_e->tag) {
//If a $$MA,LM=""$$, Tag is filled when the LM is processed.
//if doc_e->df_flags&DOCEF_LST, Tag is filled when the Define is processed.
//(The dft_flag1.tag calls this after.)
if (lx->token==TK_STR) {
st2=LexExtStr(lx);
if (i==DOCT_CHECK_BOX) {
st=MStrPrint("[X] %s",st2);
Free(st2);
doc_e->min_col=1;
} else if (doc_e->de_flags & DOCEF_LST) {
if (*st2!='[') {
st=MStrPrint("[%s]",st2);
Free(st2);
} else
st=st2;
doc_e->min_col=1;
} else if (doc_e->de_flags & DOCEF_TREE) {
st=MStrPrint("+] %s",st2);
Free(st2);
doc_e->min_col=1;
} else
st=st2;
doc_e->tag=StrNew(st,doc->mem_task);
Free(st);
} else
goto pd_err;
}
break;
case DOCEf_AUX_STR:
if (lx->token==TK_STR) {
st2=LexExtStr(lx);
doc_e->aux_str=StrNew(st2,doc->mem_task);
Free(st2);
//$AN,"Anchor",A="DataTagWidth"$
if (i==DOCT_DATA) {
if (ptr=StrMatch(":",doc_e->aux_str))
doc_e->min_col=ptr-doc_e->aux_str+1;
doc_e->tag=MAlloc(doc_e->len+doc_e->min_col+2,doc->mem_task); //+2 because "_\0"
}
} else
goto pd_err;
break;
case DOCEf_DEFINE:
if (lx->token==TK_STR) {
st2=LexExtStr(lx);
doc_e->define_str=StrNew(st2,doc->mem_task);
Free(st2);
if (doc_e->de_flags&DOCEF_LST && !doc_e->tag)
doc_e->tag=StrNew("[]",doc->mem_task);
} else
goto pd_err;
break;
case DOCEf_HTML_LINK:
if (lx->token==TK_STR) {
st2=LexExtStr(lx);
doc_e->html_link=StrNew(st2,doc->mem_task);
Free(st2);
} else
goto pd_err;
break;
case DOCEf_LEFT_EXP:
if (lx->token)
doc_e->left_exp=LexExpression(lx);
else
goto pd_err;
break;
case DOCEf_LEFT_MACRO:
if (lx->token==TK_STR) {
st2=LexExtStr(lx);
doc_e->left_macro=StrNew(st2,doc->mem_task);
Free(st2);
if (i==DOCT_MACRO && !doc_e->tag)
doc_e->tag=StrNew(doc_e->left_macro,doc->mem_task);
} else
goto pd_err;
break;
case DOCEf_RIGHT_EXP:
if (lx->token)
doc_e->right_exp=LexExpression(lx);
else
goto pd_err;
break;
case DOCEf_RIGHT_MACRO:
if (lx->token==TK_STR) {
st2=LexExtStr(lx);
doc_e->right_macro=StrNew(st2,doc->mem_task);
Free(st2);
if (i==DOCT_MACRO && !doc_e->tag)
doc_e->tag=StrNew(doc_e->right_macro,doc->mem_task);
} else
goto pd_err;
break;
case DOCEf_HAS_BIN:
if (lx->token)
doc_e->bin_num=LexExpressionI64(lx);
else
goto pd_err;
break;
case DOCEf_BIN_PTR_LINK:
if (lx->token==TK_STR) {
st2=LexExtStr(lx);
doc_e->bin_ptr_link=StrNew(st2,doc->mem_task);
Free(st2);
if (!DocBinPtrRst(doc,doc_e))
doc_e->type=DOCT_ERROR;
} else
goto pd_err;
break;
case DOCEf_RAW_TYPE:
if (lx->token==TK_IDENT) {
j=DefineMatch(lx->cur_str,"ST_RAW_TYPES");
if (j<0)
goto pd_err;
doc_e->raw_type=j;
Lex(lx);
} else
goto pd_err;
break;
case DOCEf_SHIFTED_X:
if (lx->token)
doc_e->type|=(LexExpressionI64(lx) & 0x1F)<<16;
else
goto pd_err;
break;
case DOCEf_SHIFTED_Y:
if (lx->token)
doc_e->type|=(LexExpressionI64(lx) & 0x1F)<<21;
else
goto pd_err;
break;
case DOCEf_SCROLLING_X:
if (lx->token)
doc_e->scroll_len=LexExpressionI64(lx);
else
goto pd_err;
break;
case DOCEf_USER_DATA:
if (lx->token)
doc_e->user_data=LexExpression(lx);
else
goto pd_err;
break;
case DOCEf_NUM_FLAGS-1: //nobound_switch
break;
}
}
} else {
pd_err:
if (!doc_e)
doc_e=CAlloc(sizeof(CDocEntry),doc->mem_task);
doc_e->type=DOCT_ERROR;
doc_e->de_flags=0;
}
if (doc_e->de_flags & DOCEF_LST && !(doc_e->de_flags & DOCEF_DATA_IS_PTR)) {
DocDataScan(doc,doc_e);
DocDataFmt(doc,doc_e);
}
LexDel(lx);
} catch {
Fs->catch_except=TRUE;
if (!doc_e)
doc_e=CAlloc(sizeof(CDocEntry),doc->mem_task);
doc_e->type=DOCT_ERROR;
doc_e->de_flags=0;
}
return doc_e;
}
public U0 DocInsEntry(CDoc *doc,CDocEntry *doc_e)
{//Insert entry into doc, updating its vals.
U8 *dst;
Bool unlock=DocLock(doc);
CDocEntry *doc_ce=doc->cur_entry,*doc_ne;
doc_e->x=doc_ce->x;
doc_e->y=doc_ce->y;
doc_e->page_line_num=doc_ce->page_line_num;
MemCpy(&doc_e->settings,&doc_ce->settings,sizeof(CDocSettings));
if (doc->cur_data_col>0 &&
doc_ce->type_u8==DOCT_TEXT &&
!(doc_ce->de_flags&(DOCEF_TAG_CB|DOCEF_DEFINE|
DOCEF_HTML_LINK|DOCEF_BIN_PTR_LINK)) &&
doc->cur_data_col<doc_ce->max_col) {
dst=doc_ce->tag+doc->cur_data_col;
doc_ne=DocEntryNew(doc,doc_ce,StrNew(dst,doc->mem_task));
*dst=0;
doc_ne->type=DOCT_TEXT|doc_ce->type&0xFFFFFF00;
doc_ce->max_col=doc->cur_data_col;
QueIns(doc_ne,doc_ce);
doc->cur_data_col=0;
doc_ce=doc_ne;
}
if (doc_ce->type_u8==DOCT_TEXT && doc->cur_data_col>=doc_ce->max_col) {
QueIns(doc_e,doc_ce);
doc->cur_entry=doc_e->next;
} else {
QueIns(doc_e,doc_ce->last);
doc->cur_entry=doc_ce;
}
doc->cur_data_col=doc->cur_entry->min_col;
DocRemSoftNewLines(doc,doc->cur_entry);
if (unlock)
DocUnlock(doc);
}
#help_index "DolDoc/Output"
CDocEntry *DocPutS(CDoc *doc,U8 *st)
{//Don't use this. Use $LK-UL,"DocPrint",A="MN:DocPrint"$().
//Does not handle partial Doc entries
//Returns last newly created dollar-sign CDocEntry.
U8 *ptr=st,*ptr2,*st2,*ptr3,*ptr4,*src,
*char_bitmap;
Bool unlock;
I64 ch,j;
CDocEntry *doc_e=NULL,*result=NULL,*doc_ce;
if (!st || !doc && !(doc=DocPut) || doc->doc_signature!=DOC_SIGNATURE_VAL)
return NULL;
unlock=DocLock(doc);
if (doc->flags & DOCF_PLAIN_TEXT_WITH_TABS)
char_bitmap=chars_bitmap_zero_cr_nl_cursor;
else if (doc->flags & DOCF_PLAIN_TEXT)
char_bitmap=chars_bitmap_zero_tab_ff_cr_nl_cursor;
else
char_bitmap=chars_bitmap_zero_tab_ff_cr_nl_cursor_dollar;
doc_ce=doc->cur_entry;
while (*ptr) {
ptr2=ptr;
do ch=*ptr++;
while (!Bt(char_bitmap,ch) || ch==CH_CURSOR && doc->flags&DOCF_NO_CURSOR);
ptr--;
if (!ch) {
if (j=ptr-ptr2) {
doc_e=CAlloc(sizeof(CDocEntryBase),doc->mem_task);
doc_e->type=DOCT_TEXT | doc->settings_root.dft_text_attr<<8;
doc_e->de_flags=doldoc.dft_de_flags[DOCT_TEXT];
if (doc->flags & DOCF_NO_CURSOR) {
src=MAlloc(j+1);
MemCpy(src,ptr2,j+1);
StrUtil(src,SUF_REM_CTRL_CHARS);
j=StrLen(src);
} else
src=ptr2;
doc_e->tag=MAlloc(j+1,doc->mem_task);
MemCpy(doc_e->tag,src,j+1);
doc_e->max_col=j;
DocInsEntry(doc,doc_e);
if (doc->flags & DOCF_NO_CURSOR)
Free(src);
}
} else {
if (j=ptr-ptr2) {
*ptr=0;
doc_e=CAlloc(sizeof(CDocEntryBase),doc->mem_task);
doc_e->type=DOCT_TEXT | doc->settings_root.dft_text_attr<<8;
doc_e->de_flags=doldoc.dft_de_flags[DOCT_TEXT];
if (doc->flags & DOCF_NO_CURSOR) {
src=MAlloc(j+1);
MemCpy(src,ptr2,j+1);
ptr3=src;
ptr4=src;
while (*ptr3)
if (*ptr3!=CH_CURSOR)
*ptr4++=*ptr3++;
else
ptr3++;
*ptr4=0;
j=ptr4-src;
} else
src=ptr2;
doc_e->tag=MAlloc(j+1,doc->mem_task);
MemCpy(doc_e->tag,src,j+1);
doc_e->max_col=j;
DocInsEntry(doc,doc_e);
if (doc->flags & DOCF_NO_CURSOR)
Free(src);
*ptr=ch;
}
switch (ch) {
case CH_CURSOR:
doc_e=CAlloc(sizeof(CDocEntryBase),doc->mem_task);
doc_e->type=DOCT_CURSOR | doc->settings_root.dft_text_attr<<8;
doc_e->de_flags=doldoc.dft_de_flags[DOCT_CURSOR];
DocInsEntry(doc,doc_e);
ptr++;
break;
case CH_FORM_FEED:
doc_e=CAlloc(sizeof(CDocEntryBase),doc->mem_task);
doc_e->type=DOCT_PAGE_BREAK | doc->settings_root.dft_text_attr<<8;
doc_e->de_flags=doldoc.dft_de_flags[DOCT_PAGE_BREAK];
DocInsEntry(doc,doc_e);
ptr++;
break;
case '\t':
doc_e=CAlloc(sizeof(CDocEntryBase),doc->mem_task);
doc_e->type=DOCT_TAB | doc->settings_root.dft_text_attr<<8;
doc_e->de_flags=doldoc.dft_de_flags[DOCT_TAB];
DocInsEntry(doc,doc_e);
ptr++;
break;
case '$$':
ptr++; //skip first dollar
ptr2=ptr;
while (*ptr && *ptr!='$$')
ptr++;
if (*ptr) {
*ptr=0; //zero second dollar
if (ptr-1==ptr2 && *ptr2==CH_CURSOR) {
doc_e=CAlloc(sizeof(CDocEntryBase),doc->mem_task);
doc_e->type=DOCT_CURSOR | doc->settings_root.dft_text_attr<<8;
doc_e->de_flags=doldoc.dft_de_flags[DOCT_CURSOR];
DocInsEntry(doc,doc_e);
ptr2++;
}
if (ptr==ptr2) {
doc_e=CAlloc(sizeof(CDocEntryBase),doc->mem_task);
doc_e->type=DOCT_TEXT | doc->settings_root.dft_text_attr<<8;
doc_e->max_col=1;
if (doc->flags & DOCF_DBL_DOLLARS)
doc_e->tag=StrNew("$$$$",doc->mem_task);
else
doc_e->tag=StrNew("$$",doc->mem_task);
doc_e->de_flags=doldoc.dft_de_flags[DOCT_TEXT];
DocInsEntry(doc,doc_e);
} else {
st2=MAlloc(ptr-ptr2+1);
ptr3=ptr2;
ptr4=st2;
while (ch=*ptr3++) {
if (ch==CH_CURSOR) {
doc_e=CAlloc(sizeof(CDocEntryBase),doc->mem_task);
doc_e->type=DOCT_CURSOR | doc->settings_root.dft_text_attr<<8;
doc_e->de_flags=doldoc.dft_de_flags[DOCT_CURSOR];
DocInsEntry(doc,doc_e);
} else if (ch==CH_FORM_FEED) {
doc_e=CAlloc(sizeof(CDocEntryBase),doc->mem_task);
doc_e->type=DOCT_PAGE_BREAK | doc->settings_root.dft_text_attr<<8;
doc_e->de_flags=doldoc.dft_de_flags[DOCT_PAGE_BREAK];
DocInsEntry(doc,doc_e);
} else
*ptr4++=ch;
}
*ptr4=0;
if (doc_e=PrsDollarCmd(doc,st2)) {
result=doc_e;
DocInsEntry(doc,doc_e);
}
Free(st2);
}
*ptr++='$$';
}
break;
default:
doc_e=CAlloc(sizeof(CDocEntryBase),doc->mem_task);
doc_e->type=DOCT_NEW_LINE | doc->settings_root.dft_text_attr<<8;
doc_e->de_flags=doldoc.dft_de_flags[DOCT_NEW_LINE];
DocInsEntry(doc,doc_e);
if (ch=='\r')
while (*ptr=='\r')
ptr++;
if (*ptr=='\n')
ptr++;
while (*ptr=='\r')
ptr++;
}
}
}
if (unlock)
DocUnlock(doc);
return result;
}
public CDocEntry *DocPrint(CDoc *doc,U8 *fmt,...)
{//You must not print partial doc cmds.
U8 *buf=StrPrintJoin(NULL,fmt,argc,argv);
CDocEntry *result=DocPutS(doc,buf);
Free(buf);
return result;
}
+918
View File
@@ -0,0 +1,918 @@
#help_index "DolDoc"
public I64 DocEntryRun(CDoc *doc,CDocEntry *doc_e,Bool exited,I64 *_has_action=NULL)
{//Do action on final entry selected by user.
//Sometimes returns locked, sometimes unlocked
U8 ch=doc->cmd_U8,*st;
I64 result=DOCM_CANCEL,has_action=FALSE;
CHashDefineStr *temph;
DocLock(doc);
if (!exited) {
if (doc_e->de_flags & DOCEF_ESC) {
Msg(MSG_KEY_DOWN,CH_ESC,0,1<<SVCf_DONT_FILTER);
has_action=TRUE;
goto er_done;
} if (doc_e->de_flags & DOCEF_QUIT) {
Msg(MSG_KEY_DOWN,CH_SHIFT_ESC,0,1<<SVCf_DONT_FILTER);
has_action=TRUE;
goto er_done;
} else if (doc_e->de_flags & DOCEF_CHECK_COLLAPSABLE) {
doc_e->de_flags^=DOCEF_CHECKED_COLLAPSED;
has_action=TRUE;
}
}
try {
if (ch==CH_SPACE) {
if (doc_e->de_flags & DOCEF_LINK && doc->left_click_link) {
result=(*doc->left_click_link)(doc,doc_e);
has_action=TRUE;
}
if (doc_e->de_flags & DOCEF_LEFT_EXP) {
result=doc_e->left_exp;
has_action=TRUE;
Msg(MSG_CMD,result,0,1<<SVCf_DONT_FILTER);
}
if (doc_e->de_flags & DOCEF_LEFT_CB && doc_e->left_cb) {
DocUnlock(doc);
result=(*doc_e->left_cb)(doc,doc_e);
has_action=TRUE;
Msg(MSG_CMD,result,0,1<<SVCf_DONT_FILTER);
}
if (doc_e->de_flags & DOCEF_LEFT_MACRO) {
if (doc_e->de_flags & DOCEF_POPUP) {
st=StrNew(doc_e->left_macro);
DocUnlock(doc);
PopUp(st,Fs);
Free(st);
} else {
if (doc_e->de_flags & DOCEF_LEFT_AUTO)
AutoStr("%s",doc_e->left_macro);
else
Auto("%s",doc_e->left_macro);
}
has_action=TRUE;
}
if (!exited && doc_e->de_flags & DOCEF_LST && doc_e->de_flags & DOCEF_DEFINE &&
(temph=HashFind(doc_e->define_str,doc->win_task->hash_table,HTT_DEFINE_STR)) &&
(result=PopUpPickLst(temph->data))!=DOCM_CANCEL) {
DocDataFmt(doc,doc_e,result);
DocDataScan(doc,doc_e);
has_action=TRUE;
}
} else if (ch=='\n') {
if (doc_e->de_flags & DOCEF_LINK && doc->right_click_link) {
result=(*doc->right_click_link)(doc,doc_e);
has_action=TRUE;
}
if (doc_e->de_flags & DOCEF_RIGHT_EXP) {
result=doc_e->right_exp;
has_action=TRUE;
Msg(MSG_CMD,result,0,1<<SVCf_DONT_FILTER);
}
if (doc_e->de_flags & DOCEF_RIGHT_CB && doc_e->right_cb) {
DocUnlock(doc);
result=(*doc_e->right_cb)(doc,doc_e);
has_action=TRUE;
Msg(MSG_CMD,result,0,1<<SVCf_DONT_FILTER);
}
if (doc_e->de_flags & DOCEF_RIGHT_MACRO) {
if (doc_e->de_flags & DOCEF_POPUP) {
st=StrNew(doc_e->right_macro);
DocUnlock(doc);
PopUp(st,Fs);
Free(st);
} else {
if (doc_e->de_flags & DOCEF_RIGHT_AUTO)
AutoStr("%s",doc_e->right_macro);
else
Auto("%s",doc_e->right_macro);
}
has_action=TRUE;
}
}
}
catch
DocBottom(doc);
doc->cmd_U8=CH_SPACE;
er_done:
if (_has_action) *_has_action=has_action;
return result;
}
U8 *EdOverStrikeCB(CDoc *,CDocEntry *doc_e,CTask *mem_task)
{
CDoc *doc=doc_e->user_data;
U8 *st=MAlloc(8,mem_task);
if (doc->flags & DOCF_OVERSTRIKE)
*st='O';
else
*st='Ä';
st[1]=0;
return st;
}
U8 *EdFilterCB(CDoc *,CDocEntry *doc_e,CTask *mem_task)
{
CDoc *doc=doc_e->user_data;
U8 *st=MAlloc(8,mem_task);
if (doc->find_replace->filter_lines)
*st='F';
else
*st='Ä';
st[1]=0;
return st;
}
U8 *EdDollarCB(CDoc *,CDocEntry *doc_e,CTask *mem_task)
{
CDoc *doc=doc_e->user_data;
U8 *st=MAlloc(8,mem_task);
if (doc->flags & DOCF_IN_DOLLAR)
*st='$$';
else
*st='Ä';
st[1]=0;
return st;
}
U8 *EdMoreCB(CDoc *,CDocEntry *doc_e,CTask *mem_task)
{
CDoc *doc=doc_e->user_data;
U8 *st=MAlloc(8,mem_task);
if (doc->flags&DOCF_MORE)
StrCpy(st,"MoreÄ");
else
StrCpy(st,"ÄÄÄÄÄ");
return st;
}
U8 *EdDollarTypeCB(CDoc *,CDocEntry *doc_e,CTask *mem_task)
{
CDoc *doc=doc_e->user_data;
U8 *src=DefineSub(doc->cur_entry->type_u8,"ST_DOC_CMDS"),
*st=CAlloc(8,mem_task);
if (doc->cur_entry==doc)
src="EOF";
else if (!src)
src="ERR";
StrPrint(st,"%-3ts",src);
return st;
}
public I64 DocGetKey(I64 *_sc=NULL)
{//Called by $LK,"View",A="MN:View"$. You probably don't need this.
I64 ch,sc;
Bool cont,old_preempt=IsPreempt;
do {
ch=GetKey(&sc,TRUE);
DocRecalc(DocPut);
cont=FALSE;
if (ch==CH_ESC || ch==CH_SHIFT_ESC) {//Check for exit filter mode
Preempt(OFF);
if (DocPut && DocPut->find_replace->filter_lines) {
EdUndoFilter(DocPut);
cont=TRUE;
}
Preempt(old_preempt);
}
} while (cont);
if (_sc) *_sc=sc;
return ch;
}
#help_index "DolDoc/Output"
public Bool View()
{//Go live for user interaction until <ESC> or <SHIFT-ESC>.
I64 ch;
do ch=DocGetKey;
while (ch!=CH_ESC && ch!=CH_SHIFT_ESC);
return ch==CH_ESC;
}
#help_index "DolDoc"
public Bool DocDo(CDoc *doc,I64 dof_flags=0)
{//Live for user interaction. End on <ESC> or <SHIFT-ESC>.
CDoc *old_put_doc =DocPut,
*old_display_doc=DocDisplay,
*old_border_doc =DocBorder,*bdoc;
CDocEntry *doc_e;
I64 old_attr=Fs->text_attr,
old_top =Fs->win_top, old_bottom=Fs->win_bottom,
old_left=Fs->win_left,old_right =Fs->win_right,
old_title_src=Fs->title_src;
Bool result,unlock,old_preempt;
U8 *old_task_title;
if (dof_flags&DOF_WIN_MAX)
WinMax;
unlock=DocLock(doc);
doc->win_task=Fs;
bdoc=DocNew;
bdoc->flags|=DOCF_BORDER_DOC;
DocPrint(bdoc,"$$CM+TY+LX+NC,0,-1$$");
DocPrint(bdoc,"$$TX+RX+BD,\"[X]\"$$");
DocPrint(bdoc,"$$BK,1$$$$TX+LX+BD,\"MENU\"$$$$BK,0$$");
old_task_title=StrNew(Fs->task_title);
if (Fs->title_src!=TTS_LOCKED_CONST) {
Fs->title_src=TTS_ED_FILENAME;
MemCpy(Fs->task_title,doc->filename.name,TASK_TITLE_LEN);
}
doc_e=DocPrint(bdoc,"$$DA-TRM-P+BD+RD+CX+IV,140,A=\"%%s...\",SCX=16$$");
doc_e->data=&Fs->task_title;
DocDataFmt(bdoc,doc_e);
if (doc->flags & DOCF_ALLOW_UNDO) {
DocPrint(bdoc,"$$CM+BY+LX+NC,1,1$$");
doc_e=DocPrint(bdoc,"$$DA+BD+RD-TRM,32,RT=U32,A=\"Undo:%%03d\"$$\n");
doc_e->data=&doc->undo_cnt;
DocDataFmt(bdoc,doc_e);
}
DocPrint(bdoc,"$$CM+BY+RX+NC,-30,1$$");
doc_e=DocPrint(bdoc,"$$TX+BD+TC,\" \"$$");
doc_e->user_data=doc;
doc_e->tag_cb=&EdMoreCB;
doc_e=DocPrint(bdoc,"$$TX+BD+TC,\" \"$$");
doc_e->user_data=doc;
doc_e->tag_cb=&EdDollarTypeCB;
doc_e=DocPrint(bdoc,"$$TX+BD+TC,\" \"$$");
doc_e->user_data=doc;
doc_e->tag_cb=&EdFilterCB;
doc_e=DocPrint(bdoc,"$$TX+BD+TC,\" \"$$");
doc_e->user_data=doc;
doc_e->tag_cb=&EdOverStrikeCB;
doc_e=DocPrint(bdoc,"$$TX+BD+TC,\" \"$$");
doc_e->user_data=doc;
doc_e->tag_cb=&EdDollarCB;
doc_e=DocPrint(bdoc,"$$DA+BD+RD-TRM,32,A=\"Line:%%04d \"$$");
doc_e->data=&doc->line;
DocDataFmt(bdoc,doc_e);
doc_e=DocPrint(bdoc,"$$DA+BD+RD-TRM,32,A=\"Col:%%04d\"$$\n");
doc_e->data=&doc->col;
DocDataFmt(bdoc,doc_e);
DocRecalc(bdoc);
DocRecalc(doc);
if (!(dof_flags&DOF_DONT_HOME))
DocTop(doc);
old_preempt=Preempt(OFF);
Fs->border_doc=bdoc;
if (doc!=old_display_doc)
doc->parent_doc=old_display_doc;
Fs->put_doc=Fs->display_doc=doc;
if (!(dof_flags&DOF_DONT_TEXT_ATTR))
Fs->text_attr=DOC_ATTR_DFT_TEXT;
if (!(dof_flags&DOF_DONT_SHOW)) {
LBts(&Fs->display_flags,DISPLAYf_SHOW);
WinZBufUpdate;
}
if (dof_flags&DOF_MIN_SIZE)
doc->flags|=DOCF_MIN_SIZE;
Preempt(old_preempt);
DocUnlock(doc);
if (!(dof_flags&DOF_DONT_WINMGR_SYNC)) {
WinMgrSync(2,TRUE);
if (doc->flags&DOCF_MIN_SIZE)
WinMgrSync(2,TRUE);
}
result=View;
Preempt(OFF);
DocLock(doc);
if (result) {
doc_e=doc->root.next;
while (doc_e!=doc) {
if (doc_e->type_u8==DOCT_DATA || doc_e->type_u8==DOCT_CHECK_BOX)
DocDataScan(doc,doc_e);
doc_e=doc_e->next;
}
}
if (unlock)
DocUnlock(doc);
Fs->border_doc =old_border_doc;
Fs->display_doc=old_display_doc;
Fs->put_doc =old_put_doc;
Fs->text_attr =old_attr;
if (Fs->title_src!=TTS_LOCKED_CONST) {
Fs->title_src =old_title_src;
StrCpy(Fs->task_title,old_task_title);
}
Free(old_task_title);
DocDel(bdoc);
if (dof_flags&DOF_MIN_SIZE) {
SetWinHorz(old_left,old_right);
SetWinVert(old_top,old_bottom);
}
Preempt(old_preempt);
return result;
}
#help_index "DolDoc/Input"
public Bool DocFormDo(U8 *_d,U8 *class_name=lastclass,
I64 dof_flags=0,U8 *header=NULL,U8 *footer=NULL)
{//Supply a class name that has fmtstr definitions.
//and this routine will allow user input.
//See $LK,"::/Demo/DolDoc/Form.CPP"$ and $LK,"::/Demo/LastClass.CPP"$.
CMemberLst *ml;
CDocEntry *doc_e;
U8 *fmtstr;
CHashClass *tempc;
CDoc *doc;
Bool result=FALSE;
I64 old_border_src=Fs->border_src,has_action;
if (!(tempc=HashFind(class_name,Fs->hash_table,HTT_CLASS)))
return FALSE;
doc=DocNew;
doc->desc='Form';
if (header) DocPrint(doc,"%s",header);
doc->flags|=DOCF_OVERSTRIKE|DOCF_FORM;
if (dof_flags&DOF_MIN_SIZE)
doc->flags|=DOCF_MIN_SIZE;
ml=tempc->member_lst;
while (ml) {
if (fmtstr=MemberMetaData("fmtstr",ml)) {
doc_e=DocPrint(doc,"%s",fmtstr);
doc_e->data=_d+ml->offset;
doc_e->my_fmt_data=MemberMetaData("fmtdata",ml);
DocDataFmt(doc,doc_e);
}
ml=ml->next;
}
if (footer) DocPrint(doc,"%s",footer);
if (doc->root.next!=doc) {
Fs->border_src=BDS_CONST;
DocRecalc(doc);
if (DocDo(doc,dof_flags)) {
doc_e=doc->cur_entry;
result=TRUE;
if (doc_e!=doc) {
if (DocEntryRun(doc,doc_e,TRUE,&has_action)==DOCM_CANCEL && has_action)
result=FALSE;
DocUnlock(doc);
}
}
}
DocDel(doc);
Fs->border_src=old_border_src;
return result;
}
U0 DocMenuDoEndTaskCB()
{
WinToTop;
throw;
}
public I64 DocMenuDo(CDoc *m,I64 dof_flags=0)
{//Do (Run) menu chooser doc. (Returns menu doc unlocked.)
U8 *old_end_cb=Fs->task_end_cb;
Bool old_break_shift_esc=LBts(&Fs->task_flags,TASKf_BREAK_TO_SHIFT_ESC);
CDocEntry *doc_e;
I64 old_border_src=Fs->border_src,result=DOCM_CANCEL,has_action;
Fs->task_end_cb=&DocMenuDoEndTaskCB;
try {
if (m) {
m->desc='Menu';
Fs->border_src=BDS_CONST;
md_restart:
if (DocDo(m,dof_flags)) {
doc_e=m->cur_entry;
if (doc_e!=m) {
result=DocEntryRun(m,doc_e,TRUE,&has_action);
DocUnlock(m);
if (!has_action) {
result=DOCM_CANCEL;
dof_flags|=DOF_DONT_HOME;
goto md_restart;
}
}
}
}
} catch {
if (!Fs->except_ch) {
if (!(dof_flags & DOF_INTERCEPT_TASK_END))
Exit;
Fs->catch_except=TRUE;
}
}
LBEqu(&Fs->task_flags,TASKf_BREAK_TO_SHIFT_ESC,old_break_shift_esc);
Fs->border_src=old_border_src;
Fs->task_end_cb=old_end_cb;
return result;
}
#help_index "Task/Srv"
public I64 PopUp(U8 *buf,CTask *parent=NULL,CTask **_pu_task=NULL)
{//Execute code text in PopUp win task.
I64 result;
CSrvCmd *tempc;
Bool old_preempt=Preempt(OFF);
CTask *task=Spawn(&SrvUserCmdLine,NULL,"System",,parent);
if (!parent) {
TaskExe(task,parent,buf,1<<SVCf_EXIT_ON_COMPLETE|1<<SVCf_FREE_ON_COMPLETE);
if (_pu_task) *_pu_task=task;
Preempt(old_preempt);
return 0;
} else {
Fs->popup_task=task;
tempc=TaskExe(task,parent,buf,1<<SVCf_WAKE_MASTER|1<<SVCf_FOCUS_MASTER);
if (_pu_task) *_pu_task=task;
ScanResult(tempc,&result);
Fs->popup_task=NULL;
Kill(task);
if (_pu_task) *_pu_task=NULL;
Preempt(old_preempt);
return result;
}
}
#help_index "DolDoc;Task/Srv"
public I64 PopUpEd(U8 *filename,CTask *parent=NULL,CTask **_pu_task=NULL)
{//Create PopUp win task and edit a doc.
U8 *st=MStrPrint("Ed(\"%Q\");",filename);
I64 result=PopUp(st,parent,_pu_task);
Free(st);
return result;
}
#help_index "DolDoc/Output"
public CTask *PopUpViewDoc(CDoc *doc,I64 dof_flags=0)
{//Pass doc to PopUp win task for viewing.
U8 *buf=MStrPrint("Preempt(ON);DocDo(0x%X,0x%X);",doc,dof_flags);
CTask *task=Spawn(&SrvUserCmdLine,NULL,"View",,Fs);
TaskExe(task,NULL,buf,1<<SVCf_EXIT_ON_COMPLETE|1<<SVCf_FREE_ON_COMPLETE);
Free(buf);
return task;
}
U0 PopUpViewPrintEndCB()
{
DocDel(FramePtr("ViewStrFrame"));
Exit;
}
public CTask *PopUpViewPrint(U8 *fmt,...)
{//View Print statement in PopUp win task.
CTask *task;
U8 *buf=StrPrintJoin(NULL,fmt,argc,argv);
CDoc *doc=DocNew;
DocPrint(doc,buf);
Free(buf);
task=PopUpViewDoc(doc);
FramePtrAdd("ViewStrFrame",doc,task);
task->task_end_cb=&PopUpViewPrintEndCB;
return task;
}
#help_index "DolDoc/Input"
public I64 PopUpMenu(CDoc *doc,I64 dof_flags=0)
{//Do (Run) menu chooser doc in PopUp win task.
doc->flags|=DOCF_MIN_SIZE | DOCF_FORM;
return SrvUser("DocMenuDo(0x%X,0x%X);",doc,dof_flags);
}
public Bool PopUpForm(U8 *_d,U8 *class_name=lastclass,I64 dof_flags=DOF_MIN_SIZE,
U8 *header=NULL,U8 *footer=NULL)
{//See $LK,"::/Demo/DolDoc/Form.CPP"$ and $LK,"::/Demo/LastClass.CPP"$.
return SrvUser("DocFormDo(0x%X,0x%X,0x%X,0x%X,0x%X);",_d,class_name,
dof_flags,header,footer);
}
#help_index "DolDoc/Input;File/FileNames"
public U8 *PopUpPickFile(U8 *dir=NULL)
{//Filename chooser. Uses $LK,"FileMgr",A="MN:FileMgr"$().
U8 *result,*st,*st2;
if (dir)
st=MStrPrint("Cd(\"%Q\");FileMgr(FM_PICK_FILE,Fs->parent_task);",dir);
else {
st2=CurDir;
st=MStrPrint("Cd(\"%Q\");FileMgr(FM_PICK_FILE,Fs->parent_task);",st2);
Free(st2);
}
result=PopUp(st,Fs);
Free(st);
return result;
}
public U8 *PopUpPickDir(U8 *dir=NULL)
{//File dir name chooser. Uses $LK,"FileMgr",A="MN:FileMgr"$().
U8 *result,*st,*st2;
if (dir)
st=MStrPrint("Cd(\"%Q\");FileMgr(FM_PICK_DIR,Fs->parent_task);",dir);
else {
st2=CurDir;
st=MStrPrint("Cd(\"%Q\");FileMgr(FM_PICK_DIR,Fs->parent_task);",st2);
Free(st2);
}
result=PopUp(st,Fs);
Free(st);
return result;
}
public U8 *FileNameForm(U8 *dft=NULL,I64 dof_flags=0,CTask *mem_task=NULL)
{//Text filename form in cur win, not PopUp.
CEdFileName fn;
if (dft)
StrCpy(fn.name,dft);
else
*fn.name=0;
if (DocFormDo(&fn,,dof_flags))
return StrNew(fn.name,mem_task);
else
return NULL;
}
public U8 *PopUpFileName(U8 *dft=NULL,I64 dof_flags=0)
{//Filename chooser. Uses form, not $LK,"FileMgr",A="MN:FileMgr"$().
U8 *st=MStrPrint("FileNameForm(\"%Q\",0x%X,Fs->parent_task);",dft,dof_flags|DOF_MIN_SIZE),
*result=PopUp(st,Fs);
Free(st);
return result;
}
#help_index "DolDoc"
Bool PopUpCd()
{
Bool result;
U8 *st=PopUpPickDir;
if (st) {
result=Cd(st);
Free(st);
} else
result=FALSE;
return result;
}
#help_index "DolDoc/Input;Char/Lists"
public U8 *PopUpPickLst(U8 *lst)
{//Prompt for lst entry in PopUp win task.
I64 i=0;
CDoc *doc=DocNew;
DocPrint(doc,"$$LTBLUE$$");
while (*lst) {
if (*lst=='@') {//Check for '@' alias lst entry
i--;
lst++;
}
DocPrint(doc,"$$MU,\"%s\",LE=%d$$\n",lst,i++);
lst+=StrLen(lst)+1;
}
DocPrint(doc,"\n$$MU,\"CANCEL\",LE=DOCM_CANCEL$$\n");
i=PopUpMenu(doc);
DocDel(doc);
return i;
}
public U8 *PopUpPickDefineSub(U8 *st)
{//Prompt for $LK,"Define",A="HI:Define"$ lst entry in PopUp win task.
return PopUpPickLst(Define(st));
}
#help_index "DolDoc/Input"
public I64 PopUp1(U8 *b1,I64 n1,U8 *header=NULL,U8 *footer=NULL)
{//Make PopUp win task with one button.
I64 i,l1=StrLen(b1);
CDoc *doc=DocNew;
if (header) DocPrint(doc,"%s",header);
DocPrint(doc,"$$CM+CX,%d,4$$$$BT,\"%s\",LE=%d$$\n",-l1/2,b1,n1);
if (footer) DocPrint(doc,"%s",footer);
i=PopUpMenu(doc);
DocDel(doc);
return i;
}
public I64 PopUp2(U8 *b1,I64 n1,U8 *b2,I64 n2,U8 *header=NULL,U8 *footer=NULL)
{//Make PopUp win task with two buttons.
I64 i,l1=StrLen(b1),l2=StrLen(b2),y;
CDoc *doc=DocNew;
if (header) {
DocPrint(doc,"%s",header);
y=4;
} else {
DocPrint(doc,"%*s\n",l1+l2+10,"");
y=3;
}
DocPrint(doc,"$$CM+CX,%d,%d$$$$BT,\"%s\",LE=%d$$",-(l1+l2+3)>>1,y,b1,n1);
DocPrint(doc,"$$CM+CX,%d,0$$$$BT,\"%s\",LE=%d$$\n" ,-(l1+l2+3)>>1+l1+6,b2,n2);
if (footer) DocPrint(doc,"%s",footer);
i=PopUpMenu(doc);
DocDel(doc);
return i;
}
public Bool PopUpOk(U8 *header=NULL,U8 *footer=NULL)
{//Make PopUp win task with OKAY button.
return PopUp1("OKAY",1,header,footer)>0;
}
public Bool PopUpNoYes(U8 *header=NULL,U8 *footer=NULL)
{//Make PopUp win task with NO/YES buttons.
return $WW,0$PopUp2("YES",1,"NO",0,header,footer)>0;
}
public Bool PopUpCancelOk(U8 *header=NULL,U8 *footer=NULL)
{//Make PopUp win task CANCEL/OKAY buttons.
return PopUp2("OKAY",1,"CANCEL",0,header,footer)>0;
}
#define RSAC_REPLACE 0
#define RSAC_SKIP 1
#define RSAC_ALL 2
I64 PopUpReplaceSkipAllCancel(U8 *header=NULL,U8 *footer=NULL)
{
I64 i;
CDoc *doc=DocNew;
if (header) DocPrint(doc,"%s",header);
DocPrint(doc,"$$CM+LX,1,4$$$$BT,\"REPLACE\",LE=RSAC_REPLACE$$"
"$$CM+LX,17,0$$$$BT,\"SKIP\",LE=RSAC_SKIP$$"
"$$CM+LX,1,3$$$$BT,\"ALL\",LE=RSAC_ALL$$"
"$$CM+LX,17,0$$$$BT,\"CANCEL\",LE=DOCM_CANCEL$$\n");
if (footer) DocPrint(doc,"%s",footer);
i=PopUpMenu(doc);
DocDel(doc);
return i;
}
U8 *DoPopUpGetStr(U8 *header,CTask *mem_task)
{
U8 *result,*st;
if (header)
"%s",header;
st=GetStr(,,GSF_WITH_NEW_LINE);
result=StrNew(st,mem_task);
Free(st);
return result;
}
public U8 *PopUpGetStr(U8 *header=NULL)
{//Prompt for text str in PopUp win task.
U8 *st=MStrPrint("DoPopUpGetStr(0x%X,0x%X);",header,Fs),
*result=PopUp(st,Fs);
Free(st);
return result;
}
public I64 PopUpGetI64(U8 *msg,I64 dft,I64 lo=MIN_I64,I64 hi=MAX_I64)
{//Prompt for I64 text expression in PopUp win task.
U8 *st=MStrPrint("GetI64(0x%X,0x%X,0x%X,0x%X);",msg,dft,lo,hi);
I64 result=PopUp(st,Fs);
Free(st);
return result;
}
public I64 PopUpRangeI64(I64 lo,I64 hi,I64 step=1,U8 *header=NULL,U8 *footer=NULL)
{//Evenly-spaced I64 range chooser in PopUp win task.
I64 i;
CDoc *doc=DocNew;
if (header)
DocPrint(doc,"%s",header);
DocPrint(doc,"$$LTBLUE$$");
for (i=lo;i<=hi;i+=step)
DocPrint(doc,"$$MU,\"%d\",LE=%d$$\n",i,i);
if (footer)
DocPrint(doc,"%s",footer);
i=PopUpMenu(doc);
DocDel(doc);
return i;
}
public F64 PopUpRangeF64(F64 lo,F64 hi,F64 step,
U8 *fmt="%9.4f",U8 *header=NULL,U8 *footer=NULL)
{//Evenly-spaced F64 range chooser in PopUp win task.
F64 d;
I64 i;
U8 buf[136];
CDoc *doc=DocNew;
if (header)
DocPrint(doc,"%s",header);
DocPrint(doc,"$$LTBLUE$$");
for (d=lo;d<=hi;d+=step) {
StrPrint(buf,fmt,d);
DocPrint(doc,"$$MU,\"%s\",LE=0x%X$$\n",buf,d);
}
if (footer)
DocPrint(doc,"%s",footer);
i=PopUpMenu(doc);
DocDel(doc);
return i(F64);
}
public F64 PopUpRangeF64Exp(F64 lo,F64 hi,F64 factor,
U8 *fmt="%9.4f",U8 *header=NULL,U8 *footer=NULL)
{//Exp-spaced F64 range chooser in PopUp win task.
F64 d;
I64 i;
U8 buf[136];
CDoc *doc=DocNew;
if (header)
DocPrint(doc,"%s",header);
DocPrint(doc,"$$LTBLUE$$");
for (d=lo;d<=hi;d*=factor) {
StrPrint(buf,fmt,d);
DocPrint(doc,"$$MU,\"%s\",LE=0x%X$$\n",buf,d);
}
if (footer)
DocPrint(doc,"%s",footer);
i=PopUpMenu(doc);
DocDel(doc);
return i(F64);
}
public F64 PopUpRangeF64Log(F64 lo,F64 hi,I64 steps,
U8 *fmt="%9.4f",U8 *header=NULL,U8 *footer=NULL)
{//Log-spaced F64 range chooser in PopUp win task.
return PopUpRangeF64Exp(lo,hi,Exp(Ln(hi/lo)/(steps-1)),fmt,header,footer);
}
#help_index "Task/Srv"
public I64 AdamFile(U8 *filename,Bool warn_ext=TRUE)
{//Tell adam task to compile and run a file.
Bool okay=TRUE;
U8 *name=FileNameAbs(filename),
*name2=DftExt(name,"CPP.Z");
I64 result=0;
if (warn_ext &&
!FilesFindMatch(name2,FILEMASK_JIT) &&
!PopUpCancelOk(ST_WARN_ST "Not .CPP File\n\n"))
okay=FALSE;
if (okay)
result=Adam("#include \"%s\";",name2);
Free(name2);
Free(name);
return result;
}
public I64 PopUpFile(U8 *filename,Bool warn_ext=TRUE,CTask *parent=NULL,CTask **_pu_task=NULL)
{//Run code file in PopUp win task.
Bool okay=TRUE;
U8 *st,*name=FileNameAbs(filename),
*name2=DftExt(name,"CPP.Z");
I64 result=0;
if (warn_ext &&
!FilesFindMatch(name2,FILEMASK_JIT) &&
!PopUpCancelOk(ST_WARN_ST "Not .CPP File\n\n"))
okay=FALSE;
if (okay) {
st=MStrPrint("\"$$$$WW+H,1$$$$\";Auto(\"ExeFile2(\\\"%s\\\");\\n\");UserTaskCont;",name2);
result=PopUp(st,parent,_pu_task);
Free(st);
}
Free(name2);
Free(name);
return result;
}
#help_index "Graphics/Input"
public I64 PopUpColor(U8 *header=NULL,Bool allow_transparent=TRUE,Bool allow_dft=TRUE)
{//Chooser for 16-color, default or transparent.
I64 i;
CDoc *doc=DocNew;
if (header)
DocPrint(doc,"%s",header);
if (allow_transparent)
DocPrint(doc,"$$MU,\"TRANSPARENT\",LE=TRANSPARENT$$\n");
for (i=0;i<16;i++)
DocPrint(doc,"$$BG,%d$$$$MU,\"__%-8Z__\",LE=%d$$$$BG$$\n",i,i,"ST_COLORS",i);
if (allow_dft)
DocPrint(doc,"$$BG,WHITE$$$$MU,\"DEFAULT\",LE=DOC_DFT$$$$BG$$");
i=PopUpMenu(doc);
DocDel(doc);
return i;
}
public I64 PopUpColorLighting(U8 *header=NULL)
{//Chooser for std TempleOS $LK,"GrLighting",A="MN:GrLighting"$() color.
I64 i;
CDoc *doc=DocNew;
if (header)
DocPrint(doc,"%s",header);
DocPrint(doc,"\nSingle-Sided means both sides same color."
"\nDouble-Sided means back side darker."
"\n"
"\nHalf-Range means 0 to [0,7]"
"\n [8,15]-8 to [8,15]"
"\nFull-Range means 0 to [0,7] to [0,7]+8"
"\n");
DocPrint(doc,"\n$$LTPURPLE$$Single-Sided Full-Range Double-Sided Full-Range\n$$BLACK$$");
for (i=0;i<8;i++) {
DocPrint(doc,"$$BG,%d$$$$MU,\"__%-19Z__\",LE=%d$$$$BG$$ ",i,i,"ST_COLORS",i);
DocPrint(doc,"$$BG,%d$$$$MU,\"__%-19Z__\",LE=%d$$$$BG$$\n",i,i,"ST_COLORS",ROPF_TWO_SIDED+i);
}
DocPrint(doc,"\n$$LTPURPLE$$Single-Sided Half-Range Double-Sided Half-Range\n$$BLACK$$");
for (i=0;i<16;i++) {
DocPrint(doc,"$$BG,%d$$$$MU,\"__%-19Z__\",LE=%d$$$$BG$$ ",i,i,"ST_COLORS",ROPF_HALF_RANGE_COLOR+i);
DocPrint(doc,"$$BG,%d$$$$MU,\"__%-19Z__\",LE=%d$$$$BG$$\n",i,i,"ST_COLORS",ROPF_TWO_SIDED+ROPF_HALF_RANGE_COLOR+i);
}
i=PopUpMenu(doc);
DocDel(doc);
return i;
}
class CTransformForm
{
F64 x_scale fmtstr "$$DA-TRM,32,RT=F64,A=\"X Scale :%12.6f\"$$\n";
F64 y_scale fmtstr "$$DA-TRM,32,RT=F64,A=\"Y Scale :%12.6f\"$$\n";
F64 z_scale fmtstr "$$DA-TRM,32,RT=F64,A=\"Z Scale :%12.6f\"$$\n";
F64 é_z fmtstr "\nAngles are in degrees\n$$DA-TRM,32,RT=F64,A=\"Z-Axis :%12.6f\"$$\n";
F64 é_y fmtstr "$$DA-TRM,32,RT=F64,A=\"Y-Axis :%12.6f\"$$\n";
F64 é_x fmtstr "$$DA-TRM,32,RT=F64,A=\"X-Axis :%12.6f\"$$\n";
F64 x_offset fmtstr "\n$$DA-TRM,32,RT=F64,A=\"X Offset:%12.6f\"$$\n";
F64 y_offset fmtstr "$$DA-TRM,32,RT=F64,A=\"Y Offset:%12.6f\"$$\n";
F64 z_offset fmtstr "$$DA-TRM,32,RT=F64,A=\"Z Offset:%12.6f\"$$\n";
};
Bool PopUpTransform(I64 *r)
{
CTransformForm *tf=MAlloc(sizeof(CTransformForm));
tf->x_scale=1.0;
tf->y_scale=1.0;
tf->z_scale=1.0;
tf->é_x=0.0;
tf->é_y=0.0;
tf->é_z=0.0;
tf->x_offset=0.0;
tf->y_offset=0.0;
tf->z_offset=0.0;
if (PopUpForm(tf)) {
MemSet(r,0,16*sizeof(I64));
r[0] =tf->x_scale*GR_SCALE;
r[5] =tf->y_scale*GR_SCALE;
r[10]=tf->z_scale*GR_SCALE;
r[15]=GR_SCALE;
GrRotZEqu(r,tf->é_z*ã/180.0);
GrRotYEqu(r,tf->é_y*ã/180.0);
GrRotXEqu(r,tf->é_x*ã/180.0);
r[3] =tf->x_offset*GR_SCALE;
r[7] =tf->y_offset*GR_SCALE;
r[11]=tf->z_offset*GR_SCALE;
return TRUE;
} else
return FALSE;
}
#define PU_SPACING 10
U0 DrawIt(CTask *task,CDC *dc)
{
I64 i,j,i1,j1;
CDoc *doc=DocPut(task);
for (j=0;j<17;j++)
for (i=0;i<17;i++) {
if (j<16)
j1=j;
else
j1=TRANSPARENT;
if (i<16)
i1=i;
else
i1=TRANSPARENT;
dc->color=j1+i1<<16+ROPF_DITHER;
GrRect(dc,i*PU_SPACING,j*PU_SPACING+FramePtr("DitherDoFrame",task),PU_SPACING,PU_SPACING);
}
i=(17*PU_SPACING+FONT_WIDTH-1)/FONT_WIDTH;
if (doc->max_x>i) i=doc->max_x;
SetWinHorz(task->win_left,task->win_left+i,task);
SetWinVert(task->win_top,task->win_top+doc->max_y+(17*PU_SPACING+FONT_WIDTH-1)/FONT_WIDTH,task);
}
I64 DitherColorDo(U8 *header=NULL)
{
I64 msg_code,a1,a2,result=-1,i,j;
DocClear;
"%s",header;
DocRecalc(DocPut);
FramePtrAdd("DitherDoFrame",(DocPut->max_y+1)*FONT_HEIGHT);
SettingsPush; //See $LK,"SettingsPush",A="MN:SettingsPush"$
Fs->draw_it=&DrawIt;
do {
msg_code=GetMsg(&a1,&a2,1<<MSG_IP_L_DOWN|1<<MSG_KEY_DOWN);
if (msg_code==MSG_IP_L_DOWN) {
msg_code=GetMsg(&a1,&a2,1<<MSG_IP_L_UP);
i=a1/PU_SPACING;
j=(a2-FramePtr("DitherDoFrame"))/PU_SPACING;
if (a1>=0 && a2>=0 && 0<=j<17 && 0<=i<17) {
if (j==16) j=TRANSPARENT;
if (i==16) i=TRANSPARENT;
result=j+i<<16+ROPF_DITHER;
goto dcd_done;
}
}
} while (!(msg_code==MSG_KEY_DOWN && (a1==CH_ESC || a1==CH_SHIFT_ESC)));
do GetMsg(&a1,&a2,1<<MSG_KEY_UP);
while (!a1);
dcd_done:
SettingsPop;
FramePtrDel("DitherDoFrame");
return result;
}
public I64 PopUpColorDither(U8 *header=NULL)
{//Chooser for 2 x 16 colors or transparent.
U8 buf[136];
StrPrint(buf,"DitherColorDo(0x%X);",header);
return PopUp(buf,Fs);
}
+206
View File
@@ -0,0 +1,206 @@
#help_index "DolDoc"
I64 DocCharDist(CDoc *doc,I64 x,I64 y)
{
#assert FONT_WIDTH==FONT_HEIGHT
return (SqrI64(doc->x-x)+SqrI64(doc->y-y))*FONT_WIDTH*FONT_WIDTH;
}
public U0 DocCenter(CDoc *doc=NULL,I64 recalc=DOC_RECALC)
{//Center win on doc cursor, cur_entry.
Bool unlock;
CTask *task;
if (!doc && !(doc=DocPut))
return;
unlock=DocLock(doc);
task=doc->win_task;
DocRecalc(doc,FALSE,recalc);
if (!(doc->flags&DOCF_BORDER_DOC))
doc->cur_top_line_num=doc->y-(task->win_height+1)>>1;
if (unlock)
DocUnlock(doc);
}
U0 DocDelToNum(CDoc *doc,I64 num)
{
CDocEntry *doc_e=doc->root.next,*doc_e2;
while (num-->0 && doc_e!=doc) {
doc_e2=doc_e->next;
if (!(doc_e->de_flags & (DOCEF_HOLD|DOCEF_FILTER_SKIP))) {
if (doc_e==doc->cur_entry) {
doc->cur_entry=doc_e2;
doc->cur_data_col=doc_e2->min_col;
}
DocEntryDel(doc,doc_e);
}
doc_e=doc_e2;
}
}
U0 DocDelToEntry(CDoc *doc,CDocEntry *clear_entry)
{
CDocEntry *doc_e=doc->root.next,*doc_e2;
while (doc_e!=doc) {
doc_e2=doc_e->next;
if (!(doc_e->de_flags & (DOCEF_HOLD|DOCEF_FILTER_SKIP))) {
if (doc_e==doc->cur_entry) {
doc->cur_entry=doc_e2;
doc->cur_data_col=doc_e2->min_col;
}
DocEntryDel(doc,doc_e);
}
if (doc_e==clear_entry)
break;
doc_e=doc_e2;
}
}
U0 DocBorderLstDraw(CDoc *doc)
{
CTask *win_task=doc->win_task;
I64 i,y=-1,attr=win_task->border_attr<<8;
U64 ch;
CDoc *templ=doc;
CD3I64 saved_scroll;
Bool old_preempt=Preempt(OFF);
while (templ && templ->doc_signature==DOC_SIGNATURE_VAL) {
y+=(Bsr(templ->desc)+7)>>3+1; //StrLen+1
templ=templ->parent_doc;
}
templ=doc;
if (y>win_task->win_height)
y=win_task->win_height;
WinScrollNull(win_task,&saved_scroll);
while (templ && templ->doc_signature==DOC_SIGNATURE_VAL) {
ch=templ->desc;
i=(Bsr(ch)+7)>>3; //StrLen
ch=EndianI64(ch<<((8-i)<<3));
attr=win_task->border_attr<<8;
while (i-- && y>0) {
TextChar(win_task,TRUE,-1,--y,attr+ch&0xFF);
ch>>=8;
}
y--;
templ=templ->parent_doc;
}
WinScrollRestore(win_task,&saved_scroll);
Preempt(old_preempt);
}
public U0 DocBottom(CDoc *doc=NULL)
{//Move cursor, cur_entry, to bottom.
Bool unlock;
if (!doc && !(doc=DocPut))
return;
unlock=DocLock(doc);
doc->cur_entry=doc;
doc->cur_data_col=0;
DocRecalc(doc);
if (unlock)
DocUnlock(doc);
}
public U0 DocClear(CDoc *doc=NULL)
{//Clear all doc entries, except +H, hold entries.
Bool unlock;
if (!doc && !(doc=DocPut))
return;
unlock=DocLock(doc);
DocBottom(doc);
DocPrint(doc,"$$CL$$");
DocRecalc(doc);
if (unlock)
DocUnlock(doc);
}
public Bool DocCursor(Bool show=OFF,CDoc *doc=NULL)
{//Show or hide cursor.
if (!doc && !(doc=DocPut))
return FALSE;
return !LBEqu(&doc->flags,DOCf_HIDE_CURSOR,!show);
}
public Bool DocScroll(Bool val=OFF,CDoc *doc=NULL)
{//Turn scroll bars OFF/ON.
if (!doc && !(doc=DocPut))
return FALSE;
return !LBEqu(&doc->flags,DOCf_NO_SCROLL_BARS,!val);
}
public U0 DocCollapse(Bool collapse=TRUE,CDoc *doc=NULL)
{//Collapse or uncollapse all tree widgets.
CDocEntry *doc_e;
Bool unlock;
if (!doc && !(doc=DocPut))
return;
unlock=DocLock(doc);
doc_e=doc->root.next;
while (doc_e!=doc) {
if (doc_e->de_flags&DOCEF_TREE)
BEqu(&doc_e->de_flags,DOCEf_CHECKED_COLLAPSED,collapse);
doc_e=doc_e->next;
}
DocRecalc(doc);
if (unlock)
DocUnlock(doc);
}
#help_index "DolDoc/Output"
public U0 DocPrintAtomic(CDoc *doc,U8 *fmt,...)
{//Necessary when hidden text might screw-up
//inserts. It does multiple whole doc cmds all-at-once.
U8 *buf;
Bool unlock;
I64 old_flags;
if (!doc && !(doc=DocPut))
return;
buf=StrPrintJoin(NULL,fmt,argc,argv);
unlock=DocLock(doc);
old_flags=doc->flags;
doc->flags|=DOCF_NO_CURSOR;
DocPrint(doc,"%s",buf);
DocRecalc(doc);
doc->flags=old_flags;
if (unlock)
DocUnlock(doc);
Free(buf);
}
#help_index "DolDoc/Task"
U0 DocUpdateTaskDocs(CTask *task)
{//This is called from $LK,"GrUpdateWins",A="MN:GrUpdateWins"$() by the winmgr at 30fps.
CPrt *p;
CDoc *doc;
CD3I64 saved_scroll;
Bool old_preempt=Preempt(OFF);
I64 border_attr;
if (task->border_src==BDS_CUR_PRT && task->cur_prt) {
border_attr=task->cur_prt->text_attr;
if (border_attr&15!=border_attr>>4)
task->border_attr=border_attr;
}
if (task->title_src==TTS_TASK_NAME)
StrCpy(task->task_title,task->task_name);
if ((doc=DocDisplay(task)) && !(doc->flags&DOCF_DONT_SHOW)) {
if (task->border_src==BDS_ED_FILENAME_PRT)
try {
if (p=Drv2Prt(*doc->filename.name)) {
border_attr=p->text_attr;
if (border_attr&15!=border_attr>>4)
task->border_attr=border_attr;
}
} catch
Fs->catch_except=TRUE;
if (task->title_src==TTS_ED_FILENAME)
MemCpy(task->task_title,doc->filename.name,TASK_TITLE_LEN);
Preempt(old_preempt);
DocRecalc(doc,TRUE,DOC_RECALC_TO_SCREEN);
Preempt(OFF);
}
if ((doc=DocBorder(task)) && !(doc->flags&DOCF_DONT_SHOW)) {
WinScrollNull(task,&saved_scroll);
DocRecalc(doc,FALSE,DOC_RECALC_TO_SCREEN);
WinScrollRestore(task,&saved_scroll);
}
Preempt(old_preempt);
}
File diff suppressed because it is too large. Load diff
+167
View File
@@ -0,0 +1,167 @@
#help_index "DolDoc"
public Bool DocTreeFind(CDoc *haystack_doc,U8 *needle_path,
CDocEntry **_tree_entry=NULL,
CDocEntry **_start_indent=NULL, CDocEntry **_end_indent=NULL)
{//Find registry-like tree widget start and end.
I64 i=0,k=0;
U8 *st1=StrNew(needle_path),*st2=MAlloc(StrLen(needle_path)+1);
Bool result=FALSE,unlock_doc=DocLock(haystack_doc);
CDocEntry *doc_e=haystack_doc->root.next;
if (_tree_entry) *_tree_entry=haystack_doc;
if (_start_indent) *_start_indent=haystack_doc;
if (_end_indent) *_end_indent=haystack_doc;
while (*st1 && doc_e!=haystack_doc) {
StrFirstRem(st1,"/",st2);
if (*st2) {
while (doc_e!=haystack_doc) {
if (doc_e->type_u8==DOCT_INDENT)
i+=doc_e->attr;
else if (i==k && doc_e->de_flags&DOCEF_TREE && !StrCmp(doc_e->tag+3,st2)) {
if (*st1)
break;
else {
if (_tree_entry) *_tree_entry=doc_e;
i=0;
while (doc_e!=haystack_doc && doc_e->type_u8!=DOCT_INDENT)
doc_e=doc_e->next;
if (doc_e!=haystack_doc) {
i=doc_e->attr;
if (_start_indent) *_start_indent=doc_e;
doc_e=doc_e->next;
while (doc_e!=haystack_doc && i>0) {
if (doc_e->type_u8==DOCT_INDENT) {
i+=doc_e->attr;
if (i<=0) {
if (_end_indent) *_end_indent=doc_e;
result=TRUE;
break;
}
}
doc_e=doc_e->next;
}
}
goto ft_done;
}
}
doc_e=doc_e->next;
}
k+=2;
}
}
ft_done:
if (unlock_doc)
DocUnlock(haystack_doc);
Free(st1);
Free(st2);
return result;
}
public Bool DocTreeMake(CDoc *doc,U8 *path)
{//Make registry-like tree widget.
I64 i=0,j=MIN_I64,k=0;
U8 *st1=StrNew(path),
*st2=MAlloc(StrLen(path)+1),
*st3=StrNew(path);
Bool result=TRUE,unlock_doc=DocLock(doc);
CDocEntry *doc_e=doc->root.next;
doc->cur_entry=doc;
doc->cur_data_col=0;
while (*st1 && doc_e!=doc) {
StrFirstRem(st1,"/",st2);
if (*st2) {
while (doc_e!=doc) {
if (doc_e->type_u8==DOCT_INDENT) {
i+=doc_e->attr;
if (i==j) {
doc->cur_entry=doc_e;
doc->cur_data_col=0;
goto mt_done;
}
} else if (i==k && doc_e->de_flags&DOCEF_TREE && !StrCmp(doc_e->tag+3,st2)) {
Free(st3);
st3=StrNew(st1);
j=i;
if (!*st1)
result=FALSE;
else
break;
}
doc_e=doc_e->next;
}
k+=2;
}
}
mt_done:
if (result) {
while (*st3) {
StrFirstRem(st3,"/",st2);
if (*st2) {
DocPrint(doc,"$$TR+C,\"%s\"$$\n$$ID,2$$",st2);
doc->cur_entry=DocPrint(doc,"$$ID,-2$$");
doc->cur_data_col=0;
}
}
}
if (unlock_doc)
DocUnlock(doc);
Free(st1);
Free(st2);
Free(st3);
return result;
}
#help_index "DolDoc/Compiler;Compiler"
public I64 ExeDoc(CDoc *doc,Bool just_load=FALSE)
{//JIT Compile and execute a document.
I64 result;
Bool okay=TRUE,unlock_doc=DocLock(doc);
CLex *lx=LexNew(,LF_DONT_FREE_BUF);
if (just_load)
lx->flags|=LF_JUST_LOAD;
if (Fs->last_lex!=&Fs->next_lex)
lx->opts=Fs->last_lex->opts;
QueIns(lx,Fs->last_lex);
LexAttachDoc(lx,,doc);
try {
Lex(lx);
result=ExeCmdLine(lx);
} catch {
if (Fs->except_ch=='Compiler' || Fs->except_ch=='Break') {
Fs->catch_except=TRUE;
okay=FALSE;
result=0;
}
}
QueRem(lx);
if (okay)
LexDel(lx); //TODO: can crash
if (unlock_doc)
DocUnlock(doc);
return result;
}
public I64 DocTreeBranchExe(CDoc *doc,U8 *path)
{//JIT Compile and execute code in doc tree branch.
CDoc *doc2;
Bool unlock_doc=DocLock(doc);
CDocEntry *tree_branch,*start_indent,*end_indent;
I64 result=0;
if (DocTreeFind(doc,path,&tree_branch,&start_indent,&end_indent)) {
doc2=DocCopy(doc,tree_branch,end_indent);
result=ExeDoc(doc2);
DocDel(doc2);
}
if (unlock_doc)
DocUnlock(doc);
return result;
}
public I64 ExeTreeBranch(U8 *registry_file,U8 *path)
{//JIT Compile and execute a specified branch in a specified file.
I64 result;
CDoc *doc=DocRead(registry_file);
result=DocTreeBranchExe(doc,path);
DocDel(doc);
return result;
}