/***** ** ** Module Header ******************************************************* ** ** ** ** Modules Revision 3.0 ** ** Providing a flexible user environment ** ** ** ** File: ModuleCmd_Load.c ** ** First Edition: 91/10/23 ** ** ** ** Authors: John Furlan, jlf@behere.com ** ** Jens Hamisch, jens@Strawberry.COM ** ** ** ** Description: The load and unload procedure that takes care of ** ** adding and removing modulefiles to and from the ** ** user's environment. ** ** ** ** Exports: ModuleCmd_Load ** ** ** ** Notes: ** ** ** ** ************************************************************************ ** ****/ /** ** Copyright *********************************************************** ** ** ** ** Copyright 1991-1994 by John L. Furlan. ** ** see LICENSE.GPL, which must be provided, for details ** ** ** ** ************************************************************************ **/ static char Id[] = "@(#)$Id: ModuleCmd_Load.c,v 1.5 2002/01/04 04:59:14 rkowen Exp $"; static void *UseId[] = { &UseId, Id }; /** ************************************************************************ **/ /** HEADERS **/ /** ************************************************************************ **/ #include "modules_def.h" /** ************************************************************************ **/ /** LOCAL DATATYPES **/ /** ************************************************************************ **/ /** not applicable **/ /** ************************************************************************ **/ /** CONSTANTS **/ /** ************************************************************************ **/ /** not applicable **/ /** ************************************************************************ **/ /** MACROS **/ /** ************************************************************************ **/ /** not applicable **/ /** ************************************************************************ **/ /** LOCAL DATA **/ /** ************************************************************************ **/ static char module_name[] = "ModuleCmd_Load.c"; /** File name of this module **/ #if WITH_DEBUGGING_MODULECMD static char _proc_ModuleCmd_Load[] = "ModuleCmd_Load"; #endif /** ************************************************************************ **/ /** PROTOTYPES **/ /** ************************************************************************ **/ /** not applicable **/ /*++++ ** ** Function-Header ***************************************************** ** ** ** ** Function: ModuleCmd_Load ** ** ** ** Description: Execution of the module-commands 'load' and 'unload' ** ** ** ** First Edition: 91/10/23 ** ** ** ** Parameters: Tcl_Interp *interp Attached Tcl Interp. ** ** int load Controls 'load' or ** ** 'unload' to be done ** ** int argc Number of arguments ** ** char *argv[] Argument list ** ** ** ** Result: int 0 None of the passed modules ** ** has been load ** ** 1 At least one module has been ** ** read ** ** ** ** Attached Globals: specified_module The module name from the ** ** command line ** ** g_flags These are set up accordingly before ** ** this function is called in order to ** ** control everything ** ** g_current_module The module which is handled ** ** by the current command ** ** ** ** ************************************************************************ ** ++++*/ int ModuleCmd_Load( Tcl_Interp *interp, int load, int argc, char *argv[]) { int i, return_val, /** Subroutine return values **/ a_successful_load = 0; /** Command return **/ char filename[ MOD_BUFSIZE], /** Module filename **/ modulename[ MOD_BUFSIZE]; /** Real module name **/ Tcl_Interp *tmp_interp; /** Tcl interpreter to be **/ /** used internally **/ Tcl_HashTable **oldTables = NULL; #if WITH_DEBUGGING_MODULECMD ErrorLogger( NO_ERR_START, LOC, _proc_ModuleCmd_Load, NULL); #endif /** ** Set up the flags controling the Tcl callback functions **/ if( load) g_flags |= M_LOAD; else g_flags |= M_REMOVE; /** ** Handle all module files in the order they are passed to me **/ for( i=0; i **/ filename[0] = '\0'; /** ** UNLOAD to be done ** At first check if it is loaded ... **/ if( !load) { char *tmpname; if( !IsLoaded( tmp_interp, argv[i], &tmpname, filename)) { #if 0 /** do we really care if it's not loaded ... **/ if( OK != ErrorLogger( ERR_NOTLOADED, LOC, argv[i], NULL)) #endif return_val = TCL_ERROR; } else { /** ** So it is loaded ... ** Do we know the filename? **/ strcpy( modulename, tmpname); if( !filename[0]) if( TCL_ERROR == (return_val = Locate_ModuleFile( tmp_interp, argv[i], tmpname, filename))) ErrorLogger( ERR_LOCATE, LOC, argv[i], NULL); /** ** If IsLoaded() created tmpname, then we must free it. **/ if( tmpname && tmpname != argv[i]) free( tmpname); } /** if loaded **/ /** ** LOAD to be done ** Only check the filename **/ } else { if( TCL_ERROR == (return_val = Locate_ModuleFile( tmp_interp, argv[i], modulename, filename))) ErrorLogger( ERR_LOCATE, LOC, argv[i], NULL); } /** ** If return_val has been set to something other than TCL_OK, ** then read_status should not be set -- by the ANSI definition. ** ** The functions Read_Modulefile and Update_LoadedList will take ** respect to the 'flags' which are set to M_LOAD or M_REMOVE ** according to the intention of calling this procedure. **/ g_current_module = modulename; if( TCL_OK == return_val) { return_val = Read_Modulefile( tmp_interp, filename); switch (return_val) { case TCL_OK: /** ** If module terminates TCL_OK, add it to the loaded list... **/ Update_LoadedList( tmp_interp, modulename, filename); case TCL_BREAK: /** ** If module terminates TCL_BREAK, don't add it to the list, ** but assume that everything was OK with the module anyway. **/ /** ** Save the current environment setup before the next module ** file is (un)loaded in case something is broken ... ** ... for Unwind_Modulefile_Changes later on **/ if( oldTables) { Delete_Hash_Tables( oldTables); free((char*) oldTables); } oldTables = Copy_Hash_Tables(); a_successful_load = 1; break; /* switch */ case TCL_ERROR: default: /** ** Reset what has been changed. **/ Unwind_Modulefile_Changes( tmp_interp, oldTables); oldTables = NULL; return_val = TCL_ERROR; break; /* switch */ } } Tcl_DeleteInterp(tmp_interp); } /** for **/ /** ** There may only be a spare save environment left, if the final module ** has been load successfully. Remove it in this case **/ if( return_val == TCL_OK && oldTables) { Delete_Hash_Tables( oldTables); free((char*) oldTables); } /** ** Clean up the flags and return **/ if( load) g_flags &= ~M_LOAD; else g_flags &= ~M_REMOVE; #if WITH_DEBUGGING_MODULECMD ErrorLogger( NO_ERR_END, LOC, _proc_ModuleCmd_Load, NULL); #endif return( a_successful_load); } /** End of 'ModuleCmd_Load' **/