Wild Life  2.29
 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 */
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 */
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 */
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 */
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 }
ptr_node bk_stack_insert(long comp, char *keystr, ptr_node *tree, GENERIC info)
Definition: trees.c:309
#define HEAP
Definition: def_const.h:147
#define FEATCMP
Definition: def_const.h:257
void push_ptr_value(type_ptr t, GENERIC *p)
Definition: login.c:360
ptr_node bk2_stack_insert(long comp, char *keystr, ptr_node *tree, GENERIC info)
Definition: trees.c:327
#define INTCMP
Definition: def_const.h:256
char * stack_copy_string(char *s)
Definition: trees.c:155
char * two
Definition: def_glob.h:251
ptr_node find(long comp, char *keystr, ptr_node tree)
Definition: trees.c:341
void push_ptr_value_global(type_ptr t, GENERIC *p)
Definition: login.c:488
ptr_node find_data(GENERIC p, ptr_node t)
Definition: trees.c:399
char * heap_copy_string(char *s)
Definition: trees.c:147
void heap_insert_copystr(char *keystr, ptr_node *tree, GENERIC info)
Definition: trees.c:245
GENERIC data
Definition: def_struct.h:185
#define NULL
Definition: def_const.h:203
char * heap_ncopy_string(char *s, int n)
Definition: trees.c:128
ptr_node left
Definition: def_struct.h:183
void Errorline(char *format,...)
Definition: error.c:414
ptr_node stack_insert(long comp, char *keystr, ptr_node *tree, GENERIC info)
Definition: trees.c:291
char * key
Definition: def_struct.h:182
#define TRUE
Definition: def_const.h:127
#define STRCMP
Definition: def_const.h:255
#define FALSE
Definition: def_const.h:128
ptr_node heap_insert(long comp, char *keystr, ptr_node *tree, GENERIC info)
Definition: trees.c:276
long intcmp(long a, long b)
Definition: trees.c:12
char * one
Definition: def_glob.h:250
#define STACK_ALLOC(A)
Definition: def_macro.h:16
ptr_node general_insert(long comp, char *keystr, ptr_node *tree, GENERIC info, long heapflag, long copystr, long bkflag)
Definition: trees.c:184
long featcmp(char *str1, char *str2)
Definition: trees.c:89
long is_int(char **s, long *len, long *sgn)
Definition: trees.c:27
unsigned long * GENERIC
Definition: def_struct.h:17
void delete_attr(char *s, ptr_node *n)
Definition: trees.c:466
void stack_insert_copystr(char *keystr, ptr_node *tree, GENERIC info)
Definition: trees.c:260
#define HEAP_ALLOC(A)
Definition: def_macro.h:15
GENERIC heap_alloc(long s)
Definition: memory.c:1518
GENERIC stack_alloc(long s)
Definition: memory.c:1542
#define STACK
Definition: def_const.h:148
ptr_node right
Definition: def_struct.h:184
#define int_ptr
Definition: def_const.h:172