Files
modules/ModuleCmd_Load.c
rkowen 930e57ec98 A whole slew of changes progressing to deap modulefile directories.
The current is not usuable, but will eventually be.
These changes are checked in for safe keeping while R.K.Owen is on
vacation.
2002-08-02 22:11:24 +00:00

285 lines
8.6 KiB
C
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/*****
** ** 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.7 2002/08/02 22:11:23 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: g_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<argc && argv[i]; i++) {
/**
** Set the name of the module specified on the command line
**/
g_specified_module = argv[i];
/**
** Create a Tcl interpreter and initialize it with the module commands
**/
tmp_interp = Tcl_CreateInterp();
if( TCL_OK != (return_val = InitializeModuleCommands( tmp_interp)))
return( return_val); /** -------- EXIT (FAILURE) -------> **/
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?
**/
if ((char *) NULL == stringer(modulename, MOD_BUFSIZE,
tmpname, NULL))
if( OK != ErrorLogger( ERR_STRING, LOC, NULL))
goto unwind0;
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]))
null_free((void *) &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);
null_free((void *) &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);
null_free((void *) &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);
unwind0:
return( TCL_ERROR); /** -------- EXIT (FAILURE) -------> **/
} /** End of 'ModuleCmd_Load' **/