/***********************************************
 (C) Copyright 1992-1993; dit/upm
   Distributed under the conditions stated in the
   EPS General Public License (see file LICENSE)
 ***********************************************
 $Log: clrids.c,v $
 * Revision 2.4  1993/01/12  16:34:20  eps
 * portability issues
 *
 * Revision 2.3  1992/11/17  11:47:31  eps
 * fix definition of *alloc for PC portability
 *
 * Revision 2.2  1992/01/14  15:42:57  eps
 * distribution issues
 *
 * Revision 2.1  90/10/30  08:32:28  eps
 * hardwired colours added
 * new colours I2, IAT, AT
 * ! is no longer used as colour delimiter
 * still some bugs are known w.r.t. colour deallocation
 * 
 * Revision 1.5  90/05/10  17:12:23  eps
 * change colour delimiters from !...! into {...}
 * 
 * Revision 1.4  90/03/16  15:53:50  eps
 * get and put do direct file access
 * 
 * Revision 1.3  90/02/19  19:09:07  eps
 * minor over-allocation of SNODEs fixed
 * 
 * Revision 1.2  90/01/29  14:51:46  eps
 * fixing license details
 * 
 * Revision 1.1  90/01/25  17:59:55  eps
 * Initial revision
 * 
 **********************************************/

#ifndef lint
static char rcsid[]= "$Id: clrids.c,v 2.4 1993/01/12 16:34:20 eps Exp $";
#endif

/***********************************************************************
      Tomas P. de Miguel Moro
      Jose A. Manas
      dpt. Ingenieria Telematica
      E.T.S.I. Telecomunicacion
      Ciudad Universitaria
      E-28040  MADRID

      tmiguel@dit.upm.es
      jmanas@dit.upm.es

      functions for colours that are identifiers
      [uses a hashing scheme]
**********************************************************************/

/* LINTLIBRARY */

# define cast_IMP
# include "cast.hh"

/* KJT 13/02/12: Added */
# include <string.h>
# include <stdio.h>

# define HASHSIZE 1008		/* some odd number */

/**
  * Selecting a Hashing Algorithm
  * B.J. McKenzie, R. Harries, and T. Bell
  * Software Practice & Experience
  * vol. 20(2), 209-224, Feb. 1990
 */

typedef struct Snode {
  char		*name;
  struct Snode	*next;
} SNODE;

PRIVATE SNODE *hashtab [HASHSIZE];

PRIVATE void
hashinit () 
{
  int i;

  for (i= 0; i < HASHSIZE; i++)
    hashtab[i]= NULL;
}

PRIVATE int
hash (id)	/* computes a hash index for an id */
     char *id;
{
  int h;
	 
  h= 0;
  while (*id != 0)
    h= 4*h + *(id++);
  h%= HASHSIZE;
  if (h < 0)
    h+= HASHSIZE;
  return h;
}

PUBLIC char*
newid (id)
     char *id;
{
  static int first= TRUE;
  int h;
  SNODE *n;

  if (first) {
    hashinit ();
    first= FALSE;
  }
  h= hash (id);
  for (n= hashtab[h]; n != NULL; n= n->next)
    if (strcmp (id, n->name) == 0)
      return n->name;
  n= (SNODE*) malloc (sizeof (SNODE));
  if (n == NULL)
    fatal ("newid: run out of memory");
  n->name= str_alloc (id);
  n->next= hashtab[h];
  hashtab[h]= n;
  return n->name;
}

PUBLIC CLR_TYPE
getlexv (fp)
    FILE* fp;
{
  return ((CLR_TYPE) newid ((char*) getstring (fp)));
}

PUBLIC void
putlexv (fp, val)
    FILE* fp;
    CLR_TYPE val;
{
  putstring (fp, val);
}
