hschumann2/TempleOS-Source-Code
0832
1 2#help_index "DolDoc/File"3 4public U0 DocLoad(CDoc *doc,U8 *src2,I64 size)5{//Fetch doc from raw mem buf.6 I64 i;7 U8 *src;8 Bool unlock=DocLock(doc);9 CDocBin *tmpb;10 doc->find_replace->filter_lines=0;11 if (src2) {12 DocPutS(doc,src2); //Too big DocPrint() is wasteful.13 src=src2+StrLen(src2)+1;14 i=size-(offset(CDocBin.end)-offset(CDocBin.start));15 while (src<=src2+i) {16 tmpb=CAlloc(sizeof(CDocBin),doc->mem_task);17 MemCpy(&tmpb->start,src,offset(CDocBin.end)-offset(CDocBin.start));18 src+=offset(CDocBin.end)-offset(CDocBin.start);19 tmpb->data=MAlloc(tmpb->size,doc->mem_task);20 if (tmpb->size) {21 MemCpy(tmpb->data,src,tmpb->size);22 src+=tmpb->size;23 }24 QueIns(tmpb,doc->bin_head.last);25 if (tmpb->num>=doc->cur_bin_num)26 doc->cur_bin_num=tmpb->num+1;27 }28 }29 if (!(doc->flags & (DOCF_PLAIN_TEXT|DOCF_PLAIN_TEXT_TABS)))30 DocBinsValidate(doc);31 DocTop(doc); //Calls DocRecalc(). DOCT_CURSOR will be set.32 if (unlock)33 DocUnlock(doc);34}35 36public CDoc *DocRead(U8 *name=NULL,I64 flags=0)37{//Fetch doc from disk. See flags.38 CDoc *doc=DocNew;39 U8 *src,*name2;40 I64 size=0;41 CDirContext *dirc;42 if (!name) name=blkdev.tmp_filename;43 doc->flags|=flags;44 name2=FileNameAbs(name);45 StrCpy(doc->filename.name,name2);46 if (src=FileRead(name2,&size,&doc->file_attr)) {47 if (dirc=DirContextNew(name2)) {48 DocLoad(doc,src,size);49 DirContextDel(dirc);50 }51 Free(src);52 }53 Free(name2);54 return doc;55}56 57public U8 *DocSave(CDoc *doc,I64 *_size=NULL)58{//Store doc to raw mem buf.59 CDocEntry *doc_e,*doc_e1;60 CDocBin *b;61 Bool unlock=DocLock(doc);62 I64 ch,cnt=1;//terminator63 U8 *st,*res,*dst,*src;64 65 if (!(doc->flags & (DOCF_PLAIN_TEXT|DOCF_PLAIN_TEXT_TABS)))66 DocBinsValidate(doc);67 if (doc->flags&DOCF_NO_CURSOR)68 DocRecalc(doc);69 else {70 DocRecalc(doc,RECALCF_ADD_CURSOR);71 if (doc->head.next->type_u8==DOCT_CURSOR)72 DocEntryDel(doc,doc->head.next); //If no cursor, DocLoad() puts at top.73 }74 for (doc_e=doc->head.next;doc_e!=doc;doc_e=doc_e->next) {75 if (!Bt(doldoc.type_flags_data,doc_e->type_u8)) {76 switch (doc_e->type_u8) {77 case DOCT_TAB:78 case DOCT_PAGE_BREAK:79 case DOCT_CURSOR:80 cnt++;81 break;82 case DOCT_NEW_LINE:83 if (doc->flags&DOCF_CARRIAGE_RETURN)84 cnt+=2;85 else86 cnt++;87 break;88 case DOCT_SOFT_NEW_LINE:89 break;90 case DOCT_TEXT:91 if (!(doc_e->de_flags & ~(DOCEF_TAG|DOCG_BL_IV_UL|DOCEF_WORD_WRAP|92 DOCEF_HIGHLIGHT|DOCEF_SKIP|DOCEF_FILTER_SKIP))&&93 !(doc_e->type&DOCG_BL_IV_UL)) {94 cnt+=StrLen(doc_e->tag);95 if (!(doc->flags & (DOCF_PLAIN_TEXT|DOCF_PLAIN_TEXT_TABS)) ||96 doc->flags&DOCF_DBL_DOLLARS)97 cnt+=StrOcc(doc_e->tag,'$');98 break;99 }100 default:101 st=Doc2PlainText(doc,doc_e);102 cnt+=StrLen(st)+2;103 Free(st);104 }105 }106 }107 for (b=doc->bin_head.next;b!=&doc->bin_head;b=b->next)108 if (b->use_cnt>b->tmp_use_cnt)109 cnt+=offset(CDocBin.end)-offset(CDocBin.start)+b->size;110 res=MAlloc(cnt);111 dst=res;112 doc_e=doc->head.next;113 while (doc_e!=doc) {114 doc_e1=doc_e->next;115 if (!Bt(doldoc.type_flags_data,doc_e->type_u8))116 switch (doc_e->type_u8) {117 case DOCT_CURSOR:118 DocEntryDel(doc,doc_e);119 *dst++=CH_CURSOR;120 break;121 case DOCT_TAB:122 *dst++='\t';123 break;124 case DOCT_NEW_LINE:125 if (doc->flags&DOCF_CARRIAGE_RETURN)126 *dst++='\r';127 *dst++='\n';128 break;129 case DOCT_SOFT_NEW_LINE:130 break;131 case DOCT_TEXT:132 if (!(doc_e->de_flags & ~(DOCEF_TAG|DOCG_BL_IV_UL|DOCEF_WORD_WRAP|133 DOCEF_HIGHLIGHT|DOCEF_SKIP|DOCEF_FILTER_SKIP)) &&134 !(doc_e->type&DOCG_BL_IV_UL)) {135 src=doc_e->tag;136 while (ch=*src++) {137 *dst++=ch;138 if (ch=='$' && (!(doc->flags & (DOCF_PLAIN_TEXT|139 DOCF_PLAIN_TEXT_TABS)) || doc->flags&DOCF_DBL_DOLLARS))140 *dst++=ch;141 }142 break;143 }144 default:145 *dst++='$';146 st=Doc2PlainText(doc,doc_e);147 StrCpy(dst,st);148 dst+=StrLen(st);149 *dst++='$';150 Free(st);151 }152 doc_e=doc_e1;153 }154 *dst++=0;155 b=doc->bin_head.next;156 if (b!=&doc->bin_head) {157 do {158 if (b->use_cnt>b->tmp_use_cnt) {159 MemCpy(dst,&b->start,offset(CDocBin.end)-offset(CDocBin.start));160 dst+=offset(CDocBin.end)-offset(CDocBin.start);161 MemCpy(dst,b->data,b->size);162 dst+=b->size;163 }164 b=b->next;165 } while (b!=&doc->bin_head);166 } else167 cnt--; //No terminator168 if (_size) *_size=cnt;169 if (unlock)170 DocUnlock(doc);171 return res;172}173 174public Bool DocWrite(CDoc *doc,Bool prompt=FALSE)175{//Store doc to disk.176 I64 size;177 U8 *buf;178 if (prompt && !DocForm(&doc->filename) ||179 doc->filename.name[0]=='A' && doc->filename.name[2]==':')180 return FALSE; //CANCEL || LK_DOC,LK_DOC_ANCHOR,LK_DOC_FIND,LK_DOC_LINE?181 buf=DocSave(doc,&size);182 FileWrite(doc->filename.name,buf,size,0,doc->file_attr);183 Free(buf);184 return TRUE;185}186 187#help_index "DolDoc"188public U0 DocInsDoc(CDoc *doc=NULL,CDoc *doc2)189{//Insert copy of doc2 into doc at insert pt, cur_entry.190//TODO: DocRst191 U8 *dst;192 Bool unlock_doc,unlock_doc2=DocLock(doc2);193 CDocEntry *doc_ne,*doc_e=doc2->head.next,*doc_ce;194 if (!doc) doc=DocPut;195 unlock_doc=DocLock(doc),196 DocRemSoftNewLines(doc,NULL);197 doc_ce=doc->cur_entry;198 if (doc_ce->type_u8==DOCT_TEXT && doc->cur_col>doc_ce->min_col) {199 if (doc->cur_col<doc_ce->max_col) {200 dst=doc_ce->tag+doc->cur_col;201 doc_ne=DocEntryNewTag(doc,doc_ce,dst);202 *dst=0;203 doc_ne->type=DOCT_TEXT | doc_ce->type & 0xFFFFFF00;204 doc_ce->max_col=doc->cur_col;205 QueIns(doc_ne,doc_ce);206 doc->cur_entry=doc_ne;207 doc->cur_col=doc_ne->min_col;208 } else209 if (doc_ce!=doc)210 doc->cur_entry=doc_ce->next;211 }212 while (doc_e!=doc2) {213 if (doc_e->type_u8!=DOCT_SOFT_NEW_LINE) {214 doc_ne=DocEntryCopy(doc,doc_e);215 QueIns(doc_ne,doc->cur_entry->last);216 }217 doc_e=doc_e->next;218 }219 DocRecalc(doc);220 if (unlock_doc2)221 DocUnlock(doc2);222 if (unlock_doc)223 DocUnlock(doc);224}225 226#help_index "DolDoc/Compiler;Compiler/Directive"227public U0 StreamDoc(CDoc *doc)228{//Inject doc into compile stream. Use inside #exe{}.229//TODO: DocRst230 Bool unlock_doc=DocLock(doc);231 CDocEntry *doc_e=doc->head.next;232 while (doc_e!=doc) {233 if (doc_e->type_u8==DOCT_TEXT)234 StreamPrint("%s",doc_e->tag);235 else if (doc_e->type_u8==DOCT_NEW_LINE)236 StreamPrint("\n");237 else if (doc_e->type_u8==DOCT_TAB)238 StreamPrint("\t");239 doc_e=doc_e->next;240 }241 if (unlock_doc)242 DocUnlock(doc);243}244 245#help_index "DolDoc"246Bool DocCaptureUndo(CDoc *doc,Bool force=FALSE)247{248 Bool res=FALSE,unlock;249 I64 time_stamp,flags;250 CDocUndo *u;251 if (doc->flags&DOCF_ALLOW_UNDO) {252 unlock=DocLock(doc);253 time_stamp=GetTSC;254 if (doc->flags&DOCF_UNDO_DIRTY &&255 time_stamp>doc->undo_head.last->time_stamp+cnts.time_stamp_freq<<4 ||256 force) {257 u=CAlloc(sizeof(CDocUndo),doc->mem_task);258 u->time_stamp=time_stamp;259 flags=doc->flags;260 doc->flags&=~DOCF_NO_CURSOR;261 u->body=DocSave(doc,&u->size);262 doc->flags=flags;263 QueIns(u,doc->undo_head.last);264 doc->flags&=~DOCF_UNDO_DIRTY;265 doc->undo_cnt++;266 u->doc_flags=doc->flags;267 res=TRUE;268 if (doc->flags&DOCF_AUTO_SAVE)269 DocWrite(doc);270 }271 if (unlock)272 DocUnlock(doc);273 }274 return res;275}276 277U0 DocUndoRestore(CDoc *doc)278{279 Bool unlock=DocLock(doc);280 CDocUndo *u=doc->undo_head.last,*u_next,*u_last;281 if (u!=&doc->undo_head) {282 QueRem(u);283 u_next=doc->undo_head.next;284 u_last=doc->undo_head.last;285 QueInit(&doc->undo_head);286 DocRst(doc,TRUE);287 doc->flags=u->doc_flags&~DOCF_NO_CURSOR;288 DocLoad(doc,u->body,u->size);289 doc->flags=u->doc_flags;290 DocUndoDel(doc,u);291 doc->undo_head.next=u_next;292 doc->undo_head.last=u_last;293 }294 DocUndoCntSet(doc);295 doc->flags&=~DOCF_UNDO_DIRTY;296 if (unlock)297 DocUnlock(doc);298}299 300#help_index "Graphics/Windows BMP Files;Graphics/GR Files;"\301 "DolDoc/Output;StdOut/DolDoc"302public Bool DocType(CDoc *doc=NULL,U8 *filename,I64 trailing_new_lines=1)303{//Output txt or graphic file to document.304 Bool res=FALSE;305 CDoc *doc2;306 if (!doc && !(doc=DocPut) || doc->doc_signature!=DOC_SIGNATURE_VAL)307 return FALSE;308 if (FilesFindMatch(filename,FILEMASK_TXT)) {309 doc2=DocRead(filename);310 DocInsDoc(doc,doc2);311 if (IsRaw)312 DocDump(doc2,100000);313 DocDel(doc2);314 res=TRUE;315 } else if (FilesFindMatch(filename,"*.BMP.Z")) {316 DocBMP(doc,filename,,FALSE);317 res=TRUE;318 } else if (FilesFindMatch(filename,"*.BMP;*.bmp")) {319 DocBMP(doc,filename,,TRUE);320 res=TRUE;321 } else if (FilesFindMatch(filename,"*.GR*")) {322 DocGR(doc,filename);323 res=TRUE;324 }325 if (res)326 DocPrint(doc,"%h*c",trailing_new_lines,'\n');327 return res;328}329 330#help_index "Graphics/Windows BMP Files;Graphics/GR Files;"\331 "File/Cmd Line (Typically);DolDoc/Cmd Line (Typically);"\332 "StdOut;Cmd Line (Typically)"333public Bool Type(U8 *filename,I64 trailing_new_lines=1)334{//Output txt or graphic file to command line.335 return DocType(,filename,trailing_new_lines);336}337 338#help_index "DolDoc/File"339 340public U8 *DocLineRead(U8 *filename,I64 line,CTask *mem_task=NULL)341{//Extract line from stored doc file. (Slow.)342 U8 *res=NULL;343 CDoc *doc=DocRead(filename,DOCF_PLAIN_TEXT_TABS|DOCF_NO_CURSOR);344 if (DocGoToLine(doc,line) && doc->cur_entry->type_u8==DOCT_TEXT)345 res=StrNew(doc->cur_entry->tag,mem_task);346 DocDel(doc);347 return res;348}349 350public U8 *DocLineWrite(U8 *filename,I64 line,U8 *st)351{//Write line to stored doc file. (Slow.)352 U8 *res=NULL;353 CDoc *doc=DocRead(filename,DOCF_PLAIN_TEXT_TABS|DOCF_NO_CURSOR);354 if (DocGoToLine(doc,line)) {355 if (doc->cur_entry->type_u8==DOCT_TEXT) {356 Free(doc->cur_entry->tag);357 doc->cur_entry->tag=StrNew(st);358 } else359 DocPrint(doc,"%s",st);360 DocTop(doc);361 DocWrite(doc);362 }363 DocDel(doc);364 return res;365}366 