mirror of https://github.com/minexew/Shrine.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
474 lines
11 KiB
474 lines
11 KiB
#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=User; |
|
TaskWait(task); |
|
LBtr(&task->display_flags,DISPLAYf_SHOW); |
|
} else |
|
task=NULL; |
|
|
|
cnt=0; |
|
table=h; |
|
while (table) { |
|
for (i=0;i<=table->mask;i++) { |
|
temph=table->body[i]; |
|
while (temph) { |
|
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; |
|
} |
|
} |
|
if (recurse) |
|
table=table->next; |
|
else |
|
break; |
|
} |
|
if (!cnt) goto wh_done; |
|
|
|
lst=CAlloc(cnt*sizeof(CWho)); |
|
j=0; |
|
table=h; |
|
while (table) { |
|
for (i=0;i<=table->mask;i++) { |
|
temph=table->body[i]; |
|
while (temph) { |
|
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; |
|
} |
|
} |
|
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;i<cnt;i++) { |
|
comment=NULL; |
|
ptr=lst[i].h; |
|
dbg_info=NULL; |
|
if (index) |
|
if (cur_index=lst[i].index) { |
|
if (StrCmp(cur_index,last_index)) { |
|
Free(last_index); |
|
last_index=StrNew(cur_index); |
|
if (i) |
|
DocPrint(doc,"\n\n"); |
|
DocPrint(doc,"$$WW,0$$$$PURPLE$$$$TX+CX,\"%Q\"$$$$FG$$\n",cur_index); |
|
} |
|
} |
|
|
|
if (index && ptr->type & 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=LinkedLstCnt(temph); |
|
if (j<HDR_MAX) |
|
a[j]++; |
|
cnt+=j; |
|
if (j>longest) |
|
longest=j; |
|
} |
|
} |
|
"Histogram\n"; |
|
for (i=0;i<HDR_MAX;i++) |
|
if (a[i]) |
|
"%02d:%d\n",i,a[i]; |
|
"Size:%d Count:%d Longest:%d\n", |
|
table->mask+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]=dsk.boot_drv_let; |
|
|
|
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); |
|
}
|
|
|