/[cffi-objects]/struct.lisp
ViewVC logotype

Diff of /struct.lisp

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 17 by rklochkov, Mon Dec 31 13:35:32 2012 UTC revision 18 by rklochkov, Sat Jan 12 21:26:46 2013 UTC
# Line 54  Struct may be used in OBJECT cffi-type o Line 54  Struct may be used in OBJECT cffi-type o
54  (defun pair (maybe-pair)  (defun pair (maybe-pair)
55    (if (consp maybe-pair) maybe-pair (cons maybe-pair maybe-pair)))    (if (consp maybe-pair) maybe-pair (cons maybe-pair maybe-pair)))
56    
57  (defmacro defcstruct-accessors (class)  (defun slot-accessor (designator)
58      (flet ((count-args (list)
59               (do ((list list (cdr list))
60                    (count 0 (1+ count)))
61                   ((or (null list)
62                        (char= (char (string (car list)) 0) #\&))
63                    count))))
64        (let ((lambda-list
65               (closer-mop:generic-function-lambda-list (fdefinition designator))))
66          (= (count-args lambda-list) (if (listp designator) 2 1)))))
67    
68    (defmacro defaccessor (name c-name class &body body)
69      #-message-oo (declare (ignore c-name))
70      (let ((val* (when (listp name) (list 'val))))
71        `(progn
72           (unless (fboundp ',name)
73             (defgeneric ,name (,@val* ,class)))
74           (if (slot-accessor ',name)
75               (defmethod ,name (,@val* (,class ,class))
76                 . ,body)
77               (warn 'style-warning
78                     "~a is not a slot accessor" ',name))
79           #+message-oo
80           ,(if val*
81                `(defmessage ,class (,(alexandria:format-symbol
82                                        :keyword "~A=" c-name)
83                                      val)
84                   . ,body)
85                `(defmessage ,class ,(alexandria:make-keyword c-name)
86                   . ,body)))))
87    
88    
89    (defmacro defcstruct-accessors (class &rest fields)
90    "CLASS may be symbol = class-name = struct name,    "CLASS may be symbol = class-name = struct name,
91  or may be cons (class-name . struct-name)"  or may be cons (class-name . struct-name)"
92    (destructuring-bind (class-name . struct-name) (pair class)    (destructuring-bind (class-name . struct-name) (pair class)
93      `(progn      `(progn
94         (clear-setters ,class-name)         (clear-setters ,class-name)
95         ,@(mapcar         ,@(mapcar
96            (lambda (x)            (lambda (field)
97             `(progn              (destructuring-bind (lisp-name . c-name) (pair field)
98                (unless (fboundp ',x)                `(progn
99                  (defgeneric ,x (,class-name)))                   (defaccessor ,lisp-name ,c-name ,class-name
100                (defmethod ,x ((,class-name ,class-name))                     (if (slot-boundp ,class-name 'value)
101                  (if (slot-boundp ,class-name 'value)                         (getf (slot-value ,class-name 'value) ',c-name)
102                      (getf (slot-value ,class-name 'value) ',x)                         (foreign-slot-value (pointer ,class-name)
103                      (foreign-slot-value (pointer ,class-name)                                             ',(struct-type struct-name)
104                                          ',(struct-type struct-name) ',x)))                                             ',c-name)))
105                (unless (fboundp '(setf ,x))                   (defaccessor (setf ,lisp-name) ,c-name ,class-name
106                  (defgeneric (setf ,x) (val ,class-name)))                     (if (slot-boundp ,class-name 'value)
107                (defmethod (setf ,x) (val (,class-name ,class-name))                         (setf (getf (slot-value ,class-name 'value)
108                  (if (slot-boundp ,class-name 'value)                                     ',c-name)
109                      (setf (getf (slot-value ,class-name 'value) ',x) val)                               val)
110                      (setf (foreign-slot-value (pointer ,class-name)                         (setf (foreign-slot-value
111                                                ',(struct-type struct-name) ',x)                                 (pointer ,class-name)
112                                   ',(struct-type struct-name) ',c-name)
113                            val)))                            val)))
114                (save-setter ,class-name ,x)))                (save-setter ,class-name ,lisp-name))))
115            (foreign-slot-names (struct-type struct-name))))))            (or (mapcan (lambda (field)
116                            (unless (stringp field) (list (car field))))
117                          fields)
118                  (foreign-slot-names (struct-type struct-name)))))))
119    
120  (defmacro defbitaccessors (class slot &rest fields)  (defmacro defbitaccessors (class slot &rest fields)
121    (let ((pos 0))    (let ((pos 0))
122      (flet ((build-field (field)      (flet ((build-field (field)
123               (destructuring-bind (name type size) field               (destructuring-bind (name type size) field
124                 (prog1                 (destructuring-bind (lisp-name . c-name) (pair name)
125                     `(progn                   (prog1
126                        (unless (fboundp ',name)                       `(progn
127                          (defgeneric ,name (,class)))                          (defaccessor ,lisp-name ,c-name ,class
128                        (defmethod ,name ((,class ,class))                              (convert-from-foreign
129                          (convert-from-foreign                               (ldb (byte ,size ,pos) (slot-value ,class ',slot))
130                           (ldb (byte ,size ,pos) (slot-value ,class ',slot))                               ,type))
131                           ,type))                          (defaccessor (setf ,lisp-name) ,c-name ,class
132                        (unless (fboundp '(setf ,name))                              (setf (ldb (byte ,size ,pos)
133                          (defgeneric (setf ,name) (value ,class)))                                         (slot-value ,class ',slot))
134                        (defmethod (setf ,name) (value (,class ,class))                                    (convert-to-foreign val ,type))))
135                          (setf (ldb (byte ,size ,pos) (slot-value ,class ',slot))                     (incf pos size))))))
                               (convert-to-foreign value ,type))))  
                  (incf pos size)))))  
136        (cons 'progn (mapcar #'build-field fields)))))        (cons 'progn (mapcar #'build-field fields)))))
137    
138  (defun parse-struct (body)  (defun parse-struct (body)
139    (mapcar (lambda (str)    (flet ((struct? (type)
140              (if (stringp str) str             (and (consp type) (eq (car type) :struct)))
141                  (let ((str2 (second str)))           (cname (name)
142                    (if (and (consp str2) (eq (car str2) :struct))             (destructuring-bind (lisp-name . c-name) (pair name)
143                        (list (first str) (struct-type (second str2)))               (declare (ignore lisp-name))
144                        str))))               c-name)))
145            body))      (mapcar (lambda (str)
146                  (if (stringp str) str
147                      (list*
148                       (cname (first str))
149                       (let ((type (second str)))
150                         (if (struct? type)
151                             (struct-type (second type))
152                             type))
153                       (cddr str))))
154                body)))
155    
156  (defmacro defcstruct* (class &body body)  (defmacro defcstruct* (class &body body)
157    `(progn    `(progn

Legend:
Removed from v.17  
changed lines
  Added in v.18

  ViewVC Help
Powered by ViewVC 1.1.5