Files
modules/ModuleCmd_Switch.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

310 lines
9.2 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_Switch.c **
** First Edition: 91/10/23 **
** **
** Authors: John Furlan, jlf@behere.com **
** Jens Hamisch, jens@Strawberry.COM **
** **
** Description: Switches two modulefiles such that the paths are **
** switched in-place. **
** **
** Exports: ModuleCmd_Switch **
** **
** Notes: **
** **
** ************************************************************************ **
****/
/** ** Copyright *********************************************************** **
** **
** Copyright 1991-1994 by John L. Furlan. **
** see LICENSE.GPL, which must be provided, for details **
** **
** ************************************************************************ **/
static char Id[] = "@(#)$Id: ModuleCmd_Switch.c,v 1.6 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_Switch.c"; /** File name of this module **/
/** ************************************************************************ **/
/** PROTOTYPES **/
/** ************************************************************************ **/
/** not applicable **/
/*++++
** ** Function-Header ***************************************************** **
** **
** Function: ModuleCmd_Switch **
** **
** Description: Execution of the module-command 'switch' **
** **
** First Edition: 91/10/23 **
** **
** Parameters: Tcl_Interp *interp Attached Tcl Interp. **
** int argc Number of arguments **
** char *argv[] Argument list **
** **
** Result: int TCL_ERROR Failure **
** TCL_OK Successfull operation **
** **
** Attached Globals: g_flags Controlling the callback **
** functions. **
** g_specified_module The module name from the **
** command line. **
** g_current_module The module which is handled **
** by the current command **
** **
** ************************************************************************ **
++++*/
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;
#if WITH_DEBUGGING_MODULECMD
fprintf( stderr, "ModuleCmd_Switch(%d):DEBUG: Starting\n", __LINE__);
#endif
/**
** allocate buffer memory
**/
if ((char *) NULL == (oldfile = stringer(NULL, MOD_BUFSIZE, NULL)))
if( OK != ErrorLogger( ERR_STRING, LOC, NULL))
goto unwind0;
if ((char *) NULL == (newfile = stringer(NULL, MOD_BUFSIZE, NULL)))
if( OK != ErrorLogger( ERR_STRING, LOC, NULL))
goto unwind1;
if ((char *) NULL == (oldname = stringer(NULL, MOD_BUFSIZE, NULL)))
if( OK != ErrorLogger( ERR_STRING, LOC, NULL))
goto unwind2;
if ((char *) NULL == (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((char *) NULL == (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, '/'))) {
*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);
#if WITH_DEBUGGING_MODULECMD
fprintf( stderr, "ModuleCmd_Switch(%d):DEBUG: End\n", __LINE__);
#endif
/**
** 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' **/