head	1.1;
access;
symbols;
locks;
comment	@ * @;


1.1
date	93.07.02.18.26.52;	author wolff;	state Exp;
branches;
next	;


desc
@@


1.1
log
@Initial revision
@
text
@/* Module from C. Bergmann */
#include "basic.h"
#include "pool.h"
#include <stdlib.h>
#include <string.h>

#define hashprime 1999

char *pool;
long id, position, length;

static long csize, cp, isize, ifree, fre;

static char csymbol[256];
static char *cinfo[256];
static char *symbol;
static long *name,*len,*link;
static char **info;

void pool_set(identifier)
     long identifier;
{
  id=identifier;
  if (id)
    if (id<0) { position=0; length=1; pool[0]=id+256; }
    else { position=name[id-1]; length=len[id-1]; }
  else { position=0; length=0; }
}

void pool_new()
{
  id=0; position=cp; length=0;
}

void pool_put(str,len)
     char *str;
     long len;
{
  while (csize-cp-length<=len) { csize<<=1; pool=(char *)realloc(pool,csize); }
  memcpy(pool+(cp+length),str,len);
  length+=len;
}

static void insert()
{
  len[id]=length; link[id]=-1; name[id]=cp; cp+=length+1;
  id++; symbol[id]='\0'; info[id]=NULL;
}

static void blow_up() /* Doubles isize and reallocates the arrays. */
{
  long old;

  old=isize; isize<<=1; ifree+=old;
  name=(long *)realloc((char *)name,isize*sizeof(long));
  len=(long *)realloc((char *)len,isize*sizeof(long));
  link=(long *)realloc((char *)link,isize*sizeof(long));
  symbol=(char *)realloc(symbol,isize+1);
  info=(char **)realloc((char *)info,isize*sizeof(char *));
  memset(len+old,0,old*sizeof(long));
}

void pool_id()
{
  long n,i;

  pool[cp+length]='\0';
  if (length<0 || cp!=position) exit(1);
  if (length==0) id=0;
  else if (length==1) id=(long)((unsigned char)pool[cp])-256;
  else {
    /* compute hash number */
    n=cp; id=(long)((unsigned char)pool[n]);
    for (i=1; i<length; i++) {
      id+=id+(long)((unsigned char)pool[++n]);
      while (id>=hashprime) id-=hashprime;
      i++;
    }
    while (1) {
      if (len[id]==0) {
	insert(); return;
      }
      if (len[id]==length && !strncmp(pool+cp,pool+name[id],length)) {
	id++; return;
      }
      if (link[id]<0) {
	if (ifree==0) blow_up();
	ifree--;
	while (len[fre]) fre++;
	link[id]=fre; id=fre++;
	insert(); return;
      }
      id=link[id];
    }
  }
}

char pool_sym(sym)
     char sym;
{
  if (id<0) return csymbol[id+256]?csymbol[id+256]:(csymbol[id+256]=sym);
  return symbol[id]?symbol[id]:(symbol[id]=sym);
}

void pool_change_sym(sym) /* ändert ein Symbol für die aktuelle id By M. Horstmann */
     char sym;
{
  if (id<0)
   (csymbol[id+256]=sym);
  else
   (symbol[id]=sym);
}

char *pool_info()
{
  if (id<0) return cinfo[id+256];
  return info[id];
}

void pool_set_info(i)
     char *i;
{
  if (id<0) cinfo[id+256]=i;
  else info[id]=i;
}

void pool_init()
{
  ifree=hashprime/3; isize=hashprime+ifree+1; fre=hashprime;
  cp=2; csize=isize<<3;
  pool=(char *)malloc(csize);
  name=(long *)malloc(isize*sizeof(long));
  link=(long *)malloc(isize*sizeof(long));
  len=(long *)malloc(isize*sizeof(long));
  symbol=(char *)malloc(isize+1);
  info=(char **)malloc(isize*sizeof(char *));
  memset(len,0,isize*sizeof(long));
  memset(csymbol,'\0',256);
  memset(cinfo,'\0',256*sizeof(char *));
  pool[0]=pool[1]='\0';
}

void pool_free()
{
  (void)free(pool);
  (void)free((char *)name);
  (void)free((char *)len);
  (void)free((char *)link);
  (void)free(symbol);
}
@
