Subversion Repositories pentevo

Rev

Blame | Last modification | View Log | Download | RSS feed | ?url?

  1. /* asmitree.c */
  2. /*****************************************************************************/
  3. /* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only                     */
  4. /*                                                                           */
  5. /* AS-Portierung                                                             */
  6. /*                                                                           */
  7. /* Opcode-Abfrage als Binaerbaum                                             */
  8. /*                                                                           */
  9. /* Historie: 30.10.1996 Grundsteinlegung                                     */
  10. /*            8.10.1997 Hash-Tabelle                                         */
  11. /*            6.12.1998 dynamisches Kopieren der Namen                       */
  12. /*                                                                           */
  13. /*****************************************************************************/
  14.  
  15. #include "stdinc.h"
  16. #include <string.h>
  17.  
  18. #include "chunks.h"
  19. #include "strutil.h"
  20. #include "asmdef.h"
  21. #include "asmsub.h"
  22.  
  23. #include "asmitree.h"
  24.  
  25. /*---------------------------------------------------------------------------*/
  26.  
  27. static int GetKey(const char *Name, LongWord TableSize)
  28. {
  29.   register unsigned char *p;
  30.   LongWord tmp = 0;
  31.  
  32.   for (p = (unsigned char *)Name; *p != '\0'; p++)
  33.     tmp = (tmp << 2) + ((LongWord)*p);
  34.   return tmp % TableSize;
  35. }
  36.  
  37. PInstTable CreateInstTable(int TableSize)
  38. {
  39.   int z;
  40.   PInstTableEntry tmp;
  41.   PInstTable tab;
  42.  
  43.   tmp = (PInstTableEntry) malloc(sizeof(TInstTableEntry) * TableSize);
  44.   for (z = 0; z < TableSize; z++)
  45.     tmp[z].Name = NULL;
  46.   tab = (PInstTable) malloc(sizeof(TInstTable));
  47.   tab->Fill = 0;
  48.   tab->Size = TableSize;
  49.   tab->Entries = tmp;
  50.   tab->Dynamic = FALSE;
  51.   tab->prefix_proc = NULL;
  52.   tab->prefix_proc_index = 0;
  53.   return tab;
  54. }
  55.  
  56. /*!------------------------------------------------------------------------
  57.  * \fn     inst_fnc_table_create(int table_size)
  58.  * \brief  create new instance of function table
  59.  * \param  table_size max. # of entries in table
  60.  * \return * to table
  61.  * ------------------------------------------------------------------------ */
  62.  
  63. inst_fnc_table_t *inst_fnc_table_create(int table_size)
  64. {
  65.   int z;
  66.   inst_fnc_table_entry_t *p_entries = NULL;
  67.   inst_fnc_table_t *p_ret = NULL;
  68.  
  69.   p_entries = (inst_fnc_table_entry_t*)calloc(table_size, sizeof(*p_entries));
  70.   if (!p_entries)
  71.     goto func_exit;
  72.   for (z = 0; z < table_size; z++)
  73.     p_entries[z].p_name = NULL;
  74.  
  75.   p_ret = (inst_fnc_table_t*) calloc(1, sizeof(*p_ret));
  76.   if (!p_ret)
  77.     goto func_exit;
  78.   p_ret->fill = 0;
  79.   p_ret->size = table_size;
  80.   p_ret->p_entries = p_entries; p_entries = NULL;
  81.   p_ret->dynamic = False;
  82.  
  83. func_exit:
  84.   if (p_entries)
  85.     free(p_entries);
  86.   return p_ret;
  87. }
  88.  
  89. void SetDynamicInstTable(PInstTable Table)
  90. {
  91.   Table->Dynamic = TRUE;
  92. }
  93.  
  94. void DestroyInstTable(PInstTable tab)
  95. {
  96.   int z;
  97.  
  98.   if (tab->Dynamic)
  99.     for (z = 0; z < tab->Size; z++)
  100.       free(tab->Entries[z].Name);
  101.  
  102.   free(tab->Entries);
  103.   free(tab);
  104. }
  105.  
  106. void AddInstTable(PInstTable tab, const char *Name, Word Index, InstProc Proc)
  107. {
  108.   LongWord h0 = GetKey(Name, tab->Size), z = 0;
  109.  
  110.   /* mindestens ein freies Element lassen, damit der Sucher garantiert terminiert */
  111.  
  112.   if (tab->Size - 1 <= tab->Fill)
  113.   {
  114.     fprintf(stderr, "\nhash table overflow\n");
  115.     exit(255);
  116.   }
  117.   while (1)
  118.   {
  119.     if (!tab->Entries[h0].Name)
  120.     {
  121.       int dest_index = 0;
  122.       tab->Entries[h0].Name = (tab->Dynamic) ? as_strdup(Name) : (char*)Name;
  123.       memset(tab->Entries[h0].Procs, 0, sizeof(tab->Entries[h0].Procs));
  124.       if (tab->prefix_proc)
  125.       {
  126.         tab->Entries[h0].Procs[dest_index] = tab->prefix_proc;
  127.         tab->Entries[h0].Indices[dest_index++] = tab->prefix_proc_index;
  128.       }
  129.       tab->Entries[h0].Procs[dest_index] = Proc;
  130.       tab->Entries[h0].Indices[dest_index++] = Index;
  131.       tab->Entries[h0].Coll = z;
  132.       tab->Fill++;
  133.       return;
  134.     }
  135.     if (!strcmp(tab->Entries[h0].Name, Name))
  136.     {
  137.       printf("%s double in table\n", Name);
  138.       exit(255);
  139.     }
  140.     z++;
  141.     if ((LongInt)(++h0) == tab->Size)
  142.       h0 = 0;
  143.   }
  144. }
  145.  
  146. void inst_table_set_prefix_proc(PInstTable tab, InstProc prefix_proc, Word prefix_proc_index)
  147. {
  148.   tab->prefix_proc = prefix_proc;
  149.   tab->prefix_proc_index = prefix_proc_index;
  150. }
  151.  
  152. /*!------------------------------------------------------------------------
  153.  * \fn     inst_fnc_table_add(inst_fnc_table_t *p_table, const char *p_name, Word index, inst_fnc_t fnc)
  154.  * \brief  augment table by one entry
  155.  * \param  p_table table to add to
  156.  * \param  p_name name of instruction
  157.  * \param  index callback argument
  158.  * \param  fnc callback itself
  159.  * ------------------------------------------------------------------------ */
  160.  
  161. void inst_fnc_table_add(inst_fnc_table_t *p_table, const char *p_name, Word index, inst_fnc_t fnc)
  162. {
  163.   LongWord tab_index = GetKey(p_name, p_table->size), num_coll = 0;
  164.  
  165.   /* mindestens ein freies Element lassen, damit der Sucher garantiert terminiert */
  166.  
  167.   if (p_table->size - 1 <= p_table->fill)
  168.   {
  169.     fprintf(stderr, "\nhash table overflow\n");
  170.     exit(255);
  171.   }
  172.   while (1)
  173.   {
  174.     if (!p_table->p_entries[tab_index].p_name)
  175.     {
  176.       p_table->p_entries[tab_index].p_name = (p_table->dynamic) ? as_strdup(p_name) : (char*)p_name;
  177.       p_table->p_entries[tab_index].fnc = fnc;
  178.       p_table->p_entries[tab_index].index = index;
  179.       p_table->p_entries[tab_index].coll = num_coll;
  180.       p_table->fill++;
  181.       return;
  182.     }
  183.     if (!strcmp(p_table->p_entries[tab_index].p_name, p_name))
  184.     {
  185.       printf("%s double in table\n", p_name);
  186.       exit(255);
  187.     }
  188.     num_coll++;
  189.     if ((LongInt)(++tab_index) == p_table->size)
  190.       tab_index = 0;
  191.   }
  192. }
  193.  
  194. void RemoveInstTable(PInstTable tab, const char *Name)
  195. {
  196.   LongWord h0 = GetKey(Name, tab->Size);
  197.  
  198.   while (1)
  199.   {
  200.     if (!tab->Entries[h0].Name)
  201.       return;
  202.     else if (!strcmp(tab->Entries[h0].Name, Name))
  203.     {
  204.       tab->Entries[h0].Name = NULL;
  205.       memset(tab->Entries[h0].Procs, 0, sizeof(tab->Entries[h0].Procs));
  206.       tab->Fill--;
  207.       return;
  208.     }
  209.     if ((LongInt)(++h0) == tab->Size)
  210.       h0 = 0;
  211.   }
  212. }
  213.  
  214. const TInstTableEntry *inst_table_search(PInstTable p_table, const char *p_name)
  215. {
  216.   LongWord h0 = GetKey(p_name, p_table->Size);
  217.  
  218.   while (1)
  219.   {
  220.     if (!p_table->Entries[h0].Name)
  221.       return NULL;
  222.     else if (!strcmp(p_table->Entries[h0].Name, p_name))
  223.       return &p_table->Entries[h0];
  224.     if ((LongInt)(++h0) == p_table->Size)
  225.       h0 = 0;
  226.   }
  227. }
  228.  
  229. void inst_table_exec(const TInstTableEntry *p_inst_table_entry)
  230. {
  231.   size_t index;
  232.  
  233.   for (index = 0; index < as_array_size(p_inst_table_entry->Procs); index++)
  234.     if (p_inst_table_entry->Procs[index])
  235.       p_inst_table_entry->Procs[index](p_inst_table_entry->Indices[index]);
  236.     else
  237.       return;
  238. }
  239.  
  240. Boolean LookupInstTable(PInstTable tab, const char *Name)
  241. {
  242.   const TInstTableEntry *p_inst_table_entry;
  243.  
  244.   p_inst_table_entry = inst_table_search(tab, Name);
  245.  
  246.   if (p_inst_table_entry)
  247.     inst_table_exec(p_inst_table_entry);
  248.   return !!p_inst_table_entry;
  249. }
  250.  
  251. /*!------------------------------------------------------------------------
  252.  * \fn     inst_fnc_table_lookup(const inst_fnc_table_t *p_table, const char *p_name)
  253.  * \brief  look up & execute instruction callback
  254.  * \param  p_table table with functions
  255.  * \param  p_name instruction name
  256.  * \return True if callback was found and executed
  257.  * ------------------------------------------------------------------------ */
  258.  
  259. Boolean inst_fnc_table_lookup(const inst_fnc_table_t *p_table, const char *p_name)
  260. {
  261.   LongWord index = GetKey(p_name, p_table->size);
  262.  
  263.   while (1)
  264.   {
  265.     if (!p_table->p_entries[index].p_name)
  266.       return False;
  267.     else if (!strcmp(p_table->p_entries[index].p_name, p_name))
  268.       return p_table->p_entries[index].fnc(p_table->p_entries[index].index);
  269.     if ((LongInt)(++index) == p_table->size)
  270.       index = 0;
  271.   }
  272. }
  273.  
  274. void PrintInstTable(FILE *stream, PInstTable tab)
  275. {
  276.   int z;
  277.  
  278.   for (z = 0; z < tab->Size; z++)
  279.     if (tab->Entries[z].Name)
  280.       fprintf(stream, "[%3d]: %-10s Index %4d Coll %2d\n", z,
  281.              tab->Entries[z].Name, tab->Entries[z].Indices[0], tab->Entries[z].Coll);
  282. }
  283.  
  284. /*----------------------------------------------------------------------------*/
  285.  
  286. void asmitree_init(void)
  287. {
  288. }
  289.