#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) LBEqual(&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; } Bool IsEditableText(CDocEntry *doc_e) { if (doc_e->type_u8 == DOCT_TEXT && !(doc_e->de_flags & DOCEG_DONT_EDIT)) return TRUE; else return FALSE; } CDocEntry *DocEntryNewBase(CDoc *doc, I64 type, I64 de_flags=0, I64 x=0, I64 y=0, I64 page_line_num=0) {//See also MAllocIdent and CDocEntry. CDocEntry *res = CAlloc(sizeof(CDocEntryBase), doc->mem_task); res->type = type; res->de_flags = de_flags | doldoc.default_de_flags[type.u8[0]]; res->x = x; res->y = y; res->page_line_num = page_line_num; return res; } CDocEntry *DocEntryNewTag(CDoc *doc, CDocEntry *doc_ce, U8 *tag) { I64 l = StrLen(tag); CDocEntry *res = DocEntryNewBase(doc, doc_ce->type, doc_ce->de_flags, doc_ce->x, doc_ce->y, doc_ce->page_line_num); res->de_flags = doc_ce->de_flags; //Override res->max_col = l; res->tag = MAlloc(l + 1, doc->mem_task); MemCopy(res->tag, tag, l + 1); MemCopy(&res->settings, &doc_ce->settings, sizeof(CDocSettings)); return res; } 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; QueueRemove(doc_e); if (doc_e->de_flags & DOCEF_TAG) Free(doc_e->tag); 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_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_BIN_PTR_LINK) Free(doc_e->bin_ptr_link); if (doc_e->de_flags & DOCEF_HAS_BIN) DocBinDel(doc, doc_e->bin_data); if (doc_e->de_flags & DOCEF_REMALLOC_DATA) Free(doc_e->data); Free(doc_e); } } public I64 DocEntrySize(CDoc *, CDocEntry *doc_e) {//Mem size of entry and all parts. I64 res; if (!doc_e) return 0; res = MSize2(doc_e); if (doc_e->de_flags & DOCEF_TAG) res += MSize2(doc_e->tag); if (doc_e->de_flags & DOCEF_AUX_STR) res += MSize2(doc_e->aux_str); if (doc_e->de_flags & DOCEF_DEFINE) res += MSize2(doc_e->define_str); if (doc_e->de_flags & DOCEF_HTML_LINK) res += MSize2(doc_e->html_link); if (doc_e->de_flags & DOCEF_LEFT_MACRO) res += MSize2(doc_e->left_macro); if (doc_e->de_flags & DOCEF_RIGHT_MACRO) res += MSize2(doc_e->right_macro); if (doc_e->de_flags & DOCEF_BIN_PTR_LINK) res += MSize2(doc_e->bin_ptr_link); if (doc_e->de_flags & DOCEF_REMALLOC_DATA) res += MSize2(doc_e->data); return res; } U0 DocUndoDel(CDoc *, CDocUndo *u) { Free(u->body); Free(u); } U0 DocUndoCountSet(CDoc *doc) { Bool unlock = DocLock(doc); CDocUndo *u = doc->undo_head.next; doc->undo_count = 0; while (u != &doc->undo_head) { doc->undo_count++; 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 *tmpb; CTask *task = doc->mem_task; doc_ne = MAllocIdent(doc_e, task); doc_ne->next = doc_ne; doc_ne->last = doc_ne; if (doc_e->de_flags & DOCEF_TAG) doc_ne->tag = MAllocIdent(doc_e->tag, task); if (doc_e->de_flags & DOCEF_AUX_STR) doc_ne->aux_str = MAllocIdent(doc_e->aux_str, task); if (doc_e->de_flags & DOCEF_DEFINE) doc_ne->define_str = MAllocIdent(doc_e->define_str, task); if (doc_e->de_flags & DOCEF_HTML_LINK) doc_ne->html_link = MAllocIdent(doc_e->html_link, task); if (doc_e->de_flags & DOCEF_LEFT_MACRO) doc_ne->left_macro = MAllocIdent(doc_e->left_macro, task); if (doc_e->de_flags & DOCEF_RIGHT_MACRO) doc_ne->right_macro = MAllocIdent(doc_e->right_macro, task); if (doc_e->de_flags & DOCEF_BIN_PTR_LINK) doc_ne->bin_ptr_link = MAllocIdent(doc_e->bin_ptr_link, task); if (doc_e->de_flags & DOCEF_HAS_BIN) { tmpb = MAllocIdent(doc_e->bin_data, task); tmpb->data = MAllocIdent(doc_e->bin_data->data, task); doc_ne->bin_num = doc->cur_bin_num; tmpb->num = doc->cur_bin_num++; doc_ne->bin_data = tmpb; if (doc_e->de_flags & DOCEF_TAG && doc_e->tag && *doc_e->tag) tmpb->tag = StrNew(doc_e->tag, task); else tmpb->tag = NULL; QueueInsert(tmpb, doc->bin_head.last); } if (doc_e->de_flags & DOCEF_REMALLOC_DATA) doc_ne->data = MAllocIdent(doc_e->data, task); return doc_ne; } 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->head.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_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); } public U0 DocInsEntry(CDoc *doc, CDocEntry *doc_e) {//Insert entry into doc, updating its values. 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; MemCopy(&doc_e->settings, &doc_ce->settings, sizeof(CDocSettings)); if (doc->cur_col > 0 && doc_ce->type_u8 == DOCT_TEXT && !(doc_ce->de_flags & (DOCEF_TAG_CB | DOCEF_DEFINE | DOCEF_AUX_STR | DOCEF_HTML_LINK | DOCEF_BIN_PTR_LINK)) && doc->cur_col < doc_ce->max_col) { dst = doc_ce->tag + doc->cur_col; doc_ne = DocEntryNewTag(doc, doc_ce, dst); *dst = 0; doc_ne->type = DOCT_TEXT | doc_ce->type & 0xFFFFFF00; doc_ce->max_col = doc->cur_col; QueueInsert(doc_ne, doc_ce); doc->cur_col = 0; doc_ce = doc_ne; } if (doc_ce->type_u8 == DOCT_TEXT && doc->cur_col >= doc_ce->max_col) { QueueInsert(doc_e, doc_ce); doc->cur_entry = doc_e->next; } else { QueueInsert(doc_e, doc_ce->last); doc->cur_entry = doc_ce; } doc->cur_col = doc->cur_entry->min_col; DocRemSoftNewLines(doc, doc->cur_entry); if (unlock) DocUnlock(doc); } public U0 DocReset(CDoc *doc, Bool is_old) {//Del all entries and set doc to defaults. 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->head.next; while (doc_e != doc) { doc_e2 = doc_e->next; DocEntryDel(doc, doc_e); doc_e = doc_e2; } u = doc->undo_head.next; while (u != &doc->undo_head) { u8 = u->next; DocUndoDel(doc, u); u = u8; } b = doc->bin_head.next; while (b != &doc->bin_head) { b1 = b->next; QueueRemove(b); Free(b->data); Free(b); b = b1; } } //Check DocInsDoc doc->flags &= DOCF_BREAK_UNLOCKED; doc->head.next = doc->head.last = doc; QueueInit(&doc->bin_head); QueueInit(&doc->undo_head); doc->undo_head.time_stamp = 0; doc->undo_count = 0; doc->cur_bin_num = 1; doc->dollar_buf_ptr = 0; doc->cmd_U8 = CH_SPACE; doc->page_line_num = 0; doc->best_d = I64_MAX; s = &doc->settings_head; s->left_margin = DOC_DEFAULT; s->right_margin = DOC_DEFAULT; s->indent = 0; s->page_len = 66; s->header = DOC_DEFAULT; s->footer = DOC_DEFAULT; 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->default_text_attr = DOC_ATTR_DEFAULT_TEXT; doc_e = &doc->head; 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; MemCopy(&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; DocReset(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 res = 0; if (!doc || doc->doc_signature != DOC_SIGNATURE_VAL) return 0; unlock = DocLock(doc); doc_e = doc->head.next; while (doc_e != doc) { res += DocEntrySize(doc, doc_e); doc_e = doc_e->next; } u = doc->undo_head.next; while (u != &doc->undo_head) { res += MSize2(u->body); res += MSize2(u); u = u->next; } b = doc->bin_head.next; while (b != &doc->bin_head) { res += MSize2(b->data); res += MSize2(b); b = b->next; } res += MSize2(doc->find_replace); res += MSize2(doc->dollar_buf); res += MSize2(doc); if (unlock) DocUnlock(doc); return res; } #help_index "DolDoc" public CDoc *DocNew(U8 *filename=NULL, CTask *task=NULL) {//MAlloc new DolDoc. (Begin a new doc.) CDoc *doc; if (!task) task = Fs; doc = CAlloc(sizeof(CDoc), task); if (filename) StrCopy(doc->filename.name, filename); else StrCopy(doc->filename.name, blkdev.tmp_filename); doc->find_replace = CAlloc(sizeof(CEdFindText), task); doc->find_replace->scan_fwd = TRUE; doc->find_replace->match_case = TRUE; doc->find_replace->prompt = TRUE; doc->left_click_link = &EdLeftClickLink; doc->dollar_buf_size = 84; doc->dollar_buf = MAlloc(doc->dollar_buf_size, task); doc->max_entries = I64_MAX; doc->win_task = task; doc->mem_task = task; DocReset(doc, FALSE); doc->doc_signature = DOC_SIGNATURE_VAL; return doc; }