int ModuleCmd_Switch( Tcl_Interp *interp, int argc, char *argv[]) { char *oldmodule, *newmodule, *realname, *oldfile, *newfile, *oldname, *newname, *oldmodule_buffer = (char *) NULL; int ret_val = TCL_OK; /** ** allocate buffer memory **/ if (!(oldfile = stringer(NULL, MOD_BUFSIZE, NULL))) if( OK != ErrorLogger( ERR_STRING, LOC, NULL)) goto unwind0; if (!(newfile = stringer(NULL, MOD_BUFSIZE, NULL))) if( OK != ErrorLogger( ERR_STRING, LOC, NULL)) goto unwind1; if (!(oldname = stringer(NULL, MOD_BUFSIZE, NULL))) if( OK != ErrorLogger( ERR_STRING, LOC, NULL)) goto unwind2; if (!(newname = stringer(NULL, MOD_BUFSIZE, NULL))) if( OK != ErrorLogger( ERR_STRING, LOC, NULL)) goto unwind3; /** ** Parameter check. the required syntax is: ** module switch [ <old> ] <new> ** If <old> is not specified, then the pathname of <new> is assumed. **/ if( argc == 1) { newmodule = argv[0]; if(!(oldmodule_buffer = stringer(NULL,0,newmodule,NULL))) if( OK != ErrorLogger( ERR_STRING, LOC, NULL)) goto unwind4; /* starting from the end of the module name, find the first * forward slash and replace with null */ if ((oldmodule = strrchr(oldmodule_buffer, *psep))) { *oldmodule = 0; } oldmodule = oldmodule_buffer; } else if( argc == 2) { oldmodule = argv[0]; newmodule = argv[1]; } else { if( OK != ErrorLogger( ERR_USAGE, LOC, "switch oldmodule newmodule", NULL)) return( TCL_ERROR); /** ------- EXIT (FAILURE) --------> **/ } /** ** Set the name of the module specified on the command line **/ g_specified_module = oldmodule; /** ** First try to find a match for the modulefile out of the LOADEDMODULES. **/ if( !IsLoaded( interp, oldmodule, &realname, oldfile)) if( OK != ErrorLogger( ERR_NOTLOADED, LOC, oldmodule, NULL)) goto unwind4; /** ** If we have another name to try, try finding it on disk. **/ if( realname) ret_val = Locate_ModuleFile( interp, realname, oldname, oldfile); /** ** If we've made it this far without finding a file, then look using the ** exact name the user gave me -- i.e. the old method. **/ if( ret_val == TCL_ERROR) { if( TCL_ERROR == (ret_val = Locate_ModuleFile( interp, oldmodule, oldname, oldfile))) if( OK != ErrorLogger( ERR_LOCATE, LOC, oldmodule, NULL)) goto unwind4; /** ** OK, this one is known. Is it loaded, too? **/ if( !IsLoaded( interp, oldname, NULL, oldfile)) if( OK != ErrorLogger( ERR_NOTLOADED, LOC, oldmodule, NULL)) goto unwind4; } /** ** Set the name of the module specified on the command line **/ g_specified_module = newmodule; /** ** Now try to find the new file to swap with. **/ if( TCL_ERROR == (ret_val = Locate_ModuleFile( interp, newmodule, newname, newfile))) if( OK != ErrorLogger( ERR_LOCATE, LOC, newmodule, NULL)) goto unwind4; ErrorLogger( NO_ERR_VERBOSE, LOC, "Switching '$1' to '$2'", oldmodule, newmodule, NULL); /** ** We'll remove the current modulefile with the SWITCH1 state set. ** This means that instead of really removing the paths, markers will ** be put in its place for later use. **/ g_flags |= (M_REMOVE | M_SWSTATE1); g_specified_module = oldmodule; g_current_module = oldname; if( Read_Modulefile( interp, oldfile) == 0) Update_LoadedList( interp, oldname, oldfile); else { ErrorLogger( NO_ERR_VERBOSE, LOC, "failed", NULL); goto unwind4; } g_flags &= ~(M_REMOVE | M_SWSTATE1); /** ** Move on to state SWITCH2. This loads the modulefile at the append ** and prepend markers. **/ g_flags |= M_SWSTATE2; g_specified_module = newmodule; g_current_module = newname; if( Read_Modulefile( interp, newfile) == 0) Update_LoadedList( interp, newname, newfile); else { ErrorLogger( NO_ERR_VERBOSE, LOC, "failed", NULL); goto unwind4; } g_flags &= ~M_SWSTATE2; /** ** This actually unsets environment variables and gets rid of the ** markers. **/ g_flags |= (M_REMOVE | M_SWSTATE3); g_specified_module = oldmodule; g_current_module = oldname; if( Read_Modulefile( interp, oldfile) == 0) Update_LoadedList( interp, newname, newfile); else { ErrorLogger( NO_ERR_VERBOSE, LOC, "failed", NULL); goto unwind4; } /** ** Return on success **/ ErrorLogger( NO_ERR_VERBOSE, LOC, "done", NULL); /** ** free space ** assume don't need what's pointed to by g_current_module ** and g_specified_module **/ null_free((void *) &newname); null_free((void *) &oldname); null_free((void *) &newfile); null_free((void *) &oldfile); return( TCL_OK); /** ------- EXIT (SUCCESS) --------> **/ unwind4: if (oldmodule == oldmodule_buffer) null_free((void *) &oldmodule); null_free((void *) &newname); unwind3: null_free((void *) &oldname); unwind2: null_free((void *) &newfile); unwind1: null_free((void *) &oldfile); unwind0: return( TCL_ERROR); /** ------- EXIT (FAILURE) --------> **/ } /** End of 'ModuleCmd_Switch' **/
int ModuleCmd_Whatis( Tcl_Interp *interp, int argc, char *argv[]) { struct stat stats; Tcl_Interp *whatis_interp; Tcl_DString cmdbuf; int i, result = TCL_OK, done = 0; char modulefile[ MOD_BUFSIZE], modulename[ MOD_BUFSIZE], *modpath = (char *)NULL,/** Buffer for the contents of the **/ /** environment variable MODULEPATH **/ **wptr, *dirname = (char *)NULL, *cache_file = (char *) NULL; /** Name of the cache file **/ FILE *cachefp = (FILE *) NULL; /** Cache file pointer **/ #if WITH_DEBUGGING_MODULECMD ErrorLogger( NO_ERR_START, LOC, _proc_ModuleCmd_Whatis, NULL); #endif /** ** Initialize the command buffer and set up the modules flag to ** 'whatisonly' **/ Tcl_DStringInit( &cmdbuf); g_flags |= M_WHATIS; /** ** Handle each passed module file. Create a Tcl interpreter for each ** module file to be handled and initialize it with custom module commands **/ if ( argc) { /** ** User provided a list of modules for ``whatis'' info **/ for(i=0; i<argc && argv[i]; i++) { whatis_interp = EM_CreateInterp(); if( TCL_OK != (result = InitializeModuleCommands( whatis_interp))) { EM_DeleteInterp( whatis_interp); result = TCL_ERROR; break; } /** ** locate the filename related to the passed module **/ if( TCL_ERROR == Locate_ModuleFile(whatis_interp,argv[i],modulename,modulefile)){ EM_DeleteInterp( whatis_interp); if( OK != ErrorLogger( ERR_LOCATE, LOC, argv[i], NULL)) break; else continue; } /** ** Print out everything that would happen if the module file were ** executed ... **/ g_current_module = modulename; cmdModuleWhatisInit(); result = CallModuleProcedure( whatis_interp, &cmdbuf, modulefile, "ModulesWhatis", 0); /** ** Print the result ... **/ if( whatis) { wptr = whatis; while( *wptr) fprintf( stderr, "%-21s: %s\n", argv[i], *wptr++); } /** ** Remove the Tcl interpreter that has been used for printing ... **/ EM_DeleteInterp( whatis_interp); cmdModuleWhatisShut(); } /** for **/ } else { /** ** User wants all module ``whatis'' info **/ /** ** If no MODULEPATH defined, we can not output anything **/ if( !(modpath = (char *) xgetenv( "MODULEPATH"))) if( OK != ErrorLogger( ERR_MODULE_PATH, LOC, NULL)) goto unwind0; /** ** Check whether a cache file exists then list all the ``whatis'' info ** Otherwise read all module files ... **/ cache_file = apropos_cache(); if( !sw_create && cache_file && !stat( cache_file, &stats)) { /** ** Open the cache file **/ if((FILE *) NULL == (cachefp = fopen( cache_file, "r"))) { if( OK != ErrorLogger( ERR_OPEN, LOC, cache_file, NULL)) goto unwind1; } else { /** ** Read the cache and close the file **/ result = read_cache( argc, argv, cachefp, WHATIS_ALL); if( EOF == fclose( cachefp)) if( OK != ErrorLogger( ERR_CLOSE, LOC, cache_file, NULL)) goto unwind1; done = 1; } } /** ** If we're not done now, we have to scan the files **/ if( !done) { /** ** Open the cache file if neccessary **/ if( sw_create && cache_file) if((FILE *) NULL == (cachefp = fopen( cache_file, "w"))) if( OK != ErrorLogger( ERR_OPEN, LOC, cache_file, NULL)) goto unwind1; /** ** Tokenize the module path string and check all dirs **/ for( dirname = xstrtok( modpath, ":"); dirname; dirname = xstrtok( NULL, ":") ) { if( !check_dir( dirname)) continue; whatis_dir( dirname, argc, argv, cachefp, WHATIS_ALL); } /** for **/ /** ** Close the cache file **/ if( cachefp) if( EOF == fclose( cachefp)) if( OK != ErrorLogger( ERR_CLOSE, LOC, cache_file, NULL)) goto unwind1; } } /** ** Leave the 'whatis only mode', free up what has been used and return **/ g_flags &= ~M_WHATIS; fprintf( stderr, "\n"); Tcl_DStringFree( &cmdbuf); /** ** Free up allocated resources **/ null_free((void *) &cache_file); null_free((void *) &modpath); /** ** Return on success **/ #if WITH_DEBUGGING_MODULECMD ErrorLogger( NO_ERR_END, LOC, _proc_ModuleCmd_Whatis, NULL); #endif return( result); /** --- EXIT PROCEDURE (result) --> **/ unwind1: null_free((void *) &cache_file); null_free((void *) &modpath); unwind0: return( TCL_ERROR); /** --- EXIT PROCEDURE (FAILURE) --> **/ } /** End of 'ModuleCmd_Whatis' **/
static int PerModuleHelp( Tcl_Interp *interp, int argc, char *argv[]) { Tcl_Interp *help_interp; Tcl_DString cmdbuf; int i, result; char modulefile[ MOD_BUFSIZE]; char modulename[ MOD_BUFSIZE]; #if WITH_DEBUGGING_UTIL_1 ErrorLogger( NO_ERR_START, LOC, _proc_PerModuleHelp, NULL); #endif /** ** Initialize the command buffer **/ Tcl_DStringInit( &cmdbuf); g_flags |= M_HELP; /** ** Handle each passed module file. Create a Tcl interpreter for each ** module file to be handled **/ for(i=0; i<argc; i++) { help_interp = EM_CreateInterp(); if( TCL_OK != (result = InitializeModuleCommands( help_interp))) { EM_DeleteInterp( help_interp); result = TCL_ERROR; break; } /** ** locate the filename related to the passed module **/ if( Locate_ModuleFile( help_interp, argv[i], modulename, modulefile)) { if( OK != ErrorLogger( ERR_LOCATE, LOC, argv[i], NULL)) continue; } /** ** Now print the module specific help ... **/ g_current_module = modulename; fprintf( stderr, "\n----------- Module Specific Help for '%s' %.*s-------\n\n", g_current_module, (int)(20-strlen( g_current_module)), "--------------------"); result = CallModuleProcedure( help_interp, &cmdbuf, modulefile, "ModulesHelp", 1); /** ** If there hasn't been any help ... **/ if( result == TCL_ERROR) fprintf( stderr, "\t*** No Module Specific Help for %s ***\n", g_current_module); /** ** Finally clear up the Tcl interpreter and handle the next module **/ EM_DeleteInterp( help_interp); } /** ** Free the used command buffer and return on success **/ g_flags &= ~M_HELP; Tcl_DStringFree(&cmdbuf); return( TCL_OK); } /** End of 'PerModuleHelp' **/