From 08ef8ef33cedbfd9762ad16e93e30c2a5c824144 Mon Sep 17 00:00:00 2001 From: Eli Barzilay Date: Mon, 14 Feb 2005 23:39:13 +0000 Subject: [PATCH] . original commit: 4f061af7af71c3e57f297debfcb2d071b320bbca --- collects/mzlib/foreign.ss | 62 +++++++++++++++++++++------------------ 1 file changed, 33 insertions(+), 29 deletions(-) diff --git a/collects/mzlib/foreign.ss b/collects/mzlib/foreign.ss index 1621dc9..770c54b 100644 --- a/collects/mzlib/foreign.ss +++ b/collects/mzlib/foreign.ss @@ -141,35 +141,39 @@ (provide (rename get-ffi-lib ffi-lib) ffi-lib? ffi-lib-name) -(define (get-ffi-lib name . version) - (cond - [(ffi-lib? name) name] - [(not name) (ffi-lib name)] ; #f => NULL => open this executable - [(not (or (string? name) (path? name))) - (raise-type-error 'ffi-lib "library-name" name)] - [else - ;; A possible way that this might be misleading: say that there is a - ;; "foo.so" file in the current directory, which refers to some undefined - ;; symbol, trying to use this function with "foo.so" will try a dlopen with - ;; "foo.so" which isn't found, then it tries a dlopen with - ;; "//foo.so" which fails because of the undefined symbol, and - ;; since all fails, it will use (ffi-lib "foo.so") to raise the original - ;; file-not-found error. This is because the dlopen doesn't provide a way - ;; to distinguish different errors (only dlerror, but that's unreliable). - (let* ([version (if (pair? version) (string-append "." (car version)) "")] - [fullpath (lambda (p) (path->complete-path (expand-path p)))] - [name0 (path->string (expand-path name))] ; orig name - [name (if (regexp-match lib-suffix-re name0) ; name + suffix - (string-append name0 version) - (string-append name0 "." lib-suffix version))]) - (or (ffi-lib name #t) ; try good name first - (ffi-lib name0 #t) ; try original - (and (file-exists? name) ; try a relative path - (ffi-lib (fullpath name) #t)) - (and (file-exists? name0) ; relative with original - (ffi-lib (fullpath name0) #t)) - ;; give up: call ffi-lib so it will raise an error - (ffi-lib name)))])) +(define get-ffi-lib + (case-lambda + [(name) (get-ffi-lib name "")] + [(name version) + (cond + [(ffi-lib? name) name] + [(not name) (ffi-lib name)] ; #f => NULL => open this executable + [(not (or (string? name) (path? name))) + (raise-type-error 'ffi-lib "library-name" name)] + [else + ;; A possible way that this might be misleading: say that there is a + ;; "foo.so" file in the current directory, which refers to some undefined + ;; symbol, trying to use this function with "foo.so" will try a dlopen + ;; with "foo.so" which isn't found, then it tries a dlopen with + ;; "//foo.so" which fails because of the undefined symbol, and + ;; since all fails, it will use (ffi-lib "foo.so") to raise the original + ;; file-not-found error. This is because the dlopen doesn't provide a + ;; way to distinguish different errors (only dlerror, but that's + ;; unreliable). + (let* ([version (if (pair? version) (string-append "." (car version)) "")] + [fullpath (lambda (p) (path->complete-path (expand-path p)))] + [name0 (path->string (expand-path name))] ; orig name + [name (if (regexp-match lib-suffix-re name0) ; name + suffix + (string-append name0 version) + (string-append name0 "." lib-suffix version))]) + (or (ffi-lib name #t) ; try good name first + (ffi-lib name0 #t) ; try original + (and (file-exists? name) ; try a relative path + (ffi-lib (fullpath name) #t)) + (and (file-exists? name0) ; relative with original + (ffi-lib (fullpath name0) #t)) + ;; give up: call ffi-lib so it will raise an error + (ffi-lib name)))])])) ;; These internal functions provide the functionality to be used by ;; get-ffi-obj, set-ffi-obj! and define-c below