432 lines
9.5 KiB
HolyC
Executable File
432 lines
9.5 KiB
HolyC
Executable File
#help_index "Info;Hash/System;Cmd Line (Typically)"
|
||
class CWho
|
||
{
|
||
CHashGeneric *h;
|
||
U8 *idx;
|
||
};
|
||
|
||
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 *tmpf1=h1->h,*tmpf2=h2->h;
|
||
I64 i1=HashVal(tmpf1),i2=HashVal(tmpf2);
|
||
if (i1==i2) {
|
||
i1=HashTypeNum(tmpf1);
|
||
i2=HashTypeNum(tmpf2);
|
||
if (i1==i2)
|
||
return StrCmp(tmpf1->str,tmpf2->str);
|
||
}
|
||
return i1-i2;
|
||
}
|
||
|
||
I64 HelpIndexCnt(U8 *ptr,U8 *idx)
|
||
{
|
||
I64 cnt=0,ch,idx_len=StrLen(idx);
|
||
while (*ptr) {
|
||
if (!StrNCmp(ptr,idx,idx_len))
|
||
cnt++;
|
||
while (ch=*ptr++)
|
||
if (ch==';')
|
||
break;
|
||
if (!ch)
|
||
ptr--;
|
||
}
|
||
return cnt;
|
||
}
|
||
|
||
U8 *HelpIndexStr(U8 **_ptr,U8 *idx)
|
||
{
|
||
U8 *ptr=*_ptr,*ptr2,*res;
|
||
I64 ch,idx_len=StrLen(idx);
|
||
while (*ptr) {
|
||
ptr2=ptr;
|
||
while (ch=*ptr++)
|
||
if (ch==';')
|
||
break;
|
||
if (!ch)
|
||
ptr--;
|
||
*_ptr=ptr;
|
||
if (!StrNCmp(ptr2,idx,idx_len)) {
|
||
if (ch==';')
|
||
ptr--;
|
||
*ptr=0;
|
||
res=StrNew(ptr2);
|
||
*ptr=ch;
|
||
return res;
|
||
}
|
||
}
|
||
return NULL;
|
||
}
|
||
|
||
U8 *HelpComment(CTask *task,CHash *tmph,U8 *_src_link)
|
||
{
|
||
CDoc *doc;
|
||
CDocEntry *doc_e;
|
||
U8 *res=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 (tmph->type&HTT_FUN) {
|
||
if (Bt(&tmph(CHashFun *)->flags,Ff__EXTERN) ||
|
||
Bt(&tmph(CHashFun *)->flags,Ff_INTERNAL))
|
||
while (doc_e!=doc &&
|
||
(!(doc_e->de_flags&DOCEF_TAG)||!StrOcc(doc_e->tag,';')))
|
||
doc_e=doc_e->next;
|
||
else
|
||
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++;
|
||
res=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",res);
|
||
Free(res);
|
||
res=ptr;
|
||
} else if (doc_e->de_flags&DOCEF_TAG) {
|
||
ptr=MStrPrint("%s%s",res,doc_e->tag);
|
||
Free(res);
|
||
res=ptr;
|
||
}
|
||
doc_e=doc_e->next;
|
||
}
|
||
}
|
||
XTalkWait(task,"%c",CH_SHIFT_ESC);
|
||
if (res) {
|
||
ptr=MStrUtil(res,SUF_REM_TRAILING|SUF_REM_LEADING|SUF_SINGLE_SPACE);
|
||
Free(res);
|
||
res=ptr;
|
||
}
|
||
return res;
|
||
}
|
||
|
||
I64 HashEntriesCompare3(CWho *h1,CWho *h2)
|
||
{
|
||
I64 i,i1=0,i2=0;
|
||
i=StrCmp(h1->idx,h2->idx);
|
||
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 *idx=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 *tmph;
|
||
CHashGeneric *ptr;
|
||
CWho *lst;
|
||
I64 cnt,i,j,k,f=0;
|
||
U8 buf[512],*last_idx=StrNew(""),*cur_idx,*comment;
|
||
Bool recurse,publics,map;
|
||
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 (idx) {
|
||
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++) {
|
||
tmph=table->body[i];
|
||
while (tmph) {
|
||
if (!(tmph->type & (HTF_IMPORT | HTF_PRIVATE)) &&
|
||
(tmph->type & HTF_PUBLIC || !publics)) {
|
||
if (!idx)
|
||
cnt++;
|
||
else if (tmph->type&HTG_SRC_SYM && (cur_idx=tmph->idx))
|
||
cnt+=HelpIndexCnt(cur_idx,idx);
|
||
}
|
||
tmph=tmph->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++) {
|
||
tmph=table->body[i];
|
||
while (tmph) {
|
||
if (!(tmph->type & (HTF_IMPORT | HTF_PRIVATE)) &&
|
||
(tmph->type & HTF_PUBLIC || !publics))
|
||
if (!idx)
|
||
lst[j++].h=tmph;
|
||
else if (tmph->type&HTG_SRC_SYM && (cur_idx=tmph->idx) &&
|
||
(k=HelpIndexCnt(cur_idx,idx)))
|
||
while (k--) {
|
||
lst[j].idx=HelpIndexStr(&cur_idx,idx);
|
||
lst[j++].h=tmph;
|
||
}
|
||
tmph=tmph->next;
|
||
}
|
||
}
|
||
if (recurse)
|
||
table=table->next;
|
||
else
|
||
break;
|
||
}
|
||
|
||
if (map)
|
||
QSort(lst,cnt,sizeof(CWho),&HashEntriesCompare2);
|
||
else if (idx)
|
||
QSort(lst,cnt,sizeof(CWho),&HashEntriesCompare3);
|
||
else
|
||
QSort(lst,cnt,sizeof(CWho),&HashEntriesCompare);
|
||
|
||
if (idx) {
|
||
progress1_max=cnt;
|
||
progress1=0;
|
||
}
|
||
for (i=0;i<cnt;i++) {
|
||
comment=NULL;
|
||
ptr=lst[i].h;
|
||
if (idx)
|
||
if (cur_idx=lst[i].idx) {
|
||
if (StrCmp(cur_idx,last_idx)) {
|
||
Free(last_idx);
|
||
last_idx=StrNew(cur_idx);
|
||
if (i)
|
||
DocPrint(doc,"\n\n");
|
||
DocPrint(doc,"$$WW,0$$$$PURPLE$$$$TX+CX,\"%$$Q\"$$$$FG$$\n",cur_idx);
|
||
}
|
||
}
|
||
|
||
if (idx && 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) {
|
||
DocPrint(doc,"$$LK,\"%-20s\",A=\"%s\"$$",
|
||
ptr->str,ptr(CHashSrcSym *)->src_link);
|
||
if (idx)
|
||
comment=HelpComment(task,ptr,ptr(CHashSrcSym *)->src_link);
|
||
} else
|
||
DocPrint(doc,"%-20s",ptr->str);
|
||
|
||
if (!idx) {
|
||
if (ptr->type & HTT_DEFINE_STR) {
|
||
j=ptr(CHashDefineStr *)->cnt;
|
||
if (j==-1)
|
||
StrPrint(buf,"%-10t$$Q",ptr(CHashDefineStr *)->data);
|
||
else
|
||
StrPrint(buf,"%-10t$$Q %02X",ptr(CHashDefineStr *)->data,j);
|
||
} else if (ptr->type & HTT_GLBL_VAR)
|
||
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].idx);
|
||
if (idx)
|
||
progress1++;
|
||
}
|
||
Free(lst);
|
||
if (idx)
|
||
progress1=progress1_max=0;
|
||
|
||
wh_done:
|
||
if (doc) {
|
||
if (doc->head.next==doc)
|
||
DocPrint(doc,"No Match");
|
||
else
|
||
DocRecalc(doc);
|
||
}
|
||
Free(last_idx);
|
||
Kill(task);
|
||
}
|
||
|
||
#help_index "Info;Hash;Cmd Line (Typically)"
|
||
|
||
#define HDR_NUM 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_NUM];
|
||
CHash *tmph;
|
||
if (!table) table=Fs->hash_table;
|
||
MemSet(a,0,sizeof(a));
|
||
for (i=0;i<=table->mask;i++) {
|
||
tmph=table->body[i];
|
||
if (tmph) {
|
||
j=LinkedLstCnt(tmph);
|
||
if (j<HDR_NUM)
|
||
a[j]++;
|
||
cnt+=j;
|
||
if (j>longest)
|
||
longest=j;
|
||
}
|
||
}
|
||
"Histogram\n";
|
||
for (i=0;i<HDR_NUM;i++)
|
||
if (a[i])
|
||
"%02d:%d\n",i,a[i];
|
||
"Size:%dCount:%dLongest:%d\n",
|
||
table->mask+1,cnt,longest;
|
||
return longest;
|
||
}
|
||
|
||
#help_index "Help System"
|
||
#help_file "::/Doc/HelpSystem"
|
||
|
||
public U0 DocHelpIdx(CDoc *doc,U8 *idx)
|
||
{//Put to doc report for given help idx.
|
||
Who("+p",,idx,doc);
|
||
}
|
||
|
||
public U0 PopUpHelpIndex(U8 *idx,CTask *parent=NULL)
|
||
{//PopUp win report for given help idx.
|
||
U8 *buf;
|
||
buf=MStrPrint("DocHelpIdx(DocPut,\"%s\");View;",idx);
|
||
PopUp(buf,parent);
|
||
Free(buf);
|
||
}
|
||
|
||
#help_index "Hash/System"
|
||
public U0 MapFileLoad(U8 *filename)
|
||
{//Load map file so we have src line info.
|
||
U8 *st,*ptr,*name=ExtDft(filename,"MAP.Z"),
|
||
*absname=FileNameAbs(name);
|
||
CDoc *doc=DocRead(name);
|
||
CDocEntry *doc_e;
|
||
CHashSrcSym *tmph;
|
||
I64 i,j,base=0;
|
||
CDbgInfo *dbg_info;
|
||
|
||
FileExtRem(absname);
|
||
if (absname[1]==':' && StrLen(absname)>2 &&
|
||
(tmph=HashSingleTableFind(absname+2,Fs->hash_table,HTT_MODULE)))
|
||
base=tmph(CHashGeneric *)->user_data0+sizeof(CBinFile);
|
||
|
||
if (!doc) return;
|
||
doc_e=doc->head.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 (tmph=HashSingleTableFind(st,Fs->hash_table,HTG_SRC_SYM)) {
|
||
if (*doc_e->tag) {
|
||
Free(tmph->src_link);
|
||
tmph->src_link=doc_e->aux_str;
|
||
ptr=tmph->src_link;
|
||
if (ptr[0] && ptr[1] && ptr[2]==':') {
|
||
if (ptr[3]==':')
|
||
ptr[3]=blkdev.boot_drv_let;
|
||
else if (ptr[3]=='~')
|
||
ptr[3]=*blkdev.home_dir;
|
||
}
|
||
doc_e->aux_str=NULL;
|
||
}
|
||
if (tmph->type&(HTT_FUN|HTT_EXPORT_SYS_SYM) &&
|
||
!(dbg_info=tmph->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;
|
||
tmph->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);
|
||
}
|