/****************************************************************************/
/*                                                                          */
/*                      Chaine de CAO & VLSI   Alliance                     */
/*                                                                          */
/*    Produit : DESB  v2.n                                                  */
/*    Fichier : vh_util.c                                                   */
/*                                                                          */
/*    (c) copyright 1991 Laboratoire MASI equipe CAO & VLSI                 */
/*    Tous droits reserves                                                  */
/*    Support : e-mail cao-vlsi@masi.ibp.fr                                 */
/*                                                                          */
/*    Auteur(s) : Marc LAURENTIN                        le : 06/09/1991     */
/*                                                                          */
/*    Modifie par :                                     le : ../../....     */
/*    Modifie par :                                     le : ../../....     */
/*    Modifie par :                                     le : ../../....     */
/*                                                                          */
/****************************************************************************/

#include"head.h"

static struct dct_entry **vhu_initab ()

  {
  struct dct_entry **head;
  int                i;

  head = (struct dct_entry **)
         mbkalloc (sizeof(struct dct_entry *) * VHU_HSZDFN);

  for (i=0 ; i<VHU_HSZDFN ; i++)
    head[i] = NULL;

  return (head);
  }

static void vhu_addtab (head,key_str,ctx_str,field,valu)

struct dct_entry **head;
char              *key_str;
char              *ctx_str;
int                field;
int                valu;

  {
  int               found = 0;
  int               index;
  struct dct_entry *entry_pnt;
  struct dct_recrd *recrd_pnt;

  index     = (int) key_str % VHU_HSZDFN;
  entry_pnt = head[index];

  while (entry_pnt != NULL)
    {
    if (entry_pnt->key == key_str)
      {
      found = 1;
      break;
      }
    entry_pnt = entry_pnt->next;
    }

  if (found == 0)
    {
    head[index] = vhu_addent (head[index],key_str); 
    entry_pnt = head[index]; 
    }

  found = 0;
  recrd_pnt = entry_pnt->data;
  while (recrd_pnt != NULL)
    {
    if (recrd_pnt->key == ctx_str)
      {
      found = 1;
      break;
      }
    recrd_pnt = recrd_pnt->next;
    }

  if (found == 0)
    {
    entry_pnt->data = vhu_addrcd (entry_pnt->data,ctx_str); 
    recrd_pnt       = entry_pnt->data ;
    }

  switch (field)
    {
    case 0 :
      recrd_pnt->fd0_val = valu;
      break;
    case 1 :
      recrd_pnt->fd1_val = valu;
      break;
    case 2 :
      recrd_pnt->fd2_val = valu;
      break;
    case 3 :
      recrd_pnt->fd3_val = valu;
      break;
    case 4 :
      recrd_pnt->fd4_val = valu;
      break;
    case 5 :
      recrd_pnt->fd5_val = valu;
      break;
    case 6 :
      recrd_pnt->fd6_val = valu;
      break;
    case 7 :
      recrd_pnt->pnt_val = valu;
      break;
    }

  }

static int vhu_chktab (head,key_str,ctx_str,field)

struct dct_entry **head;
char              *key_str;
char              *ctx_str;
int                field;

  {
  int               found = 0;
  int               valu = 0;
  struct dct_entry *entry_pnt;
  struct dct_recrd *recrd_pnt;

  entry_pnt = head [(int)key_str % VHU_HSZDFN];

  while (entry_pnt != NULL)
    {
    if (entry_pnt->key == key_str)
      {
      found = 1;
      break;
      }
    entry_pnt = entry_pnt->next;
    }

  if (found == 1)
    {
    found = 0;
    recrd_pnt = entry_pnt->data;
    while (recrd_pnt != NULL)
      {
      if (recrd_pnt->key == ctx_str)
        {
        found = 1;
        break;
        }
      recrd_pnt = recrd_pnt->next;
      }
    if (found == 1)
      {
      switch (field)
        {
        case 0 :
          valu = recrd_pnt->fd0_val;
          break;
        case 1 :
          valu = recrd_pnt->fd1_val;
          break;
        case 2 :
          valu = recrd_pnt->fd2_val;
          break;
        case 3 :
          valu = recrd_pnt->fd3_val;
          break;
        case 4 :
          valu = recrd_pnt->fd4_val;
          break;
        case 5 :
          valu = recrd_pnt->fd5_val;
          break;
        case 6 :
          valu = recrd_pnt->fd6_val;
          break;
        case 7 :
          valu = recrd_pnt->pnt_val;
          break;
        }
      }
    }

  return (valu);
  }

static void vhu_fretab (pt_hash)

