#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "struct.h"
/*
* Vocab.c: Version 1.08
* Author: Alan Cox
* Last Changed: 2/6/90
*
* Purpose:
* Manages the system vocabulary lists. Finds, adds and deletes
* vocabulary entries, whle maintaing the vocabulary lists and usage
* counters.
*
* Bugs & Limits
* stricmp assumes ASCII set and can be fooled. Really needs
* a #ifdef ANSI to remove it on ANSI systems.
*
* Functions Provided:
* AddWord,DelWord,FindWord,FindNumWord,stricmp,ResolveWord
* Functions Used:
* Allocator:estralloc,Allocator:emalloc
*
*/
extern char *estralloc();
static struct Word *WordList=NULL; /* Vocabulary linked list */
static void LockWord(wp)
struct Word *wp;
{
wp->wd_Use++;
}
/*
* Add a word to the system vocabulary, or if it exists increase its
* usage count.
*/
void AddWord(x,v,t)
char *x;
int t;
tag v;
{
extern struct Word *FindWord();
struct Word *nwd=FindWord(x,t);
if(nwd)
{
LockWord(nwd);
return;
}
nwd=(struct Word *)emalloc(sizeof(struct Word));
nwd->wd_Text=estralloc(x);
nwd->wd_Type=t;
nwd->wd_Code=v;
nwd->wd_Use=1;
nwd->wd_Next=WordList;
WordList=nwd;
}
/*
* Reduce usage count of a word, and remove if nothing left.
*/
void DelWord(wp)
struct Word *wp;
{
struct Word *w=WordList;
wp->wd_Use--;
if(wp->wd_Use)
return;
if(w==wp)
{
WordList=w->wd_Next;
free(wp->wd_Text);
free(wp);
return;
}
while(w->wd_Next!=NULL)
{
if(w->wd_Next==wp)
{
w->wd_Next=w->wd_Next->wd_Next;
free(wp->wd_Text);
free(wp);
return;
}
w=w->wd_Next;
}
fprintf(stderr,"[SYSTEM ERROR]: DelWord - Trash pointer\n");
}
/*
* Find a word in the vocabulary
*/
struct Word *FindWord(x,t)
char *x;
int t;
{
struct Word *w=WordList;
/* if(Me()==1) UPrintf("Looking for '%s' type %d.\n",x,t);*/
while(w)
{
if((t==w->wd_Type||t==0)&&stricmp(w->wd_Text,x)==0)
return(w);
w=w->wd_Next;
}
return(NULL);
}
/*
* Find a word by word number in the vocabulary
*/
struct Word *FindNumWord(x,t)
int x;
int t;
{
struct Word *w=WordList;
while(w)
{
if((t==w->wd_Type||t==0)&&VAL(w->wd_Code)==x)
return(w);
w=w->wd_Next;
}
return(NULL);
}
/*
* Reasonably fast case independant string compare. This can be fooled
* by some system characters - works fine for normal characters
* Assumes ascii - FIX ME
*/
int stricmp(x,y)
char *x,*y;
{
while(*x)
{
if(!*y)
return(1);
if((*x&~32)!=(*y&~32))
return(1);
x++;
y++;
}
if(*y)
return(1);
return(0);
}
tag ResolveWord(x)
char *x;
{
int vt;
struct Word *w;
switch(*x)
{
case 'V':;
case 'v':vt=1;break;
case 'A':;
case 'a':vt=2;break;
case 'N':;
case 'n':vt=3;break;
case 'P':;
case 'p':vt=4;break;
default:ELine();
fprintf(stderr,"[ERROR]: Unknown word type in '%s.\n",x);
break;
}
w=FindWord(x+2,vt);
if(!w)
{
ELine();
fprintf(stderr,"[ERROR]: Unknown word for '%s.\n",x);
exit(0);
}
return(w->wd_Code);
}