#include "Structures.h" #include <regex.h> #pragma implementation long hps=0; h_pair::h_pair(String* in, Value* val, h_pair* nxt){ index = in; data = val; next = nxt; } h_pair::~h_pair(){ delete index; data->release(); } StringValHash::StringValHash(){ int i; for (i=0 ; i<HASH_WIDTH ; i++) htable[i] = (h_pair*) NULL; } StringValHash::~StringValHash(){ h_pair* hl, *next; int i; for (i = 0 ; i<HASH_WIDTH ; i++) for (hl = htable[i] ; hl ; hl=next) {next=hl->next; delete hl;} } #define HASH(a) ((*(a)) ? (((a)[0] ^ ~(a)[1]) & 3) : 0) Value* StringValHash::lookup (String* instring){ char* searchstr; int l, i; h_pair* hl; l = instring->length(); searchstr = (char*)instring->chars(); i = HASH(searchstr); for (hl = htable [ HASH(searchstr) ] ; hl && (hl->index->length() <= l) ; hl=hl->next) {if (! fcompare (*instring, *(hl->index))) return (hl->data);} return NULL; } int StringValHash::add (Value* inval, String* key){ h_pair* *temp; h_pair *newnode; char* searchstr; int l; l = key->length(); searchstr = (char*)key->chars(); for (temp = &(htable [HASH(searchstr)]); *temp && ((*temp)->index->length() <= l); temp = &((*temp)->next)) if (!fcompare (*((*temp)->index) , *key)) {(*temp)->data->release(); (*temp)->data = inval->grab(); return 1;} newnode = new h_pair (new String (*key), inval->grab(), *temp); (*temp) = newnode; return 0; } int StringValHash::remove (String* sym){ h_pair **temp, *next; char* searchstr; int l; searchstr = (char*)sym->chars(); l = sym->length(); for (temp = &(htable [HASH(searchstr)]) ; *temp && ((*temp)->index->length() <= l) ; temp = &((*temp)->next)) if (!fcompare (*((*temp)->index) , *sym)) {next = ((*temp)->next); delete (*temp); *temp = next; return 1;} return 0; } Value* StringValHash::list_vars(){ int i; h_pair* ht = NULL; Value* retval = NULL; Val_List* outlist = NULL; for (i=0 ; i<HASH_WIDTH ; i++) for (ht = htable[i] ; ht ; ht=ht->next) {outlist = new Val_List ((new Value (new String (*ht->index), SYM)), outlist);} retval = new Value (outlist); return retval; }; void StringValHash::dump_to_stdout(){ int i; h_pair* ht = NULL; Value* tempval; for (i=0 ; i<HASH_WIDTH ; i++) for (ht = htable[i] ; ht ; ht=ht->next) {cout << *(ht->index) << "\n"; tempval = ht->data->copy(); tempval->print_val(); delete tempval; cout << "\n/\n";} } char* StringValHash::pack_syms(char* buf){ int i; h_pair* h; for (i=0 ; i<HASH_WIDTH ; i++) for (h = htable[i] ; h ; h=h->next) {strcpy (buf , (char*)h->index->chars()); buf += h->index->length() + 1; buf = h->data->pack_value(buf);} *buf = '\0'; return (buf+1); } /************************************************************ ******** SymVal_List functions: **************************** ************************************************************/ SymVal_List::SymVal_List(){ pair_list = NULL; } SymVal_List::~SymVal_List(){ struct svl_rep* temp; while (pair_list) pop(); } void SymVal_List::push (String* s, Value* v){ struct svl_rep* temp; temp = new struct svl_rep; temp->symbol = new String (*s); temp->val = v->grab(); temp->next = pair_list; pair_list = temp; } void SymVal_List::pop (){ struct svl_rep* temp; if (pair_list) {temp = pair_list->next; pair_list->val->release(); delete pair_list->symbol; delete pair_list; pair_list = temp;} } Value* SymVal_List::peek (){ if (pair_list) return pair_list->val; return NULL; } String* SymVal_List::peek_symbol (){ if (pair_list) return pair_list->symbol; return NULL; } Value* SymVal_List::lookup (String* s){ struct svl_rep* temp, *prev; int i; for (i=0, temp=pair_list ; temp ; prev = temp, temp=temp->next, i++) if (*s == *(temp->symbol)) return temp->val; return NULL; } int SymVal_List::assign (String* s, Value* v){ struct svl_rep* temp; for (temp=pair_list ; temp ; temp=temp->next) if (*s == *(temp->symbol)) {temp->val->release(); temp->val = v->grab(); return 1;} return 0; } /************************************************************ ******** ReStringList functions: **************************** ************************************************************/ ReList::ReList(String* s, Regex* r, String* d, ReList* n){ index = s; condensed = r; data = d; next = n; } ReList::~ReList(){ delete index; delete condensed; delete data; } #define HASH_RE(a) ((a) ? ((a) & 3) : 0) ReStringHash::ReStringHash(){ int i; for (i=0 ; i<HASH_WIDTH ; i++) rtable[i] = NULL; } ReStringHash::~ReStringHash(){ ReList* ptr; int i; for (i=0 ; i<HASH_WIDTH ; i++) while (rtable[i]) {ptr=rtable[i]->next; delete rtable[i]; rtable[i]=ptr;} } #define WILD_CARD(a) (buf[0] == '.' || buf[0] == '[' || buf[0] == '(' || \ buf[0] == '+' || buf[0] == '*' || buf[0] == ']' || \ buf[0] == '\\' || buf[0] == '?') int valid_regexp (String* key){ int i, l, bct=0, pct=0, esc=0; char* buf; l = key->length(); buf = (char*)key->chars(); for (i=0 ; i<l ; i++) {switch (buf[i]) {case '\\': esc++; break; case '[': if (!(esc % 2)) {bct++;} esc=0; break; case ']': if (!(esc % 2)) {bct--;} esc=0; break; case '(': if (!(esc % 2)) {pct++;} esc=0; break; case ')': if (!(esc % 2)) {pct--;} esc=0; break; default: esc=0; break;}} return (!bct && !pct); } int ok_regexp (String* key){ int i, l, bct=0, pct=0, esc=0; char* buf; l = key->length(); buf = (char*)key->chars(); if (!l || WILD_CARD(buf[0]) || (l > 1 && (buf[1] == '*' || buf[1] == '?'))) return 0; return valid_regexp (key); } Regex* ReStringHash::add(String* key, String* indata){ ReList* temp; int h; if (! ok_regexp (key)) {delete key; delete indata; return NULL;} h = HASH_RE (key->chars()[0]); temp = new ReList (key, new Regex(key->chars(),0,key->length()), indata, rtable[h]); rtable [h] = temp; return temp->condensed; } String* ReStringHash::lookup (String* pattern){ ReList* traverser; for (traverser = rtable [HASH_RE (pattern->chars()[0])] ; traverser ; traverser = traverser->next) if (pattern->matches(*traverser->condensed)) {return traverser->data;} return NULL; } Val_List* ReStringHash::lookup_all (String* pattern){ Val_List* retval=NULL; ReList* traverser; int h; h = HASH_RE (pattern->chars()[0]); for (traverser = rtable [h] ; traverser ; traverser = traverser->next) if (pattern->matches(*traverser->condensed)) {retval = new Val_List (new Value (new String (*traverser->data), SYM), retval);} return retval; } int ReStringHash::remove (String* pattern){ ReList** traverser, *temp; traverser = &rtable [HASH_RE (pattern->chars()[0])]; for ( ; *traverser ; traverser = &((*traverser)->next)) if (pattern->matches(*(*traverser)->condensed)) {temp = (*traverser)->next; delete (*traverser); *traverser = temp; return 1;} return 0; } int ReStringHash::purge (){ ReList *temp; int i; for (i = 0 ; i<HASH_WIDTH ; i++) {while (rtable [i]) {temp = rtable[i]; rtable[i] = rtable[i] -> next; delete temp;}} return 1; } char* ReStringHash::pack_cmds(char* buf){ ReList* temp, *rlist; int i; for (i=0 ; i<HASH_WIDTH ; i++) {rlist = rtable [i]; for (temp = rlist ; temp ; temp=temp->next) {strcpy (buf , (char*)temp->index->chars()); buf += temp->index->length() + 1; strcpy (buf , (char*)temp->data->chars()); buf += temp->data->length() + 1;}} *buf = '\0'; return ++buf; } char* ReStringHash::unpack(char* buf){ String *tempstring, *tempstring2; while (*buf) {tempstring = new String (buf); buf += tempstring->length() + 1; tempstring2 = new String (buf); buf += tempstring2->length() + 1; add (tempstring , tempstring2);} return buf+1; } Value* ReStringHash::list_cmds(){ ReList *rl, *rlist; int i; Val_List* biglist=NULL, *outlist; for (i=0 ; i<HASH_WIDTH ; i++) {rlist = rtable [i]; for (rl = rlist ; rl ; rl = rl->next) {outlist=NULL; outlist = new Val_List ((new Value (new String (*rl->data), SYM)), outlist); outlist = new Val_List ((new Value (new String (*rl->index))), outlist); biglist = new Val_List ((new Value (outlist)), biglist);}} return new Value (biglist); } void ReStringHash::dump_to_stdout(){ ReList *rl; int i; for (i=0 ; i<HASH_WIDTH ; i++) for (rl = rtable[i] ; rl ; rl = rl->next) {cout << *(rl->index) << "\n"; cout << *(rl->data) << "\n";} }