#help_index "DolDoc/Link" /* See ZealOS 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" "MN:SymName" "PI:filename" "PF:haystack_filename,needle_str" "PF:haystack_filename,needle_str:occurnum" "PL:filename,linenum" "BF:haystack_bible_book,needle_str" "DN:word" "DN:word,defnum" "HI:index" "AD:code_address_number" To edit a doc structure already in memory. See SpriteEdText(). "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_FILE 0 #define LK_FILE_ANCHOR 1 #define LK_FILE_FIND 2 #define LK_FILE_LINE 3 #define LK_MAN_PAGE 4 #define LK_PLAIN 5 #define LK_PLAIN_FIND 6 #define LK_PLAIN_LINE 7 #define LK_BIBLE_FIND 8 #define LK_DEF 9 #define LK_HELP_INDEX 10 #define LK_ADDR 11 #define LK_DOC 12 //See SpriteEdText() #define LK_DOC_ANCHOR 13 #define LK_DOC_FIND 14 #define LK_DOC_LINE 15 #define LK_PLACE_ANCHOR 16 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; } 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), res = FALSE, other_found = FALSE; U8 *st1, *st2; try { switch (type) { case LK_PLAIN: flags = DOCF_PLAIN_TEXT | DOCF_NO_CURSOR; case LK_DOC: type = LK_FILE; break; case LK_DOC_ANCHOR: type = LK_FILE_ANCHOR; break; case LK_PLAIN_FIND: flags = DOCF_PLAIN_TEXT | DOCF_NO_CURSOR; case LK_DOC_FIND: type = LK_FILE_FIND; break; case LK_PLAIN_LINE: flags = DOCF_PLAIN_TEXT | DOCF_NO_CURSOR; case LK_DOC_LINE: type = LK_FILE_LINE; break; case LK_BIBLE_FIND: flags = DOCF_PLAIN_TEXT | DOCF_NO_CURSOR; break; } flags |= DOCF_ALLOW_UNDO; if (LK_DOC <= _type <= LK_DOC_LINE) { doc = Str2I64(filename);//See SpriteEdText() res = TRUE; } else { st1 = StrNew(filename); st2 = StrNew(filename); StrLastRemove(st1, "/", st2); //st2 is name without dir if (!FileNameCheck(st2)) doc = NULL; else { Silent; if (Bt(&edf_dof_flags, EDf_BAIL)) //if bail, scan parents res = FileFind(filename,, FUF_JUST_FILES | FUF_SCAN_PARENTS); else if (!(res = FileFind(filename,, FUF_JUST_FILES))) other_found = FileFind(filename,, FUF_JUST_FILES | FUF_SCAN_PARENTS); doc = DocRead(filename, flags); doc->desc = 'Edit'; Silent(old_silent); Fs->border_src = BDS_ED_FILENAME_DRIVE; } Free(st1); Free(st2); } if (!doc || doc->doc_signature != DOC_SIGNATURE_VAL) res = FALSE; else { if (Bt(&edf_dof_flags, EDf_COLLAPSE)) DocCollapse(TRUE, doc); else if (Bt(&edf_dof_flags, EDf_UNCOLLAPSE)) DocCollapse(FALSE, doc); if (res || other_found) switch (type) { case LK_FILE_LINE: res = DocGoToLine(doc, *_num); break; case LK_FILE_ANCHOR: res = DocAnchorFind(doc, needle_str); break; case LK_FILE_FIND: res = DocFind(doc,, needle_str, *_num); break; case LK_BIBLE_FIND: res = DocFind(doc, *_num, needle_str); break; default: DocCenter(doc); } *_num = doc->cur_entry->y + 1; if (edf_dof_flags & EDF_WAS_WRITE) res = FALSE; if (!(edf_dof_flags & EDF_BAIL)) { if (*doc->filename.name) doc->filename.dirc = DirContextNew(doc->filename.name); else doc->filename.dirc = NULL; if (DocEd(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 (edf_dof_flags & EDF_WAS_WRITE) res = TRUE; } } DirContextDel(doc->filename.dirc); } if (!(LK_DOC <= _type <= LK_DOC_LINE)) DocDel(doc); } } catch { Silent(old_silent); res = FALSE; } Fs->border_src = old_border_src; return res; } #define DEFAULT_ADDR_LINK_BIN_SIZE 64 public I64 EdLinkConvert(U8 *link_st, U8 **_filename=NULL, U8 **_needle_str=NULL, I64 *_num=NULL, I64 edf_dof_flags=0) {//Editor Link--> filename, needle_str and line number. U8 *st, *ptr, *src, *filename = NULL, *needle_str = NULL, *filename2; I64 res, i, num = 1; CHashSrcSym *tmph; if (!link_st || !*link_st) { if (edf_dof_flags & EDF_BAIL) return -1; link_st = blkdev.tmp_filename; } st = StrNew(link_st); res = LK_FILE; if (StrLen(st) > 3 && st[2] == ':') { st[2] = 0; filename2 = st + 3; switch (res = DefineMatch(st, "ST_LINK_TYPES", LMF_IGNORE_CASE)) { case LK_MAN_PAGE: if (tmph = HashFind(filename2, Fs->hash_table, HTG_SRC_SYM)) res = EdLinkConvert(tmph->src_link, &filename, &needle_str, &num, edf_dof_flags); else res = -1; goto lc_done; case LK_ADDR: if (ptr = StrLastOcc(filename2, ",")) { *ptr = 0; i = Str2I64(ptr + 1); } else i = DEFAULT_ADDR_LINK_BIN_SIZE; if (ptr = SrcEdLink(ExePrint("%s;", filename2), i)) { res = EdLinkConvert(ptr, &filename, &needle_str, &num, edf_dof_flags); Free(ptr); } else res = -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; src = ptr + 1; while (*src) {//We do not allow ending verse if (*src == '-') *src = 0; src++; } needle_str = StrNew(ptr + 1); } i = DefineMatch(filename2, "ST_BIBLE_BOOKS", LMF_IGNORE_CASE); if (i < 0) res = -1; else { num = Str2I64(DefineSub(i, "ST_BIBLE_BOOK_LINES")); filename2 = BIBLE_FILENAME; } 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 (res >= 0) { if (LK_DOC <= res <= LK_DOC_LINE) filename = StrNew(filename2); //Holds document address as number. else filename = FileNameAbs(filename2); } 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 res; } public Bool DocLinkCheck(CDoc *doc, U8 *link_st) {//Check for bad Editor Link. U8 *filename, *st; Bool res = FALSE; CDirContext *dirc; if (link_st) { st = FileNameAbs(doc->filename.name); dirc = DirContextNew(st); Free(st); switch (EdLinkConvert(link_st, &filename)) { case -1: break; case LK_FILE_LINE: case LK_PLAIN_LINE: case LK_FILE: //We don't check line number res = FileFind(filename,, FUF_JUST_FILES | FUF_SCAN_PARENTS); break; case LK_BIBLE_FIND: st = StrNew(link_st + 3); if (StrOcc(st, ',')) StrLastRemove(st, ","); if (DefineMatch(st, "ST_BIBLE_BOOKS", LMF_IGNORE_CASE) >= 0) res = TRUE; Free(st); break; default://TODO: Need to validate HI: and DN: if (Ed(link_st, EDF_BAIL)) res = TRUE; } Free(filename); DirContextDel(dirc); } return res; } public U8 *DocLinkFile(U8 *link_st, CTask *mem_task=NULL) {//Return the file for an Editor Link Types. U8 *filename = NULL, *st, *res = NULL; if (link_st) { switch (EdLinkConvert(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_SCAN_PARENTS); res = StrNew(st); Free(st); break; case LK_BIBLE_FIND: res = StrNew(BIBLE_FILENAME, mem_task); break; } Free(filename); } return res; }