(file) Return to daVarRegister.c CVS log (file) (dir) Up to [HallC] / Analyzer / CTP

  1 saw   1.1 /*-----------------------------------------------------------------------------
  2            * Copyright (c) 1992 Southeastern Universities Research Association,
  3            *                    Continuous Electron Beam Accelerator Facility
  4            *
  5            * This software was developed under a United States Government license
  6            * described in the NOTICE file included as part of this distribution.
  7            *
  8            * Stephen A. Wood, 12000 Jefferson Ave., Newport News, VA 23606
  9            * Email: saw@cebaf.gov  Tel: (804) 249-7367  Fax: (804) 249-5800
 10            *-----------------------------------------------------------------------------
 11            * 
 12            * Description:
 13            *	C and Fortran routines for registering variables to be used by
 14            *      the test, histogram and parameter packages.
 15            *	
 16            * Author:  Stephen Wood, CEBAF HALL C
 17            *
 18            * Revision History:
 19            *   $Log: daVarRegister.c,v $
 20 saw   1.3  *   Revision 1.2  1999/11/04 20:34:04  saw
 21            *   Alpha compatibility.
 22            *   New RPC call needed for root event display.
 23            *   Start of code to write ROOT trees (ntuples) from new "tree" block
 24            *
 25 saw   1.2  *   Revision 1.13  1999/08/25 13:16:05  saw
 26            *   *** empty log message ***
 27            *
 28            *   Revision 1.12  1999/03/01 19:51:32  saw
 29            *   Add Absoft Fortran stuff
 30            *
 31            *   Revision 1.11  1997/05/29 18:56:25  saw
 32            *   Lock changes before adding Absoft(Linux) compatibility
 33            *
 34 saw   1.1  *	  Revision 1.10  1996/07/31  20:37:53  saw
 35            *	  Use hash table for name storage.
 36            *
 37            *	  Revision 1.9  1994/09/27  20:20:53  saw
 38            *	  Remove linux dependencies, allow  wild cards in daVarList
 39            *
 40            *	  Revision 1.8  1994/08/24  14:27:00  saw
 41            *	  Have daVarLookupPWithClass return S_DAVAR_UNKNOWN if var not found
 42            *
 43            *	  Revision 1.7  1994/06/03  20:59:26  saw
 44            *	  Replace stderr with STDERR
 45            *
 46            *	  Revision 1.6  1994/02/10  21:58:33  saw
 47            *	  Change node variable name to nd to not conflict with node type.
 48            *
 49            *	  Revision 1.5  1994/02/10  18:34:05  saw
 50            *	  Small fixes for SGI compatibility
 51            *
 52            *	  Revision 1.4  1993/11/24  21:37:39  saw
 53            *	  Add fortran calls for registering double (REAL *8) variable type.
 54            *
 55 saw   1.1  *	  Revision 1.3  1993/11/22  20:09:42  saw
 56            *	  Add REGPARMSTRING fortran call for new Fortran string type DAVARFSTRING
 57            *
 58            *	  Revision 1.2  1993/08/12  19:58:10  saw
 59            *	  On HPUX don't use native tsearch.
 60            *
 61            *	  Revision 1.1  1993/05/10  20:05:09  saw
 62            *	  Initial revision
 63            *
 64            *
 65            *  18-dec-92 saw Original version
 66            *
 67            *
 68            * Routines available to general users:
 69            * --------
 70            *              daVarRegister(int flag, daVarStruct *args)
 71            *              daVarLookup(char *name, daVarStruct *results)
 72            *
 73            * Routines available to "friendly" packages (e.g.) RPC service routines
 74            * --------
 75            *              daVarLookupP(char *name, daVarStruct **results)
 76 saw   1.1  *              daVarList(char ***listp)
 77            *              daVarFreeList(char **list)
 78            *
 79            *
 80            */
 81           #include "cfortran.h"
 82           #include "daVar.h"
 83           
 84           #define USEHASH
 85           #ifdef USEHASH
 86           #include "daVarHash.h"
 87           #else
 88           #if !defined(ultrix)
 89           #define NO_TSEARCH
 90           #endif
 91           
 92           #include <stdio.h>
 93           #ifdef NOFNMATCH
 94           #include "fnmatch.h"
 95           #else
 96           #include <fnmatch.h>
 97 saw   1.1 #endif
 98           
 99           /* Stuff for Tsearch routines*/
