1    | /*****
2    |  ** ** Module Header ******************************************************* **
3    |  ** 									     **
4    |  **   Modules Revision 3.0						     **
5    |  **   Providing a flexible user environment				     **
6    |  ** 									     **
7    |  **   File:		cmdVersion.c					     **
8    |  **   First Edition:	1995/12/28					     **
9    |  ** 									     **
10   |  **   Authors:	Jens Hamisch, jens@Strawberry.COM			     **
11   |  ** 									     **
12   |  **   Description:	The Tcl module-version routine which provides the    **
13   |  **			definition of symbolic version names and the module- **
14   |  **			alias command providing the definition of module and **
15   |  **			version aliases					     **
16   |  ** 									     **
17   |  **   Exports:		cmdModuleVersion				     **
18   |  **			cmdModuleAlias					     **
19   |  **			CleanupVersion					     **
20   |  **			AliasLookup					     **
21   |  **			ExpandVersions					     **
22   |  ** 									     **
23   |  **   Notes:	This module defines the callback functions for the defi-     **
24   |  **		nition of symbolic module names and module aliases. The      **
25   |  **		syntax of the according commands is defined as:		     **
26   |  ** 									     **
27   |  **	    Module-Versions:						     **
28   |  **		module-version <module>/<version> <name> [ <name> ... ]	     **
29   |  **		module-version /<version> <name> [ <name> ... ]		     **
30   |  **		module-version <module> <name> [ <name> ... ]		     **
31   |  **		module-version <alias> <name> [ <name> ... ]		     **
32   |  ** 									     **
33   |  **	    Module-Alias:						     **
34   |  **		module-alias <alias> <module>/<version>			     **
35   |  **		module-alias <alias> /<version>				     **
36   |  **		module-alias <alias> <module>				     **
37   |  **		module-alias <alias> <alias>				     **
38   |  ** 									     **
39   |  ** 									     **
40   |  ** ************************************************************************ **
41   |  ****/
42   | 
43   | /** ** Copyright *********************************************************** **
44   |  ** 									     **
45   |  ** Copyright 1991-1994 by John L. Furlan.                      	     **
46   |  ** see LICENSE.GPL, which must be provided, for details		     **
47   |  ** 									     ** 
48   |  ** ************************************************************************ **/
49   | 
50   | static char Id[] = "@(#)$Id: cmdVersion.c.src.html,v 1.6 2006/01/18 05:35:11 rkowen Exp $";
51   | static void *UseId[] = { &UseId, Id };
52   | 
53   | /** ************************************************************************ **/
54   | /** 				      HEADERS				     **/
55   | /** ************************************************************************ **/
56   | 
57   | #include "modules_def.h"
58   | 
59   | /** ************************************************************************ **/
60   | /** 				  LOCAL DATATYPES			     **/
61   | /** ************************************************************************ **/
62   | 
63   | /** ************************************************************************ **/
64   | /**									     **/
65   | /**   The whole thing is handled in memory. The structure is build of module **/
66   | /**   and name records. There are 3 types of name records: version, name     **/
67   | /**   and alias. 							     **/
68   | /**									     **/
69   | /**         |                                                    |	     **/
70   | /**     +---+---+<-------------------------------+           +---+---+	     **/
71   | /**     | module| ------------------------+      |           | alias |	     **/
72   | /**     +---+---+ --------+               |      |           +-------+	     **/
73   | /**         |   ^    +----+----+          |      |               |	     **/
74   | /**         |   +--- | version |       +--+--+   |           +---+---+	     **/
75   | /**         |   |    +----+----+       | name|---+     <-----| alias |	     **/
76   | /**         |   |         |            +--+--+   |           +---+---+	     **/
77   | /**         |   |    +----+----+          |      |               |	     **/
78   | /**         |   +--- | version |------>+--+--+   |           +---+---+	     **/
79   | /**         |   |    +----+----+<-+--- | name|---+           | alias |	     **/
80   | /**         |   |         |       | +- +--+--+   |           +---+---+	     **/
81   | /**         |   |    +----+----+  | |     |      |               |	     **/
82   | /**         |   +--- | version |  | |  +--+--+   |           +---+---+	     **/
83   | /**         |   |    +----+----+  | |  | name|---+     <-----| alias |	     **/
84   | /**         |   |         |       | |  +--+--+   |           +---+---+	     **/
85   | /**         |                     | |     |      |               |	     **/
86   | /**         |                     | +->+--+--+   |           +---+---+	     **/
87   | /**     +---+---+                 +--- | name|---+           | alias |	     **/
88   | /**     | module|                      +--+--+   |           +---+---+	     **/
89   | /**     +---+---+                         |      |               |	     **/
90   | /**         |								     **/
91   | /**			       alphabetic ordered     alphabtic ordered	     **/
92   | /**			    list of names depending    list of aliases	     **/
93   | /**			    to a single module file			     **/
94   | /**									     **/
95   | /**   Each module name points to a list of symbolic names and versions.	     **/
96   | /**   The versions themselfes can be symbolic names and therefore are of the **/
97   | /**   same record type as the names.					     **/
98   | /**   The name and the version list is alphabetically sorted (even the       **/
99   | /**   module list is). A version record points to a related name record	     **/
100  | /**   containing a symbolic name for the version. Starting at this record,   **/
101  | /**   the name records built a queue of symbolic names for the version.	     **/
102  | /**   Both, the version and the name record do have a backward pointer to    **/
103  | /**   the module record.						     **/
104  | /**									     **/
105  | /**   The alias list builds a alphabetic ordered list of defined aliases.    **/
106  | /**   Each alias record points to the related name record.		     **/
107  | /**									     **/
108  | /** ************************************************************************ **/
109  | 
110  | typedef	struct	_mod_module	{
111  |     struct _mod_module	*next;		/** alphabetic queue		     **/
112  |     struct _mod_name	*version;	/** version queue   		     **/
113  |     struct _mod_name	*name;		/** name queue      		     **/
114  |     char		*module;	/** the name itsself		     **/
115  | } ModModule;
116  | 
117  | typedef	struct	_mod_name	{
118  |     struct _mod_name	*next;		/** alphabetic queue		     **/
119  |     struct _mod_name	*ptr;		/** logical next    		     **/
120  |     struct _mod_name	*version;	/** backwards version pointer	     **/
121  |     struct _mod_module	*module;	/** related module  		     **/
122  |     char		*name;		/** the name itsself		     **/
123  | } ModName;
124  | 
125  | /** ************************************************************************ **/
126  | /** 				     CONSTANTS				     **/
127  | /** ************************************************************************ **/
128  | 
129  | #define	HISTTAB	100
130  | 
131  | /** ************************************************************************ **/
132  | /**				      MACROS				     **/
133  | /** ************************************************************************ **/
134  | 
135  | /** not applicable **/
136  | 
137  | /** ************************************************************************ **/
138  | /** 				    LOCAL DATA				     **/
139  | /** ************************************************************************ **/
140  | 
141  | static	char	module_name[] = "cmdVersion.c";	/** File name of this module **/
142  | #if WITH_DEBUGGING_CALLBACK
143  | static	char	_proc_cmdModuleVersion[] = "cmdModuleVersion";
144  | static	char	_proc_cmdModuleAlias[] = "cmdModuleAlias";
145  | #endif
146  | #if WITH_DEBUGGING_UTIL_2
147  | static	char	_proc_CleanupVersion[] = "CleanupVersion";
148  | #endif
149  | #if WITH_DEBUGGING_UTIL_1
150  | static	char	_proc_AddModule[] = "AddModule";
151  | static	char	_proc_FindModule[] = "FindModule";
152  | static	char	_proc_AddName[] = "AddName";
153  | static	char	_proc_FindName[] = "FindName";
154  | #endif
155  | 
156  | /**
157  |  **  The module and aliases list
158  |  **/
159  | 
160  | static	ModModule	*modlist = (ModModule *) NULL;
161  | static	ModName		*aliaslist = (ModName *) NULL;
162  | 
163  | /** ************************************************************************ **/
164  | /**				    PROTOTYPES				     **/
165  | /** ************************************************************************ **/
166  | 
167  | static	void		 CleanupVersionSub(	ModModule	 *ptr);
168  | 
169  | static	void		 CleanupName(		ModName		 *ptr);
170  | 
171  | static	ModModule	*AddModule(		char		 *name);
172  | 
173  | static	ModModule	*FindModule(		char		 *name,
174  | 						ModModule	**prev);
175  | 
176  | static	ModName		*AddName(		char		 *name,
177  | 						ModName		**start,
178  | 						ModModule	 *module);
179  | 
180  | static	ModName		*FindName(		char		 *name,
181  | 						ModName		 *start,
182  | 						ModName		**prev);
183  | 
184  | static	char		*CheckModuleVersion(	char 		 *name);
185  | 
186  | static	char		*scan_versions(		char 		 *buffer,
187  | 						char		 *base,
188  | 						ModName 	 *ptr,
189  | 						ModModule 	 *modptr);
190  | 
191  | /*++++
192  |  ** ** Function-Header ***************************************************** **
193  |  ** 									     **
194  |  **   Function:		cmdModuleVersion				     **
195  |  ** 									     **
196  |  **   Description:	Callback function for 'version'			     **
197  |  ** 									     **
198  |  **   First Edition:	1995/12/28					     **
199  |  ** 									     **
200  |  **   Parameters:	ClientData	 client_data			     **
201  |  **			Tcl_Interp	*interp		According Tcl interp.**
202  |  **			int		 argc		Number of arguments  **
203  |  **			char		*argv[]		Argument array	     **
204  |  ** 									     **
205  |  **   Result:		int	TCL_OK		Successfull completion	     **
206  |  **				TCL_ERROR	Any error		     **
207  |  ** 									     **
208  |  **   Attached Globals:	modlist		List containing all version names    **
209  |  **   			g_flags		These are set up accordingly before  **
210  |  **					this function is called in order to  **
211  |  **					control everything		     **
212  |  ** 									     **
213  |  ** ************************************************************************ **
214  |  ++++*/
215  | 
216  | int	cmdModuleVersion(	ClientData	 client_data,
217  | 	      			Tcl_Interp	*interp,
218  | 	      			int		 argc,
219  | 	      			CONST84 char	*argv[])
220  | {
221  |     char	*version, *module;
222  |     ModModule	*modptr;
223  |     ModName	*versptr, *nameptr, *tmp, *ptr;
224  |     int 	 i;
225  | 
226  | #if WITH_DEBUGGING_CALLBACK
227  |     ErrorLogger( NO_ERR_START, LOC, _proc_cmdModuleVersion, NULL);
228  | #endif
229  | 
230  |     /**
231  |      **  Whatis mode?
232  |      **/
233  | 
234  |     if( g_flags & M_WHATIS) 
235  |         return( TCL_OK);		/** ------- EXIT PROCEDURE -------> **/
236  | 	
237  |     /**
238  |      **  Parameter check
239  |      **/
240  | 
241  |     if( argc < 3) {
242  | 	if( OK != ErrorLogger( ERR_USAGE, LOC, argv[0], " modulename ",
243  | 	    " symbolic-version [symbolic-version ...] ", NULL))
244  | 	    return( TCL_ERROR);		/** -------- EXIT (FAILURE) -------> **/
245  |     }
246  | 
247  |     if((char *) NULL == (module = CheckModuleVersion( (char *) argv[1]))) {
248  | 	ErrorLogger( ERR_BADMODNAM, LOC, argv[1], NULL);
249  | 	return( TCL_ERROR);		/** -------- EXIT (FAILURE) -------> **/
250  |     }
251  | 
252  |     /**
253  |      **  Display mode?
254  |      **/
255  | 
256  |     if( g_flags & M_DISPLAY) {
257  | 	fprintf( stderr, "%s\t ", argv[ 0]);
258  | 	for( i=1; i<argc; i++)
259  | 	    fprintf( stderr, "%s ", argv[ i]);
260  | 	fprintf( stderr, "\n");
261  |     }
262  | 
263  |     /**
264  |      **  get the version from the argument
265  |      **/
266  | 
267  |     if((char *) NULL == (version = strrchr( module, '/'))) {
268  | 	if( OK != ErrorLogger( ERR_INTERAL, LOC, NULL))
269  | 	    return( TCL_ERROR);		/** -------- EXIT (FAILURE) -------> **/
270  |     }
271  |     *version++ = '\0';
272  | 
273  |     /**
274  |      **  Now we have a module and a version.
275  |      **  Check wheter it exists (cond. create them). Check both, the version
276  |      **  and the name queue in order to locate the desired version ...
277  |      **/
278  | 
279  |     if((ModModule *) NULL == (modptr = AddModule( module))) {
280  | 	ErrorLogger( ERR_BADMODNAM, LOC, argv[1], NULL);
281  | 	return( TCL_ERROR);		/** -------- EXIT (FAILURE) -------> **/
282  |     }
283  | 
284  |     if((ModName *) NULL == (ptr = FindName( version, modptr->version, &tmp))) {
285  | 	if((ModName *) NULL == (ptr = FindName( version, modptr->name, &tmp))) 
286  | 	    versptr = AddName( version, &modptr->version, modptr);
287  | 	else
288  | 	    versptr = ptr->version;
289  |     } else
290  | 	versptr = ptr;
291  | 
292  |     /**
293  |      **  Check all symbolic names now and allocate a name record for them
294  |      **/
295  |     
296  |     for( i=2; i<argc; i++) {
297  | 
298  | 	if( FindName( (char *) argv[ i], modptr->name, &tmp)) {
299  | 	    if( OK != ErrorLogger( ERR_DUP_SYMVERS, LOC, argv[ i], NULL))
300  | 		break;
301  | 	    else
302  | 		continue;
303  | 	}
304  | 
305  | 	if((ModName *)NULL == (nameptr = AddName((char *)argv[ i],&modptr->name,
306  | 	    modptr))) {
307  | 	    if( OK != ErrorLogger( ERR_INTERAL, LOC, NULL))
308  | 		break;
309  | 	    else
310  | 		continue;
311  | 	}
312  | 
313  | 	/**
314  | 	 **  Concat the new element at the beginning of the name queue ...
315  | 	 **/
316  | 
317  | 	nameptr->ptr = versptr->ptr;
318  | 	versptr->ptr = nameptr;
319  | 	nameptr->version = versptr;
320  |     }
321  | 
322  | #if WITH_DEBUGGING_CALLBACK
323  |     ErrorLogger( NO_ERR_END, LOC, _proc_cmdModuleVersion, NULL);
324  | #endif
325  | 
326  |     return( TCL_OK);
327  | 
328  | } /** End of 'cmdModuleVersion' **/
329  | 
330  | /*++++
331  |  ** ** Function-Header ***************************************************** **
332  |  ** 									     **
333  |  **   Function:		ExpandVersions					     **
334  |  ** 									     **
335  |  **   Description:	Callback function for 'version'			     **
336  |  ** 									     **
337  |  **   First Edition:	1995/12/28					     **
338  |  ** 									     **
339  |  **   Parameters:	char	*name		Name to be expanded	     **
340  |  ** 									     **
341  |  **   Result:		char*	NULL		No symbols found	     **
342  |  **				Otherwise	Pointer to the list string   **
343  |  ** 									     **
344  |  ** ************************************************************************ **
345  |  ++++*/
346  | 
347  | char	*ExpandVersions( char	*name)
348  | {
349  |     char	*version, *module, *s;
350  |     static char	 buffer[ BUFSIZ];
351  |     ModModule	*modptr, *tmp1;
352  |     ModName	*ptr, *tmp2;
353  | 
354  | #if WITH_DEBUGGING_CALLBACK
355  |     ErrorLogger( NO_ERR_START, LOC, _proc_cmdModuleVersion, NULL);
356  | #endif
357  | 
358  |     /**
359  |      **  Parameter check
360  |      **/
361  | 
362  |     if((char *) NULL == (module = CheckModuleVersion( name))) 
363  | 	return((char *) NULL );		/** -------- EXIT (FAILURE) -------> **/
364  | 
365  |     if((char *) NULL == (version = strrchr( module, '/'))) {
366  | 	if( OK != ErrorLogger( ERR_INTERAL, LOC, NULL))
367  | 	    return((char *) NULL );	/** -------- EXIT (FAILURE) -------> **/
368  |     }
369  | 
370  |     *version++ = '\0';
371  | 
372  |     /**
373  |      **  Now we have a module and a version.
374  |      **  Check wheter it exists
375  |      **/
376  | 
377  |     if((ModModule *) NULL == (modptr = FindModule( module, &tmp1)))
378  | 	return((char *) NULL );		/** -------- EXIT (FAILURE) -------> **/
379  | 
380  |     if((ModName *) NULL == (ptr = FindName( version, modptr->version, &tmp2))) {
381  | 	if((ModName *) NULL == (ptr = FindName( version, modptr->name, &tmp2))) 
382  | 	    return((char *) NULL );	/** -------- EXIT (FAILURE) -------> **/
383  | 	ptr = ptr->version;
384  |     }
385  | 
386  |     if( !ptr->ptr)
387  | 	return((char *) NULL );		/** -------- EXIT (FAILURE) -------> **/
388  | 
389  |     /**
390  |      **  Now scan in all the symbolic version names
391  |      **/
392  |  
393  |     *buffer = '\0';
394  |     if( s = scan_versions( buffer, buffer, ptr->ptr, modptr)) 
395  | 	*--s = '\0';			/** remove trailing ':'		     **/
396  | 
397  | #if WITH_DEBUGGING_CALLBACK
398  |     ErrorLogger( NO_ERR_END, LOC, _proc_cmdModuleVersion, NULL);
399  | #endif
400  | 
401  |     return( buffer);
402  | 
403  | } /** End of 'ExpandVersions' **/
404  | 
405  | /*++++
406  |  ** ** Function-Header ***************************************************** **
407  |  ** 									     **
408  |  **   Function:		scan_versions					     **
409  |  ** 									     **
410  |  **   Description:	Scan all symbolic versions pointed to be the passed  **
411  |  **			ModName pointer and print them as a list into the    **
412  |  **			passed buffer.					     **
413  |  ** 									     **
414  |  **   First Edition:	1995/12/28					     **
415  |  ** 									     **
416  |  **   Parameters:	char	*buffer		Buffer for printing in	     **
417  |  **			ModName	*ptr		Name structure pointer	     **
418  |  **			ModModule  *modptr	Assigned module name	     **
419  |  ** 									     **
420  |  **   Result:		char*	NULL		Nothing printed into the     **
421  |  **						buffer			     **
422  |  **				Otherwise	Pointer to the end of the    **
423  |  **						string in the buffer	     **
424  |  ** 									     **
425  |  ** ************************************************************************ **
426  |  ++++*/
427  | 
428  | static	char	*scan_versions( char		 *buffer,
429  | 				char		 *base,
430  | 				ModName		 *ptr,
431  | 				ModModule	 *modptr)
432  | {
433  |     ModName     *tmp, *vers;
434  |     char 	*s;
435  | 
436  |     /**
437  |      **  Recursively print the queue of names
438  |      **/
439  | 
440  |     if( !ptr)
441  | 	return((char *) NULL);			/** ------ EXIT (END) -----> **/
442  | 
443  |     if( !ptr->name) {
444  | 	if( OK != ErrorLogger( ERR_INTERAL, LOC, NULL))
445  | 	    return((char *) NULL);		/** ---- EXIT (FAILURE) ---> **/
446  | 
447  |     } else {
448  | 
449  | 	/**
450  | 	 **  Prevent endless loops
451  | 	 **/
452  | 
453  | 	if( strstr( base, ptr->name)) {
454  | 	    ErrorLogger( ERR_SYMLOOP, LOC, ptr->name, NULL);
455  | 	    return((char *) NULL);		/** ---- EXIT (FAILURE) ---> **/
456  | 	}
457  | 
458  | 	/**
459  | 	 **  Now print ...
460  | 	 **/
461  | 
462  | 	/* sprintf( buffer, "%s:", ptr->name); */
463  | 	strcpy( buffer, ptr->name);
464  | 	strcat( buffer, ":");
465  | 	buffer += strlen( buffer);
466  | 
467  | 	/**
468  | 	 **  Check wheter this is a version name again ...
469  | 	 **  This is a recursion, too
470  | 	 **/
471  | 
472  | 	if((ModName *) NULL != (vers = FindName( ptr->name, modptr->version,
473  | 	    &tmp))) {
474  | 	    if( s = scan_versions( buffer, base, vers->ptr, modptr))
475  | 		buffer = s;
476  | 	}
477  |     }
478  | 
479  |     /**
480  |      **  This is the recursion. Preserve the buffer end pointer
481  |      **/
482  | 
483  |     if( s = scan_versions( buffer, base, ptr->ptr, modptr))
484  | 	buffer = s;
485  | 
486  |     return( buffer);
487  | 
488  | } /** End of 'scan_versions' **/
489  | 
490  | /*++++
491  |  ** ** Function-Header ***************************************************** **
492  |  ** 									     **
493  |  **   Function:		CheckModuleVersion				     **
494  |  ** 									     **
495  |  **   Description:	Reduce the passed module name into a <mod>/<vers>    **
496  |  **			string						     **
497  |  ** 									     **
498  |  **   First Edition:	1995/12/28					     **
499  |  ** 									     **
500  |  **   Parameters:	char	*name		name to be checked	     **
501  |  ** 									     **
502  |  **   Result:		char*	NULL		any error		     **
503  |  **				Otherwise	Pointer to a <mod>/<vers>    **
504  |  **						string			     **
505  |  ** 									     **
506  |  **   Attached Globals:	modlist		List containing all version names    **
507  |  **			aliaslist	List containing all alises	     **
508  |  **			g_current_module	The module which is handled  **
509  |  **						by the current command	     **
510  |  ** 									     **
511  |  ** ************************************************************************ **
512  |  ++++*/
513  | 
514  | static	char	*CheckModuleVersion( char *name)
515  | {
516  |     static char	 buffer[ BUFSIZ];
517  |     char	*s, *t;
518  | 
519  |     /**
520  |      **  Check the first parameter and extract modulename and version
521  |      **/
522  | 
523  |     if( '/' == *name) {			/** only the version specified	     **/
524  | 
525  | 	/**
526  | 	 **  get the module name from the current module ...
527  | 	 **/
528  | 
529  | 	if( !g_current_module)
530  | 	    return((char *) NULL);
531  | 
532  | 	strcpy( buffer, g_current_module);
533  | 	if((char *) NULL == (t = strrchr( buffer, '/')))
534  | 	    t = buffer + strlen( buffer);
535  | 	*t++ = '/';
536  | 	*t = '\0';
537  | 
538  | 	/**
539  | 	 **  The version has been specified as a parameter
540  | 	 **/
541  | 
542  | 	if( s = strrchr( name, '/')) {
543  | 	    s++;
544  | 	} else {
545  | 	    ErrorLogger( ERR_INTERAL, LOC, NULL);
546  | 	    return((char *) NULL);
547  | 	}
548  | 
549  | 	strcpy( t, s);
550  | 
551  |     } else {				/** Maybe an alias or a module	     **/
552  | 
553  | 	strcpy( buffer, name);
554  | 	if( !strrchr( buffer, '/')) {
555  | 
556  | 	    /**
557  | 	     **  Check wheter this is an alias ...
558  | 	     **/
559  | 
560  | 	    if( AliasLookup( buffer, &s, &t)) {
561  | 
562  | 		/* sprintf( buffer, "%s/%s", s, t); */
563  | 		strcpy( buffer, s);
564  | 		strcat( buffer, "/");
565  | 		strcat( buffer, t);
566  | 
567  | 	    } else {
568  | 
569  | 		/**
570  | 		 **  The default version is being selected
571  | 		 **/
572  | 
573  | 		t = buffer + strlen( buffer);
574  | 		if( '/' != *t)
575  | 		    *t++ = '/';
576  | 		strcpy( t, _default);
577  | 	    }
578  | 	}
579  |     }
580  | 
581  |     /**
582  |      **  Pass the buffer reference to the caller
583  |      **/
584  | 
585  |     return( buffer);
586  | 
587  | } /** End of 'CheckModuleVersion' **/
588  | 
589  | /*++++
590  |  ** ** Function-Header ***************************************************** **
591  |  ** 									     **
592  |  **   Function:		cmdModuleAlias					     **
593  |  ** 									     **
594  |  **   Description:	Callback function for 'alias'			     **
595  |  ** 									     **
596  |  **   First Edition:	1995/12/28					     **
597  |  ** 									     **
598  |  **   Parameters:	ClientData	 client_data			     **
599  |  **			Tcl_Interp	*interp		According Tcl interp.**
600  |  **			int		 argc		Number of arguments  **
601  |  **			char		*argv[]		Argument array	     **
602  |  ** 									     **
603  |  **   Result:		int	TCL_OK		Successfull completion	     **
604  |  **				TCL_ERROR	Any error		     **
605  |  ** 									     **
606  |  **   Attached Globals:	aliaslist	List containing all alises	     **
607  |  **   			g_flags		These are set up accordingly before  **
608  |  **					this function is called in order to  **
609  |  **					control everything		     **
610  |  ** 									     **
611  |  ** ************************************************************************ **
612  |  ++++*/
613  | 
614  | int	cmdModuleAlias(	ClientData	 client_data,
615  | 	      		Tcl_Interp	*interp,
616  | 	      		int		 argc,
617  | 	      		CONST84 char	*argv[])
618  | {
619  |     ModName	*tmp, *ptr;
620  |     char	*version, *module;
621  |     ModName	*trg_alias;
622  |     ModModule	*modptr;
623  | 
624  | #if WITH_DEBUGGING_CALLBACK
625  |     ErrorLogger( NO_ERR_START, LOC, _proc_cmdModuleAlias, NULL);
626  | #endif
627  | 
628  |     /**
629  |      **  Parameter check
630  |      **/
631  | 
632  |     if( argc != 3) {
633  | 	if( OK != ErrorLogger( ERR_USAGE, LOC, argv[0], " aliasname ",
634  | 	    "modulename", NULL))
635  | 	    return( TCL_ERROR);		/** -------- EXIT (FAILURE) -------> **/
636  |     }
637  | 
638  |     /**
639  |      **  Whatis mode?
640  |      **/
641  | 
642  |     if( g_flags & M_WHATIS) 
643  |         return( TCL_OK);		/** ------- EXIT PROCEDURE -------> **/
644  | 
645  |     if( g_flags & M_DISPLAY) {
646  | 	fprintf( stderr, "%s\t %s %s\n", argv[ 0], argv[ 1], argv[ 2]);
647  |     }
648  | 	
649  |     /**
650  |      **  Check if the target is an alias ...
651  |      **  Conditionally split up the passed <module>/<version> pair.
652  |      **/
653  | 
654  |     trg_alias = FindName( (char *) argv[ 2], aliaslist, &tmp);
655  |     if( !trg_alias) {
656  | 
657  |     	if((char *) NULL == (module = CheckModuleVersion( (char *) argv[2])))
658  | 	    module = (char *) argv[ 2];
659  | 
660  |     	if((char *) NULL != (version = strrchr( module, '/')))
661  | 	    *version++ = '\0';
662  |     }
663  | 
664  |     /**
665  |      **  Any alias record existing with this name?
666  |      **  If it does, we're finished ...
667  |      **/
668  | 
669  |     if( ptr = FindName( (char *) argv[ 1], aliaslist, &tmp)) {
670  | 
671  | 	if( !ptr->ptr || !ptr->ptr->name ||
672  | 	    !trg_alias && (!ptr->ptr->module || !ptr->ptr->module->module) ) {
673  | 	    ErrorLogger( ERR_INTERAL, LOC, NULL);
674  | 	    return( TCL_ERROR);		/** -------- EXIT (FAILURE) -------> **/
675  | 	}
676  | 
677  | 	if( trg_alias && !strcmp( ptr->ptr->name, argv[ 2]) ||
678  | 	    !trg_alias && !strcmp( ptr->ptr->name, version) &&
679  | 		!strcmp( ptr->ptr->module->module, module))
680  | 	    return( TCL_OK);		/** -------- EXIT (SUCCESS) -------> **/
681  | 
682  | 	if( OK != ErrorLogger( ERR_DUP_ALIAS, LOC, argv[1], NULL))
683  | 	    return( TCL_ERROR);		/** -------- EXIT (FAILURE) -------> **/
684  | 
685  |     } else {
686  | 
687  | 	/**
688  | 	 **  We have to allocate a new alias entry
689  | 	 **/
690  | 
691  | 	if((ModName *) NULL == (ptr = AddName((char *) argv[ 1],
692  | 		&aliaslist,NULL))) {
693  | 	    ErrorLogger( ERR_INTERAL, LOC, NULL);
694  | 	    return( TCL_ERROR);		/** -------- EXIT (FAILURE) -------> **/
695  | 	}
696  |     }
697  | 
698  |     /**
699  |      **  Now ptr points to the affected module alias record ...
700  |      **  Conditionally we have to create the module and the version record now.
701  |      **/
702  | 
703  |     if( trg_alias) {
704  | 	ptr->ptr = trg_alias;
705  | 
706  |     } else {
707  | 	if((ModModule *) NULL == (modptr = AddModule( module))) {
708  | 	    ErrorLogger( ERR_BADMODNAM, LOC, argv[2], NULL);
709  | 	    ptr->ptr = (ModName *) NULL;
710  | 	    return( TCL_ERROR);		/** -------- EXIT (FAILURE) -------> **/
711  | 	}
712  | 	ptr->ptr = AddName( (version ? version : _default), &modptr->version,
713  | 	    modptr);
714  |     }
715  | 
716  | #if WITH_DEBUGGING_CALLBACK
717  |     ErrorLogger( NO_ERR_END, LOC, _proc_cmdModuleAlias, NULL);
718  | #endif
719  | 
720  |     return( TCL_OK);
721  | 
722  | } /** End of 'cmdModuleAlias' **/
723  | 
724  | /*++++
725  |  ** ** Function-Header ***************************************************** **
726  |  ** 									     **
727  |  **   Function:		AliasLookup					     **
728  |  ** 									     **
729  |  **   Description:	Resolves a given alias to a module/version string    **
730  |  ** 									     **
731  |  **   First Edition:	1995/12/28					     **
732  |  ** 									     **
733  |  **   Parameters:	char	*alias		Name of the alias to be re-  **
734  |  **						solved			     **
735  |  **			char	**module	Buffer for the module name   **
736  |  **			char	**version	Buffer for the module version**
737  |  ** 									     **
738  |  **   Result:		int	1		Success, value in the buffer **
739  |  **						is valid		     **
740  |  **				0		Any error, or not found	     **
741  |  ** 									     **
742  |  **   Attached Globals:	aliaslist	List containing all alises	     **
743  |  ** 									     **
744  |  ** ************************************************************************ **
745  |  ++++*/
746  | 
747  | int	AliasLookup(	char	*alias,
748  | 			char	**module,
749  | 			char	**version)
750  | {
751  |     ModName	*ptr, *tmp, *oldptr = NULL;
752  | 
753  |     while( 1) {
754  | 
755  | 	/**
756  | 	 **  Lokate the alias entry and check intergrity
757  | 	 **/
758  | 
759  | 	if((ModName *) NULL == (ptr = FindName( alias, aliaslist, &tmp)))
760  | 	    return( 0);			/** ------- EXIT (not found) ------> **/
761  | 
762  | 	if( ptr == oldptr || !ptr->ptr || !ptr->ptr->name ) {
763  | 	    ErrorLogger( ERR_INTERAL, LOC, NULL);
764  | 	    return( 0);			/** -------- EXIT (FAILURE) -------> **/
765  | 	}
766  | 
767  | 	/**
768  | 	 **  Do we have to loop? Another alias has no module reference ...
769  | 	 **/
770  | 
771  |         if( !ptr->ptr->module) {
772  | 	    alias = ptr->ptr->name;
773  | 	    oldptr = ptr;
774  | 	    continue;
775  | 	}
776  | 
777  | 	/**
778  | 	 **  Got it. Get the module name and the version from the found
779  | 	 **  entry.
780  | 	 **  Dereference symbolic module versions
781  | 	 **/
782  | 
783  | 	*module = ptr->ptr->module->module;
784  | 	*version = ptr->ptr->name;
785  | 
786  | 	if((ModName *) NULL != (ptr = FindName( *version,
787  | 	    ptr->ptr->module->name, &tmp))) {
788  | 	    if( !ptr->version || !ptr->version->name) {
789  | 		if( OK != ErrorLogger( ERR_INTERAL, LOC, NULL))
790  | 		    return( 0);
791  | 	    } else 
792  | 		*version = ptr->version->name;
793  | 	}
794  | 
795  | 	break;
796  | 
797  |     } /** while **/
798  | 
799  |     return( 1);
800  | 
801  | } /** End of 'AliasLookup' **/
802  | 
803  | /*++++
804  |  ** ** Function-Header ***************************************************** **
805  |  ** 									     **
806  |  **   Function:		VersionLookup					     **
807  |  ** 									     **
808  |  **   Description:	Resolves a given alias to a module/version string    **
809  |  ** 									     **
810  |  **   First Edition:	1995/12/28					     **
811  |  ** 									     **
812  |  **   Parameters:	char	*alias		Name of the alias to be re-  **
813  |  **						solved			     **
814  |  **			char	**module	Buffer for the module name   **
815  |  **			char	**version	Buffer for the module version**
816  |  ** 									     **
817  |  **   Result:		int	1		Success, value in the buffer **
818  |  **						is valid		     **
819  |  **				0		Any error, or not found	     **
820  | 
821  |  **   Attached Globals:	g_current_module	The module which is handled  **
822  |  **						by the current command	     **
823  |  ** 									     **
824  |  ** ************************************************************************ **
825  |  ++++*/
826  | 
827  | int	VersionLookup(	char *name, char **module, char **version)
828  | {
829  |     static char  buffer[ BUFSIZ];
830  |     ModModule	*mptr, *mtmp;
831  |     ModName	*vptr, *vtmp;
832  |     ModName	**history;
833  |     char	*s, *t;
834  |     int		 histsize = 0, histndx = 0, i;
835  | 
836  |     /**
837  |      **  Check whether this is an alias ...
838  |      **  BTW: Alias lookups return the FQMN (full qualifed module name ;-)
839  |      **/
840  | 
841  |     if( '/' == *name) {
842  | 	strcpy( buffer, g_current_module);
843  | 	if( s = strrchr( buffer, '/'))
844  | 	    *s = '\0';
845  | 	*module = buffer;
846  | 	*version = name + 1;
847  |     
848  |     } else {
849  | 
850  | 	strcpy( buffer, name);
851  | 	*module = buffer;
852  | 
853  | 	if((char *) NULL == (*version = strrchr( buffer, '/'))) {
854  | 
855  | 	    if( AliasLookup( buffer, &s, &t)) {
856  | 		*module = s; *version = t;
857  | 
858  | 	    } else
859  | 		*version = _default;
860  | 
861  | 	} else 
862  | 	    *(*version)++ = '\0';
863  |     }
864  | 
865  |     /**
866  |      **  Look up modulename ...
867  |      **  We call it success, if we do not find a registerd name.
868  |      **  In this case <module>/<version> will be returned as passed.
869  |      **/
870  |     if((ModModule *) NULL == (mptr = FindModule( *module, &mtmp))) {
871  | 	return( 1);			/** -------- EXIT (SUCCESS) -------> **/
872  |     }
873  | 
874  |     /**
875  |      **  This is for preventing from endless loops
876  |      **/
877  |     histsize = HISTTAB;
878  |     histndx = 0;
879  | 
880  |     if((ModName **) NULL == (history = (ModName **) malloc( histsize * 
881  | 	sizeof( ModName *)))) {
882  | 	ErrorLogger( ERR_ALLOC, LOC, NULL);
883  | 	return( 0);			/** -------- EXIT (FAILURE) -------> **/
884  |     }
885  | 
886  |     /**
887  |      **  Now look up the version name. Check symbolic names first. If some-
888  |      **  thing is found, check if the related version record itsself relates
889  |      **  to a name record ...
890  |      **/
891  |     while( 1) {
892  | 
893  | 	/**
894  | 	 **  Check the symbolic names ...
895  | 	 **/
896  | 	if((ModName *) NULL != (vptr = FindName( *version, mptr->name, &vtmp))){
897  | 	    if( !vptr->version || !vptr->version->name) {
898  | 		if( OK != ErrorLogger( ERR_INTERAL, LOC, NULL)) 
899  | 		    *version = (char *) NULL;
900  | 		break;
901  | 	    }
902  | 
903  | 	    *version = vptr->version->name;
904  | 
905  | 	    /**
906  | 	     **  Prevent from looping ...
907  | 	     **/
908  | 	    for( i=0; i<histndx; i++) {
909  | 		if( history[ i] == vptr) {		/** That's the loop  **/
910  | 		    ErrorLogger( ERR_SYMLOOP, LOC, *version, NULL);
911  | 		    *version = (char *) NULL;
912  | 		    break;
913  | 		}
914  | 	    }
915  | 
916  | 	    if( !*version)
917  | 		break;
918  | 
919  | 	    if( histndx >= histsize) {
920  | 		histsize += HISTTAB;
921  | 
922  | 		if((ModName **) NULL == (history = (ModName **) realloc(
923  | 		    history, histsize * sizeof( ModName *)))) {
924  | 		    ErrorLogger( ERR_ALLOC, LOC, NULL);
925  | 		    return( 0);		/** -------- EXIT (FAILURE) -------> **/
926  | 		}
927  | 	    }
928  | 
929  | 	    history[ histndx++] = vptr;
930  | 
931  | 	} else {
932  | 	    break;
933  | 
934  | 	} /** if( FindName) **/
935  |     } /** while( 1) **/
936  | 
937  |     /**
938  |      **  Free the loop preventing list
939  |      **  If version is NULL now, something went wrong in the lookup loop above
940  |      **/
941  |     null_free((void *) &history);
942  |     return((char *) NULL != *version);
943  | 
944  | } /** End of 'VersionLookup' **/
945  | 
946  | /*++++
947  |  ** ** Function-Header ***************************************************** **
948  |  ** 									     **
949  |  **   Function:		CleanupVersion					     **
950  |  ** 									     **
951  |  **   Description:	Cleanup the version structure			     **
952  |  ** 									     **
953  |  **   First Edition:	1995/12/28					     **
954  |  ** 									     **
955  |  **   Parameters:	-						     **
956  |  ** 									     **
957  |  **   Result:		-						     **
958  |  ** 									     **
959  |  **   Attached Globals:	modlist		List containing all version names    **
960  |  **			aliaslist	List containing all alises	     **
961  |  ** 									     **
962  |  ** ************************************************************************ **
963  |  ++++*/
964  | 
965  | void	CleanupVersion(ModModule *ptr)
966  | {
967  | #if WITH_DEBUGGING_UTIL_2
968  |     ErrorLogger( NO_ERR_START, LOC, _proc_CleanupVersion, NULL);
969  | #endif
970  | 
971  |     CleanupVersionSub( modlist);
972  |     modlist = (ModModule *) NULL;
973  | 
974  |     CleanupName( aliaslist);
975  |     aliaslist = (ModName *) NULL;
976  | 
977  | } /** End of 'CleanupVersion' **/
978  | 
979  | static void	CleanupVersionSub( ModModule *ptr)
980  | {
981  |     /**
982  |      **  Recursion
983  |      **/
984  | 
985  |     if( !ptr)
986  | 	return;
987  | 
988  |     CleanupVersion( ptr->next);
989  | 
990  |     /**
991  |      **  Cleanup everything that relates to this record
992  |      **/
993  | 
994  |     CleanupName( ptr->version);
995  |     CleanupName( ptr->name);
996  |     null_free((void *) &(ptr->module));
997  | 
998  | } /** End of 'CleanupVersionSub' **/
999  | 
1000 | static void	CleanupName( ModName *ptr)
1001 | {
1002 |     /**
1003 |      **  Recursion
1004 |      **/
1005 | 
1006 |     if( !ptr)
1007 | 	return;
1008 | 
1009 |     CleanupName( ptr->next);
1010 | 
1011 |     /**
1012 |      **  Cleanup everything that relates to this record
1013 |      **/
1014 | 
1015 |     null_free((void *) &(ptr->name));
1016 | 
1017 | } /** End of 'CleanupName' **/
1018 | 
1019 | /*++++
1020 |  ** ** Function-Header ***************************************************** **
1021 |  ** 									     **
1022 |  **   Function:		AddModule					     **
1023 |  ** 									     **
1024 |  **   Description:	Add a new entry to the modules queue		     **
1025 |  ** 									     **
1026 |  **   First Edition:	1995/12/28					     **
1027 |  ** 									     **
1028 |  **   Parameters:	char	*name		Name of the new module	     **
1029 |  ** 									     **
1030 |  **   Result:		ModModule*	NULL	Any error                    **
1031 |  **					Else	Pointer to the new record    **
1032 |  ** 									     **
1033 |  **   Attached Globals:	modlist		List containing all version names    **
1034 |  ** 									     **
1035 |  ** ************************************************************************ **
1036 |  ++++*/
1037 | 
1038 | static	ModModule	*AddModule(	char	*name)
1039 | {
1040 |     ModModule	*app_ptr, *ptr;
1041 | 
1042 | #if WITH_DEBUGGING_UTIL_1
1043 |     ErrorLogger( NO_ERR_START, LOC, _proc_AddModule, NULL);
1044 | #endif
1045 | 
1046 |     /**
1047 |      **  We do not trust in NULL module names
1048 |      **/
1049 | 
1050 |     if( !name || !*name)
1051 | 	return((ModModule *) NULL);
1052 | 
1053 |     /**
1054 |      **  Check if the module name already exists and save the 'prev' pointer
1055 |      **  for appending the new one.
1056 |      **/
1057 | 
1058 |     if( ptr = FindModule( name, &app_ptr))
1059 | 	return( ptr);
1060 | 
1061 |     /**
1062 |      **  Allocate a new guy
1063 |      **/
1064 | 
1065 |     if((ModModule *) NULL == (ptr = (ModModule *) malloc( sizeof(ModModule)))) {
1066 | 	ErrorLogger( ERR_ALLOC, LOC, NULL);
1067 | 	return((ModModule *) NULL);
1068 |     }
1069 | 
1070 |     /**
1071 |      **  Fill the name in and put it in the queue
1072 |      **/
1073 | 
1074 |     if((char *) NULL == (ptr->module = strdup( name))) {
1075 | 	ErrorLogger( ERR_ALLOC, LOC, NULL);
1076 | 	null_free((void *) &ptr);
1077 | 	return((ModModule *) NULL);
1078 |     }
1079 | 
1080 |     if( app_ptr) {
1081 | 	ptr->next = app_ptr->next;
1082 | 	app_ptr->next = ptr;
1083 |     } else {
1084 | 	ptr->next = modlist;
1085 | 	modlist = ptr;
1086 |     }
1087 | 
1088 |     ptr->version = (ModName *) NULL;
1089 |     ptr->name = (ModName *) NULL;
1090 | 
1091 |     /**
1092 |      **  Pass back the pointer to the new entry
1093 |      **/
1094 | 
1095 | #if WITH_DEBUGGING_UTIL_1
1096 |     ErrorLogger( NO_ERR_END, LOC, _proc_AddModule, NULL);
1097 | #endif
1098 | 
1099 |     return( ptr);
1100 | 
1101 | } /** End of 'AddModule' **/
1102 | 
1103 | /*++++
1104 |  ** ** Function-Header ***************************************************** **
1105 |  ** 									     **
1106 |  **   Function:		FindModule					     **
1107 |  ** 									     **
1108 |  **   Description:	Find a new entry in the modules queue		     **
1109 |  ** 									     **
1110 |  **   First Edition:	1995/12/28					     **
1111 |  ** 									     **
1112 |  **   Parameters:	char		*name	Name of be found	     **
1113 |  **			ModModule	**prev	Buffer for the 'previous'    **
1114 |  **						pointer			     **
1115 |  ** 									     **
1116 |  **   Result:		ModModule*	NULL	Any error or not found       **
1117 |  **					Else	Pointer to the record	     **
1118 |  ** 									     **
1119 |  **   Attached Globals:	modlist		List containing all version names    **
1120 |  ** 									     **
1121 |  ** ************************************************************************ **
1122 |  ++++*/
1123 | 
1124 | static	ModModule	*FindModule(	char		 *name,
1125 | 					ModModule	**prev)
1126 | {
1127 |     ModModule	*ptr = modlist;
1128 |     int		 cmp = 1;
1129 | 
1130 | #if WITH_DEBUGGING_UTIL_1
1131 |     ErrorLogger( NO_ERR_START, LOC, _proc_FindModule, NULL);
1132 | #endif
1133 | 
1134 |     *prev = (ModModule *) NULL;
1135 |     while( ptr && 0 < (cmp = strcmp( name, ptr->module))) {
1136 | 	*prev = ptr;
1137 | 	ptr = ptr->next;
1138 |     }
1139 | 
1140 | #if WITH_DEBUGGING_UTIL_1
1141 |     ErrorLogger( NO_ERR_END, LOC, _proc_FindModule, NULL);
1142 | #endif
1143 | 
1144 |     return( cmp ? (ModModule *) NULL : ptr);
1145 | 
1146 | } /** End of 'FindModule' **/
1147 | 
1148 | /*++++
1149 |  ** ** Function-Header ***************************************************** **
1150 |  ** 									     **
1151 |  **   Function:		AddName						     **
1152 |  ** 									     **
1153 |  **   Description:	Add a new entry to the name queue		     **
1154 |  ** 									     **
1155 |  **   First Edition:	1995/12/28					     **
1156 |  ** 									     **
1157 |  **   Parameters:	char	 *name		Name of the new entry	     **
1158 |  **			ModName	**start		Start of the queue	     **
1159 |  **			ModModule *module	Parent module record pointer **
1160 |  ** 									     **
1161 |  **   Result:		ModName*	NULL	Any error                    **
1162 |  **					Else	Pointer to the new record    **
1163 |  ** 									     **
1164 |  ** ************************************************************************ **
1165 |  ++++*/
1166 | 
1167 | static	ModName	*AddName(	char	 *name,
1168 | 				ModName	**start,
1169 | 				ModModule *module)
1170 | {
1171 |     ModName	*app_ptr, *ptr;
1172 | 
1173 | #if WITH_DEBUGGING_UTIL_1
1174 |     ErrorLogger( NO_ERR_START, LOC, _proc_AddName, NULL);
1175 | #endif
1176 | 
1177 |     /**
1178 |      **  Check if the name already exists and save the 'prev' pointer
1179 |      **  for appending the new one.
1180 |      **/
1181 | 
1182 |     if( ptr = FindName( name, *start, &app_ptr))
1183 | 	return( ptr);
1184 | 
1185 |     /**
1186 |      **  Allocate a new guy
1187 |      **/
1188 | 
1189 |     if((ModName *) NULL == (ptr = (ModName *) malloc( sizeof(ModName)))) {
1190 | 	ErrorLogger( ERR_ALLOC, LOC, NULL);
1191 | 	return((ModName *) NULL);
1192 |     }
1193 | 
1194 |     /**
1195 |      **  Fill the name in and put it in the queue
1196 |      **/
1197 | 
1198 |     if((char *) NULL == (ptr->name = strdup( name))) {
1199 | 	ErrorLogger( ERR_ALLOC, LOC, NULL);
1200 | 	null_free((void *) &ptr);
1201 | 	return((ModName *) NULL);
1202 |     }
1203 | 
1204 |     if( app_ptr) {
1205 | 	ptr->next = app_ptr->next;
1206 | 	app_ptr->next = ptr;
1207 |     } else {
1208 | 	ptr->next = *start;
1209 | 	*start = ptr;
1210 |     }
1211 | 
1212 |     ptr->module = module;
1213 |     ptr->version = ptr->ptr = (ModName *) NULL;
1214 | 
1215 |     /**
1216 |      **  Pass back the pointer to the new entry
1217 |      **/
1218 | 
1219 | #if WITH_DEBUGGING_UTIL_1
1220 |     ErrorLogger( NO_ERR_END, LOC, _proc_AddName, NULL);
1221 | #endif
1222 | 
1223 |     return( ptr);
1224 | 
1225 | } /** End of 'AddName' **/
1226 | 
1227 | /*++++
1228 |  ** ** Function-Header ***************************************************** **
1229 |  ** 									     **
1230 |  **   Function:		FindName					     **
1231 |  ** 									     **
1232 |  **   Description:	Find a new entry in the modules queue		     **
1233 |  ** 									     **
1234 |  **   First Edition:	1995/12/28					     **
1235 |  ** 									     **
1236 |  **   Parameters:	char	 *name		Name of be found	     **
1237 |  **			ModName  *start		Start of the name queue      **
1238 |  **			ModName	**prev		Buffer for the 'previous'    **
1239 |  **						pointer			     **
1240 |  ** 									     **
1241 |  **   Result:		ModName*	NULL	Any error or not found       **
1242 |  **					Else	Pointer to the record	     **
1243 |  ** 									     **
1244 |  ** ************************************************************************ **
1245 |  ++++*/
1246 | 
1247 | static	ModName	*FindName(	char	 *name,
1248 | 				ModName  *start,
1249 | 				ModName	**prev)
1250 | {
1251 |     ModName	*ptr = start;
1252 |     int		 cmp = 1;
1253 | 
1254 | #if WITH_DEBUGGING_UTIL_1
1255 |     ErrorLogger( NO_ERR_START, LOC, _proc_FindName, NULL);
1256 | #endif
1257 | 
1258 |     *prev = (ModName *) NULL;
1259 |     while( ptr && 0 < (cmp = strcmp( name, ptr->name))) {
1260 | 	*prev = ptr;
1261 | 	ptr = ptr->next;
1262 |     }
1263 | 
1264 | #if WITH_DEBUGGING_UTIL_1
1265 |     ErrorLogger( NO_ERR_END, LOC, _proc_FindName, NULL);
1266 | #endif
1267 | 
1268 |     return( cmp ? (ModName *) NULL : ptr);
1269 | 
1270 | } /** End of 'FindName' **/