1    | /*****
2    |  ** ** Module Header ******************************************************* **
3    |  ** 									     **
4    |  **   Modules Revision 3.0						     **
5    |  **   Providing a flexible user environment				     **
6    |  ** 									     **
7    |  **   File:		cmdTrace.c					     **
8    |  **   First Edition:	1995/12/26					     **
9    |  ** 									     **
10   |  **   Authors:	Jens Hamisch, jens@Strawberry.COM			     **
11   |  ** 									     **
12   |  **   Description:	The Tcl module-trace routine which provides a con-   **
13   |  **			trolling interface to the modulecmd tracing feature  **
14   |  ** 									     **
15   |  **   Exports:		cmdModuleTrace					     **
16   |  **			GetTraceSel					     **
17   |  **			CheckTracing					     **
18   |  **			CheckTracingList				     **
19   |  ** 									     **
20   |  **   Notes:								     **
21   |  ** 									     **
22   |  ** ************************************************************************ **
23   |  ****/
24   | 
25   | /** ** Copyright *********************************************************** **
26   |  ** 									     **
27   |  ** Copyright 1991-1994 by John L. Furlan.                      	     **
28   |  ** see LICENSE.GPL, which must be provided, for details		     **
29   |  ** 									     ** 
30   |  ** ************************************************************************ **/
31   | 
32   | static char Id[] = "@(#)$Id: cmdTrace.c.src.html,v 1.6 2006/01/18 05:35:11 rkowen Exp $";
33   | static void *UseId[] = { &UseId, Id };
34   | 
35   | /** ************************************************************************ **/
36   | /** 				      HEADERS				     **/
37   | /** ************************************************************************ **/
38   | 
39   | #include "modules_def.h"
40   | 
41   | /** ************************************************************************ **/
42   | /** 				  LOCAL DATATYPES			     **/
43   | /** ************************************************************************ **/
44   | 
45   | typedef	struct	_mod_trace	{
46   |     char	 **re_ptr;		/** Pointer to the reqular expr.     **/
47   | 					/** which identifies the command     **/
48   |     char const	 *cmd;			/** The spelled command for printing **/
49   |     char	 *tracing;		/** The tracing setup	  	     **/
50   |     char	  alloc;		/** Alloc flag		    	     **/
51   | } ModTrace;
52   | 
53   | /** ************************************************************************ **/
54   | /** 				     CONSTANTS				     **/
55   | /** ************************************************************************ **/
56   | 
57   | #ifdef	WITH_TRACE_LOAD
58   | #   define	MOD_TR_LOAD	WITH_TRACE_LOAD
59   | #else
60   | #   define	MOD_TR_LOAD	_all_off
61   | #endif
62   | 
63   | #ifdef  WITH_TRACE_UNLOAD
64   | #   define	MOD_TR_UNLOAD	WITH_TRACE_UNLOAD
65   | #else
66   | #   define	MOD_TR_UNLOAD	_all_off
67   | #endif
68   | 
69   | #ifdef  WITH_TRACE_SWITCH
70   | #   define	MOD_TR_SWITCH	WITH_TRACE_SWITCH
71   | #else
72   | #   define	MOD_TR_SWITCH	_all_off
73   | #endif
74   | 
75   | #ifdef  WITH_TRACE_DISP
76   | #   define	MOD_TR_DISP	WITH_TRACE_DISP
77   | #else
78   | #   define	MOD_TR_DISP	_all_off
79   | #endif
80   | 
81   | #ifdef  WITH_TRACE_LIST
82   | #   define	MOD_TR_LIST	WITH_TRACE_LIST
83   | #else
84   | #   define	MOD_TR_LIST	_all_off
85   | #endif
86   | 
87   | #ifdef  WITH_TRACE_AVAIL
88   | #   define	MOD_TR_AVAIL	WITH_TRACE_AVAIL
89   | #else
90   | #   define	MOD_TR_AVAIL	_all_off
91   | #endif
92   | 
93   | #ifdef  WITH_TRACE_HELP
94   | #   define	MOD_TR_HELP	WITH_TRACE_HELP
95   | #else
96   | #   define	MOD_TR_HELP	_all_off
97   | #endif
98   | 
99   | #ifdef  WITH_TRACE_INIT
100  | #   define	MOD_TR_INIT	WITH_TRACE_INIT
101  | #else
102  | #   define	MOD_TR_INIT	_all_off
103  | #endif
104  | 
105  | #ifdef  WITH_TRACE_USE
106  | #   define	MOD_TR_USE	WITH_TRACE_USE
107  | #else
108  | #   define	MOD_TR_USE	_all_off
109  | #endif
110  | 
111  | #ifdef  WITH_TRACE_UNUSE
112  | #   define	MOD_TR_UNUSE	WITH_TRACE_UNUSE
113  | #else
114  | #   define	MOD_TR_UNUSE	_all_off
115  | #endif
116  | 
117  | #ifdef  WITH_TRACE_UPDATE
118  | #   define	MOD_TR_UPDATE	WITH_TRACE_UPDATE
119  | #else
120  | #   define	MOD_TR_UPDATE	_all_off
121  | #endif
122  | 
123  | #ifdef  WITH_TRACE_PURGE
124  | #   define	MOD_TR_PURGE	WITH_TRACE_PURGE
125  | #else
126  | #   define	MOD_TR_PURGE	_all_off
127  | #endif
128  | 
129  | #ifdef  WITH_TRACE_CLEAR
130  | #   define	MOD_TR_CLEAR	WITH_TRACE_CLEAR
131  | #else
132  | #   define	MOD_TR_CLEAR	_all_off
133  | #endif
134  | 
135  | #ifdef  WITH_TRACE_APROPOS
136  | #   define	MOD_TR_APROPOS	WITH_TRACE_APROPOS
137  | #else
138  | #   define	MOD_TR_APROPOS	_all_off
139  | #endif
140  | 
141  | #ifdef  WITH_TRACE_REFRESH
142  | #   define	MOD_TR_REFRESH	WITH_TRACE_REFRESH
143  | #else
144  | #   define	MOD_TR_REFRESH	_all_off
145  | #endif
146  | 
147  | #ifdef  WITH_TRACE_WHATIS
148  | #   define	MOD_TR_WHATIS	WITH_TRACE_WHATIS
149  | #else
150  | #   define	MOD_TR_WHATIS	_all_off
151  | #endif
152  | 
153  | /** ************************************************************************ **/
154  | /**				      MACROS				     **/
155  | /** ************************************************************************ **/
156  | 
157  | /** not applicable **/
158  | 
159  | /** ************************************************************************ **/
160  | /** 				    LOCAL DATA				     **/
161  | /** ************************************************************************ **/
162  | 
163  | static	char	module_name[] = "cmdTrace.c";	/** File name of this module **/
164  | #if WITH_DEBUGGING_CALLBACK
165  | static	char	_proc_cmdModuleTrace[] = "cmdModuleTrace";
166  | #endif
167  | 
168  | /**
169  |  **  Tracing strings
170  |  **  contain a colon separated list of 'switch on/switch off' selector for
171  |  **  module files. Each selector beginning with a '+' means 'tracing on', '-'
172  |  **  means 'tracing off'.
173  |  **  The +/- switch is followed by the name of the modulefile to which it
174  |  **  belongs. All valif TCL regexps may be specified here.
175  |  **/
176  | 
177  | static	char	_all[] = ".*";
178  | static	char	_all_on[] = "+.*";
179  | static	char	_all_off[] = "-.*";
180  | 
181  | /** 
182  |  **  The tracing selection table
183  |  **/
184  | 
185  | static	ModTrace	TraceSelect[] = {
186  |     { &addRE,		"load",		MOD_TR_LOAD,	0 },	/**  0 **/
187  |     { &rmRE,		"unload",	MOD_TR_UNLOAD,	0 },	/**  1 **/
188  |     { &swRE,		"switch",	MOD_TR_SWITCH,	0 },	/**  2 **/
189  |     { &dispRE,		"display",	MOD_TR_DISP,	0 },	/**  3 **/
190  |     { &listRE,		"list",		MOD_TR_LIST,	0 },	/**  4 **/
191  |     { &availRE,		"avail",	MOD_TR_AVAIL,	0 },	/**  5 **/
192  |     { &helpRE,		"help",		MOD_TR_HELP,	0 },	/**  6 **/
193  |     { &initRE,		"init",		MOD_TR_INIT,	0 },	/**  7 **/
194  |     { &useRE,		"use",		MOD_TR_USE,	0 },	/**  8 **/
195  |     { &unuseRE,		"unuse",	MOD_TR_UNUSE,	0 },	/**  9 **/
196  |     { &updateRE,	"update",	MOD_TR_UPDATE,	0 },	/** 10 **/
197  |     { &purgeRE,		"purge",	MOD_TR_PURGE,	0 },	/** 11 **/
198  |     { &clearRE,		"clear",	MOD_TR_CLEAR,	0 },	/** 12 **/
199  |     { &whatisRE,	"whatis",	MOD_TR_WHATIS,	0 },	/** 13 **/
200  |     { &aproposRE,	"apropos",	MOD_TR_APROPOS,	0 },	/** 14 **/
201  |     { &refreshRE,	"refresh",	MOD_TR_REFRESH,	0 }	/** 15 **/
202  | };
203  | /** ************************************************************************ **/
204  | 
205  | /** ************************************************************************ **/
206  | /**				    PROTOTYPES				     **/
207  | /** ************************************************************************ **/
208  | 
209  | static	int	GetTraceTable(	Tcl_Interp *interp,
210  | 				char *cmd,
211  | 				int num);
212  | 
213  | static	int	ChangeTraceSel(	Tcl_Interp *interp,
214  | 				char	*cmd_tab,
215  | 				int	 cmd_tab_size,
216  | 				char	 on_off,
217  | 				char	*module_pat);
218  | 
219  | static	int	CheckTracingPat(	Tcl_Interp *interp,
220  | 					char	*pattern,
221  | 					char	*modulefile);
222  | 
223  | /*++++
224  |  ** ** Function-Header ***************************************************** **
225  |  ** 									     **
226  |  **   Function:		cmdModuleTrace					     **
227  |  ** 									     **
228  |  **   Description:	Callback function for 'trace'			     **
229  |  ** 									     **
230  |  **   First Edition:	1995/12/26					     **
231  |  ** 									     **
232  |  **   Parameters:	ClientData	 client_data			     **
233  |  **			Tcl_Interp	*interp		According Tcl interp.**
234  |  **			int		 argc		Number of arguments  **
235  |  **			char		*argv[]		Argument array	     **
236  |  ** 									     **
237  |  **   Result:		int	TCL_OK		Successfull completion	     **
238  |  **				TCL_ERROR	Any error		     **
239  |  ** 									     **
240  |  **   Attached Globals:	TraceSelect	List containing all tracing settings **
241  |  **   			g_flags		These are set up accordingly before  **
242  |  **					this function is called in order to  **
243  |  **					control everything		     **
244  |  ** 									     **
245  |  ** ************************************************************************ **
246  |  ++++*/
247  | 
248  | int	cmdModuleTrace(	ClientData	 client_data,
249  | 	      		Tcl_Interp	*interp,
250  | 	      		int		 argc,
251  | 	      		CONST84 char	*argv[])
252  | {
253  |     char 	  on_off = '+';		/** The first argument		     **/
254  |     char	**args;			/** Argument pointer for scanning    **/
255  |     int 	  i, k;			/** Loop counter		     **/
256  |     int		  cmd_tab_size;
257  |     char	 *cmd_table;		/** Command table		     **/
258  |     int		  ret = TCL_OK;
259  | 
260  | #if WITH_DEBUGGING_CALLBACK
261  |     ErrorLogger( NO_ERR_START, LOC, _proc_cmdModuleTrace, NULL);
262  | #endif
263  | 
264  |     /**
265  |      **  Whatis mode?
266  |      **/
267  |     if( g_flags & (M_WHATIS | M_HELP))
268  |         return( TCL_OK);		/** ------- EXIT PROCEDURE -------> **/
269  | 	
270  |     /**
271  |      **  Parameter check
272  |      **/
273  |     if( argc < 2) {
274  | 	if( OK != ErrorLogger( ERR_USAGE, LOC, argv[0], "on|off",
275  | 	    "[cmd [cmd ...]]", "[ -module module [module ...]]", NULL))
276  | 	    return( TCL_ERROR);		/** -------- EXIT (FAILURE) -------> **/
277  |     }
278  | 
279  |     /**
280  |      **  On or off?
281  |      **/
282  |     if( !strcmp( argv[ 1], "on"))
283  | 	on_off = '+';
284  |     else if( !strcmp( argv[ 1], "off"))
285  | 	on_off = '-';
286  |     else {
287  | 	if( OK != ErrorLogger( ERR_USAGE, LOC, argv[0], "on|off",
288  | 	    "[cmd [cmd ...]]", "[ -module module [module ...]]", NULL))
289  | 	    return( TCL_ERROR);		/** -------- EXIT (FAILURE) -------> **/
290  |     }
291  |  
292  |   
293  |     /**
294  |      **  Non-persist mode?
295  |      **/
296  |     
297  |     if (g_flags & M_NONPERSIST) {
298  | 	return (TCL_OK);
299  |     }
300  | 
301  |     /**
302  |      **  Display mode?
303  |      **/
304  |     if( g_flags & M_DISPLAY) {
305  | 	fprintf( stderr, "%s\t ", argv[ 0]);
306  | 	for( i=1; i<argc; i++)
307  | 	    fprintf( stderr, "%s ", argv[ i]);
308  | 	fprintf( stderr, "\n");
309  |         return( TCL_OK);		/** ------- EXIT PROCEDURE -------> **/
310  |     }
311  | 
312  |     /**
313  |      **  We need a table of module command involved in this trace selection.
314  |      **  Allocate one and initialize it.
315  |      **/
316  |     cmd_tab_size = sizeof( TraceSelect) / sizeof( TraceSelect[ 0]);
317  |     if((char *) NULL == (cmd_table = (char *) malloc( cmd_tab_size)))
318  | 	return((OK == ErrorLogger( ERR_ALLOC, LOC, NULL)) ? TCL_OK : TCL_ERROR);
319  | 
320  |     /**
321  |      **  Scan all commands specified as options. The last option to be scanned
322  |      **  is either the real last one, or the '-module' one
323  |      **/
324  |     args = (char **) argv + 2; i = argc - 2;
325  |     memset( cmd_table, !i, cmd_tab_size);
326  | 
327  |     while( i--) {
328  | 	char *tmp = *args++;
329  | 
330  | 	/**
331  | 	 **  Check for '-module'
332  | 	 **/
333  | 	if( !strncmp( tmp, "-module", strlen( tmp)))
334  | 	    break;
335  | 
336  | 	/**
337  | 	 **  This should be a module command.
338  | 	 **  Check it against the TraceSelect table
339  | 	 **/
340  | 	if( -1 != (k = GetTraceTable(interp, tmp, cmd_tab_size))) {
341  | 	    cmd_table[ k] = 1;
342  | 	} else {
343  | 	    if( OK != ErrorLogger( ERR_COMMAND, LOC, tmp, NULL)) {
344  | 		null_free((void *) &cmd_table);
345  | 		return( TCL_ERROR);
346  | 	    }
347  | 	}
348  | 
349  |     } /** while( i--) **/
350  | 
351  |     /**
352  |      **  Now scan all Modulefiles concerned in the current command
353  |      **  If we ran to the end of the argument list (i==0), ALL files are
354  |      **  concerned in this ...
355  |      **/
356  |     if( 0 >= i) {	
357  | 	ret = ChangeTraceSel(interp, cmd_table, cmd_tab_size, on_off, _all);
358  |     } else {
359  | 	while( i-- && TCL_OK == ret) 
360  | 	    ret = ChangeTraceSel(interp, cmd_table, cmd_tab_size,
361  | 		on_off, *args++);
362  |     }
363  | 
364  |     /**
365  |      **  Cleanup finally and return
366  |      **/
367  |     null_free((void *) &cmd_table);
368  | 
369  | #if WITH_DEBUGGING_CALLBACK
370  |     ErrorLogger( NO_ERR_END, LOC, _proc_cmdModuleTrace, NULL);
371  | #endif
372  | 
373  |     return( ret);
374  | 
375  | } /** End of 'cmdModuleTrace' **/
376  | 
377  | /*++++
378  |  ** ** Function-Header ***************************************************** **
379  |  ** 									     **
380  |  **   Function:		GetTraceTable					     **
381  |  ** 									     **
382  |  **   Description:	Returns the TraceSelect index for the passed module  **
383  |  **			subcommand					     **
384  |  ** 									     **
385  |  **   First Edition:	1995/12/26					     **
386  |  ** 									     **
387  |  **   Parameters:	char	*cmd		Subcommand to be checked     **
388  |  **			int	 num		Number of commands to be chk **
389  |  ** 									     **
390  |  **   Result:		int	>= 0		Successfull completion	     **
391  |  **				-1		Any error		     **
392  |  ** 									     **
393  |  ** ************************************************************************ **
394  |  ++++*/
395  | 
396  | static	int	GetTraceTable(Tcl_Interp *interp, char *cmd, int num)
397  | {
398  |     int k;
399  | 
400  |     for( k=0; k < num; k++) {
401  | 	if( Tcl_RegExpMatch(interp, cmd, *(TraceSelect[k].re_ptr))) 
402  | 	    return( k);			/** ----------- Got it ------------> **/
403  |     } /** for( k) **/
404  | 
405  |     /**
406  |      **  Not found ..
407  |      **/
408  |     return( -1);
409  | 
410  | } /** End of 'GetTraceTable' **/
411  | 
412  | /*++++
413  |  ** ** Function-Header ***************************************************** **
414  |  ** 									     **
415  |  **   Function:		GetTraceSel					     **
416  |  ** 									     **
417  |  **   Description:	Retrieve the trace selection pattern for the passed  **
418  |  **			module command					     **
419  |  ** 									     **
420  |  **   First Edition:	1995/12/26					     **
421  |  ** 									     **
422  |  **   Parameters:	char	*cmd		Subcommand to be checked     **
423  |  ** 									     **
424  |  **   Result:		char *	NULL		Module subcommand not found  **
425  |  **				Otherwise	Assigned trace pattern	     **
426  |  ** 									     **
427  |  ** ************************************************************************ **
428  |  ++++*/
429  | 
430  | char	*GetTraceSel(	Tcl_Interp *interp,
431  | 			char	*cmd)
432  | {
433  |     int k;
434  | 
435  |     if( -1 == (k = GetTraceTable(interp, cmd,
436  | 	(sizeof( TraceSelect) / sizeof( TraceSelect[ 0]) ))))
437  | 	return((char *) NULL);
438  | 
439  |     return( TraceSelect[ k].tracing);
440  | 
441  | } /** End of 'GetTraceSel' **/
442  | 
443  | /*++++
444  |  ** ** Function-Header ***************************************************** **
445  |  ** 									     **
446  |  **   Function:		ChangeTraceSel					     **
447  |  ** 									     **
448  |  **   Description:	Change the trace selection for all commands speci-   **
449  |  **			fied in the passed 'cmd_table'. The passed module-   **
450  |  **			name has to be changed according 'on_off'	     **
451  |  ** 									     **
452  |  **   First Edition:	1995/12/26					     **
453  |  ** 									     **
454  |  **   Parameters:	char	*cmd_table	Boolean array indicating all **
455  |  **						commands in the TraceSelect  **
456  |  **						table to be changed	     **
457  |  **			int	 cmd_tab_size	Size of this array	     **
458  |  **			char	 on_off		'+' switch tracing on	     **
459  |  **						'-' switch tracing off       **
460  |  **			char	*module_pat	Pattern for the affected     **
461  |  **						module files		     **
462  |  ** 									     **
463  |  **   Result:		int	TCL_OK		Successfull completion	     **
464  |  **				TCL_ERROR	Any error		     **
465  |  ** 									     **
466  |  ** ************************************************************************ **
467  |  ++++*/
468  | 
469  | static	int	ChangeTraceSel(	Tcl_Interp *interp,
470  | 				char	*cmd_table,
471  | 				int	 cmd_tab_size,
472  | 				char	 on_off,
473  | 				char	*module_pat)
474  | {
475  |     char	*pattern, *s, *t, *tmp;
476  |     int		 len = strlen( module_pat);
477  |     int 	 i;
478  |     int		 ret = TCL_OK;
479  | 
480  |     /**
481  |      **  Need a buffer for to build the complete pattern
482  |      **/
483  |     if((char *) NULL == (pattern = (char *) malloc( len + 2))) {
484  | 	ErrorLogger( ERR_ALLOC, LOC, NULL);
485  | 	return( TCL_ERROR);
486  |     }
487  | 
488  |     /**
489  |      **  Check if this is the ALL pattern. If it is, replace all affected
490  |      **  entries with '_all_on' or '_all_off'
491  |      **/
492  |     if( !strcmp( module_pat, _all)) {
493  | 
494  | 	for( i=0; i < cmd_tab_size; i++) {
495  | 	    if( cmd_table[ i]) {
496  | 
497  | 		if( TraceSelect[ i].alloc)
498  | 		    null_free((void *) &(TraceSelect[ i].tracing));
499  | 		TraceSelect[ i].alloc = 0;
500  | 
501  | 		TraceSelect[ i].tracing = ('+' == on_off) ?
502  | 		    _all_on : _all_off;
503  | 	    }
504  | 	}
505  | 
506  |     } else { /** if( ALL pattern) **/
507  | 
508  | 	/**
509  | 	 **  Check the pattern for colons ...
510  | 	 **/
511  | 	if( strchr( module_pat, ':')) 
512  | 	    if( OK != ErrorLogger( ERR_COLON, LOC, module_pat, NULL))
513  | 		ret = TCL_ERROR;
514  | 
515  | 	if( TCL_OK == ret) {
516  | 
517  | 	    /**
518  | 	     **  Build the complete pattern
519  | 	     **/
520  | 	    *pattern = on_off;
521  | 	    strcpy( pattern + 1, module_pat);
522  | 	    len += 1;
523  | 
524  | 	    /**
525  | 	     **  Loop for all entries to be changed
526  | 	     **/
527  | 	    for( i=0; i < cmd_tab_size; i++) {
528  | 		if( cmd_table[ i]) {
529  | 
530  | 		    /**
531  | 		     **  allocate a buffer for the new pattern
532  | 		     **/
533  | 		    if((char *) NULL == (tmp = (char *) malloc( len + 2 +
534  | 			strlen( TraceSelect[ i].tracing)))) {
535  | 			if( OK == ErrorLogger( ERR_ALLOC, LOC, NULL)) {
536  | 			    continue;
537  | 			} else {
538  | 			    ret = TCL_ERROR;
539  | 			    break;
540  | 			}
541  | 		    }
542  | 
543  | 		    /**
544  | 		     **  Copy the new pattern to the buffer at first
545  | 		     **/
546  | 		    strcpy( tmp, pattern);
547  | 		    t = tmp + len;
548  | 
549  | 		    /**
550  | 		     **  Tokenize the old pattern and remove duplicates
551  | 		     **/
552  | 		    for( s = strtok( TraceSelect[ i].tracing, ":");
553  | 			 s;
554  | 			 s = strtok( NULL, ":") ) {
555  | 
556  | 			if( strcmp( (s+1), module_pat)) {
557  | 			    *t++ = ':';
558  | 			    while( *t++ = *s++);
559  | 			    t--;
560  | 			}
561  | 
562  | 		    } /** for **/
563  | 
564  | 		    /**
565  | 		     **  Finally check if we have to dealloc and set up the
566  | 		     **  new pattern
567  | 		     **/
568  | 
569  | 		    if( TraceSelect[ i].alloc)
570  | 			null_free((void *) &(TraceSelect[ i].tracing));
571  | 
572  | 		    TraceSelect[ i].tracing = tmp;
573  | 		    TraceSelect[ i].alloc = 1;
574  | 
575  | 		} /** if **/
576  | 	    } /** for **/
577  | 
578  | 	} /** if( ret) **/
579  |     } /** if( ALL pattern) **/
580  | 	
581  |     /**
582  |      **  Free what has been allocated an return 
583  |      **/
584  |     null_free((void *) &pattern);
585  |     return( ret);
586  | 
587  | } /** End of 'ChangeTraceSel' **/
588  | 
589  | /*++++
590  |  ** ** Function-Header ***************************************************** **
591  |  ** 									     **
592  |  **   Function:		CheckTracing					     **
593  |  ** 									     **
594  |  **   Description:	Check wheter thracing is turned on for the passed    **
595  |  **			command and modulefile				     **
596  |  ** 									     **
597  |  **   First Edition:	1995/12/26					     **
598  |  ** 									     **
599  |  **   Parameters:	char	*cmd		Subcommand to be checked     **
600  |  **			char	*modulefile	Modulefile to be checked     **
601  |  ** 									     **
602  |  **   Result:		int	0		No tracing		     **
603  |  **				1		Tracing enabled		     **
604  |  ** 									     **
605  |  ** ************************************************************************ **
606  |  ++++*/
607  | 
608  | int	CheckTracing(	Tcl_Interp *interp,
609  | 			char	*cmd,
610  | 			char	*modulefile)
611  | {
612  |     int 	 k;
613  | 
614  |     /**
615  |      **  Get the TraceSelect table index
616  |      **/
617  | 
618  |     if( -1 == (k = GetTraceTable(interp, cmd,
619  | 	(sizeof( TraceSelect) / sizeof( TraceSelect[0]) )))) {
620  | 	ErrorLogger( ERR_COMMAND, LOC, cmd, NULL);
621  | 	return( 0);
622  |     }
623  | 
624  |     /**
625  |      **  Now check this guy ...
626  |      **/
627  | 
628  |     return( CheckTracingPat(interp, TraceSelect[ k].tracing, modulefile));
629  | 
630  | } /** End of 'CheckTracing' **/
631  | 
632  | /*++++
633  |  ** ** Function-Header ***************************************************** **
634  |  ** 									     **
635  |  **   Function:		CheckTracingPat					     **
636  |  ** 									     **
637  |  **   Description:	Check the passed pattern if it enables tracing for   **
638  |  **			the passed module file				     **
639  |  ** 									     **
640  |  **   First Edition:	1995/12/26					     **
641  |  ** 									     **
642  |  **   Parameters:	char	*pattern	Pattern to be checked	     **
643  |  **			char	*modulefile	Modulefile to be checked     **
644  |  ** 									     **
645  |  **   Result:		int	0		No tracing		     **
646  |  **				1		Tracing enabled		     **
647  |  ** 									     **
648  |  ** ************************************************************************ **
649  |  ++++*/
650  | 
651  | static	int	CheckTracingPat(	Tcl_Interp *interp,
652  | 					char	*pattern,
653  | 					char	*modulefile)
654  | {
655  |     char	*s;
656  |     int		 ret;
657  | 
658  |     /**
659  |      **  Tokenize the pattern and check if it matches ...
660  |      **/
661  | 
662  |     for( s = strtok( pattern, ":");
663  | 	 s;
664  | 	 s = strtok( NULL, ":") ) {
665  | 
666  | 	ret = ('+' == *s++);
667  | 	if( Tcl_RegExpMatch(interp, modulefile, s))
668  | 	    return( ret);
669  | 
670  |     } /** for **/
671  | 
672  |     /**
673  |      **  No pattern matched the module file name ...
674  |      **/
675  | 
676  |     return( 0);
677  | 
678  | } /** End of 'CheckTracingPat' **/
679  | 
680  | /*++++
681  |  ** ** Function-Header ***************************************************** **
682  |  ** 									     **
683  |  **   Function:		CheckTracingList				     **
684  |  ** 									     **
685  |  **   Description:	Check wheter tracing is turned on for the passed     **
686  |  **			command and at least one of the passed modulefiles   **
687  |  ** 									     **
688  |  **   First Edition:	1995/12/26					     **
689  |  ** 									     **
690  |  **   Parameters:	char	*cmd		Subcommand to be checked     **
691  |  **			int	 count		Number of passed modulefiles **
692  |  **			char	**modules	Modulefiles to be checked    **
693  |  ** 									     **
694  |  **   Result:		int	0		No tracing		     **
695  |  **				1		Tracing enabled		     **
696  |  ** 									     **
697  |  ** ************************************************************************ **
698  |  ++++*/
699  | 
700  | int	CheckTracingList(	Tcl_Interp *interp,
701  | 				char	 *cmd,
702  | 				int	  count,
703  | 				char	**modules)
704  | {
705  |     int 	 k;
706  | 
707  |     /**
708  |      **  Get the TraceSelect table index
709  |      **/
710  | 
711  |     if( -1 == (k = GetTraceTable(interp, cmd,
712  | 	(sizeof( TraceSelect) / sizeof( TraceSelect[0]) )))) {
713  | 	ErrorLogger( ERR_COMMAND, LOC, cmd, NULL);
714  | 	return( 0);
715  |     }
716  | 
717  |     /**
718  |      **  Now check whether one of them requires tracing
719  |      **/
720  | 
721  |     while( count--)
722  |         if( CheckTracingPat(interp, TraceSelect[ k].tracing, *modules++))
723  | 	    return( 1);
724  | 
725  |     return( 0);
726  | 
727  | } /** End of 'CheckTracingList' **/
728  |