#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); }