A TempleOS distro for heretics
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.
 
 
 
 

433 lines
9.7 KiB

#help_index "Info;Hash/System;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) {
if (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;
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++;
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 *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,f=0;
U8 buf[512],*st,*last_index=StrNew(""),*cur_index,*comment;
Bool recurse,publics,map,old_preempt=Preempt;
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 (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;
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) {
DocPrint(doc,"$$LK,\"%-20s\",A=\"%s\"$$",
ptr->str,ptr(CHashSrcSym *)->src_link);
if (index)
comment=HelpComment(task,ptr,ptr(CHashSrcSym *)->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)
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) {
if (doc->root.next==doc)
DocPrint(doc,"No Match");
else
DocRecalc(doc);
}
Free(last_index);
Kill(task);
}
#help_index "Info;Hash;Cmd Line (Typically)"
#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"
#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/System"
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);
}