summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2019-01-16 06:20:12 -0800
committerKaz Kylheku <kaz@kylheku.com>2019-01-16 06:20:12 -0800
commit2143d29cf5ae78fc3ab31fb9079cafa89ab42d7f (patch)
tree718b44f3053dfaeb9feb60b3828790fed0f5647f
parent05b1383fae022cea0548ed9c587c4a1289c6b1e6 (diff)
downloadtxr-2143d29cf5ae78fc3ab31fb9079cafa89ab42d7f.tar.gz
txr-2143d29cf5ae78fc3ab31fb9079cafa89ab42d7f.tar.bz2
txr-2143d29cf5ae78fc3ab31fb9079cafa89ab42d7f.zip
ffi: diagnose missing with-dyn-lib.
If the programmer writes a deffi, deffi-sym or deffi-var that makes simple references, and that macro is not wrapped in with-dyn-lib, an unhelpful error message results about sys:ffi-lib being unbound. We can detect this situation and provide a warning. * share/txr/stdlib/ffi.tl (sys:with-dyn-lib-check, sys:expand-sym-ref): New functions. (deffi, deffi-sym, deffi-var): Capture environment parameter. Common code replaced by call to sys:expand-sym-ref, where the missing sys:ffi-lib situation is diagnosed. This is only done in cases when the simple reference syntax occurs.
-rw-r--r--share/txr/stdlib/ffi.tl47
1 files changed, 23 insertions, 24 deletions
diff --git a/share/txr/stdlib/ffi.tl b/share/txr/stdlib/ffi.tl
index 99992bc5..bc6c207f 100644
--- a/share/txr/stdlib/ffi.tl
+++ b/share/txr/stdlib/ffi.tl
@@ -37,6 +37,22 @@
(symacrolet ((sys:ffi-lib ,keep-var))
,*body))))
+(defun sys:with-dyn-lib-check (f e ref)
+ (when (eq (macroexpand 'sys:ffi-lib e) 'sys:ffi-lib)
+ (compile-warning f "simple ref ~s requires ~s"
+ ref 'with-dyn-lib)))
+
+(defun sys:expand-sym-ref (f e exp)
+ (cond
+ ((stringp exp)
+ (sys:with-dyn-lib-check f e exp)
+ ^(dlsym-checked sys:ffi-lib ,exp))
+ ((and (consp exp) (stringp (car exp)))
+ (mac-param-bind f (sym ver) exp
+ (sys:with-dyn-lib-check f e exp)
+ ^(dlvsym-checked sys:ffi-lib ,sym ,ver)))
+ (t exp)))
+
(defun sys:analyze-argtypes (form argtypes)
(let ((p (posq : argtypes)))
(when p
@@ -45,14 +61,9 @@
(del [argtypes p])))
(list* (length argtypes) p argtypes)))
-(defmacro deffi (:form f name fun-expr rettype argtypes)
- (let ((fun-ref (cond
- ((stringp fun-expr)
- ^(dlsym-checked sys:ffi-lib ,fun-expr))
- ((consp fun-expr)
- (mac-param-bind f (sym ver) fun-expr
- ^(dlvsym-checked sys:ffi-lib ,sym ,ver)))
- (t fun-expr)))
+
+(defmacro deffi (:form f :env e name fun-expr rettype argtypes)
+ (let ((fun-ref (sys:expand-sym-ref f e fun-expr))
(ret-type-sym (gensym "ret-type-"))
(arg-types-sym (gensym "arg-types-"))
(call-desc-sym (gensym "call-desc-"))
@@ -96,26 +107,14 @@
(defmacro deffi-cb-unsafe (:form f name rettype argtypes)
(sys:deffi-cb-expander f name rettype argtypes nil nil))
-(defmacro deffi-sym (:form f name var-expr : type-sym)
- (let ((var-ref (cond
- ((stringp var-expr)
- ^(dlsym-checked sys:ffi-lib ,var-expr))
- ((consp var-expr)
- (mac-param-bind f (sym ver) var-expr
- ^(dlvsym-checked sys:ffi-lib ,sym ,ver)))
- (t var-expr))))
+(defmacro deffi-sym (:form f :env e name var-expr : type-sym)
+ (let ((var-ref (sys:expand-sym-ref f e var-expr)))
^(defparml ,name ,(if type-sym
^(cptr-cast ',type-sym ,var-ref)
var-ref))))
-(defmacro deffi-var (:form f name var-expr type)
- (let ((var-ref (cond
- ((stringp var-expr)
- ^(dlsym-checked sys:ffi-lib ,var-expr))
- ((consp var-expr)
- (mac-param-bind f (sym ver) var-expr
- ^(dlvsym-checked sys:ffi-lib ,sym ,ver)))
- (t var-expr)))
+(defmacro deffi-var (:form f :env e name var-expr type)
+ (let ((var-ref (sys:expand-sym-ref f e var-expr))
(type-sym (gensym "type-"))
(var-sym (gensym "var-")))
^(progn