#include <dl.h>
#include <string.h>

extern int errno;

static void Load_Them (names) Object names; {
    char *fn;
    shl_t handle;
    SYM *sp;
    Declare_C_Strings;

    for ( ; !Nullp (names); names = Cdr (names)) {
	Make_C_String (Car (names), fn);
	if (Verbose)
	    printf ("shl_load(%s)\n", fn);
	if ((handle = shl_load (fn, BIND_IMMEDIATE|BIND_VERBOSE, 0L)) == 0) {
	    Saved_Errno = errno;
	    Primitive_Error ("shl_load of ~s failed: ~E", Car (names));
	}
	if (The_Symbols)
	    Free_Symbols (The_Symbols);
	The_Symbols = Open_File_And_Snarf_Symbols (fn);
	for (sp = The_Symbols->first; sp; sp = sp->next)
	    if (shl_findsym (&handle, sp->name, TYPE_UNDEFINED, &sp->value)) {
		Saved_Errno = errno;
		Primitive_Error ("~s: shl_findsym on ~s failed: ~E",
		    Car (names),
		    Make_String (sp->name, strlen (sp->name)));
	}
	if (!Call_Initializers (The_Symbols, 0))
	    Primitive_Error ("no initializers in ~s", Car (names));
    }
    Dispose_C_Strings;
}

Load_Object (names) Object names; {
    Object port, tail, fullnames, str;
    char *p, *libs = "";
    static struct lib_loaded {
	struct lib_loaded *next;
	char *lib_name;
    } *libs_loaded, *lp;
	
    GC_Node3;
    Declare_C_Strings;

    port = tail = fullnames = Null;
    GC_Link3 (port, tail, fullnames);
    for (tail = names; !Nullp (tail); tail = Cdr (tail)) {
	port = General_Open_File (Car (tail), P_INPUT, Var_Get (V_Load_Path));
	fullnames = Cons (PORT(port)->name, fullnames);
	(void)P_Close_Input_Port (port);
    }
    tail = Var_Get (V_Load_Libraries);
    if (TYPE(tail) == T_String)
	Make_C_String (tail, libs);
    for (tail = Null; (p = strtok (libs, " \t")) != 0; libs = 0) {
	for (lp = libs_loaded; lp; lp = lp->next)
	    if (strcmp (lp->lib_name, p) == 0) break;
	if (lp) continue;
	lp = (struct lib_loaded *)Safe_Malloc (sizeof (*lp));
	lp->lib_name = strdup (p);
	lp->next = libs_loaded;
	libs_loaded = lp;
	str = Make_String (p, strlen (p));
	tail = Cons (str, tail);
    }
    Load_Them (tail);
    Load_Them (fullnames);
    GC_Unlink;
    Dispose_C_Strings;
}