struct dct_entry **pt_hash;
  {
  struct dct_entry *pt_entry;
  struct dct_entry *pt_nxtentry;
  struct dct_recrd *pt_record;
  int               i;

  if (pt_hash != NULL)
    {
    for (i=0 ; i<VHU_HSZDFN ; i++)
      {
      if ((pt_entry = pt_hash[i]) != NULL)
        {
        while (pt_entry != NULL)
          {
          pt_record = pt_entry->data;

          while (pt_record->next != NULL)
            pt_record = pt_record->next;

          pt_record->next = VHU_DCRHED;
          VHU_DCRHED      = pt_entry->data;

          pt_nxtentry     = pt_entry->next;
          pt_entry->next  = VHU_DCEHED;
          VHU_DCEHED      = pt_entry;
          pt_entry        = pt_nxtentry;
          }
        }
      }
    free (pt_hash);
    }
  }

static struct dct_entry *vhu_addent (head , key)

struct dct_entry *head;
char             *key;

  {
  struct dct_entry *entry;
  int               i;

  if (VHU_DCEHED == NULL)
    {
    VHU_DCEHED = (struct dct_entry *)
                 mbkalloc (sizeof(struct dct_entry) * VHU_ALODFN);

    entry = VHU_DCEHED;
    for (i=1 ; i<VHU_ALODFN ; i++)
      {
      entry->next = entry + 1;
      entry++;
      }
    entry->next = NULL;
    }

  entry       = VHU_DCEHED;
  VHU_DCEHED  = VHU_DCEHED->next;

  entry->next = head;
  entry->data = NULL;
  entry->key  = key;

  return (entry);
  }

static struct dct_recrd *vhu_addrcd (head , key)

struct dct_recrd *head;
char             *key;

  {
  struct dct_recrd *recrd;
  int               i;

  if (VHU_DCRHED == NULL)
    {
    VHU_DCRHED = (struct dct_recrd *)
                 mbkalloc (sizeof(struct dct_recrd) * VHU_ALODFN);

    recrd = VHU_DCRHED;
    for (i=1 ; i<VHU_ALODFN ; i++)
      {
      recrd->next = recrd + 1;
      recrd++;
      }
    recrd->next = NULL;
    }

  recrd           = VHU_DCRHED;
  VHU_DCRHED      = VHU_DCRHED->next;

  recrd->next     = head;
  recrd->fd0_val  = 0;
  recrd->fd1_val  = 0;
  recrd->fd2_val  = 0;
  recrd->fd3_val  = 0;
  recrd->fd4_val  = 0;
  recrd->fd5_val  = 0;
  recrd->fd6_val  = 0;
  recrd->pnt_val  = 0;
  recrd->key      = key;

  return (recrd);
  }

char *vhdlname (name)

char *name;

  {
  char                     *new_name;
  char                     *prv_name;
  char                     *tmp_name;
  char                      buffer[200];
  int                       i,j,flag,number;
  static struct dct_entry **namtab=NULL;

  if (namtab == NULL)
    namtab = vhu_initab ();

  tmp_name = namealloc (name);
  new_name = (char *) vhu_chktab (namtab,tmp_name,NULL,VHU_PNTDFN);

  if (vhu_chktab (namtab,tmp_name,NULL,VHU_NAMDFN) == 0)
    {
    i = 0;
    j = 0;
    number = 0;
    flag = 1;
    while (tmp_name[i] != '\0')
      {
      buffer[j] = tmp_name[i];
      if ( ((tmp_name[i] >= 'a') && (tmp_name[i] <= 'z')) ||
           ((tmp_name[i] >= 'A') && (tmp_name[i] <= 'Z')) ||
           ((tmp_name[i] == '(') || (tmp_name[i] == ')')) ||
           ((tmp_name[i] >= '0') && (tmp_name[i] <= '9') && (i != 0)))
        flag = 0;
      else
        {
        if (flag == 1)
          buffer[j++] = 'v';
        buffer[j] = '_';
        flag = 1;
        }
      i++;
      j++;
      }
    if (buffer[j-1] == '_')
      buffer[j++] = '0';
    buffer[j] = '\0';
    new_name = namealloc (buffer);

    prv_name = new_name;
    while (vhu_chktab (namtab,new_name,NULL,VHU_NEWDFN) != 0)
      {
      new_name = prv_name;
      sprintf (buffer,"%s_%d",new_name,number++);
      prv_name = new_name;
      new_name = namealloc (buffer);
      }
    vhu_addtab (namtab,new_name,NULL,VHU_NEWDFN,1);
    vhu_addtab (namtab,tmp_name,NULL,VHU_PNTDFN,(int)new_name);
    vhu_addtab (namtab,tmp_name,NULL,VHU_NAMDFN,1);
    }

  return (new_name);
  }
