244 lines
5.9 KiB
HolyC
244 lines
5.9 KiB
HolyC
|
#help_index "DolDoc/Tree"
|
||
|
|
||
|
public Bool DocTreeFind(CDoc *haystack_doc,U8 *needle_path,
|
||
|
CDocEntry **_tree_entry=NULL,
|
||
|
CDocEntry **_start_indent=NULL, CDocEntry **_end_indent=NULL)
|
||
|
{//Find tree widget start and end.
|
||
|
I64 i=0,k=0;
|
||
|
U8 *st1=StrNew(needle_path),*st2=MAlloc(StrLen(needle_path)+1);
|
||
|
Bool res=FALSE,unlock_doc=DocLock(haystack_doc);
|
||
|
CDocEntry *doc_e=haystack_doc->head.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;
|
||
|
res=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 res;
|
||
|
}
|
||
|
|
||
|
public Bool DocTreeFFind(U8 *name,U8 *path)
|
||
|
{//Find tree widget in file.
|
||
|
CDoc *doc=DocRead(name);
|
||
|
Bool res=DocTreeFind(doc,path);
|
||
|
DocDel(doc);
|
||
|
return res;
|
||
|
}
|
||
|
|
||
|
public Bool DocTreeMake(CDoc *doc,U8 *path)
|
||
|
{//Make tree widget.
|
||
|
I64 i=0,j=I64_MIN,k=0;
|
||
|
U8 *st1=StrNew(path),
|
||
|
*st2=MAlloc(StrLen(path)+1),
|
||
|
*st3=StrNew(path);
|
||
|
Bool res=TRUE,unlock_doc=DocLock(doc);
|
||
|
CDocEntry *doc_e=doc->head.next;
|
||
|
doc->cur_entry=doc;
|
||
|
doc->cur_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_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)
|
||
|
res=FALSE;
|
||
|
else
|
||
|
break;
|
||
|
}
|
||
|
doc_e=doc_e->next;
|
||
|
}
|
||
|
k+=2;
|
||
|
}
|
||
|
}
|
||
|
mt_done:
|
||
|
if (res) {
|
||
|
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_col=0;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
if (unlock_doc)
|
||
|
DocUnlock(doc);
|
||
|
Free(st1);
|
||
|
Free(st2);
|
||
|
Free(st3);
|
||
|
return res;
|
||
|
}
|
||
|
|
||
|
Bool DocTreeWriteJoin(CDoc *doc,U8 *path,Bool write,U8 *fmt,I64 argc,I64 *argv)
|
||
|
{//Rewrite doc tree branch.
|
||
|
CDocEntry *tree_branch,*start_indent,*end_indent;
|
||
|
U8 *buf=StrPrintJoin(NULL,fmt,argc,argv);
|
||
|
Bool res,unlock_doc=DocLock(doc);
|
||
|
if (res=DocTreeFind(doc,path,
|
||
|
&tree_branch,&start_indent,&end_indent)) {
|
||
|
DocCut(doc,start_indent->next,end_indent->last);
|
||
|
doc->cur_entry=start_indent->next;
|
||
|
doc->cur_col=doc->cur_entry->min_col;
|
||
|
} else
|
||
|
DocTreeMake(doc,path);
|
||
|
DocPrint(doc,"%s",buf);
|
||
|
if (write && DrvIsWritable(*doc->filename.name))
|
||
|
DocWrite(doc);
|
||
|
if (unlock_doc)
|
||
|
DocUnlock(doc);
|
||
|
Free(buf);
|
||
|
return res;
|
||
|
}
|
||
|
|
||
|
Bool DocTreeAppendJoin(CDoc *doc,U8 *path,Bool write,U8 *fmt,I64 argc,I64 *argv)
|
||
|
{//Append to doc tree branch.
|
||
|
CDocEntry *tree_branch,*start_indent,*end_indent;
|
||
|
U8 *buf=StrPrintJoin(NULL,fmt,argc,argv);
|
||
|
Bool res,unlock_doc=DocLock(doc);
|
||
|
if (res=DocTreeFind(doc,path,
|
||
|
&tree_branch,&start_indent,&end_indent)) {
|
||
|
doc->cur_entry=end_indent;
|
||
|
doc->cur_col=doc->cur_entry->min_col;
|
||
|
} else
|
||
|
DocTreeMake(doc,path);
|
||
|
DocPrint(doc,"%s",buf);
|
||
|
if (write && DrvIsWritable(*doc->filename.name))
|
||
|
DocWrite(doc);
|
||
|
if (unlock_doc)
|
||
|
DocUnlock(doc);
|
||
|
Free(buf);
|
||
|
return res;
|
||
|
}
|
||
|
|
||
|
public Bool DocTreeWrite(CDoc *doc,U8 *path,Bool write=TRUE,U8 *fmt,...)
|
||
|
{//Rewrite doc tree branch.
|
||
|
return DocTreeWriteJoin(doc,path,write,fmt,argc,argv);
|
||
|
}
|
||
|
|
||
|
public Bool DocTreeAppend(CDoc *doc,U8 *path,Bool write=TRUE,U8 *fmt,...)
|
||
|
{//Append to doc tree branch.
|
||
|
return DocTreeAppendJoin(doc,path,write,fmt,argc,argv);
|
||
|
}
|
||
|
|
||
|
public Bool DocTreeFWrite(U8 *name,U8 *path,U8 *fmt,...)
|
||
|
{//Rewrite doc tree branch in file.
|
||
|
CDoc *doc=DocRead(name);
|
||
|
Bool res=DocTreeWriteJoin(doc,path,TRUE,fmt,argc,argv);
|
||
|
DocDel(doc);
|
||
|
return res;
|
||
|
}
|
||
|
|
||
|
public Bool DocTreeFAppend(U8 *name,U8 *path,U8 *fmt,...)
|
||
|
{//Append to doc tree branch in file.
|
||
|
CDoc *doc=DocRead(name);
|
||
|
Bool res=DocTreeAppendJoin(doc,path,TRUE,fmt,argc,argv);
|
||
|
DocDel(doc);
|
||
|
return res;
|
||
|
}
|
||
|
|
||
|
#help_index "DolDoc/Compiler;Compiler"
|
||
|
public I64 ExeDoc(CDoc *doc,I64 ccf_flags=0)
|
||
|
{//JIT Compile and execute a document.
|
||
|
I64 res;
|
||
|
Bool okay=TRUE,unlock_doc=DocLock(doc);
|
||
|
CCmpCtrl *cc=CmpCtrlNew(,ccf_flags|CCF_DONT_FREE_BUF);
|
||
|
if (Fs->last_cc!=&Fs->next_cc)
|
||
|
cc->opts=Fs->last_cc->opts;
|
||
|
QueIns(cc,Fs->last_cc);
|
||
|
LexAttachDoc(cc,,doc);
|
||
|
try {
|
||
|
Lex(cc);
|
||
|
res=ExeCmdLine(cc);
|
||
|
} catch {
|
||
|
if (Fs->except_ch=='Compiler' || Fs->except_ch=='Break') {
|
||
|
Fs->catch_except=TRUE;
|
||
|
okay=FALSE;
|
||
|
res=0;
|
||
|
}
|
||
|
}
|
||
|
QueRem(cc);
|
||
|
if (okay)
|
||
|
CmpCtrlDel(cc); //TODO: can crash
|
||
|
if (unlock_doc)
|
||
|
DocUnlock(doc);
|
||
|
return res;
|
||
|
}
|
||
|
|
||
|
#help_index "DolDoc/Tree;DolDoc/Compiler;Compiler"
|
||
|
public I64 DocTreeExe(CDoc *doc,U8 *path)
|
||
|
{//Execute doc tree branch.
|
||
|
CDoc *doc2;
|
||
|
Bool unlock_doc=DocLock(doc);
|
||
|
CDocEntry *tree_branch,*start_indent,*end_indent;
|
||
|
I64 res=0;
|
||
|
if (DocTreeFind(doc,path,&tree_branch,&start_indent,&end_indent)) {
|
||
|
doc2=DocCopy(doc,tree_branch,end_indent);
|
||
|
res=ExeDoc(doc2);
|
||
|
DocDel(doc2);
|
||
|
}
|
||
|
if (unlock_doc)
|
||
|
DocUnlock(doc);
|
||
|
return res;
|
||
|
}
|
||
|
|
||
|
public I64 DocTreeFExe(U8 *name,U8 *path)
|
||
|
{//Execute doc tree branch in file.
|
||
|
I64 res;
|
||
|
CDoc *doc=DocRead(name);
|
||
|
res=DocTreeExe(doc,path);
|
||
|
DocDel(doc);
|
||
|
return res;
|
||
|
}
|