C:/Users/Dennis/src/lang/Life_start/Life/life-1.02/source/trees.c

Go to the documentation of this file.
00001 /* Copyright 1991 Digital Equipment Corporation.
00002 ** All Rights Reserved.
00003 *****************************************************************/
00004 /*      $Id: trees.c,v 1.3 1995/07/27 21:22:21 duchier Exp $     */
00005 
00006 #ifndef lint
00007 static char vcid[] = "$Id: trees.c,v 1.3 1995/07/27 21:22:21 duchier Exp $";
00008 #endif /* lint */
00009 
00010 #include "extern.h"
00011 #include "print.h"
00012 #include "memory.h"
00013 #include "login.h"
00014 
00015   
00016 
00017 /******** INTCMP(a,b)
00018   Compares two integers, for use in FIND or INSERT.
00019 */
00020 long intcmp(a,b)
00021 long a;
00022 long b;
00023 {
00024   return a-b;
00025 }
00026 
00027 
00028 /* Return TRUE iff the string s represents an integer. */
00029 /* Modify s to point to first non-zero digit. */
00030 /* Return number of significant digits in the integer and its sign. */
00031 long is_int(s, len, sgn)
00032 char **s;
00033 long *len;
00034 long *sgn;
00035 {
00036   char *sint; /* Ptr to first non-zero digit */
00037   char *stmp; /* Scratchpad for string ptr */
00038 
00039   /*
00040   { register char *p= *s;
00041     register char c= *p;
00042     if(c>'0' && c<='9' && *(p+1)==0) return TRUE;
00043   }
00044   */
00045   
00046   stmp=(*s);
00047   if (*sgn=(*stmp=='-')) {
00048     stmp++;
00049     if (!*stmp) return FALSE;
00050   }
00051   if (!*stmp) return FALSE; /* 6.10 */
00052   while (*stmp=='0') stmp++;
00053   sint=stmp;
00054   while (*stmp) {
00055     if (*stmp<'0' || *stmp>'9') return FALSE;
00056     stmp++;
00057   }
00058   *len=stmp-sint;
00059   *s=sint;
00060   return TRUE;
00061 }
00062 
00063 
00064 
00065 
00066 /******** FEATCMP(s1,s2)
00067   Compares two strings which represent features, for use
00068   in FIND or INSERT.  This differs from strcmp for those strings
00069   that represent integers.  These are compared as integers.
00070   In addition, all integers are considered to be less than
00071   all strings that do not represent integers.
00072 */
00073 long featcmp(str1,str2)
00074 char *str1, *str2;
00075 {
00076   long len1,len2,sgn1,sgn2;
00077   char *s1,*s2;
00078 
00079   if(str1==str2)
00080     return 0;
00081   
00082   /* if (*str1==0 && *str2==0) return 0; "" bug is unaffected -- PVR 23.2.94 */
00083 
00084   if(*(str1+1)==0 && *(str2+1)==0)
00085     return *str1 - *str2;
00086   
00087   
00088   s1=str1; /* Local copies of the pointers */
00089   s2=str2;
00090 
00091   if (is_int(&s1,&len1,&sgn1)) {
00092     if (is_int(&s2,&len2,&sgn2)) {
00093       if (sgn1!=sgn2) return (sgn2-sgn1); /* Check signs first */
00094       if (len1!=len2) return (len1-len2); /* Then check lengths */
00095       return strcmp(s1,s2); /* Use strcmp only if same sign and length */
00096     }
00097     else
00098       return -1;
00099   }
00100   else {
00101     if (is_int(&s2,&len2,&sgn2))
00102       return 1;
00103     else
00104       return strcmp(s1,s2);
00105   }
00106 }
00107 
00108 
00109 /******** HEAP_NCOPY_STRING(string,length)
00110   Make a copy of the string in the heap, and return a pointer to that.
00111   Exceptions: "1" and "2" are unique (and in the heap).
00112 */
00113 char *heap_ncopy_string(s,n)
00114 char *s;
00115 int n;
00116 {
00117   char *p;
00118   
00119   if (s==one || s==two) return s;
00120 
00121   p=(char *)heap_alloc(n+1);
00122   strncpy(p,s,n);
00123   p[n]='\0';
00124   
00125   return p;
00126 }
00127 
00128 /******** HEAP_COPY_STRING(string)
00129   Make a copy of the string in the heap, and return a pointer to that.
00130   Exceptions: "1" and "2" are unique (and in the heap).
00131 */
00132 char *heap_copy_string(s)
00133 char *s;
00134 { return heap_ncopy_string(s,strlen(s)); }
00135 
00136 
00137 
00138 /******** STACK_COPY_STRING(string)
00139   Make a copy of the string in the stack, and return a pointer to that.
00140   Exceptions: "1" and "2" are unique (and in the heap).
00141 */
00142 char *stack_copy_string(s)
00143 char *s;
00144 {
00145   char *p;
00146   
00147   if (s==one || s==two) return s;
00148 
00149   p=(char *)stack_alloc(strlen(s)+1);
00150   strcpy(p,s);
00151   
00152   return p;
00153 }
00154 
00155 
00156 
00157 /******** GENERAL_INSERT(comp,keystr,tree,info,heapflag,copystr,bkflag)
00158   General tree insertion routine.
00159   comp     = comparison routine for insertion.
00160   keystr   = the insertion key.
00161   tree     = the tree to insert in.
00162   info     = the information to insert.
00163   heapflag = HEAP or STACK for heap or stack allocation of insertion node.
00164   copystr  = TRUE iff copy the keystr to the heap on insertion.
00165   bkflag   = 1 iff the insertion is backtrackable (trailed with trail check).
00166              2 iff the insertion must always be trailed.
00167   Returns a pointer to the node containing the pair (keystr,info).
00168 
00169   Here KEYSTR can be either a pointer to a string, an integer, or a feature.
00170   COMP is the function to call to compare 2 keys so it has three
00171   possible values: COMP==strcmp(), COMP==intcmp(), or COMP==featcmp().
00172   COMP(a,b) should return n where: n=0 if a=b; n>0 if a>b; n<0 if a<b.
00173 */
00174 ptr_node general_insert(comp,keystr,tree,info,heapflag,copystr,bkflag)
00175 long (*comp)();
00176 char *keystr;
00177 ptr_node *tree;
00178 GENERIC info;
00179 long heapflag, copystr, bkflag;
00180 {
00181   long cmp;
00182   ptr_node result;
00183   long to_do=TRUE;
00184 
00185   
00186   do {
00187     if (*tree==NULL) {
00188       if (bkflag==1) push_ptr_value(int_ptr,tree);
00189       else if (bkflag==2) push_ptr_value_global(int_ptr,tree);
00190       *tree = (heapflag==HEAP) ? HEAP_ALLOC(node): STACK_ALLOC(node);
00191       result= *tree;
00192       (*tree)->key = copystr ? heap_copy_string(keystr) : keystr;
00193       (*tree)->left=NULL;
00194       (*tree)->right=NULL;
00195       (*tree)->data=info;
00196       to_do=FALSE;
00197     }
00198     else {
00199       cmp=(*comp)(keystr,(*tree)->key);
00200       if (cmp<0)
00201         tree=(&((*tree)->left));
00202       else
00203         if (cmp==0) {
00204           if (bkflag)
00205             Errorline("attempt to overwrite an existing feature; ignored.\n");
00206           else
00207             (*tree)->data=info;
00208           result= *tree;
00209           to_do=FALSE;
00210         }
00211         else
00212           tree=(&((*tree)->right));
00213     }
00214   } while (to_do);
00215   
00216   return result;
00217 }
00218 
00219 
00220 
00221 /******** HEAP_INSERT_COPYSTR(keystr,tree,info)
00222   Insert the pointer INFO under the reference string KEYSTR (which is
00223   a feature name) in the binary tree TREE.  KEYSTR is copied to the heap.
00224   A potential additional node allocated to TREE is put on the heap.
00225 */
00226 void heap_insert_copystr(keystr,tree,info)
00227 char *keystr;
00228 ptr_node *tree;
00229 GENERIC info;
00230 {
00231   general_insert(featcmp,keystr,tree,info,HEAP,TRUE,0);
00232 }
00233 
00234 
00235 
00236 /******** STACK_INSERT_COPYSTR(keystr,tree,info)
00237   Insert the pointer INFO under the reference string KEYSTR (which is
00238   a feature name) in the binary tree TREE.  KEYSTR is copied to the heap.
00239   A potential additional node allocated to TREE is put on the stack.
00240 */
00241 void stack_insert_copystr(keystr,tree,info)
00242 char *keystr;
00243 ptr_node *tree;
00244 GENERIC info;
00245 {
00246   general_insert(featcmp,keystr,tree,info,STACK,TRUE,0);
00247 }
00248 
00249 
00250 
00251 /******** HEAP_INSERT(comp,keystr,tree,info)
00252   Insert the pointer INFO under the reference KEYSTR in the
00253   binary tree TREE stored in the heap.
00254   Return the pointer to the node of KEYSTR.
00255 */
00256 ptr_node heap_insert(comp,keystr,tree,info)
00257 long (*comp)();
00258 char *keystr;
00259 ptr_node *tree;
00260 GENERIC info;
00261 {
00262   return general_insert(comp,keystr,tree,info,HEAP,FALSE,0);
00263 }
00264 
00265 
00266 
00267 /******** STACK_INSERT(comp,keystr,tree,info)
00268   Exactly the same as heap_insert, only the new node is in the stack.
00269 */
00270 ptr_node stack_insert(comp,keystr,tree,info)
00271 long (*comp)();
00272 char *keystr;
00273 ptr_node *tree;
00274 GENERIC info;
00275 {
00276   return general_insert(comp,keystr,tree,info,STACK,FALSE,0);
00277 }
00278 
00279 
00280 
00281 /******** BK_STACK_INSERT(comp,keystr,tree,info)
00282   Insert the pointer INFO under the reference string KEYSTR of
00283   length len in the binary tree TREE. Return the pointer to the permanent
00284   storage place of KEY. This is used by C_APPLY_LABEL
00285   Trail the change with a trail check.
00286 */
00287 ptr_node bk_stack_insert(comp,keystr,tree,info)
00288 long (*comp)();
00289 char *keystr;
00290 ptr_node *tree;
00291 GENERIC info;
00292 {
00293   return general_insert(comp,keystr,tree,info,STACK,FALSE,1);
00294 }
00295 
00296 
00297 
00298 /******** BK2_STACK_INSERT(comp,keystr,tree,info)
00299   Insert the pointer INFO under the reference string KEYSTR of
00300   length len in the binary tree TREE. Return the pointer to the permanent
00301   storage place of KEY. This is used by C_APPLY_LABEL
00302   Always trail the change.
00303 */
00304 ptr_node bk2_stack_insert(comp,keystr,tree,info)
00305 long (*comp)();
00306 char *keystr;
00307 ptr_node *tree;
00308 GENERIC info;
00309 {
00310   return general_insert(comp,keystr,tree,info,STACK,FALSE,2);
00311 }
00312 
00313 
00314 
00315 /******** FIND(comp,keystr,tree)
00316   Return the NODE address corresponding to key KEYSTR in TREE using function
00317   COMP to compare keys.
00318 */
00319 ptr_node find(comp,keystr,tree)
00320 long (*comp)();
00321 char *keystr;
00322 ptr_node tree;
00323 {
00324   ptr_node result;
00325   long cmp;
00326   long to_do=TRUE;
00327 
00328   /*
00329     if(comp==strcmp)
00330     printf("%s ",keystr);
00331     */
00332     
00333   do {
00334     if (tree==NULL) {
00335       result=NULL;
00336       to_do=FALSE;
00337     }
00338     else {
00339       cmp=(*comp)(keystr,tree->key);
00340       if (cmp<0)
00341         tree=tree->left;
00342       else
00343         if (cmp==0) {
00344           result=tree;
00345           to_do=FALSE;
00346         }
00347       else
00348         tree=tree->right;
00349     }
00350   } while (to_do);
00351 
00352 
00353   /* RM: Jan 27 1993 
00354     if(comp==strcmp)
00355     printf("Find: '%s' -> %x\n",keystr,result);
00356     */
00357   
00358   return result;
00359 }
00360 
00361 
00362 
00363 /******** FIND_DATA(p,t)
00364   Return the node containing the data P in tree T. This is a linear search and
00365   can be used to find the key to some data if it is unkown.
00366   Return NULL if no key corresponds to data P.
00367 */
00368 ptr_node find_data(p,t)
00369 GENERIC p;
00370 ptr_node t;
00371 {
00372   ptr_node r=NULL;
00373 
00374   if(t) 
00375     if(t->data==p)
00376       r=t;
00377     else {
00378       r=find_data(p,t->left);
00379       if(r==NULL)
00380         r=find_data(p,t->right);
00381     }
00382   
00383   return r;
00384 }
00385 
00386 
00387 
00388 /******** UPDATE_SYMBOL(s)
00389   S is a string of characters encountered during parsing.
00390   If it is an existing symbol then simply return its definition,
00391   otherwise create a definition for it, and return that.
00392 */
00393 /*  Commented out by RM: Jan  7 1993
00394     New routine is in modules.c
00395     
00396 ptr_definition update_symbol(s)
00397 char *s;
00398 {
00399   ptr_node n;
00400   ptr_definition result;
00401 
00402   n=find(strcmp,s,symbol_table);
00403   if(n)
00404     result=(ptr_definition )n->data;
00405   else {
00406     s=heap_copy_string(s);
00407       
00408     result=HEAP_ALLOC(definition);
00409     result->keyword->symbol=s;
00410     result->rule=NULL;
00411     result->properties=NULL;
00412     result->date=0;
00413     result->type=undef;
00414     result->always_check=TRUE;
00415     result->protected=TRUE;
00416     result->evaluate_args=TRUE;
00417     result->already_loaded=FALSE;
00418     result->children=NULL;
00419     result->parents=NULL;
00420     result->code=NOT_CODED;
00421     result->op_data=NULL;
00422     
00423     heap_insert(strcmp,s,&symbol_table,result);
00424   }
00425 
00426   return result;
00427 }
00428 */
00429 
00430 
00431 
00432 /******** DELETE_ATTR(key,tree)
00433   Remove the node addressed by KEY from TREE.
00434 */
00435 void delete_attr(s,n)
00436 char *s;
00437 ptr_node *n;
00438 {
00439   long cmp;
00440   ptr_node new,r;
00441 
00442   if (*n) {
00443     cmp=featcmp(s,(*n)->key);
00444     if (cmp<0)
00445       delete_attr(s,&((*n)->left));
00446     else if (cmp>0)
00447         delete_attr(s,&((*n)->right));
00448     else if ((*n)->left) {
00449       if ((*n)->right) {
00450         r=(*n)->right;
00451         new=heap_insert(featcmp,r->key,&((*n)->left),r->data);
00452         new->left=r->left;
00453         new->right=r->right;
00454         *n = (*n) -> left;
00455       }
00456       else
00457         *n = (*n)->left;
00458     }
00459     else
00460       *n = (*n)->right;
00461   }
00462 }

Generated on Sat Jan 26 08:48:08 2008 for WildLife by  doxygen 1.5.4