Forgot to add changes in prevois commit.
[cl-zmq.git] / meta.lisp
blob92e4810005c1dfa35f8493f2d7517dc91df1924f
1 ;; Copyright (c) 2009, 2010 Vitaly Mayatskikh <v.mayatskih@gmail.com>
2 ;;
3 ;; This file is part of CL-ZMQ.
4 ;;
5 ;; Vitaly Mayatskikh grants you the rights to distribute
6 ;; and use this software as governed by the terms
7 ;; of the Lisp Lesser GNU Public License
8 ;; (http://opensource.franz.com/preamble.html),
9 ;; known as the LLGPL.
11 (in-package :zeromq)
13 (define-condition error-again (error)
14 ((argument :reader error-again :initarg :argument))
15 (:report (lambda (condition stream)
16 (write-string (convert-from-foreign
17 (%strerror (error-again condition))
18 :string)
19 stream))))
21 (defmacro defcfun* (name-and-options return-type &body args)
22 (let* ((c-name (car name-and-options))
23 (l-name (cadr name-and-options))
24 (n-name (cffi::format-symbol t "%~A" l-name))
25 (name (list c-name n-name))
27 (docstring (when (stringp (car args)) (pop args)))
28 (ret (gensym)))
29 (loop with opt
30 for i in args
31 unless (consp i) do (setq opt t)
32 else
33 collect i into args*
34 and if (not opt) collect (car i) into names
35 else collect (car i) into opts
36 and collect (list (car i) 0) into opts-init
37 end
38 finally (return
39 `(progn
40 (defcfun ,name ,return-type
41 ,@args*)
43 (defun ,l-name (,@names ,@(when opts-init `(&optional ,@opts-init)))
44 ,docstring
45 (let ((,ret (,n-name ,@names ,@opts)))
46 (if ,(if (eq return-type :pointer)
47 `(zerop (pointer-address ,ret))
48 `(not (zerop ,ret)))
49 (let ((errno (errno)))
50 (cond
51 #-windows
52 ((eq errno isys:ewouldblock) (error 'error-again :argument errno))
53 (t (error (convert-from-foreign (%strerror errno) :string)))))
54 ,ret))))))))