chiark / gitweb /
Size of TYPE-NUMBER detected by calling C
[clg] / glib / gtype.lisp
CommitLineData
112ac1d3 1;; Common Lisp bindings for GTK+ v2.x
74821f75 2;; Copyright 2000-2006 Espen S. Johnsen <espen@users.sf.net>
560af5c5 3;;
112ac1d3 4;; Permission is hereby granted, free of charge, to any person obtaining
5;; a copy of this software and associated documentation files (the
6;; "Software"), to deal in the Software without restriction, including
7;; without limitation the rights to use, copy, modify, merge, publish,
8;; distribute, sublicense, and/or sell copies of the Software, and to
9;; permit persons to whom the Software is furnished to do so, subject to
10;; the following conditions:
560af5c5 11;;
112ac1d3 12;; The above copyright notice and this permission notice shall be
13;; included in all copies or substantial portions of the Software.
560af5c5 14;;
112ac1d3 15;; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16;; EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17;; MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
18;; IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
19;; CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
20;; TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
21;; SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
1199ddd2 23;; $Id: gtype.lisp,v 1.61 2007-02-23 12:53:08 espen Exp $
560af5c5 24
25(in-package "GLIB")
26
27(use-prefix "g")
28
e0349dbd 29;; Initialize the glib type system
30(defbinding type-init () nil)
31(type-init)
560af5c5 32
1199ddd2 33(eval-when (:compile-toplevel :load-toplevel :execute)
34 (defbinding (bitsize-of-gtype "bitsize_of_gtype") () unsigned-int))
35
36(deftype type-number () `(unsigned-byte ,(bitsize-of-gtype)))
560af5c5 37
e74cfcab 38(deftype gtype () 'symbol)
39
75689fea 40(define-type-method alien-type ((type gtype))
41 (declare (ignore type))
e74cfcab 42 (alien-type 'type-number))
43
74821f75 44(define-type-method size-of ((type gtype) &key (inlined t))
45 (assert-inlined type inlined)
e74cfcab 46 (size-of 'type-number))
47
74821f75 48(define-type-method to-alien-form ((type gtype) gtype &optional copy-p)
49 (declare (ignore type copy-p))
e74cfcab 50 `(find-type-number ,gtype t))
51
74821f75 52(define-type-method to-alien-function ((type gtype) &optional copy-p)
53 (declare (ignore type copy-p))
e74cfcab 54 #'(lambda (gtype)
55 (find-type-number gtype t)))
56
74821f75 57(define-type-method from-alien-form ((type gtype) form &key ref)
58 (declare (ignore type ref))
59 `(type-from-number ,form))
e74cfcab 60
74821f75 61(define-type-method from-alien-function ((type gtype) &key ref)
62 (declare (ignore type ref))
e74cfcab 63 #'(lambda (type-number)
63752532 64 (type-from-number type-number)))
e74cfcab 65
74821f75 66(define-type-method writer-function ((type gtype) &key temp (inlined t))
67 (declare (ignore temp))
68 (assert-inlined type inlined)
e74cfcab 69 (let ((writer (writer-function 'type-number)))
70 #'(lambda (gtype location &optional (offset 0))
71 (funcall writer (find-type-number gtype t) location offset))))
72
74821f75 73(define-type-method reader-function ((type gtype) &key ref (inlined t))
74 (declare (ignore ref))
75 (assert-inlined type inlined)
e74cfcab 76 (let ((reader (reader-function 'type-number)))
74821f75 77 #'(lambda (location &optional (offset 0))
63752532 78 (type-from-number (funcall reader location offset)))))
e74cfcab 79
80
93aa67db 81(eval-when (:compile-toplevel :load-toplevel :execute)
d4b21b08 82 (defclass type-query (struct)
93aa67db 83 ((type-number :allocation :alien :type type-number)
74821f75 84 (name :allocation :alien :type (copy-of string))
93aa67db 85 (class-size :allocation :alien :type unsigned-int)
86 (instance-size :allocation :alien :type unsigned-int))
d168bafd 87 (:metaclass struct-class)))
93aa67db 88
89
e74cfcab 90(defbinding type-query (type) nil
91 ((find-type-number type t) type-number)
74821f75 92 ((make-instance 'type-query) type-query :in/return))
93aa67db 93
94(defun type-instance-size (type)
95 (slot-value (type-query type) 'instance-size))
96
97(defun type-class-size (type)
98 (slot-value (type-query type) 'class-size))
560af5c5 99
d4b21b08 100(defbinding type-class-ref (type) pointer
101 ((find-type-number type t) type-number))
560af5c5 102
74821f75 103(defbinding type-class-unref () nil
104 (class pointer))
93aa67db 105
d4b21b08 106(defbinding type-class-peek (type) pointer
107 ((find-type-number type t) type-number))
93aa67db 108
560af5c5 109
74821f75 110
d4b21b08 111;;;; Mapping between lisp types and glib types
560af5c5 112
dfa4f314 113(defvar *registered-types* ())
114(defvar *registered-type-aliases* ())
44f47f3d 115(defvar *registered-static-types* ())
dfa4f314 116(defvar *lisp-type-to-type-number* (make-hash-table))
117(defvar *type-number-to-lisp-type* (make-hash-table))
d4b21b08 118
119(defbinding %type-from-name () type-number
120 (name string))
121
dfa4f314 122(defun type-number-from-glib-name (name &optional (error-p t))
123 (let ((type-number (%type-from-name name)))
124 (cond
125 ((not (zerop type-number)) type-number)
126 (error-p (error "Invalid gtype name: ~A" name)))))
127
d32cbb7a 128(defun type-from-glib-name (name)
129 (type-from-number (type-number-from-glib-name name) t))
130
dfa4f314 131(defun register-type (type id)
74821f75 132 (cond
133 ((find-type-number type))
134 ((not id) (warn "Can't register type with no foreign id: ~A" type))
135 (t
136 (pushnew (cons type id) *registered-types* :key #'car)
137 (let ((type-number
138 (typecase id
139 (string (type-number-from-glib-name id))
140 (symbol (funcall id)))))
141 (setf (gethash type *lisp-type-to-type-number*) type-number)
142 (setf (gethash type-number *type-number-to-lisp-type*) type)
143 type-number))))
dfa4f314 144
145(defun register-type-alias (type alias)
146 (pushnew (cons type alias) *registered-type-aliases* :key #'car)
147 (setf
148 (gethash type *lisp-type-to-type-number*)
149 (find-type-number alias t)))
150
151(defun reinitialize-all-types ()
152 (clrhash *lisp-type-to-type-number*)
153 (clrhash *type-number-to-lisp-type*)
154 (type-init) ; initialize the glib type system
155 (mapc #'(lambda (type)
156 (register-type (car type) (cdr type)))
157 *registered-types*)
58a1fb1d 158 (mapc #'(lambda (type)
74821f75 159 (apply #'register-new-type type))
d32cbb7a 160 (reverse *registered-static-types*))
dfa4f314 161 (mapc #'(lambda (type)
162 (register-type-alias (car type) (cdr type)))
163 *registered-type-aliases*))
164
165(pushnew 'reinitialize-all-types
166 #+cmu *after-save-initializations*
74821f75 167 #+sbcl *init-hooks*
168 #+clisp custom:*init-hooks*)
dfa4f314 169
170#+cmu
171(pushnew 'system::reinitialize-global-table ; we shouldn't have to do this?
172 *after-save-initializations*)
173
174
175(defun find-type-number (type &optional error-p)
560af5c5 176 (etypecase type
177 (integer type)
dfa4f314 178 (string (type-number-from-glib-name type error-p))
d4b21b08 179 (symbol
dfa4f314 180 (or
181 (gethash type *lisp-type-to-type-number*)
182 (and error-p (error "Type not registered: ~A" type))))
183 (class (find-type-number (class-name type) error-p))))
560af5c5 184
4de90d10 185(defun type-from-number (type-number &optional error)
186 (multiple-value-bind (type found)
dfa4f314 187 (gethash type-number *type-number-to-lisp-type*)
e7dbc3bf 188 (if found
189 type
dfa4f314 190 (let ((name (find-foreign-type-name type-number)))
e7dbc3bf 191 (cond
cd859052 192 ((and name (not (= (type-number-from-glib-name name nil) type-number)))
e7dbc3bf 193 ;; This is a hack because GdkEvent seems to be registered
194 ;; multiple times
195 (type-from-number (type-number-from-glib-name name)))
196 ((and error name)
197 (error "Type number not registered: ~A (~A)" type-number name))
198 ((and error)
199 (error "Invalid type number: ~A" type-number)))))))
560af5c5 200
dfa4f314 201(defbinding (find-foreign-type-name "g_type_name") (type) (copy-of string)
d4b21b08 202 ((find-type-number type t) type-number))
203
204(defun type-number-of (object)
205 (find-type-number (type-of object) t))
206
21299acf 207(eval-when (:compile-toplevel :load-toplevel :execute)
dfa4f314 208 (defvar *type-initializers* ())
209 (defun %find-types-in-library (pathname prefixes ignore)
74821f75 210 (let ((process
211 (run-program
212 "/usr/bin/nm"
213 #+clisp :arguments
e3b11dff 214 (list #-darwin"--defined-only" #-darwin"-D" "-g" #+darwin"-f"
215 #+darwin"-s" #+darwin"__TEXT" #+darwin"__text"
216 (namestring (truename pathname)))
74821f75 217 :output :stream :wait nil)))
21299acf 218 (unwind-protect
219 (loop
e3b11dff 220 as line = (read-line
221 #+(or cmu sbcl) (process-output process)
222 #+clisp process
223 nil)
224 as symbol = (when line
225 (let ((pos (position #\Space line :from-end t)))
226 #-darwin(subseq line (1+ pos))
d998fbdd 227 #+darwin
e3b11dff 228 (when (char= (char line (1- pos)) #\T)
229 (subseq line (+ pos 2)))))
230 while line
21299acf 231 when (and
e3b11dff 232 symbol (> (length symbol) 9)
8672dc09 233 (not (char= (char symbol 0) #\_))
dfa4f314 234 (or
235 (not prefixes)
236 (some #'(lambda (prefix)
237 (and
238 (> (length symbol) (length prefix))
239 (string= prefix symbol :end2 (length prefix))))
240 (mklist prefixes)))
241 (string= "_get_type" symbol :start2 (- (length symbol) 9))
21299acf 242 (not (member symbol ignore :test #'string=)))
243 collect symbol)
74821f75 244 (#+(or cmu sbcl)process-close
245 #+clisp close
246 process)))))
21299acf 247
560af5c5 248
735a29da 249(defmacro init-types-in-library (filename &key prefix ignore)
21299acf 250 (let ((names (%find-types-in-library filename prefix ignore)))
251 `(progn
252 ,@(mapcar #'(lambda (name)
253 `(progn
254 (defbinding (,(intern name) ,name) () type-number)
dfa4f314 255 (,(intern name))
256 (pushnew ',(intern name) *type-initializers*)))
21299acf 257 names))))
258
dfa4f314 259(defun find-type-init-function (type-number)
735a29da 260 (loop
261 for type-init in *type-initializers*
262 when (= type-number (funcall type-init))
263 do (return type-init)))
264
265(defun register-type-as (type-number)
266 (or
267 (find-type-init-function type-number)
268 (find-foreign-type-name type-number)
269 (error "Unknown type-number: ~A" type-number)))
dfa4f314 270
271(defun default-type-init-name (type)
272 (find-symbol (format nil "~A_~A_get_type"
273 (package-prefix *package*)
274 (substitute #\_ #\- (string-downcase type)))))
275
21299acf 276
15cbdefc 277(eval-when (:compile-toplevel :load-toplevel :execute)
278 (defclass type-info (struct)
279 ((class-size :allocation :alien :type (unsigned 16) :initarg :class-size)
280 (base-init :allocation :alien :type pointer)
281 (base-finalize :allocation :alien :type pointer)
282 (class-init :allocation :alien :type pointer)
283 (class-finalize :allocation :alien :type pointer)
284 (class-data :allocation :alien :type pointer)
285 (instance-size :allocation :alien :type (unsigned 16)
286 :initarg :instance-size)
287 (n-preallocs :allocation :alien :type (unsigned 16))
288 (instance-init :allocation :alien :type pointer)
289 (value-table :allocation :alien :type pointer))
290 (:metaclass struct-class)))
291
292(defbinding %type-register-static () type-number
e7dbc3bf 293 (parent-type type-number)
15cbdefc 294 (name string)
295 (info type-info)
296 (0 unsigned-int))
297
92a07e63 298(defun register-new-type (type parent &optional foreign-name)
15cbdefc 299 (let ((parent-info (type-query parent)))
300 (with-slots ((parent-number type-number) class-size instance-size) parent-info
301 (let ((type-number
302 (%type-register-static
303 parent-number
92a07e63 304 (or foreign-name (default-alien-type-name type))
15cbdefc 305 (make-instance 'type-info :class-size class-size :instance-size instance-size))))
44f47f3d 306 (pushnew (list type parent foreign-name) *registered-static-types* :key #'car)
307 (setf (gethash type *lisp-type-to-type-number*) type-number)
308 (setf (gethash type-number *type-number-to-lisp-type*) type)
309 type-number))))
15cbdefc 310
311
21299acf 312
313;;;; Metaclass for subclasses of ginstance
314
315(eval-when (:compile-toplevel :load-toplevel :execute)
316 (defclass ginstance-class (proxy-class)
6497583a 317 ((gtype :initarg :gtype :initform nil :reader ginstance-class-gtype))))
cd859052 318
319
1eaa1bd6 320(defun update-size (class)
321 (let ((type-number (find-type-number class)))
322 (cond
74821f75 323 ((not (foreign-size-p class))
324 (setf (foreign-size class) (type-instance-size type-number)))
1eaa1bd6 325 ((and
74821f75 326 (foreign-size-p class)
327 (not (= (type-instance-size type-number) (foreign-size class))))
1eaa1bd6 328 (warn "Size mismatch for class ~A" class)))))
329
09f6e237 330
cd859052 331(defmethod finalize-inheritance ((class ginstance-class))
74821f75 332 (prog1
333 #+clisp(call-next-method)
334 (let* ((class-name (class-name class))
335 (super (most-specific-proxy-superclass class))
336 (gtype (or
337 (first (ginstance-class-gtype class))
338 (default-alien-type-name class-name)))
339 (type-number
340 (or
341 (find-type-number class-name)
342 (let ((type-number
343 (if (or
344 (symbolp gtype)
345 (type-number-from-glib-name gtype nil))
346 (register-type class-name gtype)
347 (register-new-type class-name (class-name super) gtype))))
348 (type-class-ref type-number)
349 type-number))))
584285fb 350 #+nil
74821f75 351 (when (and
352 (supertype type-number)
353 (not (eq (class-name super) (supertype type-number))))
354 (warn "Super class mismatch between CLOS and GObject for ~A"
355 class-name)))
356 (update-size class))
357 #-clisp(call-next-method))
1eaa1bd6 358
359
360(defmethod shared-initialize ((class ginstance-class) names &rest initargs)
74821f75 361 (declare (ignore names initargs))
1eaa1bd6 362 (call-next-method)
363 (when (class-finalized-p class)
364 (update-size class)))
365
4de90d10 366
21299acf 367(defmethod validate-superclass ((class ginstance-class) (super standard-class))
368 (subtypep (class-name super) 'ginstance))
369
560af5c5 370
93aa67db 371;;;; Superclass for wrapping types in the glib type system
560af5c5 372
373(eval-when (:compile-toplevel :load-toplevel :execute)
af338f4a 374 (defclass ginstance (ref-counted-object)
09f6e237 375 (;(class :allocation :alien :type pointer :offset 0)
376 )
377 (:metaclass proxy-class)
378 (:size #.(size-of 'pointer))))
560af5c5 379
74821f75 380(defun ref-type-number (location &optional offset)
381 (declare (ignore location offset)))
382
383(setf (symbol-function 'ref-type-number) (reader-function 'type-number))
384
895c9a9e 385(defun %type-number-of-ginstance (location)
74821f75 386 (let ((class (ref-pointer location)))
387 (ref-type-number class)))
560af5c5 388
74821f75 389(defmethod make-proxy-instance :around ((class ginstance-class) location
390 &rest initargs)
d168bafd 391 (declare (ignore class))
895c9a9e 392 (let ((class (labels ((find-known-class (type-number)
393 (or
394 (find-class (type-from-number type-number) nil)
395 (unless (zerop type-number)
396 (find-known-class (type-parent type-number))))))
397 (find-known-class (%type-number-of-ginstance location)))))
74821f75 398 ;; Note that chancing the class argument should not alter "the
8958fa4a 399 ;; ordered set of applicable methods" as specified in the
400 ;; Hyperspec
d168bafd 401 (if class
8958fa4a 402 (apply #'call-next-method class location initargs)
403 (error "Object at ~A has an unkown type number: ~A"
404 location (%type-number-of-ginstance location)))))
405
560af5c5 406
d4b21b08 407;;;; Registering fundamental types
408
63752532 409(register-type 'nil "void")
d4b21b08 410(register-type 'pointer "gpointer")
411(register-type 'char "gchar")
412(register-type 'unsigned-char "guchar")
413(register-type 'boolean "gboolean")
d4b21b08 414(register-type 'int "gint")
73383a9e 415(register-type-alias 'integer 'int)
dfa4f314 416(register-type-alias 'fixnum 'int)
d4b21b08 417(register-type 'unsigned-int "guint")
418(register-type 'long "glong")
419(register-type 'unsigned-long "gulong")
420(register-type 'single-float "gfloat")
421(register-type 'double-float "gdouble")
a8cb9408 422(register-type 'pathname "gchararray")
4de90d10 423(register-type 'string "gchararray")
d4b21b08 424
425
62f12808 426;;;; Introspection of type information
d4b21b08 427
e77e7713 428(defvar *derivable-type-info* (make-hash-table))
d4b21b08 429
62f12808 430(defun register-derivable-type (type id expander &optional dependencies)
d4b21b08 431 (register-type type id)
e77e7713 432 (let ((type-number (register-type type id)))
62f12808 433 (setf
434 (gethash type-number *derivable-type-info*)
435 (list expander dependencies))))
d4b21b08 436
4de90d10 437(defun find-type-info (type)
438 (dolist (super (cdr (type-hierarchy type)))
e77e7713 439 (let ((info (gethash super *derivable-type-info*)))
4de90d10 440 (return-if info))))
441
62f12808 442(defun expand-type-definition (type forward-p options)
443 (let ((expander (first (find-type-info type))))
444 (funcall expander (find-type-number type t) forward-p options)))
d4b21b08 445
74821f75 446
d4b21b08 447(defbinding type-parent (type) type-number
448 ((find-type-number type t) type-number))
449
450(defun supertype (type)
451 (type-from-number (type-parent type)))
452
337933d8 453(defbinding %type-interfaces (type) pointer
454 ((find-type-number type t) type-number)
455 (n-interfaces unsigned-int :out))
456
457(defun type-interfaces (type)
458 (multiple-value-bind (array length) (%type-interfaces type)
459 (unwind-protect
d168bafd 460 (map-c-vector 'list #'identity array 'type-number length)
337933d8 461 (deallocate-memory array))))
462
463(defun implements (type)
464 (mapcar #'type-from-number (type-interfaces type)))
465
d4b21b08 466(defun type-hierarchy (type)
467 (let ((type-number (find-type-number type t)))
468 (unless (= type-number 0)
469 (cons type-number (type-hierarchy (type-parent type-number))))))
470
471(defbinding (type-is-p "g_type_is_a") (type super) boolean
472 ((find-type-number type) type-number)
473 ((find-type-number super) type-number))
474
475(defbinding %type-children () pointer
476 (type-number type-number)
477 (num-children unsigned-int :out))
478
479(defun map-subtypes (function type &optional prefix)
480 (let ((type-number (find-type-number type t)))
481 (multiple-value-bind (array length) (%type-children type-number)
482 (unwind-protect
d168bafd 483 (map-c-vector
d4b21b08 484 'nil
485 #'(lambda (type-number)
486 (when (or
487 (not prefix)
dfa4f314 488 (string-prefix-p prefix (find-foreign-type-name type-number)))
d4b21b08 489 (funcall function type-number))
490 (map-subtypes function type-number prefix))
491 array 'type-number length)
492 (deallocate-memory array)))))
493
494(defun find-types (prefix)
495 (let ((type-list nil))
e77e7713 496 (maphash
497 #'(lambda (type-number expander)
498 (declare (ignore expander))
499 (map-subtypes
500 #'(lambda (type-number)
501 (pushnew type-number type-list))
502 type-number prefix))
503 *derivable-type-info*)
d4b21b08 504 type-list))
505
74821f75 506(defun find-type-dependencies (type &optional options)
507 (let ((find-dependencies (second (find-type-info type))))
508 (when find-dependencies
509 (remove-duplicates
510 (mapcar #'find-type-number
511 (funcall find-dependencies (find-type-number type t) options))))))
512
513
514;; The argument is a list where each elements is on the form
584285fb 515;; (type . dependencies). This function will not handle indirect
516;; dependencies and types depending on them selve.
74821f75 517(defun sort-types-topologicaly (unsorted)
518 (flet ((depend-p (type1)
519 (find-if #'(lambda (type2)
520 (and
521 ;; If a type depends a subtype it has to be
522 ;; forward defined
523 (not (type-is-p (car type2) (car type1)))
524 (find (car type2) (cdr type1))))
525 unsorted)))
526 (let ((sorted
527 (loop
528 while unsorted
529 nconc (multiple-value-bind (sorted remaining)
530 (delete-collect-if
531 #'(lambda (type)
532 (or (not (cdr type)) (not (depend-p type))))
533 unsorted)
534 (cond
535 ((not sorted)
536 ;; We have a circular dependency which have to
537 ;; be resolved
538 (let ((selected
539 (find-if
540 #'(lambda (type)
541 (every
542 #'(lambda (dep)
543 (or
544 (not (type-is-p (car type) dep))
545 (not (find dep unsorted :key #'car))))
546 (cdr type)))
547 unsorted)))
548 (unless selected
549 (error "Couldn't resolve circular dependency"))
550 (setq unsorted (delete selected unsorted))
551 (list selected)))
552 (t
553 (setq unsorted remaining)
554 sorted))))))
555
556 ;; Mark types which have to be forward defined
557 (loop
558 for tmp on sorted
559 as (type . dependencies) = (first tmp)
560 collect (cons type (and
561 dependencies
562 (find-if #'(lambda (type)
563 (find (car type) dependencies))
564 (rest tmp))
565 t))))))
d4b21b08 566
567
568(defun expand-type-definitions (prefix &optional args)
dfa4f314 569 (flet ((type-options (type-number)
570 (let ((name (find-foreign-type-name type-number)))
4de90d10 571 (cdr (assoc name args :test #'string=)))))
d4b21b08 572
e77e7713 573 (let ((type-list
574 (delete-if
575 #'(lambda (type-number)
dfa4f314 576 (let ((name (find-foreign-type-name type-number)))
e77e7713 577 (or
578 (getf (type-options type-number) :ignore)
579 (find-if
580 #'(lambda (options)
581 (and
582 (string-prefix-p (first options) name)
80a09c29 583 (getf (cdr options) :ignore-prefix)
584 (not (some
585 #'(lambda (exception)
586 (string= name exception))
587 (getf (cdr options) :except)))))
e77e7713 588 args))))
589 (find-types prefix))))
21299acf 590
e77e7713 591 (dolist (type-number type-list)
dfa4f314 592 (let ((name (find-foreign-type-name type-number)))
e77e7713 593 (register-type
594 (getf (type-options type-number) :type (default-type-name name))
735a29da 595 (register-type-as type-number))))
21299acf 596
74821f75 597 ;; This is needed for some unknown reason to get type numbers right
598 (mapc #'find-type-dependencies type-list)
599
600 (let ((sorted-type-list
601 #+clisp (mapcar #'list type-list)
602 #-clisp
603 (sort-types-topologicaly
604 (mapcar
605 #'(lambda (type)
606 (cons type (find-type-dependencies type (type-options type))))
607 type-list))))
62f12808 608 `(progn
609 ,@(mapcar
21299acf 610 #'(lambda (pair)
611 (destructuring-bind (type . forward-p) pair
612 (expand-type-definition type forward-p (type-options type))))
613 sorted-type-list)
62f12808 614 ,@(mapcar
21299acf 615 #'(lambda (pair)
616 (destructuring-bind (type . forward-p) pair
617 (when forward-p
618 (expand-type-definition type nil (type-options type)))))
62f12808 619 sorted-type-list))))))
e77e7713 620
d4b21b08 621(defmacro define-types-by-introspection (prefix &rest args)
4de90d10 622 (expand-type-definitions prefix args))
21299acf 623
74821f75 624(defexport define-types-by-introspection (prefix &rest args)
fbd2b3d9 625 (list-autoexported-symbols (expand-type-definitions prefix args)))
74821f75 626
21299acf 627
628;;;; Initialize all non static types in GObject
629
daa10b6d 630(init-types-in-library #.(concatenate 'string (pkg-config:pkg-variable "glib-2.0" "libdir") "/libgobject-2.0." asdf:*dso-extension*))