#help_index "Info;Hash;Cmd Line (Typically)" class CWho { CHashGeneric *h; U8 *index; }; I64 HashEntriesCompare(CWho *h1,CWho *h2) { I64 i1,i2; if (i1=StrCmp(h1->h->str,h2->h->str)) return i1; i1=HashTypeNum(h1->h); i2=HashTypeNum(h2->h); return i1-i2; } I64 HashEntriesCompare2(CWho *h1,CWho *h2) { CHashFun *tempf1=h1->h,*tempf2=h2->h; I64 i1=HashVal(tempf1),i2=HashVal(tempf2); if (i1==i2) { i1=HashTypeNum(tempf1); i2=HashTypeNum(tempf2); if (i1==i2) return StrCmp(tempf1->str,tempf2->str); } return i1-i2; } I64 HelpIndexCnt(U8 *ptr,U8 *index) { I64 cnt=0,ch,index_len=StrLen(index); while (*ptr) { if (!StrNCmp(ptr,index,index_len)) cnt++; while (ch=*ptr++) if (ch==';') break; if (!ch) ptr--; } return cnt; } U8 *HelpIndexStr(U8 **_ptr,U8 *index) { U8 *ptr=*_ptr,*ptr2,*result; I64 ch,index_len=StrLen(index); while (*ptr) { ptr2=ptr; while (ch=*ptr++) if (ch==';') break; if (!ch) ptr--; *_ptr=ptr; if (!StrNCmp(ptr2,index,index_len)) { if (ch==';') ptr--; *ptr=0; result=StrNew(ptr2); *ptr=ch; return result; } } return NULL; } U8 *HelpComment(CTask *task,CHash *temph,U8 *_src_link) { CDoc *doc; CDocEntry *doc_e; U8 *result=NULL,*ptr,*ptr2,*src_link=StrNew(_src_link); if (*src_link=='F' && src_link[2]==':') *src_link='P'; XTalkWait(task,"Ed(0x%X,DOF_DONT_WINMGR_SYNC|DOF_DONT_SHOW);\n",src_link); Free(src_link); doc=DocPut(task); doc_e=doc->cur_entry; if (temph->type&HTT_FUN && !Bt(&temph(CHashFun *)->flags,Ff__EXTERN) && !Bt(&temph(CHashFun *)->flags,Ff_INTERNAL)) while (doc_e!=doc && (!(doc_e->de_flags&DOCEF_TAG)||!StrOcc(doc_e->tag,'{'))) doc_e=doc_e->next; if (doc_e!=doc) { if (doc_e->de_flags&DOCEF_TAG) { ptr=doc_e->tag; if (ptr2=StrMatch("//",ptr)) ptr=ptr2+2; else if (ptr2=StrMatch("/*",ptr)) ptr=ptr2+2; else if (!StrNCmp(ptr,"public",6)) ptr+=6; while (*ptr==CH_SPACE) ptr++; result=StrNew(ptr); doc_e=doc_e->next; } while (doc_e!=doc && doc_e->type_u8!=DOCT_NEW_LINE) { if (doc_e->type_u8==DOCT_TAB) { ptr=MStrPrint("%s ",result); Free(result); result=ptr; } else if (doc_e->de_flags&DOCEF_TAG) { ptr=MStrPrint("%s%s",result,doc_e->tag); Free(result); result=ptr; } doc_e=doc_e->next; } } XTalkWait(task,"%c",CH_SHIFT_ESC); if (result) { ptr=MStrUtil(result,SUF_REM_TRAILING|SUF_REM_LEADING|SUF_SINGLE_SPACE); Free(result); result=ptr; } return result; } I64 HashEntriesCompare3(CWho *h1,CWho *h2) { I64 i,i1=0,i2=0; i=StrCmp(h1->index,h2->index); if (i) return i; else { if (h1->h->type&HTT_HELP_FILE) i1=1; if (h2->h->type&HTT_HELP_FILE) i2=1; i=i2-i1; if (i) return i; else return StrCmp(h1->h->str,h2->h->str); } } public U0 Who(U8 *fu_flags=NULL,CHashTable *h=NULL, U8 *outname=NULL,U8 mapfile_drv=0,U8 *index=NULL,CDoc *_doc=NULL) {//Dump hash symbol table. // "+p" for only public symbols // "+m" to order by number (normally alphabetical) // "-r" just local hash table CHashTable *table; CHashSrcSym *temph; CHashGeneric *ptr; CWho *lst; I64 cnt,i,j,k,size,f=0,dbg_bin_num; U8 buf[512],*st,*src_link,*last_index=StrNew(""),*cur_index,*comment; CDoc *doc; Bool recurse,publics,map,old_preempt=Preempt(OFF); CDocBin *tempb; CDbgInfo *dbg_info; CTask *task; ScanFlags(&f,Define("ST_FILE_UTIL_FLAGS"),"+r"); ScanFlags(&f,Define("ST_FILE_UTIL_FLAGS"),fu_flags); if (f&~(FUF_RECURSE|FUF_PUBLIC|FUF_MAP)) throw('FUF'); recurse=Bt(&f,FUf_RECURSE); publics=Bt(&f,FUf_PUBLIC); map =Bt(&f,FUf_MAP); if (!h) h=Fs->hash_table; if (_doc) doc=_doc; else if (outname) { doc=DocNew(outname); doc->flags|=DOCF_NO_CURSOR; } else doc=NULL; if (index) { task=SpawnUser; TaskWait(task); LBtr(&task->display_flags,DISPLAYf_SHOW); } else task=NULL; cnt=0; table=h; while (table) { temph=table->next_added; while (temph!=table) { if (!(temph->type & (HTF_IMPORT | HTF_PRIVATE)) && (temph->type & HTF_PUBLIC || !publics)) { if (!index) cnt++; else if (temph->type&HTG_SRC_SYM && (cur_index=temph->index)) cnt+=HelpIndexCnt(cur_index,index); } temph=temph->next_added; } if (recurse) table=table->next; else break; } if (!cnt) goto wh_done; lst=CAlloc(cnt*sizeof(CWho)); j=0; table=h; while (table) { temph=table->next_added; while (temph!=table) { if (!(temph->type & (HTF_IMPORT | HTF_PRIVATE)) && (temph->type & HTF_PUBLIC || !publics)) if (!index) lst[j++].h=temph; else if (temph->type&HTG_SRC_SYM && (cur_index=temph->index) && (k=HelpIndexCnt(cur_index,index))) while (k--) { lst[j].index=HelpIndexStr(&cur_index,index); lst[j++].h=temph; } temph=temph->next_added; } if (recurse) table=table->next; else break; } Preempt(old_preempt); if (map) QSort(lst,cnt,sizeof(CWho),&HashEntriesCompare2); else if (index) QSort(lst,cnt,sizeof(CWho),&HashEntriesCompare3); else QSort(lst,cnt,sizeof(CWho),&HashEntriesCompare); if (index) { progress1_max=cnt; progress1=0; } for (i=0;itype & HTT_HELP_FILE) { DocPrint(doc,"$$WW,1$$"); DocType(doc,ptr->str); DocPrint(doc,"$$WW,0$$"); } else { if (ptr->type&HTG_SRC_SYM && ptr(CHashSrcSym *)->src_link) { src_link=StrNew(ptr(CHashSrcSym *)->src_link); if (mapfile_drv && StrLen(src_link)>4 && buf[1]==':' && src_link[4]==':') src_link[3]=mapfile_drv; dbg_info=NULL; if (outname && doc && ptr->type & HTT_FUN) { if (dbg_info=ptr(CHashFun *)->dbg_info) { size=offset(CDbgInfo.body)+sizeof(U32)*(dbg_info->max_line+2-dbg_info->min_line); if (size>MSize(dbg_info)) { "Corrupt Map Entry\n"; dbg_info=NULL; } else { if (dbg_info->min_line<=dbg_info->max_line) { tempb=CAlloc(sizeof(CDocBin)); tempb->size=size; tempb->data=MAlloc(size); MemCpy(tempb->data,dbg_info,size); dbg_bin_num=tempb->num=doc->cur_bin_num++; tempb->use_cnt=1; QueIns(tempb,doc->bin_root.last); } else dbg_info=NULL; } } } if (dbg_info) DocPrint(doc,"$$LK,\"%-20s\",A=\"%s\",BI=%d$$",ptr->str,src_link,dbg_bin_num); else { DocPrint(doc,"$$LK,\"%-20s\",A=\"%s\"$$",ptr->str,src_link); if (index) comment=HelpComment(task,ptr,src_link); } Free(src_link); } else DocPrint(doc,"%-20s",ptr->str); if (!index) { if (ptr->type & HTT_DEFINE_STR) { st=MStrUtil(ptr(CHashDefineStr *)->data,SUF_SAFE_DOLLAR); j=ptr(CHashDefineStr *)->cnt; if (j==-1) StrPrint(buf,"%-10tQ ",st); else StrPrint(buf,"%-10tQ %02X",st,j); Free(st); } else if (ptr->type & HTT_GLBL_VAR) { if (outname) StrPrint(buf,"%010X ",ptr(CHashGlblVar *)->data_addr_ip); else StrPrint(buf,"%010X ",ptr(CHashGlblVar *)->data_addr); } else StrPrint(buf,"%010X ",HashVal(ptr)); j=HashEntrySize(ptr); if (j==-1) CatPrint(buf," %04X ",ptr->use_cnt); else CatPrint(buf," %04X %010X ",ptr->use_cnt,j); } else *buf=0; k=ptr->type; if (publics) k&=~HTF_PUBLIC; if (!(k&HTG_TYPE_MASK)) CatPrint(buf,"NULL "); while (k) { j=Bsf(k); if (j<0) break; Btr(&k,j); CatPrint(buf,"%Z ",j,"ST_HTT_TYPES"); } DocPrint(doc,"%s",buf); if (comment) { DocPrint(doc,"$$GREEN$$%s$$FG$$",comment); Free(comment); } DocPrint(doc,"\n"); } Free(lst[i].index); if (index) progress1++; } Free(lst); if (index) progress1=progress1_max=0; wh_done: Preempt(old_preempt); if (doc) { DocBinsValidate(doc); if (!_doc) { DocWrite(doc); DocDel(doc); } else { if (doc->root.next==doc) DocPrint(doc,"No Match"); else DocRecalc(doc); } } Free(last_index); Kill(task); } #define HDR_MAX 16 public I64 HashDepthRep(CHashTable *table=NULL) {//Hash table linked-list chain depth report. //Histogram of collision count. I64 i,j,longest=0,cnt=0,a[HDR_MAX]; CHash *temph; if (!table) table=Fs->hash_table; MemSet(a,0,sizeof(a)); for (i=0;i<=table->mask;i++) { temph=table->body[i]; if (temph) { j=1; while (temph->next) { temph=temph->next; j++; } if (jlongest) longest=j; } } "Histogram\n"; for (i=0;imask+1,cnt,longest; return longest; } #help_index "Help System;Training" #help_file "::/Doc/HelpSystem" public U0 DocHelpIndex(CDoc *doc,U8 *index) {//Put to doc report for given help index. Who("+p",,,,index,doc); } public U0 PopUpHelpIndex(U8 *index,CTask *parent=NULL) {//PopUp win report for given help index. U8 *buf; buf=MStrPrint("DocHelpIndex(DocPut,\"%s\");View;",index); PopUp(buf,parent); Free(buf); } #help_index "Hash" public U0 MapFileLoad(U8 *filename) {//Load map file so we have src line info. U8 *st,*ptr,*name=DftExt(filename,"MAP.Z"), *absname=FileNameAbs(name); CDoc *doc=DocRead(name); CDocEntry *doc_e; CHashSrcSym *temph; I64 i,j,base=0; CDbgInfo *dbg_info; FileExtRem(absname); if (absname[1]==':' && StrLen(absname)>2 && (temph=HashSingleTableFind(absname+2,Fs->hash_table,HTT_MODULE))) base=temph(CHashGeneric *)->user_data0+sizeof(CBinFile); if (!doc) return; doc_e=doc->root.next; while (doc_e!=doc) { if (doc_e->type_u8==DOCT_LINK) { if (*doc_e->tag) st=MStrUtil(doc_e->tag,SUF_REM_TRAILING); else st=MStrUtil(doc_e->aux_str,SUF_REM_TRAILING); if (temph=HashSingleTableFind(st,Fs->hash_table,HTG_SRC_SYM)) { if (*doc_e->tag) { Free(temph->src_link); temph->src_link=doc_e->aux_str; ptr=temph->src_link; if (ptr[0] && ptr[1] && ptr[2]==':' && ptr[3]==':') ptr[3]=*sys_acct; doc_e->aux_str=NULL; } if (temph->type&(HTT_FUN|HTT_EXPORT_SYS_SYM) && !(dbg_info=temph->dbg_info) && doc_e->bin_data && (dbg_info=doc_e->bin_data->data)) { if (doc_e->bin_data->size>MSize(dbg_info)) "Corrupt Map Entry\n"; else { doc_e->bin_data->data=NULL; temph->dbg_info=dbg_info; for (i=dbg_info->min_line;i<=dbg_info->max_line+1;i++) { j=i-dbg_info->min_line; if (dbg_info->body[j]) dbg_info->body[j]=dbg_info->body[j]+base; } } } } Free(st); } doc_e=doc_e->next; } DocDel(doc); Free(name); Free(absname); }