Index: src/NativeFunction.cc =================================================================== --- src/NativeFunction.cc (revision 189) +++ src/NativeFunction.cc (working copy) @@ -20,6 +20,9 @@ #include +#include +#include +#include #include "Error.hh" #include "NativeFunction.hh" @@ -28,6 +31,61 @@ vector NativeFunction::valid_functions; +static bool file_exists_and_is_readable( string pathname ) +{ + struct stat buf; + const char *path = pathname.c_str(); + + if( stat( path, &buf ) != -1 ) { + if( S_ISREG( buf.st_mode ) ) { + if( access( path, R_OK ) == 0 ) { + return true; + } + } + } + + return false; +} + +static void *load_lib( string path ) +{ + void *handle = dlopen( path.c_str(), RTLD_NOW ); + if( handle == NULL ) { + Workspace::more_error() = UCS_string(dlerror()); + } + return handle; +} + +static void *find_lib_with_extensions( string path ) +{ + if( file_exists_and_is_readable( path ) ) { + return load_lib( path ); + } + else if( file_exists_and_is_readable( path + ".so" ) ) { + return load_lib( path + ".so" ); + } + else if( file_exists_and_is_readable( path + ".dylib" ) ) { + return load_lib( path + ".dylib" ); + } + else { + stringstream out; + out << "File not found: " << path; + Workspace::more_error() = out.str().c_str(); + return NULL; + } +} + +static void *find_library( string path ) +{ + if( path.find( '/' ) == string::npos && path.find( '\\' ) == string::npos ) { + string pkg_path = PKGLIBDIR; + return find_lib_with_extensions( pkg_path + path ); + } + else { + return find_lib_with_extensions( path ); + } +} + //----------------------------------------------------------------------------- NativeFunction::NativeFunction(const UCS_string & so_name, const UCS_string & apl_name) @@ -40,65 +98,9 @@ { // open .so file... // - { - UTF8_string lib_name(so_path); - handle = 0; - - if ((strchr(lib_name.c_str(), '/') == 0) && - (strchr(lib_name.c_str(), '\\') == 0)) - { - // the lib_name contains no path prefix. Try: - // - // PKGLIBDIR/lib_name - // PKGLIBDIR/lib_name.so - // PKGLIBDIR/lib_name.dylib - // - UTF8_string pkg_path = PKGLIBDIR; - pkg_path.append('/'); - pkg_path.append(lib_name); - handle = dlopen(pkg_path.c_str(), RTLD_NOW); - if (handle == 0) // no luck: try pkg_path.so - { - UTF8_string pkg_path__so(pkg_path); - pkg_path__so.append(UTF8_string(".so")); - handle = dlopen(pkg_path__so.c_str(), RTLD_NOW); - } - if (handle == 0) // still no luck: try pkg_path.dylib - { - UTF8_string pkg_path__dylib(pkg_path); - pkg_path__dylib.append(UTF8_string(".dylib")); - handle = dlopen(pkg_path__dylib.c_str(), RTLD_NOW); - } - } - - if (handle == 0) // lib_name was not in PKGLIBDIR. - { - // Try: - // - // lib_name - // lib_name.so - // lib_name.dylib - - handle = dlopen(lib_name.c_str(), RTLD_NOW); - if (handle == 0) // no luck: try lib_name.so - { - UTF8_string lib_name__so(lib_name); - lib_name__so.append(UTF8_string(".so")); - handle = dlopen(lib_name__so.c_str(), RTLD_NOW); - } - if (handle == 0) // still no luck: try lib_name.dylib - { - UTF8_string lib_name__dylib(lib_name); - lib_name__dylib.append(UTF8_string(".dylib")); - handle = dlopen(lib_name__dylib.c_str(), RTLD_NOW); - } - } - - if (handle == 0) // all dlopen() failed - { - Workspace::more_error() = UCS_string(dlerror()); - return; - } + handle = find_library( so_path.to_string() ); + if( handle == NULL ) { + return; } // get the function multiplexer