bool glxlink::set_target(char *name) { char libname[1024]; char path[1024]; sprintf(libname,PREFIX "glx%s" DLEXT,name); if ( find_file(libname,NULL,X_OK,path,sizeof(path))!=NULL ) { // load library handle = DLLOAD(path); if ( handle==NULL ) { output_error("unable to load '%s' for target '%s': %s", path,name,DLERR); return false; } // attach functions settag = (bool(*)(glxlink*,char*,char*))DLSYM(handle,"glx_settag"); init = (bool(*)(glxlink*))DLSYM(handle,"glx_init"); sync = (TIMESTAMP(*)(glxlink*,TIMESTAMP))DLSYM(handle,"glx_sync"); term = (bool(*)(glxlink*))DLSYM(handle,"glx_term"); // call create routine bool (*create)(glxlink*,CALLBACKS*) = (bool(*)(glxlink*,CALLBACKS*))DLSYM(handle,"glx_create"); if ( create!=NULL && create(this,module_callbacks()) ) { strcpy(target,name); return true; } else { output_error("library '%s' for target '%s' does not define/export glx_create properly", path,name); return false; } } else { output_error("library '%s' for target '%s' not found", libname, name); return false; } }
MODULE *module_load(const char *file, /**< module filename, searches \p PATH */ int argc, /**< count of arguments in \p argv */ char *argv[]) /**< arguments passed from the command line */ { /* check for already loaded */ MODULE *mod = module_find((char *)file); char buffer[FILENAME_MAX+1]; char *fmod; bool isforeign = false; char pathname[1024]; char *tpath = NULL; #ifdef WIN32 char from='/', to='\\'; #else char from='\\', to='/'; #endif char *p = NULL; void *hLib = NULL; LIBINIT init = NULL; int *pMajor = NULL, *pMinor = NULL; CLASS *previous = NULL; CLASS *c; #ifdef NEVER /* this shouldn't ever be necessary but sometimes for debugging purposes it is helpful */ /* if LD_LIBRARY_PATH is not set, default to current directory */ if (getenv("LD_LIBRARY_PATH")==NULL) { putenv("LD_LIBRARY_PATH=."); output_verbose("Setting default LD_LIBRARY_DEFAULT to current directory"); } #endif if (mod!=NULL) { output_verbose("%s(%d): module '%s' already loaded", __FILE__, __LINE__, file); return mod; } else { output_verbose("%s(%d): module '%s' not yet loaded", __FILE__, __LINE__, file); } /* check for foreign modules */ strcpy(buffer,file); fmod = strtok(buffer,"::"); if (fmod!=NULL && strcmp(fmod, file) != 0) { char *modname = strtok(NULL,"::"); MODULE *parent_mod = module_find(fmod); if(parent_mod == NULL) parent_mod = module_load(fmod, 0, NULL); previous = class_get_last_class(); if(parent_mod != NULL && parent_mod->subload != NULL) { /* if we've defined a subload routine and already loaded the parent module*/ MODULE *child_mod; if(module_find(fmod) == NULL) module_load(fmod, 0, NULL); child_mod = parent_mod->subload(modname, &mod, (previous ? &(previous->next) : &previous), argc, argv); if(child_mod == NULL) { /* failure */ output_error("module_load(file='%s::%s'): subload failed", fmod, modname); return NULL; } if (mod != NULL) { /* if we want to register another module */ last_module->next = mod; last_module = mod; mod->oclass = previous ? previous->next : class_get_first_class(); } return last_module; } else { struct { char *name; LOADER loader; } fmap[] = { {"matlab",NULL}, {"java",load_java_module}, {"python",load_python_module}, {NULL,NULL} /* DO NOT DELETE THIS TERMINATOR ENTRY */ }, *p; for (p=fmap; p->name!=NULL; p++) { if (strcmp(p->name, fmod)==0) { static char *args[1]; isforeign = true; if (p->loader!=NULL) /* use external loader */ return p->loader(modname,argc,argv); /* use a module with command args */ argv = args; argc=1; argv[0] = modname; file=buffer; break; } } if (p==NULL) { output_error("module_load(file='%s',...): foreign module type %s not recognized or supported", fmod); return NULL; } } } /* create a new module entry */ mod = (MODULE *)malloc(sizeof(MODULE)); if (mod==NULL) { output_verbose("%s(%d): module '%s' memory allocation failed", __FILE__, __LINE__, file); errno=ENOMEM; return NULL; } else output_verbose("%s(%d): module '%s' memory allocated", __FILE__, __LINE__, file); /* locate the module */ snprintf(pathname, 1024, "%s" DLEXT, file); tpath = find_file(pathname, NULL, X_OK|R_OK); if(tpath == NULL) { output_verbose("unable to locate %s in GLPATH, using library loader instead", pathname); tpath=pathname; } else { #ifndef WIN32 /* if the path is a relative path */ struct stat buf; if (tpath[0]!='/' && stat(tpath,&buf)==0) { char buffer[1024]; /* add ./ to the beginning of the path */ sprintf(buffer,"./%s", tpath); strcpy(tpath,buffer); } #endif output_verbose("full path to library '%s' is '%s'", file, tpath); } /* convert path delims based on OS preference */ for (p=strchr(tpath,from); p!=NULL; p=strchr(p,from)) *p=to; /* ok, let's do it */ hLib = DLLOAD(tpath); if (hLib==NULL) { #if defined WIN32 && ! defined MINGW output_error("%s(%d): module '%s' load failed - %s (error code %d)", __FILE__, __LINE__, file, strerror(errno), GetLastError()); #else output_error("%s(%d): module '%s' load failed - %s", __FILE__, __LINE__, file, dlerror()); output_debug("%s(%d): path to module is '%s'", __FILE__, __LINE__, tpath); #endif dlload_error(pathname); errno = ENOENT; free(mod); return NULL; } else output_verbose("%s(%d): module '%s' loaded ok", __FILE__, __LINE__, file); /* get the initialization function */ init = (LIBINIT)DLSYM(hLib,"init"); if (init==NULL) { output_error("%s(%d): module '%s' does not export init()", __FILE__, __LINE__, file); dlload_error(pathname); errno = ENOEXEC; free(mod); return NULL; } else output_verbose("%s(%d): module '%s' exports init()", __FILE__, __LINE__, file); /* connect the module's exported data & functions */ mod->hLib = (void*)hLib; pMajor = (int*)DLSYM(hLib, "major"); pMinor = (int*)DLSYM(hLib, "minor"); mod->major = pMajor?*pMajor:0; mod->minor = pMinor?*pMinor:0; mod->import_file = (int(*)(char*))DLSYM(hLib,"import_file"); mod->export_file = (int(*)(char*))DLSYM(hLib,"export_file"); mod->setvar = (int(*)(char*,char*))DLSYM(hLib,"setvar"); mod->getvar = (void*(*)(char*,char*,unsigned int))DLSYM(hLib,"getvar"); mod->check = (int(*)())DLSYM(hLib,"check"); #ifndef _NO_CPPUNIT mod->module_test = (int(*)(TEST_CALLBACKS*,int,char*[]))DLSYM(hLib,"module_test"); #endif mod->cmdargs = (int(*)(int,char**))DLSYM(hLib,"cmdargs"); mod->kmldump = (int(*)(FILE*,OBJECT*))DLSYM(hLib,"kmldump"); mod->subload = (MODULE *(*)(char *, MODULE **, CLASS **, int, char **))DLSYM(hLib, "subload"); mod->test = (void(*)(int,char*[]))DLSYM(hLib,"test"); mod->globals = NULL; strcpy(mod->name,file); mod->next = NULL; /* call the initialization function */ mod->oclass = (*init)(&callbacks,(void*)mod,argc,argv); if (mod->oclass==NULL) return NULL; /* connect intrinsic functions */ for (c=mod->oclass; c!=NULL; c=c->next) { char fname[1024]; struct { FUNCTIONADDR *func; char *name; int optional; } map[] = { {&c->create,"create",FALSE}, {&c->init,"init",TRUE}, {&c->sync,"sync",TRUE}, {&c->commit,"commit",TRUE}, {&c->notify,"notify",TRUE}, {&c->isa,"isa",TRUE}, {&c->plc,"plc",TRUE}, {&c->recalc,"recalc",TRUE}, }; int i; for (i=0; i<sizeof(map)/sizeof(map[0]); i++) { snprintf(fname, 1024,"%s_%s",map[i].name,isforeign?fmod:c->name); if ((*(map[i].func) = (FUNCTIONADDR)DLSYM(hLib,fname))==NULL && !map[i].optional) { output_fatal("intrinsic %s is not defined in class %s", fname,file); /* TROUBLESHOOT A required intrinsic function was not found. Please review and modify the class definition. */ errno=EINVAL; return NULL; } else if(!map[i].optional) output_verbose("%s(%d): module '%s' intrinsic %s found", __FILE__, __LINE__, file, fname); } } /* attach to list of known modules */ if (first_module==NULL) first_module = mod; else last_module->next = mod; last_module = mod; return last_module; }