100           typedef struct node_t
101           {
102               daVarStruct *key;
103               struct node_t *left, *right;
104           } node;
105           
106           #ifdef NO_TSEARCH
107           typedef enum { preorder, postorder, endorder, leaf } VISIT;
108           node *mytsearch(void *key, node **rootp, int (* compar)());
109           node *mytfind(void *key, node **rootp, int (* compar)());
110           void mytwalk();
111           #else
112           #include <search.h>
113           #define mytsearch tsearch
114           #define mytfind tfind
115           #define mytwalk twalk
116           #endif
117           #endif
118 saw   1.1 
119           #ifdef USEHASH
120           symbolEntry *hash_table[TABLE_SIZE];
121           int hashNotInited=1;
122           #else
123           node *daVarRoot=0;
124           #endif
125           int daVarCount=0;		/* Used by daVarList */
126           char **daVarListGlob;
127           char *daVarListPattern;
128           int (*daVarListCompFunction)();
129           int daVarListPattern_length;
130           
131           /* Local prototypes */
132           int daVarComp(daVarStruct *item1, daVarStruct *item2);
133           
134           /* Code */
135 saw   1.2 int daVarRegister(int flag, daVarStruct *args)
136 saw   1.1 /* Should accept a title arg of zero and create a null string in that
137              case.
138           */
139           {
140             daVarStruct search, *new, **searchresult;
141             int fullnamelen;
142           
143             if(flag != 0) {
144               fprintf(STDERR,
145           	    "(daVarRegister) Only zero allowed for flag argument now.\n");
146               return(S_FAILURE);
147             }
148           
149             search.name = args->name;
150           /*  printf("Searching for %s\n",args->name);*/
151           #ifdef USEHASH
152             if(hashNotInited) {crlHashCreate(hash_table); hashNotInited = 0;}
153             if(searchresult = (daVarStruct **) crlHashFind((CrlSymbol) &search,hash_table)) {
154           #else
155             if(searchresult = (daVarStruct **) mytfind(&search,&daVarRoot,daVarComp)){
156           #endif
157 saw   1.1     fprintf(STDERR,
158           	    "(daVar) Replacing definition of variable \"%s\" in table\n",
159           	    args->name);
160               free((*searchresult)->title);
161               if(args->title) {
162                 if(((*searchresult)->title = (char *) malloc(strlen(args->title)+1))
163           	 == NULL)
164           	return(S_FAILURE);
165                 strcpy((*searchresult)->title,args->title);
166               } else {
167                 if(((*searchresult)->title = (char *) malloc(1))
168           	 == NULL)
169           	return(S_FAILURE);
170                 (*searchresult)->title[0] = '\0';
171               }
172               (*searchresult)->varptr = args->varptr;
173               (*searchresult)->size = (args->size<=0) ? 1 : args->size;
174               (*searchresult)->type = args->type;
175               (*searchresult)->flag = args->flag;
176               (*searchresult)->rhook = args->rhook;
177               (*searchresult)->whook = args->whook;
178 saw   1.1     (*searchresult)->opaque = args->opaque;
179               return(S_DAVAR_REPLACED);
180             } else {
181               if((new = (daVarStruct *) malloc(sizeof(daVarStruct))) == NULL)
182                 return(S_FAILURE);
183               if((new->name =  (char *) malloc(strlen(args->name)+1)) == NULL)
184                  return(S_FAILURE);
185               strcpy(new->name,args->name);
186           
187           
188               if(args->title) {
189                 if((new->title =  (char *) malloc(strlen(args->title)+1)) == NULL)
190           	return(S_FAILURE);
191                 strcpy(new->title,args->title);
192               } else {
193                 if((new->title =  (char *) malloc(1)) == NULL)
194           	return(S_FAILURE);
195                 new->title[0] = '\0';
196               }
197               new->type = args->type;
198               new->varptr = args->varptr;
199 saw   1.1     new->size = (args->size<=0) ? 1 : args->size;
200               new->flag = args->flag;
201               new->rhook = args->rhook;
202               new->whook = args->whook;
203               new->opaque = args->opaque;
204           
205           #ifdef USEHASH
206               if(crlHashAdd((CrlSymbol) new, hash_table))
207           #else    
208               if(mytsearch((void *) new,&daVarRoot,daVarComp))
209           #endif
210                 return(S_SUCCESS);
211               else
212                 return(S_FAILURE);
213             }
214           }
215           
216           
217 saw   1.2 int daVarLookup(char *name, daVarStruct *result)
218 saw   1.1 {
219             daVarStruct search, **searchresult;
220             static char *namel=0;		/* Pointers to  static space for copies of */
221             static int namelsize=0;
222             static char *titlel=0;	/* the name and title pointers */
223             static int titlelsize=0;
224             int len;
225           
226             search.name = name;
227           #ifdef USEHASH
228             if(searchresult = (daVarStruct **) crlHashFind((CrlSymbol) &search,hash_table)) {
229           #else
230             if(searchresult = (daVarStruct **) mytfind(&search,&daVarRoot,daVarComp)){
231           #endif
232           
233               len=strlen((*searchresult)->name);
234               if(len >= namelsize) {
235                 if(namel) free(namel);
236                 namel = (char *) malloc(len+1);
237                 namelsize = len+1;
238               }
239 saw   1.1     strcpy(namel,(*searchresult)->name);
240               result->name = namel;
241           
242               len=strlen((*searchresult)->title);
243               if(len >= titlelsize) {
244                 if(titlel) free(titlel);
245                 titlel = (char *) malloc(len + 1);
246                 titlelsize = len+1;
247               }
248               strcpy(titlel,(*searchresult)->title);
249               result->title = titlel;
250           
251               result->type = (*searchresult)->type;
252               result->varptr = (*searchresult)->varptr;
253               result->size = (*searchresult)->size;
254               result->opaque = (*searchresult)->opaque;
255               result->rhook = (*searchresult)->rhook;
256               result->whook = (*searchresult)->whook;
257               return(S_SUCCESS);
258             } else
259               return(S_DAVAR_UNKNOWN);
260 saw   1.1 }
261 saw   1.2 int daVarStrcmp(register char *s1, register char *s2)
262 saw   1.1 {
263             while(toupper(*s1) == toupper(*s2++))
264               if(*s1++ == '\0')
265                 return(0);
266             return(toupper(*s1) - toupper(*--s2));
267           }
268           int daVarFnmatch(register char *pattern, register char *s, register int n)
269           {
270             return(fnmatch(pattern,s,0));
271           }
272           int daVarStrncmp(register char *s1, register char *s2, register int n)
273           {
274             while(toupper(*s1) == toupper(*s2++))
275               if(*s1++ == '\0' || (--n) <= 0)
276                 return(0);
277             return(toupper(*s1) - toupper(*--s2));
278           }
279           
280           int daVarComp(daVarStruct *item1, daVarStruct *item2)
281           /* Do case insensitive comparisons of keys */
282           {
283 saw   1.1   return(daVarStrcmp(item1->name,item2->name));
284           }
285           
286 saw   1.2 int daVarLookupP(char *name, daVarStruct **varstructptr)
287 saw   1.1 {
288             daVarStruct search, **searchresult;
289           
290             search.name = name;
291           #ifdef USEHASH
292             if(searchresult = (daVarStruct **) crlHashFind((CrlSymbol) &search,hash_table)) {
293           #else
294             if(searchresult = (daVarStruct **) mytfind(&search,&daVarRoot,daVarComp)){
295           #endif
296               *varstructptr = *searchresult;
297               return(S_SUCCESS);
298             } else
299               return(S_DAVAR_UNKNOWN);
300           }
301           
302           daVarLookupPWithClass(char *name, char **prefixlist, daVarStruct **varp)
303           { 
304             int namlen,namtrylen;
305             char *namtry;
306           
307             namlen = strlen(name);
308 saw   1.1   if(daVarLookupP(name,varp)==S_SUCCESS) return(S_SUCCESS);
309             namtrylen = namlen + 10;
310             namtry = (char *) malloc(namtrylen+1);
311             while(*prefixlist){
312               int thislen;
313               thislen = strlen(*prefixlist) + namlen + 1;
314               if(thislen > namtrylen) {
315                 namtrylen = thislen;
316                 namtry = (char *) realloc(namtry,namtrylen);
317               }
318               strcpy(namtry,*prefixlist);
319               strcat(namtry,".");
320               strcat(namtry,name);
321               if(daVarLookupP(namtry,varp)==S_SUCCESS) {
322                 free(namtry);
323                 return(S_SUCCESS);
324               }
325               prefixlist++;
326             }
327             free(namtry);
328             return(S_DAVAR_UNKNOWN);	/* Variable not registered */
329 saw   1.1 }
330           
331 saw   1.2 void daVarCount_node
332 saw   1.1 #ifdef USEHASH
333           (void *entry)
334           {
335           #else
336           (node *nd,VISIT order, int level)
337           {
338             if(order==postorder || order == leaf)
339           #endif
340             daVarCount++;
341           }
342           
343 saw   1.3 void daVarList_node
344 saw   1.1 #ifdef USEHASH
345           (void *entry)
346           {
347           #else
348           (node *nd,VISIT order, int level)
349           {
350             if(order==postorder || order == leaf)
351           #endif
352               {
353                 char *name;
354           
355                 name = ((daVarStruct *) entry)->name;
356                 if(daVarListPattern_length == 0 ||
357           	 (daVarListCompFunction)(daVarListPattern,name,daVarListPattern_length) == 0)
358           	daVarListGlob[daVarCount++] = name;
359               }
360           }
361           
362           
363 saw   1.2 int daVarList(char *pattern, char ***listp, int *count)
364 saw   1.1 /* User is not allowed to muck with the strings pointed to in the list
365              because they are the actual strings in the tables. */
366           {
367           
368             if(strchr(pattern,'*') || strchr(pattern,'?')) {
369               daVarListCompFunction = daVarFnmatch;
370             } else {
371               daVarListCompFunction = daVarStrncmp;
372             }
373             if(pattern) {
374               daVarListPattern = pattern;
375               daVarListPattern_length = strlen(daVarListPattern);
376             } else
377               daVarListPattern_length = 0;
378             daVarCount = 0;
379           #ifdef USEHASH
380             crlHashWalk(hash_table,daVarCount_node);
381           #else
382             mytwalk(daVarRoot,daVarCount_node);/* Should make list only big enough
383           					for what matches */
384           #endif
385 saw   1.1 
386             if((*listp = daVarListGlob = 
387                 (char **) malloc((daVarCount)*sizeof(char *))) == NULL)
388               return(S_FAILURE);
389             daVarCount = 0;
390           #ifdef USEHASH
391             crlHashWalk(hash_table,daVarList_node);
392           #else
393             mytwalk(daVarRoot,daVarList_node);
394           #endif
395             *count = daVarCount;
396             return(S_SUCCESS);
397           }
398           #ifndef USEHASH
399           daVarPrint_node(node *nd,VISIT order, int level)
400           {
401             char *name,*title;
402           
403             if(order==postorder || order == leaf) {
404               name = ((daVarStruct *) nd->key)->name;
405               title = ((daVarStruct *) nd->key)->title;
406 saw   1.1     printf("XX: %s %s %x %x\n",name,title,nd,nd->key);
407             }
408           }
409           
410 saw   1.2 int daVarPrint()
411 saw   1.1 {
412             mytwalk(daVarRoot,daVarPrint_node);
413             return(S_SUCCESS);
414           }
415           #endif
416 saw   1.2 int daVarFreeList(char **list)
417 saw   1.1 /* Free's up the list of variables in listp */
418           {
419             int i;
420           
421             free(list);
422             return(S_SUCCESS);
423           }
424           
425           /* Fortran entry points */
426           
427           #define LENDEFARRAY int *size,
428           #define LENDEFSCALER
429           #define LENARGARRAY *size
430           #define LENARGSCALER 1
431           
432           #define MAKEFSUB(SUBNAME,CLASS,TYPENAME,DATYPE,ARRAY) \
433 saw   1.2 int SUBNAME(char *name, TYPENAME *vptr, LENDEF##ARRAY char *title\
434 saw   1.1 	      ,unsigned l_name, unsigned l_title)\
435           {\
436 saw   1.2   int A0;\
437 saw   1.1   daVarStruct args;\
438             char *BN=0;\
439             char *BT=0;\
440             char *BF = 0;\
441           \
442             BF = malloc(strlen(CLASS)+l_name+1);\
443             strcpy(BF,CLASS);\
444             args.name = strcat(BF,((!*(int *)name)?0:memchr(name,'\0',l_name)?name:\
445           			 (memcpy(BN=(char *) malloc(l_name+1),name,l_name)\
446           			  ,BN[l_name]='\0',kill_trailing(BN,' '))));\
447             args.title = ((!*(int *)title)?0:memchr(title,'\0',l_title)?title:\
448           		 (memcpy(BT=(char *) malloc(l_title+1),title,l_title)\
449           		  ,BT[l_title]='\0',kill_trailing(BT,' ')));\
450             args.size = LENARG##ARRAY;\
451             args.varptr = (void *) vptr;\
452             args.flag = DAVAR_READWRITE;\
453             args.type = DATYPE;\
454             args.opaque = 0;\
455 saw   1.3   args.rhook = 0;\
456             args.whook = 0;\
457 saw   1.1   A0 = daVarRegister((int) 0, &args);\
458             if(BF) free(BF);\
459             if(BN) free(BN);\
460             if(BT) free(BT);\
461             return(A0);\
462           }
463 saw   1.2 
464           /* Can't figure out a more clever way */
465           #ifdef AbsoftUNIXFortran
466 saw   1.1 MAKEFSUB(regreal,"",float,DAVARFLOAT,SCALER)
467           MAKEFSUB(regdouble,"",double,DAVARDOUBLE,SCALER)
468           MAKEFSUB(regint,"",int,DAVARINT,SCALER)
469           MAKEFSUB(regrealarray,"",float,DAVARFLOAT,ARRAY)
470           MAKEFSUB(regdoublearray,"",double,DAVARDOUBLE,ARRAY)
471           MAKEFSUB(regintarray,"",int,DAVARINT,ARRAY)
472           
473           MAKEFSUB(regparmreal,"parm.",float,DAVARFLOAT,SCALER)
474           MAKEFSUB(regparmdouble,"parm.",double,DAVARDOUBLE,SCALER)
475           MAKEFSUB(regeventreal,"event.",float,DAVARFLOAT,SCALER)
476           MAKEFSUB(regeventdouble,"event.",double,DAVARDOUBLE,SCALER)
477           MAKEFSUB(regparmint,"parm.",int,DAVARINT,SCALER)
478           MAKEFSUB(regeventint,"event.",int,DAVARINT,SCALER)
479           MAKEFSUB(regparmrealarray,"parm.",float,DAVARFLOAT,ARRAY)
480           MAKEFSUB(regparmdoublearray,"parm.",double,DAVARDOUBLE,ARRAY)
481           MAKEFSUB(regeventrealarray,"event.",float,DAVARFLOAT,ARRAY)
482           MAKEFSUB(regeventdoublearray,"event.",double,DAVARDOUBLE,ARRAY)
483           MAKEFSUB(regparmintarray,"parm.",int,DAVARINT,ARRAY)
484           MAKEFSUB(regeventintarray,"event.",int,DAVARINT,ARRAY)
485           
486           MAKEFSUB(regtestint,"test.",int,DAVARINT,SCALER)
487 saw   1.1 MAKEFSUB(regtestintarray,"test.",int,DAVARINT,ARRAY)
488           #else
489           MAKEFSUB(regreal_,"",float,DAVARFLOAT,SCALER)
490           MAKEFSUB(regdouble_,"",double,DAVARDOUBLE,SCALER)
491           MAKEFSUB(regint_,"",int,DAVARINT,SCALER)
492           MAKEFSUB(regrealarray_,"",float,DAVARFLOAT,ARRAY)
493           MAKEFSUB(regdoublearray_,"",double,DAVARDOUBLE,ARRAY)
494           MAKEFSUB(regintarray_,"",int,DAVARINT,ARRAY)
495           
496           MAKEFSUB(regparmreal_,"parm.",float,DAVARFLOAT,SCALER)
497           MAKEFSUB(regparmdouble_,"parm.",double,DAVARDOUBLE,SCALER)
498           MAKEFSUB(regeventreal_,"event.",float,DAVARFLOAT,SCALER)
499           MAKEFSUB(regeventdouble_,"event.",double,DAVARDOUBLE,SCALER)
500           MAKEFSUB(regparmint_,"parm.",int,DAVARINT,SCALER)
501           MAKEFSUB(regeventint_,"event.",int,DAVARINT,SCALER)
502           MAKEFSUB(regparmrealarray_,"parm.",float,DAVARFLOAT,ARRAY)
503           MAKEFSUB(regparmdoublearray_,"parm.",double,DAVARDOUBLE,ARRAY)
504           MAKEFSUB(regeventrealarray_,"event.",float,DAVARFLOAT,ARRAY)
505           MAKEFSUB(regeventdoublearray_,"event.",double,DAVARDOUBLE,ARRAY)
506           MAKEFSUB(regparmintarray_,"parm.",int,DAVARINT,ARRAY)
507           MAKEFSUB(regeventintarray_,"event.",int,DAVARINT,ARRAY)
508 saw   1.1 
509           MAKEFSUB(regtestint_,"test.",int,DAVARINT,SCALER)
510           MAKEFSUB(regtestintarray_,"test.",int,DAVARINT,ARRAY)
511           #endif
512           
513           /* Entry points for String registration.  Do entry points for anything other
514           than parmameters make sense? */
515 saw   1.2 #ifdef AbsoftUNIXFortran
516           int regparmstring
517 saw   1.1 #else
518 saw   1.2 int regparmstring_
519 saw   1.1 #endif
520           (char *name, char *sptr, char *title
521           		    ,unsigned l_name, unsigned l_sptr, unsigned l_title)
522           {
523 saw   1.2   int A0;
524 saw   1.1   daVarStruct args;
525             char *BN=0;
526           
527             char *BT=0;
528             char *BF = 0;
529           
530             BF = malloc(5+l_name+1);
531             strcpy(BF,"parm.");
532             args.name = strcat(BF,((!*(int *)name)?0:memchr(name,'\0',l_name)?name:
533           			 (memcpy(BN=(char *) malloc(l_name+1),name,l_name)
534           			  ,BN[l_name]='\0',kill_trailing(BN,' '))));
535             args.title = ((!*(int *)title)?0:memchr(title,'\0',l_title)?title:
536           		 (memcpy(BT=(char *) malloc(l_title+1),title,l_title)
537           		  ,BT[l_title]='\0',kill_trailing(BT,' ')));
538             args.size = l_sptr;
539             args.varptr = (void *) sptr;
540             args.flag = DAVAR_READWRITE;
541             args.type = DAVARFSTRING;
542             args.opaque = 0;
543 saw   1.3   args.rhook = 0;
544             args.whook = 0;
545 saw   1.1   A0 = daVarRegister((int) 0, &args);
546             if(BF) free(BF);
547             if(BN) free(BN);
548             return(A0);
549           }
550           
551           #ifdef NO_TSEARCH
552           /*
553            * Tree search generalized from Knuth (6.2.2) Algorithm T just like
554            * the AT&T man page says.
555            *
556            * The node_t structure is for internal use only, lint doesn't grok it.
557            *
558            * Written by reading the System V Interface Definition, not the code.
559            *
560            * Totally public domain.
561            */
562           /*LINTLIBRARY*/
563           
564           /*
565           #include <search.h>
566 saw   1.1 
567           typedef struct node_t
568           {
569               char	  *key;
570               struct node_t *left, *right;
571           }
572           node;
573           */
574           
575           node *mytsearch(key, rootp, compar)
576           /* find or insert datum into search tree */
577           void 	*key;			/* key to be located */
578           register node	**rootp;	/* address of tree root */
579           int	(*compar)();		/* ordering function */
580           {
581               register node *q;
582           
583               if (rootp == (struct node_t **)0)
584           	return ((struct node_t *)0);
585               while (*rootp != (struct node_t *)0)	/* Knuth's T1: */
586               {
587 saw   1.1 	int r;
588           
589           	if ((r = (*compar)(key, (*rootp)->key)) == 0)	/* T2: */
590           	    return (*rootp);		/* we found it! */
591           	rootp = (r < 0) ?
592           	    &(*rootp)->left :		/* T3: follow left branch */
593           	    &(*rootp)->right;		/* T4: follow right branch */
594               }
595               q = (node *) malloc(sizeof(node));	/* T5: key not found */
596               if (q != (struct node_t *)0)	/* make new node */
597               {
598           	*rootp = q;			/* link new node to old */
599           	q->key = key;			/* initialize new node */
600           	q->left = q->right = (struct node_t *)0;
601               }
602               return (q);
603           }
604           
605           node *mytdelete(key, rootp, compar)
606           /* delete node with given key */
607           char	*key;			/* key to be deleted */
608 saw   1.1 register node	**rootp;	/* address of the root of tree */
609           int	(*compar)();		/* comparison function */
610           {
611               node *p;
612               register node *q;
613               register node *r;
614               int cmp;
615           
616               if (rootp == (struct node_t **)0 || (p = *rootp) == (struct node_t *)0)
617           	return ((struct node_t *)0);
618               while ((cmp = (*compar)(key, (*rootp)->key)) != 0)
619               {
620           	p = *rootp;
621           	rootp = (cmp < 0) ?
622           	    &(*rootp)->left :		/* follow left branch */
623           	    &(*rootp)->right;		/* follow right branch */
624           	if (*rootp == (struct node_t *)0)
625           	    return ((struct node_t *)0);	/* key not found */
626               }
627               r = (*rootp)->right;			/* D1: */
628               if ((q = (*rootp)->left) == (struct node_t *)0)	/* Left (struct node_t *)0? */
629 saw   1.1 	q = r;
630               else if (r != (struct node_t *)0)		/* Right link is null? */
631               {
632           	if (r->left == (struct node_t *)0)	/* D2: Find successor */
633           	{
634           	    r->left = q;
635           	    q = r;
636           	}
637           	else
638           	{			/* D3: Find (struct node_t *)0 link */
639           	    for (q = r->left; q->left != (struct node_t *)0; q = r->left)
640           		r = q;
641           	    r->left = q->right;
642           	    q->left = (*rootp)->left;
643           	    q->right = (*rootp)->right;
644           	}
645               }
646               free((struct node_t *) *rootp);	/* D4: Free node */
647               *rootp = q;				/* link parent to new node */
648               return(p);
649           }
650 saw   1.1 
651           static void trecurse(root, action, level)
652           /* Walk the nodes of a tree */
653           register node	*root;		/* Root of the tree to be walked */
654           register void	(*action)();	/* Function to be called at each node */
655           register int	level;
656           {
657               if (root->left == (struct node_t *)0 && root->right == (struct node_t *)0)
658           	(*action)(root, leaf, level);
659               else
660               {
661           	(*action)(root, preorder, level);
662           	if (root->left != (struct node_t *)0)
663           	    trecurse(root->left, action, level + 1);
664           	(*action)(root, postorder, level);
665           	if (root->right != (struct node_t *)0)
666           	    trecurse(root->right, action, level + 1);
667           	(*action)(root, endorder, level);
668               }
669           }
670           
671 saw   1.1 void mytwalk(root, action)		/* Walk the nodes of a tree */
672           node	*root;			/* Root of the tree to be walked */
673           void	(*action)();		/* Function to be called at each node */
674           {
675               if (root != (node *)0 && action != (void(*)())0)
676           	trecurse(root, action, 0);
677           }
678           
679           /* mytsearch.c ends here */
680           /*
681            * Tree search generalized from Knuth (6.2.2) Algorithm T just like
682            * the AT&T man page says.
683            *
684            * The node_t structure is for internal use only, lint doesn't grok it.
685            *
686            * Written by reading the System V Interface Definition, not the code.
687            *
688            * Totally public domain.
689            */
690           /*LINTLIBRARY*/
691           /*
692 saw   1.1 #include <search.h>
693           
694           typedef struct node_t
695           {
696               char	  *key;
697               struct node_t *left, *right;
698           } node;
699           */
700           
701           node *mytfind(key, rootp, compar)
702           /* find a node, or return 0 */
703           void		*key;		/* key to be found */
704           register node	**rootp;	/* address of the tree root */
705           int		(*compar)();	/* ordering function */
706           {
707               if (rootp == (struct node_t **)0)
708           	return ((struct node_t *)0);
709               while (*rootp != (struct node_t *)0)	/* T1: */
710               {
711           	int r;
712           	if ((r = (*compar)(key, (*rootp)->key)) == 0)	/* T2: */
713 saw   1.1 	    return (*rootp);		/* key found */
714           	rootp = (r < 0) ?
715           	    &(*rootp)->left :		/* T3: follow left branch */
716           	    &(*rootp)->right;		/* T4: follow right branch */
717               }
718               return (node *)0;
719           }
720           #endif

Analyzer/Replay: Mark Jones, Documents: Stephen Wood
Powered by
ViewCVS 0.9.2-cvsgraph-1.4.0