hschumann2/TempleOS-Source-Code
0838
1 2I64 HashTypeNum(CHash *tmph)3{//Return bit num of hash type, limited to just types.4 if (tmph)5 return Bsf(tmph->type&HTG_TYPE_MASK);6 else7 return -1;8}9 10I64 HashVal(CHash *tmph)11{//Returns most likely desired value.12 switch [HashTypeNum(tmph)] {13 case HTt_EXPORT_SYS_SYM:14 return tmph(CHashExport *)->val;15 case HTt_IMPORT_SYS_SYM:16 return tmph(CHashImport *)->module_base;17 case HTt_DEFINE_STR:18 case HTt_CLASS:19 case HTt_INTERNAL_TYPE:20 case HTt_WORD:21 case HTt_DICT_WORD:22 case HTt_OPCODE:23 case HTt_HELP_FILE:24 return tmph;25 case HTt_GLBL_VAR:26 if (tmph(CHashGlblVar *)->flags&GVF_EXTERN)27 return &tmph(CHashGlblVar *)->data_addr;28 else29 return tmph(CHashGlblVar *)->data_addr;30 case HTt_FUN:31 if (Bt(&tmph(CHashFun *)->flags,Cf_EXTERN))32 return tmph;33 else34 return tmph(CHashFun *)->exe_addr;35 case HTt_REG:36 return tmph(CHashReg *)->reg_num|tmph(CHashReg *)->reg_type<<8;37 case HTt_KEYWORD:38 case HTt_ASM_KEYWORD:39 case HTt_MODULE:40 case HTt_FILE:41 case HTt_FRAME_PTR:42 return tmph(CHashGeneric *)->user_data0;43 44 case -1: //nobound switch45 case HTt_TYPES_NUM: //nobound switch46 default:47 return 0;48 }49}50 51CHashTable *HashTableNew(I64 size,CTask *mem_task=NULL)52{//New hash table, power-of-two in size.53 CHashTable *table;54 table=CAlloc(sizeof(CHashTable),mem_task);55 table->body=CAlloc(size<<3,mem_task);56 table->mask=size-1;57 return table;58}59 60U0 HashDel(CHashSrcSym *tmph)61{//Free a std TempleOS system hash entry.62 if (!tmph) return;63 if (!(tmph->type&HTT_DICT_WORD))64 Free(tmph->str);65 if (tmph->type & HTG_SRC_SYM) {66 Free(tmph->src_link);67 Free(tmph->idx);68 Free(tmph->import_name);69 LinkedLstDel(tmph->ie_lst);70 if (tmph->type & (HTT_FUN | HTT_EXPORT_SYS_SYM))71 Free(tmph->dbg_info);72 if (tmph->type & (HTT_FUN | HTT_CLASS))73//Assumes code not on heap, so doesn't Free.74 //ClassMemberLstDel() is an import to the Kernel module75 ClassMemberLstDel(tmph);76 else if (tmph->type&HTT_DEFINE_STR)77 Free(tmph(CHashDefineStr *)->data);78 else if (tmph->type & HTT_GLBL_VAR) {79 if (!(tmph(CHashGlblVar *)->flags&GVF_ALIAS))80 Free(tmph(CHashGlblVar *)->data_addr);81 LinkedLstDel(tmph(CHashGlblVar *)->dim.next);82 if (tmph(CHashGlblVar *)->fun_ptr)83 HashDel(tmph(CHashGlblVar *)->fun_ptr84 -tmph(CHashGlblVar *)->fun_ptr->ptr_stars_cnt);85 }86 } else if (tmph->type & HTT_FILE)87 Free(tmph(CHashGeneric *)->user_data0);88 Free(tmph);89}90 91U0 HashTableDel(CHashTable *table)92{//Free std system hash table, calling HashDel() on entries.93 I64 i;94 CHashSrcSym *tmph,*tmph1;95 if (!table) return;96 for (i=0;i<=table->mask;i++) {97 tmph=table->body[i];98 while (tmph) {99 tmph1=tmph->next;100 HashDel(tmph);101 tmph=tmph1;102 }103 }104 Free(table->body);105 Free(table);106}107 108I64 HashTablePurge(CHashTable *table)109{//Eliminate ExportSysSyms that have been usurped.110 I64 i,res=0;111 CHashSrcSym *tmph,*tmph1,*tmph2;112 if (!table) return 0;113 PUSHFD114 CLI //Precaution115 for (i=0;i<=table->mask;i++) {116 tmph=table->body[i];117 while (tmph) {118 tmph1=tmph->next; //We delete only older ones119 if (tmph->type&(HTT_FUN|HTT_GLBL_VAR)) {120 tmph2=tmph->next; //Older always later in chain121 while (tmph2) {122 if ((tmph2->type&HTT_EXPORT_SYS_SYM ||123 tmph2->type&HTG_TYPE_MASK==HTT_INVALID) &&124 !StrCmp(tmph2->str,tmph->str)) {125 if (tmph2->type&HTG_TYPE_MASK==HTT_INVALID)126 tmph2->type=HTT_KEYWORD;//Won't delete HTT_INVALID127 HashRemDel(tmph2,table);128 res++;129 break;130 }131 tmph2=tmph2->next;132 }133 }134 tmph=tmph1;135 }136 }137 POPFD138 return res;139}140 141CHashGeneric *HashGenericAdd(U8 *name,I64 type,142 I64 u0=0,I64 u1=0,I64 u2=0,CTask *task=NULL)143{//Add any type to task hash_table, 3 user_data values.144 if (!task) task=Fs;145 CHashGeneric *res=CAlloc(sizeof(CHashGeneric),task);146 res->type=type;147 res->user_data0=u0;148 res->user_data1=u1;149 res->user_data2=u2;150 res->str=StrNew(name,task);151 HashAdd(res,task->hash_table);152 return res;153}154 155U0 HashSrcFileSet(CCmpCtrl *cc,CHashSrcSym *h,I64 line_num_offset=0)156{//Set CHashSrcSym link and help_index by cur cc pos.157 CLexFile *tmpf=cc->lex_include_stk;158 I64 line_num=tmpf->line_num+line_num_offset;159 if (line_num<1) line_num=1;160 Free(h->src_link);161 h->src_link=MStrPrint("FL:%s,%d",tmpf->full_name,line_num);162 if (Bt(&cc->opts,OPTf_KEEP_PRIVATE))163 h->type|=HTF_PRIVATE;164 Free(h->idx);165 if (cc->cur_help_idx && *cc->cur_help_idx)166 h->idx=StrNew(cc->cur_help_idx);167 else168 h->idx=NULL;169}170 171CHashGeneric *HashPublic(U8 *st,I64 mask,Bool val=TRUE)172{//Mark a hash entry as public and HashSrcFileSet().173 CHashGeneric *res;174 if (res=HashFind(st,Fs->hash_table,mask)) {175 if (val)176 res->type|=HTF_PUBLIC;177 else178 res->type&=~HTF_PUBLIC;179 if (res->type&HTG_SRC_SYM)180 HashSrcFileSet(Fs->last_cc,res);181 return res;182 } else183 return NULL;184}185 186I64 HashLstAdd(U8 *lst,I64 type,CHashTable *table)187{//Add a list to a hash table.188 I64 i=0;189 CHashGeneric *tmph;190 if (lst) {191 while (*lst) {192 if (*lst=='@')193 lst++;194 else195 i++;196 tmph=CAlloc(sizeof(CHashGeneric));197 tmph->user_data0=i-1;198 tmph->str=StrNew(lst);199 tmph->type=type;200 HashAdd(tmph,table);201 while (*lst++);202 }203 }204 return i;205}206 207I64 HashDefineLstAdd(U8 *dname,I64 type,CHashTable *table)208{//Add define list to a hash table. See ::/Adam/DolDoc/DocInit.HC.209 CHashDefineStr *tmph;210 if (tmph=HashFind(dname,Fs->hash_table,HTT_DEFINE_STR))211 return HashLstAdd(tmph->data,type,table);212 else213 return 0;214}215 216I64 FramePtr(U8 *name,CTask *task=NULL)217{//Find entry in task->hash_table, Return user_data.218 CHashGeneric *tmph;219 if (!task) task=Fs;220 if (tmph=HashFind(name,task->hash_table,HTT_FRAME_PTR))221 return tmph->user_data0;222 else223 return 0;224}225 226CHashGeneric *FramePtrAdd(U8 *name,I64 val=0,CTask *task=NULL)227{//Add named value to task->hash_table.228 return HashGenericAdd(name,HTT_FRAME_PTR,val,0,0,task);229}230 231I64 FramePtrSet(U8 *name,I64 val,CTask *task=NULL)232{//Find hash entry in task->hash_table. Change user_data0.233 CHashGeneric *tmph;234 if (!task) task=Fs;235 if (tmph=HashFind(name,task->hash_table,HTT_FRAME_PTR))236 return LXchgI64(&tmph->user_data0,val);237 else238 return 0;239}240 241I64 FramePtrDel(U8 *name,CTask *task=NULL)242{//Remove entry and delete.243 CHashGeneric *tmph;244 I64 res=0;245 if (!task) task=Fs;246 if (tmph=HashFind(name,task->hash_table,HTT_FRAME_PTR)) {247 res=tmph->user_data0;248 HashRemDel(tmph,task->hash_table);249 }250 return res;251}252 