/*This line lets emacs recognize this as -*- C -*- Code
 *-----------------------------------------------------------------------------
 *
 * Project:	Tcl Modules
 * Created:	91/10/23
 * Author:	John L. Furlani<john.furlani@East.Sun.COM>
 *
 * Description:
 *      The load and unload procedure that takes care of adding and removing
 *  modulefiles to and from the user's environment.
 *	
 * $Log: ModuleCmd_Load.c,v $
 *
 *
 * Revision 1.6  1993/01/25  18:48:13  jlf
 * Changed the method for keeping and unwinding failed modulefiles.
 * The output returns to its optimized state where only the aggregate
 * changes to the environment are sent to the executing shell.
 *
 * Revision 1.5  1993/01/23  01:01:23  jlf
 * Fixed a number of memory leaks and large static arrays.
 *
 * Revision 1.4  1993/01/20  21:55:31  jlf
 * Modified the unload portion so it will work with the old version of
 * modulecmd.
 *
 * Revision 1.3  1993/01/20  03:33:24  jlf
 * Fixed some load/unload bugs.  Updated to use new Locate_Modulefile function.
 *
 * Revision 1.2  1992/11/19  04:56:27  jlf
 * Fixed the bug that all modulefiles prior to any modulefile that causes
 * an error does not get loaded.  But, all of the modulefiles after the
 * error modulefile upto the end are loaded.  It was due to the fact that
 * the environment changes were not being output after each successful
 * modulefile load.
 *
 * Revision 1.1  1992/11/05  23:51:06  jlf
 * Initial revision
 *
 *---------------------------------------------------------------------------*/
static char Id[] =
    "$Id: ModuleCmd_Load.c,v 2.0 1993/02/21 00:00:12 jlf Exp jlf $";

#include "global.h"

int
ModuleCmd_Load(Tcl_Interp* interp,
               int         load,
               int         argc_module_list,
               char*       module_list[])
{
    int    i, return_val;
    char   filename[1024];
    char   modulename[1024];
    Tcl_Interp* tmp_interp;
    Tcl_HashTable** oldTables = NULL;

    if(load)
        flags |= M_LOAD;
    else
        flags |= M_REMOVE;
    
    for(i = 0; module_list[i]; i++) {
        return_val = TCL_OK;
        tmp_interp = Tcl_CreateInterp();
        InitializeModuleCommands(tmp_interp);
        filename[0] = '\0';

        if(!load) {  /* unload */
            char* tmpname;
            if(!IsLoaded(tmp_interp, module_list[i], &tmpname, filename)) {
                Tcl_AppendResult(tmp_interp,
                                 "modulefile '", module_list[i], 
                                 "' is not currently loaded", NULL);
                return_val = TCL_ERROR;
            } else { 
                strcpy(modulename, tmpname);
                if(!filename[0]) /* it's loaded but we know its filename */
                    if((return_val = 
                        Locate_ModuleFile(tmp_interp, module_list[i], 
                                          tmpname, filename)) == 
                       TCL_ERROR) {
                        Tcl_AppendResult(tmp_interp, 
                                         "Couldn't find modulefile '", 
                                         module_list[i], "' in MODULEPATH", 
                                         NULL);
                    }
                /*
                 *  If IsLoaded() created tmpname, then we must free it.
                 */
                if(tmpname != module_list[i]) 
                    free(tmpname);
            }
        } else {
                if((return_val = 
                    Locate_ModuleFile(tmp_interp, module_list[i], 
                                      modulename, filename)) == TCL_ERROR) {
                    Tcl_AppendResult(tmp_interp, "Couldn't find modulefile '", 
                                     module_list[i], "' in MODULEPATH", NULL);
                }
        }

	current_module = modulename;
	if((return_val == TCL_OK) && 
           (Read_Modulefile(tmp_interp, filename) == 0)) {
	    Update_LoadedList(tmp_interp, modulename, filename);
            if(oldTables) {
                Delete_Hash_Tables(oldTables);
                free((char*)oldTables);
            }
            oldTables = Copy_Hash_Tables();
	} else {
            Unwind_Modulefile_Changes(tmp_interp, module_list[i], oldTables);
            oldTables = NULL;
	    return_val = TCL_ERROR;
	}

        Tcl_DeleteInterp(tmp_interp);
    }
    
    if(return_val == TCL_OK && oldTables) {
        Delete_Hash_Tables(oldTables);
        free((char*)oldTables);
    }

    if(load)
        flags &= ~M_LOAD;
    else
        flags &= ~M_REMOVE;

    return TCL_OK;
}
