1 // Buffer variable binding interface
2 // Copyright (C) 2000 Core Technologies.
3
4 // This file is part of e93.
5 //
6 // e93 is free software; you can redistribute it and/or modify
7 // it under the terms of the e93 LICENSE AGREEMENT.
8 //
9 // e93 is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // e93 LICENSE AGREEMENT for more details.
13 //
14 // You should have received a copy of the e93 LICENSE AGREEMENT
15 // along with e93; see the file "LICENSE.TXT".
16
17 #include "includes.h"
18
19 typedef struct variableBinding
20 {
21 struct variableBinding
22 *previousBinding, // pointer to previous binding in the global binding list
23 *nextBinding, // pointer to next binding in the global binding list (in user defined order)
24 *nextHashBinding; // pointer to next binding in local hash list
25 char
26 *variableName, // name of this variable
27 *variableText; // data contained in this variable
28 } VARIABLE_BINDING;
29
GetBindingHashListHead(VARIABLE_TABLE * variableTable,char * variableName)30 static VARIABLE_BINDING **GetBindingHashListHead(VARIABLE_TABLE *variableTable,char *variableName)
31 // perform hashing function on variableName, return pointer to list head
32 // for bindings
33 {
34 UINT32
35 count,
36 length,
37 sum;
38
39 length=strlen(variableName);
40 sum=0;
41 for(count=0;count<length;count++) // very crude hash function
42 {
43 sum+=variableName[count];
44 }
45 return(&(variableTable->variableBindingTable[sum&0xFF]));
46 }
47
GetVariableBindingName(VARIABLE_BINDING * binding)48 char *GetVariableBindingName(VARIABLE_BINDING *binding)
49 // return a pointer to the variable binding name for binding
50 {
51 return(binding->variableName);
52 }
53
GetVariableBindingText(VARIABLE_BINDING * binding)54 char *GetVariableBindingText(VARIABLE_BINDING *binding)
55 // return a pointer to the variable binding text for binding
56 {
57 return(binding->variableText);
58 }
59
LocateVariableBindingLocation(VARIABLE_TABLE * variableTable,char * variableName,VARIABLE_BINDING *** hashListHead,VARIABLE_BINDING ** previousHashEntry,VARIABLE_BINDING ** entry)60 static bool LocateVariableBindingLocation(VARIABLE_TABLE *variableTable,char *variableName,VARIABLE_BINDING ***hashListHead,VARIABLE_BINDING **previousHashEntry,VARIABLE_BINDING **entry)
61 // locate a variable binding in the binding table, return pointers to important entries
62 {
63 bool
64 found;
65 VARIABLE_BINDING
66 *currentEntry;
67
68 currentEntry=*(*hashListHead=GetBindingHashListHead(variableTable,variableName)); // point to the head of the linked list at this hash entry
69 *previousHashEntry=NULL;
70 found=false;
71 while(currentEntry&&!found)
72 {
73 if(strcmp(variableName,currentEntry->variableName)==0)
74 {
75 found=true;
76 *entry=currentEntry;
77 }
78 else
79 {
80 *previousHashEntry=currentEntry;
81 currentEntry=currentEntry->nextHashBinding;
82 }
83 }
84 return(found);
85 }
86
LocateNextVariableBinding(VARIABLE_BINDING * currentBinding)87 VARIABLE_BINDING *LocateNextVariableBinding(VARIABLE_BINDING *currentBinding)
88 // return the next variable binding from the current one
89 // if there is none, return NULL
90 {
91 return(currentBinding->nextBinding);
92 }
93
LocateVariableBinding(VARIABLE_TABLE * variableTable,char * variableName)94 VARIABLE_BINDING *LocateVariableBinding(VARIABLE_TABLE *variableTable,char *variableName)
95 // find a key binding that matches the variableName, and return it
96 // if there is none, return NULL
97 {
98 bool
99 found;
100 VARIABLE_BINDING
101 *currentEntry;
102
103 currentEntry=*GetBindingHashListHead(variableTable,variableName); // point to the head of the linked list at this hash entry
104 found=false;
105 while(currentEntry&&!found)
106 {
107 if(strcmp(variableName,currentEntry->variableName)==0)
108 {
109 found=true;
110 }
111 else
112 {
113 currentEntry=currentEntry->nextHashBinding;
114 }
115 }
116 return(currentEntry);
117 }
118
DeleteVariableBinding(VARIABLE_TABLE * variableTable,char * variableName)119 bool DeleteVariableBinding(VARIABLE_TABLE *variableTable,char *variableName)
120 // attempt to locate the given binding in variableTable, and
121 // remove it if it is found
122 // if it is not located, return false
123 {
124 VARIABLE_BINDING
125 **hashListHead,
126 *previousHashEntry,
127 *entry;
128
129 if(LocateVariableBindingLocation(variableTable,variableName,&hashListHead,&previousHashEntry,&entry))
130 {
131 if(previousHashEntry)
132 {
133 previousHashEntry->nextHashBinding=entry->nextHashBinding; // unlink the located entry
134 }
135 else
136 {
137 *hashListHead=entry->nextHashBinding;
138 }
139 if(entry->previousBinding)
140 {
141 if((entry->previousBinding->nextBinding=entry->nextBinding))
142 {
143 entry->nextBinding->previousBinding=entry->previousBinding;
144 }
145 }
146 else
147 {
148 if((variableTable->variableBindingListHead=entry->nextBinding))
149 {
150 variableTable->variableBindingListHead->previousBinding=NULL;
151 }
152 }
153 MDisposePtr(entry->variableName);
154 MDisposePtr(entry->variableText);
155 MDisposePtr(entry);
156 return(true);
157 }
158 return(false);
159 }
160
CreateVariableBinding(VARIABLE_TABLE * variableTable,char * variableName,char * variableText)161 bool CreateVariableBinding(VARIABLE_TABLE *variableTable,char *variableName,char *variableText)
162 // search the variable binding table for an entry that matches the one given, and delete it if
163 // it exists. Then add this entry to the table
164 // if there is a problem, SetError, and return false
165 {
166 VARIABLE_BINDING
167 **hashListHead,
168 *newEntry;
169
170 DeleteVariableBinding(variableTable,variableName); // try to delete one if it exists
171 hashListHead=GetBindingHashListHead(variableTable,variableName); // point to head of list in hash table where this binding will go
172 if((newEntry=(VARIABLE_BINDING *)MNewPtr(sizeof(VARIABLE_BINDING))))
173 {
174 if((newEntry->variableName=(char *)MNewPtr(strlen(variableName)+1)))
175 {
176 if((newEntry->variableText=(char *)MNewPtr(strlen(variableText)+1)))
177 {
178 strcpy(newEntry->variableName,variableName); // copy in name
179 strcpy(newEntry->variableText,variableText); // copy in text
180 newEntry->nextHashBinding=*hashListHead;
181 *hashListHead=newEntry; // link to head of hash list
182 newEntry->previousBinding=NULL;
183 if((newEntry->nextBinding=variableTable->variableBindingListHead)) // point to the next entry
184 {
185 variableTable->variableBindingListHead->previousBinding=newEntry;
186 }
187 variableTable->variableBindingListHead=newEntry;
188 return(true);
189 }
190 MDisposePtr(newEntry->variableName);
191 }
192 MDisposePtr(newEntry);
193 }
194 return(false);
195 }
196
InitVariableBindingTable(VARIABLE_TABLE * variableTable)197 bool InitVariableBindingTable(VARIABLE_TABLE *variableTable)
198 // clear the variable binding table so that there are no bindings present
199 // if there is a problem, SetError, and return false
200 {
201 int
202 i;
203
204 for(i=0;i<256;i++)
205 {
206 variableTable->variableBindingTable[i]=NULL;
207 }
208 variableTable->variableBindingListHead=NULL;
209 return(true);
210 }
211
UnInitVariableBindingTable(VARIABLE_TABLE * variableTable)212 void UnInitVariableBindingTable(VARIABLE_TABLE *variableTable)
213 // remove all variable bindings from the bindings table
214 {
215 int
216 i;
217 VARIABLE_BINDING
218 *currentEntry,
219 *nextEntry;
220
221 for(i=0;i<256;i++)
222 {
223 currentEntry=variableTable->variableBindingTable[i];
224 while(currentEntry)
225 {
226 nextEntry=currentEntry->nextHashBinding;
227 MDisposePtr(currentEntry->variableName);
228 MDisposePtr(currentEntry->variableText);
229 MDisposePtr(currentEntry);
230 currentEntry=nextEntry;
231 }
232 variableTable->variableBindingTable[i]=NULL;
233 }
234 variableTable->variableBindingListHead=NULL;
235 }
236