/* search for abstraction; register a creator if found */ static int sys_do_load_abs(t_canvas *canvas, const char *objectname, const char *path) { int fd; static t_gobj*abstraction_classes = 0; char dirbuf[MAXPDSTRING], classslashclass[MAXPDSTRING], *nameptr; /* NULL-path is only used as a last resort, but we have already tried all paths */ if (!path) return (0); snprintf(classslashclass, MAXPDSTRING, "%s/%s", objectname, objectname); if ((fd = sys_trytoopenone(path, objectname, ".pd", dirbuf, &nameptr, MAXPDSTRING, 1)) >= 0 || (fd = sys_trytoopenone(path, objectname, ".pat", dirbuf, &nameptr, MAXPDSTRING, 1)) >= 0 || (fd = sys_trytoopenone(path, classslashclass, ".pd", dirbuf, &nameptr, MAXPDSTRING, 1)) >= 0) { t_class*c=0; close(fd); /* found an abstraction, now register it as a new pseudo-class */ class_set_extern_dir(gensym(dirbuf)); if((c=class_new(gensym(objectname), (t_newmethod)do_create_abstraction, 0, 0, 0, A_GIMME, 0))) { /* store away the newly created class, maybe we will need it one day */ t_gobj*absclass=0; absclass=t_getbytes(sizeof(*absclass)); absclass->g_pd=c; absclass->g_next=abstraction_classes; abstraction_classes=absclass; } class_set_extern_dir(&s_); return (1); } return (0); }
static int sys_do_load_lib(t_canvas *canvas, char *objectname) { char symname[MAXPDSTRING], filename[MAXPDSTRING], dirbuf[MAXPDSTRING], *classname, *nameptr, altsymname[MAXPDSTRING]; void *dlobj; t_xxx makeout = NULL; int i, hexmunge = 0, fd; #ifdef _WIN32 HINSTANCE ntdll; #endif if (classname = strrchr(objectname, '/')) classname++; else classname = objectname; if (sys_onloadlist(objectname)) { post("%s: already loaded", objectname); return (1); } for (i = 0, nameptr = classname; i < MAXPDSTRING-7 && *nameptr; nameptr++) { char c = *nameptr; if ((c>='0' && c<='9') || (c>='A' && c<='Z')|| (c>='a' && c<='z' )|| c == '_') { symname[i] = c; i++; } /* trailing tilde becomes "_tilde" */ else if (c == '~' && nameptr[1] == 0) { strcpy(symname+i, "_tilde"); i += strlen(symname+i); } else /* anything you can't put in a C symbol is sprintf'ed in hex */ { sprintf(symname+i, "0x%02x", c); i += strlen(symname+i); hexmunge = 1; } } symname[i] = 0; if (hexmunge) { memmove(symname+6, symname, strlen(symname)+1); strncpy(symname, "setup_", 6); } else strcat(symname, "_setup"); #if 0 fprintf(stderr, "lib: %s\n", classname); #endif /* try looking in the path for (objectname).(sys_dllextent) ... */ if ((fd = canvas_open(canvas, objectname, sys_dllextent, dirbuf, &nameptr, MAXPDSTRING, 1)) >= 0) goto gotone; /* same, with the more generic sys_dllextent2 */ if ((fd = canvas_open(canvas, objectname, sys_dllextent2, dirbuf, &nameptr, MAXPDSTRING, 1)) >= 0) goto gotone; /* next try (objectname)/(classname).(sys_dllextent) ... */ strncpy(filename, objectname, MAXPDSTRING); filename[MAXPDSTRING-2] = 0; strcat(filename, "/"); strncat(filename, classname, MAXPDSTRING-strlen(filename)); filename[MAXPDSTRING-1] = 0; if ((fd = canvas_open(canvas, filename, sys_dllextent, dirbuf, &nameptr, MAXPDSTRING, 1)) >= 0) goto gotone; if ((fd = canvas_open(canvas, filename, sys_dllextent2, dirbuf, &nameptr, MAXPDSTRING, 1)) >= 0) goto gotone; return (0); gotone: close(fd); class_set_extern_dir(gensym(dirbuf)); /* rebuild the absolute pathname */ strncpy(filename, dirbuf, MAXPDSTRING); filename[MAXPDSTRING-2] = 0; strcat(filename, "/"); strncat(filename, nameptr, MAXPDSTRING-strlen(filename)); filename[MAXPDSTRING-1] = 0; #ifdef HAVE_LIBDL dlobj = dlopen(filename, RTLD_NOW | RTLD_GLOBAL); if (!dlobj) { post("%s: %s", filename, dlerror()); class_set_extern_dir(&s_); return (0); } makeout = (t_xxx)dlsym(dlobj, symname); /* fprintf(stderr, "symbol %s\n", symname); */ #endif #ifdef _WIN32 sys_bashfilename(filename, filename); ntdll = LoadLibrary(filename); if (!ntdll) { post("%s: couldn't load", filename); class_set_extern_dir(&s_); return (0); } makeout = (t_xxx)GetProcAddress(ntdll, symname); #endif if (!makeout) { post("load_object: Symbol \"%s\" not found", symname); class_set_extern_dir(&s_); return 0; } (*makeout)(); class_set_extern_dir(&s_); sys_putonloadlist(objectname); return (1); }
static int sys_do_load_lib(t_canvas *canvas, char *objectname) { char symname[MAXPDSTRING], filename[MAXPDSTRING], dirbuf[MAXPDSTRING], *classname, *nameptr, altsymname[MAXPDSTRING]; void *dlobj; t_xxx makeout = NULL; int i, hexmunge = 0, fd; #ifdef _WIN32 HINSTANCE ntdll; #endif if (classname = strrchr(objectname, '/')) classname++; else classname = objectname; if (sys_onloadlist(objectname)) { post("%s: already loaded", objectname); return (1); } for (i = 0, nameptr = classname; i < MAXPDSTRING-7 && *nameptr; nameptr++) { char c = *nameptr; if ((c>='0' && c<='9') || (c>='A' && c<='Z')|| (c>='a' && c<='z' )|| c == '_') { symname[i] = c; i++; } /* trailing tilde becomes "_tilde" */ else if (c == '~' && nameptr[1] == 0) { strcpy(symname+i, "_tilde"); i += strlen(symname+i); } else /* anything you can't put in a C symbol is sprintf'ed in hex */ { sprintf(symname+i, "0x%02x", c); i += strlen(symname+i); hexmunge = 1; } } symname[i] = 0; if (hexmunge) { memmove(symname+6, symname, strlen(symname)+1); strncpy(symname, "setup_", 6); } else strcat(symname, "_setup"); #if 0 fprintf(stderr, "lib: %s\n", classname); #endif /* try looking in the path for (objectname).(sys_dllextent) ... */ if ((fd = canvas_open(canvas, objectname, sys_dllextent, dirbuf, &nameptr, MAXPDSTRING, 1)) >= 0) goto gotone; /* same, with the more generic sys_dllextent2 */ if ((fd = canvas_open(canvas, objectname, sys_dllextent2, dirbuf, &nameptr, MAXPDSTRING, 1)) >= 0) goto gotone; /* next try (objectname)/(classname).(sys_dllextent) ... */ strncpy(filename, objectname, MAXPDSTRING); filename[MAXPDSTRING-2] = 0; strcat(filename, "/"); strncat(filename, classname, MAXPDSTRING-strlen(filename)); filename[MAXPDSTRING-1] = 0; if ((fd = canvas_open(canvas, filename, sys_dllextent, dirbuf, &nameptr, MAXPDSTRING, 1)) >= 0) goto gotone; if ((fd = canvas_open(canvas, filename, sys_dllextent2, dirbuf, &nameptr, MAXPDSTRING, 1)) >= 0) goto gotone; return (0); gotone: close(fd); class_set_extern_dir(gensym(dirbuf)); /* rebuild the absolute pathname */ strncpy(filename, dirbuf, MAXPDSTRING); filename[MAXPDSTRING-2] = 0; strcat(filename, "/"); strncat(filename, nameptr, MAXPDSTRING-strlen(filename)); filename[MAXPDSTRING-1] = 0; #ifdef _WIN32 { char dirname[MAXPDSTRING], *s, *basename; sys_bashfilename(filename, filename); /* set the dirname as DllDirectory, meaning in the path for loading other DLLs so that dependent libraries can be included in the same folder as the external. SetDllDirectory() needs a minimum supported version of Windows XP SP1 for SetDllDirectory, so WINVER must be 0x0502 */ strncpy(dirname, filename, MAXPDSTRING); s = strrchr(dirname, '\\'); basename = s; if (s && *s) *s = '\0'; if (!SetDllDirectory(dirname)) error("Could not set '%s' as DllDirectory(), '%s' might not load.", dirname, basename); /* now load the DLL for the external */ ntdll = LoadLibrary(filename); if (!ntdll) { post("%s: couldn't load", filename); class_set_extern_dir(&s_); return (0); } makeout = (t_xxx)GetProcAddress(ntdll, symname); if (!makeout) makeout = (t_xxx)GetProcAddress(ntdll, "setup"); SetDllDirectory(NULL); /* reset DLL dir to nothing */ } #elif defined HAVE_LIBDL dlobj = dlopen(filename, RTLD_NOW | RTLD_GLOBAL); if (!dlobj) { post("%s: %s", filename, dlerror()); class_set_extern_dir(&s_); return (0); } makeout = (t_xxx)dlsym(dlobj, symname); if(!makeout) makeout = (t_xxx)dlsym(dlobj, "setup"); #else #warning "No dynamic loading mechanism specified, libdl or WIN32 required for loading externals!" #endif if (!makeout) { post("load_object: Symbol \"%s\" not found", symname); class_set_extern_dir(&s_); return 0; } (*makeout)(); class_set_extern_dir(&s_); sys_putonloadlist(objectname); return (1); }
static int sys_do_load_lib(t_canvas *canvas, const char *objectname, const char *path) { char symname[MAXPDSTRING], filename[MAXPDSTRING], dirbuf[MAXPDSTRING], *nameptr; const char**dllextent; const char *classname, *cnameptr; void *dlobj; t_xxx makeout = NULL; int i, hexmunge = 0, fd; #ifdef _WIN32 HINSTANCE ntdll; #endif /* NULL-path is only used as a last resort, but we have already tried all paths */ if(!path)return (0); if ((classname = strrchr(objectname, '/'))) classname++; else classname = objectname; for (i = 0, cnameptr = classname; i < MAXPDSTRING-7 && *cnameptr; cnameptr++) { char c = *cnameptr; if ((c>='0' && c<='9') || (c>='A' && c<='Z')|| (c>='a' && c<='z' )|| c == '_') { symname[i] = c; i++; } /* trailing tilde becomes "_tilde" */ else if (c == '~' && cnameptr[1] == 0) { strcpy(symname+i, "_tilde"); i += strlen(symname+i); } else /* anything you can't put in a C symbol is sprintf'ed in hex */ { sprintf(symname+i, "0x%02x", c); i += strlen(symname+i); hexmunge = 1; } } symname[i] = 0; if (hexmunge) { memmove(symname+6, symname, strlen(symname)+1); strncpy(symname, "setup_", 6); } else strcat(symname, "_setup"); #if 0 fprintf(stderr, "lib: %s\n", classname); #endif /* try looking in the path for (objectname).(sys_dllextent) ... */ for(dllextent=sys_dllextent; *dllextent; dllextent++) { if ((fd = sys_trytoopenone(path, objectname, *dllextent, dirbuf, &nameptr, MAXPDSTRING, 1)) >= 0) goto gotone; } /* next try (objectname)/(classname).(sys_dllextent) ... */ strncpy(filename, objectname, MAXPDSTRING); filename[MAXPDSTRING-2] = 0; strcat(filename, "/"); strncat(filename, classname, MAXPDSTRING-strlen(filename)); filename[MAXPDSTRING-1] = 0; for(dllextent=sys_dllextent; *dllextent; dllextent++) { if ((fd = sys_trytoopenone(path, filename, *dllextent, dirbuf, &nameptr, MAXPDSTRING, 1)) >= 0) goto gotone; } #ifdef ANDROID /* Android libs have a 'lib' prefix, '.so' suffix and don't allow ~ */ char libname[MAXPDSTRING] = "lib"; strncat(libname, objectname, MAXPDSTRING - 4); int len = strlen(libname); if (libname[len-1] == '~' && len < MAXPDSTRING - 6) { strcpy(libname+len-1, "_tilde"); } if ((fd = sys_trytoopenone(path, libname, ".so", dirbuf, &nameptr, MAXPDSTRING, 1)) >= 0) goto gotone; #endif return (0); gotone: close(fd); class_set_extern_dir(gensym(dirbuf)); /* rebuild the absolute pathname */ strncpy(filename, dirbuf, MAXPDSTRING); filename[MAXPDSTRING-2] = 0; strcat(filename, "/"); strncat(filename, nameptr, MAXPDSTRING-strlen(filename)); filename[MAXPDSTRING-1] = 0; #ifdef _WIN32 { char dirname[MAXPDSTRING], *s, *basename; sys_bashfilename(filename, filename); /* set the dirname as DllDirectory, meaning in the path for loading other DLLs so that dependent libraries can be included in the same folder as the external. SetDllDirectory() needs a minimum supported version of Windows XP SP1 for SetDllDirectory, so WINVER must be 0x0502 */ strncpy(dirname, filename, MAXPDSTRING); s = strrchr(dirname, '\\'); basename = s; if (s && *s) *s = '\0'; if (!SetDllDirectory(dirname)) error("Could not set '%s' as DllDirectory(), '%s' might not load.", dirname, basename); /* now load the DLL for the external */ ntdll = LoadLibrary(filename); if (!ntdll) { error("%s: couldn't load", filename); class_set_extern_dir(&s_); return (0); } makeout = (t_xxx)GetProcAddress(ntdll, symname); if (!makeout) makeout = (t_xxx)GetProcAddress(ntdll, "setup"); SetDllDirectory(NULL); /* reset DLL dir to nothing */ } #elif defined(HAVE_LIBDL) || defined(__FreeBSD__) dlobj = dlopen(filename, RTLD_NOW | RTLD_GLOBAL); if (!dlobj) { error("%s: %s", filename, dlerror()); class_set_extern_dir(&s_); return (0); } makeout = (t_xxx)dlsym(dlobj, symname); if(!makeout) makeout = (t_xxx)dlsym(dlobj, "setup"); #else #warning "No dynamic loading mechanism specified, \ libdl or WIN32 required for loading externals!" #endif if (!makeout) { error("load_object: Symbol \"%s\" not found", symname); class_set_extern_dir(&s_); return 0; } (*makeout)(); class_set_extern_dir(&s_); return (1); }