Wild Life: trees.c Source File

Wild Life 2.29

- Main Page
- Data Structures
- Files

- File List
- Globals

All Data Structures Files Functions Variables Typedefs Macros
trees.c
Go to the documentation of this file.
1 /* Copyright 1991 Digital Equipment Corporation.
2 ** All Rights Reserved.
3 *****************************************************************/
4 /* $Id: trees.c,v 1.3 1995/07/27 21:22:21 duchier Exp $ */
5
6 #include "defs.h"
7
8
9 /******** INTCMP(a,b)
10 Compares two integers, for use in FIND or INSERT.
11 */
12 long intcmp(a,b)
13 long a;
14 long b;
15
16 {
17 #ifdef CMPDBG
18 printf("intcmp a = %ld b = %ld a - b = %ld\n", a ,b , a - b);
19 #endif
20 return a - b;
21 }
22
23
24 /* Return TRUE iff the string s represents an integer. */
25 /* Modify s to point to first non-zero digit. */
26 /* Return number of significant digits in the integer and its sign. */
27 long is_int(s, len, sgn)
28 char **s;
29 long *len;
30 long *sgn;
31 {
32 char *sint; /* Ptr to first non-zero digit */
33 char *stmp; /* Scratchpad for string ptr */
34 #ifdef CMPDBG
35 printf("is_int *s = %s\n",*s);
36 #endif
37 /*
38 { register char *p= *s;
39 register char c= *p;
40 if(c>'0' && c<='9' && *(p+1)==0) return TRUE;
41 }
42 */
43
44 stmp=(*s);
45 if ((*sgn=(*stmp=='-'))) {
46 stmp++;
47 if (!*stmp)
48 {
49 #ifdef CMPDBG
50 printf("is_int = FALSE\n");
51 #endif
52 return FALSE;
53 }
54 }
55 if (!*stmp)
56 {
57 #ifdef CMPDBG
58 printf("is_int = FALSE\n");
59 #endif
60 return FALSE; /* 6.10 */
61 }
62 while (*stmp=='0') stmp++;
63 sint=stmp;
64 while (*stmp) {
65 if (*stmp<'0' || *stmp>'9')
66 {
67 #ifdef CMPDBG
68 printf("is_int = FALSE\n");
69 #endif
70 return FALSE;
71 }
72 stmp++;
73 }
74 *len=stmp-sint;
75 *s=sint;
76 #ifdef CMPDBG
77 printf("is_int = TRUE *len = %ld *sgn = %ld *s = %s\n",*len,*sgn,*s);
78 #endif
79 return TRUE;
80 }
81
82 /******** FEATCMP(s1,s2)
83 Compares two strings which represent features, for use
84 in FIND or INSERT. This differs from strcmp for those strings
85 that represent integers. These are compared as integers.
86 In addition, all integers are considered to be less than
87 all strings that do not represent integers.
88 */
89 long featcmp(str1,str2)
90 char *str1, *str2;
91 {
92 long len1,len2,sgn1,sgn2;
93 char *s1,*s2;
94
95 if(str1==str2)
96 return 0;
97
98 /* if (*str1==0 && *str2==0) return 0; "" bug is unaffected -- PVR 23.2.94 */
99
100 if(*(str1+1)==0 && *(str2+1)==0)
101 return *str1 - *str2;
102
103
104 s1=str1; /* Local copies of the pointers */
105 s2=str2;
106
107 if (is_int(&s1,&len1,&sgn1)) {
108 if (is_int(&s2,&len2,&sgn2)) {
109 if (sgn1!=sgn2) return (sgn2-sgn1); /* Check signs first */
110 if (len1!=len2) return (len1-len2); /* Then check lengths */
111 return strcmp(s1,s2); /* Use strcmp only if same sign and length */
112 }
113 else
114 return -1;
115 }
116 else {
117 if (is_int(&s2,&len2,&sgn2))
118 return 1;
119 else
120 return strcmp(s1,s2);
121 }
122 }
123
124 /******** HEAP_NCOPY_STRING(string,length)
125 Make a copy of the string in the heap, and return a pointer to that.
126 Exceptions: "1" and "2" are unique (and in the heap).
127 */
128 char *heap_ncopy_string(s,n)
129 char *s;
130 int n;
131 {
132 char *p;
133
134 if (s==one || s==two) return s;
135
136 p=(char *)heap_alloc(n+1);
137 strncpy(p,s,n);
138 p[n]='\0';
139
140 return p;
141 }
142
143 /******** HEAP_COPY_STRING(string)
144 Make a copy of the string in the heap, and return a pointer to that.
145 Exceptions: "1" and "2" are unique (and in the heap).
146 */
147 char *heap_copy_string(s)
148 char *s;
149 { return heap_ncopy_string(s,strlen(s)); }
150
151 /******** STACK_COPY_STRING(string)
152 Make a copy of the string in the stack, and return a pointer to that.
153 Exceptions: "1" and "2" are unique (and in the heap).
154 */
155 char *stack_copy_string(s)
156 char *s;
157 {
158 char *p;
159
160 if (s==one || s==two) return s;
161
162 p=(char *)stack_alloc(strlen(s)+1);
163 strcpy(p,s);
164
165 return p;
166 }
167 /******** GENERAL_INSERT(comp,keystr,tree,info,heapflag,copystr,bkflag)
168 General tree insertion routine.
169 comp = comparison routine for insertion.
170 keystr = the insertion key.
171 tree = the tree to insert in.
172 info = the information to insert.
173 heapflag = HEAP or STACK for heap or stack allocation of insertion node.
174 copystr = TRUE iff copy the keystr to the heap on insertion.
175 bkflag = 1 iff the insertion is backtrackable (trailed with trail check).
176 2 iff the insertion must always be trailed.
177 Returns a pointer to the node containing the pair (keystr,info).
178
179 Here KEYSTR can be either a pointer to a string, an integer, or a feature.
180 COMP is the function to call to compare 2 keys so it has three
181 possible values: COMP==strcmp(), COMP==intcmp(), or COMP==featcmp().
182 COMP(a,b) should return n where: n=0 if a=b; n>0 if a>b; n<0 if a<b.
183 */
184 ptr_node general_insert(comp,keystr,tree,info,heapflag,copystr,bkflag)
185 long comp;
186 char *keystr;
187 ptr_node *tree;
188 GENERIC info;
189 long heapflag, copystr, bkflag;
190 {
191 long cmp;
192 ptr_node result;
193 long to_do=TRUE;
194
195
196 do {
197 if (*tree==NULL) {
198 if (bkflag==1) push_ptr_value(int_ptr,(GENERIC *)tree);
199 else if (bkflag==2) push_ptr_value_global(int_ptr,(GENERIC *)tree);
200 *tree = (heapflag==HEAP) ? HEAP_ALLOC(node): STACK_ALLOC(node);
201 result= *tree;
202 (*tree)->key = copystr ? heap_copy_string(keystr) : keystr;
203 (*tree)->left=NULL;
204 (*tree)->right=NULL;
205 (*tree)->data=info;
206 to_do=FALSE;
207 }
208 else {
209 if (comp == INTCMP)
210 cmp = intcmp((long)keystr,(long) (*tree)->key);
211 else if (comp == FEATCMP)
212 cmp = featcmp(keystr,(*tree)->key);
213 else if (comp == STRCMP)
214 cmp = strcmp(keystr,(*tree)->key);
215 else
216 Errorline("Bad comp in general_insert.\n");
217
218 if (cmp<0)
219 tree=(&((*tree)->left));
220 else
221 if (cmp==0) {
222 if (bkflag)
223 Errorline("attempt to overwrite an existing feature; ignored.\n");
224 else
225 (*tree)->data=info;
226 result= *tree;
227 to_do=FALSE;
228 }
229 else
230 tree=(&((*tree)->right));
231 }
232 } while (to_do);
233
234 return result;
235 }
236
237
238
239
240 /******** HEAP_INSERT_COPYSTR(keystr,tree,info)
241 Insert the pointer INFO under the reference string KEYSTR (which is
242 a feature name) in the binary tree TREE. KEYSTR is copied to the heap.
243 A potential additional node allocated to TREE is put on the heap.
244 */
245 void heap_insert_copystr(keystr,tree,info)
246 char *keystr;
247 ptr_node *tree;
248 GENERIC info;
249 {
250 (void)general_insert(FEATCMP,keystr,tree,info,HEAP,TRUE,0L);
251 }
252
253
254
255 /******** STACK_INSERT_COPYSTR(keystr,tree,info)
256 Insert the pointer INFO under the reference string KEYSTR (which is
257 a feature name) in the binary tree TREE. KEYSTR is copied to the heap.
258 A potential additional node allocated to TREE is put on the stack.
259 */
260 void stack_insert_copystr(keystr,tree,info)
261 char *keystr;
262 ptr_node *tree;
263 GENERIC info;
264 {
265
266 (void)general_insert(FEATCMP,keystr,tree,info,STACK,TRUE,0L);
267 }
268
269
270
271 /******** HEAP_INSERT(comp,keystr,tree,info)
272 Insert the pointer INFO under the reference KEYSTR in the
273 binary tree TREE stored in the heap.
274 Return the pointer to the node of KEYSTR.
275 */
276 ptr_node heap_insert(comp,keystr,tree,info)
277 long comp;
278 char * keystr;
279 ptr_node *tree;
280 GENERIC info;
281 {
282
283 return general_insert(comp,keystr,tree,info,HEAP,FALSE,0L);
284 }
285
286
287
288 /******** STACK_INSERT(comp,keystr,tree,info)
289 Exactly the same as heap_insert, only the new node is in the stack.
290 */
291 ptr_node stack_insert(comp,keystr,tree,info)
292 long comp;
293 char * keystr;
294 ptr_node *tree;
295 GENERIC info;
296 {
297
298 return general_insert(comp,keystr,tree,info,STACK,FALSE,0L);
299 }
300
301
302
303 /******** BK_STACK_INSERT(comp,keystr,tree,info)
304 Insert the pointer INFO under the reference string KEYSTR of
305 length len in the binary tree TREE. Return the pointer to the permanent
306 storage place of KEY. This is used by C_APPLY_LABEL
307 Trail the change with a trail check.
308 */
309 ptr_node bk_stack_insert(comp,keystr,tree,info)
310 long comp;
311 char * keystr;
312 ptr_node *tree;
313 GENERIC info;
314 {
315
316 return general_insert(comp,keystr,tree,info,STACK,FALSE,1L);
317 }
318
319
320
321 /******** BK2_STACK_INSERT(comp,keystr,tree,info)
322 Insert the pointer INFO under the reference string KEYSTR of
323 length len in the binary tree TREE. Return the pointer to the permanent
324 storage place of KEY. This is used by C_APPLY_LABEL
325 Always trail the change.
326 */
327 ptr_node bk2_stack_insert(comp,keystr,tree,info)
328 long comp;
329 char * keystr;
330 ptr_node *tree;
331 GENERIC info;
332 {
333
334 return general_insert(comp,keystr,tree,info,STACK,FALSE,2L);
335 }
336
337 /******** FIND(comp,keystr,tree)
338 Return the NODE address corresponding to key KEYSTR in TREE using function
339 COMP to compare keys.
340 */
341 ptr_node find(comp,keystr,tree)
342 long comp;
343 char *keystr;
344 ptr_node tree;
345 {
346 ptr_node result;
347 long cmp;
348 long to_do=TRUE;
349
350 /*
351 if(comp==strcmp)
352 printf("%s ",keystr);
353 */
354
355 do {
356 if (tree==NULL) {
357 result=NULL;
358 to_do=FALSE;
359 }
360 else {
361 if (comp == INTCMP)
362 cmp = intcmp((long)keystr,(long) (tree)->key);
363 else if (comp == FEATCMP)
364 cmp = featcmp(keystr,(tree)->key);
365 else if (comp == STRCMP)
366 cmp = strcmp(keystr,(tree)->key);
367 else
368 Errorline("Bad comp in general_insert.\n");
369
370 if (cmp<0)
371 tree=tree->left;
372 else
373 if (cmp==0) {
374 result=tree;
375 to_do=FALSE;
376 }
377 else
378 tree=tree->right;
379 }
380 } while (to_do);
381
382
383 /* RM: Jan 27 1993
384 if(comp==strcmp)
385 printf("Find: '%s' -> %x\n",keystr,result);
386 */
387
388 return result;
389 }
390
391
392
393
394 /******** FIND_DATA(p,t)
395 Return the node containing the data P in tree T. This is a linear search and
396 can be used to find the key to some data if it is unkown.
397 Return NULL if no key corresponds to data P.
398 */
399 ptr_node find_data(p,t)
400 GENERIC p;
401 ptr_node t;
402 {
403 ptr_node r=NULL;
404
405 if(t)
406 if(t->data==p)
407 r=t;
408 else {
409 r=find_data(p,t->left);
410 if(r==NULL)
411 r=find_data(p,t->right);
412 }
413
414 return r;
415 }
416
417
418
419 /******** UPDATE_SYMBOL(s)
420 S is a string of characters encountered during parsing.
421 If it is an existing symbol then simply return its definition,
422 otherwise create a definition for it, and return that.
423 */
424 /* Commented out by RM: Jan 7 1993
425 New routine is in modules.c
426
427 ptr_definition update_symbol(s)
428 char *s;
429 {
430 ptr_node n;
431 ptr_definition result;
432
433 n=find(STRCMP,s,symbol_table);
434 if(n)
435 result=(ptr_definition )n->data;
436 else {
437 s=heap_copy_string(s);
438
439 result=HEAP_ALLOC(definition);
440 result->keyword->symbol=s;
441 result->rule=NULL;
442 result->properties=NULL;
443 result->date=0;
444 result->type=undef;
445 result->always_check=TRUE;
446 result->protected=TRUE;
447 result->evaluate_args=TRUE;
448 result->already_loaded=FALSE;
449 result->children=NULL;
450 result->parents=NULL;
451 result->code=NOT_CODED;
452 result->op_data=NULL;
453
454 heap_insert(strcmp,s,&symbol_table,result);
455 }
456
457 return result;
458 }
459 */
460
461
462
463 /******** DELETE_ATTR(key,tree)
464 Remove the node addressed by KEY from TREE.
465 */
466 void delete_attr(s,n)
467 char *s;
468 ptr_node *n;
469 {
470 long cmp;
471 ptr_node new,r;
472
473 if (*n) {
474 cmp=featcmp(s,(*n)->key);
475 if (cmp<0)
476 delete_attr(s,&((*n)->left));
477 else if (cmp>0)
478 delete_attr(s,&((*n)->right));
479 else if ((*n)->left) {
480 if ((*n)->right) {
481 r=(*n)->right;
482 new=heap_insert(FEATCMP,r->key,&((*n)->left),r->data);
483 new->left=r->left;
484 new->right=r->right;
485 *n = (*n) -> left;
486 }
487 else
488 *n = (*n)->left;
489 }
490 else
491 *n = (*n)->right;
492 }
493 }
bk_stack_insert
ptr_node bk_stack_insert(long comp, char *keystr, ptr_node *tree, GENERIC info)
Definition: trees.c:309
HEAP
#define HEAP
Definition: def_const.h:147
FEATCMP
#define FEATCMP
Definition: def_const.h:257
push_ptr_value
void push_ptr_value(type_ptr t, GENERIC *p)
Definition: login.c:360
bk2_stack_insert
ptr_node bk2_stack_insert(long comp, char *keystr, ptr_node *tree, GENERIC info)
Definition: trees.c:327
INTCMP
#define INTCMP
Definition: def_const.h:256
stack_copy_string
char * stack_copy_string(char *s)
Definition: trees.c:155
two
char * two
Definition: def_glob.h:251
find
ptr_node find(long comp, char *keystr, ptr_node tree)
Definition: trees.c:341
push_ptr_value_global
void push_ptr_value_global(type_ptr t, GENERIC *p)
Definition: login.c:488
find_data
ptr_node find_data(GENERIC p, ptr_node t)
Definition: trees.c:399
defs.h
heap_copy_string
char * heap_copy_string(char *s)
Definition: trees.c:147
heap_insert_copystr
void heap_insert_copystr(char *keystr, ptr_node *tree, GENERIC info)
Definition: trees.c:245
wl_node::data
GENERIC data
Definition: def_struct.h:185
NULL
#define NULL
Definition: def_const.h:203
heap_ncopy_string
char * heap_ncopy_string(char *s, int n)
Definition: trees.c:128
wl_node::left
ptr_node left
Definition: def_struct.h:183
Errorline
void Errorline(char *format,...)
Definition: error.c:414
stack_insert
ptr_node stack_insert(long comp, char *keystr, ptr_node *tree, GENERIC info)
Definition: trees.c:291
wl_node::key
char * key
Definition: def_struct.h:182
TRUE
#define TRUE
Definition: def_const.h:127
STRCMP
#define STRCMP
Definition: def_const.h:255
FALSE
#define FALSE
Definition: def_const.h:128
heap_insert
ptr_node heap_insert(long comp, char *keystr, ptr_node *tree, GENERIC info)
Definition: trees.c:276
intcmp
long intcmp(long a, long b)
Definition: trees.c:12
one
char * one
Definition: def_glob.h:250
STACK_ALLOC
#define STACK_ALLOC(A)
Definition: def_macro.h:16
general_insert
ptr_node general_insert(long comp, char *keystr, ptr_node *tree, GENERIC info, long heapflag, long copystr, long bkflag)
Definition: trees.c:184
featcmp
long featcmp(char *str1, char *str2)
Definition: trees.c:89
wl_node
Definition: def_struct.h:181
is_int
long is_int(char **s, long *len, long *sgn)
Definition: trees.c:27
GENERIC
unsigned long * GENERIC
Definition: def_struct.h:17
delete_attr
void delete_attr(char *s, ptr_node *n)
Definition: trees.c:466
stack_insert_copystr
void stack_insert_copystr(char *keystr, ptr_node *tree, GENERIC info)
Definition: trees.c:260
HEAP_ALLOC
#define HEAP_ALLOC(A)
Definition: def_macro.h:15
heap_alloc
GENERIC heap_alloc(long s)
Definition: memory.c:1518
stack_alloc
GENERIC stack_alloc(long s)
Definition: memory.c:1542
STACK
#define STACK
Definition: def_const.h:148
wl_node::right
ptr_node right
Definition: def_struct.h:184
int_ptr
#define int_ptr
Definition: def_const.h:172