0560ddb42c4cf9f0334155f7fe311dfa63af4ced
[cl-gtk2.git] / glib / gobject.generating.lisp
1 (in-package :gobject)
2
3 (defvar *lisp-name-package* nil
4   "For internal use (used by class definitions generator). Specifies the package in which symbols are interned.")
5 (defvar *strip-prefix* "")
6 (defvar *lisp-name-exceptions* nil)
7 (defvar *generation-exclusions* nil)
8 (defvar *known-interfaces* (make-hash-table :test 'equal))
9 (defvar *additional-properties* nil)
10 (defvar *generated-types* nil)
11
12 (defun name->supplied-p (name)
13   (make-symbol (format nil "~A-SUPPLIED-P" (symbol-name name))))
14
15 (defstruct property name accessor-name readable writable)
16
17 (defstruct (gobject-property (:include property)) gname type)
18
19 (defstruct (cffi-property (:include property)) type reader writer)
20
21 (defmethod make-load-form ((object gobject-property) &optional env)
22   (declare (ignore env))
23   `(make-gobject-property :name ',(property-name object)
24                           :accessor-name ',(property-accessor-name object)
25                           :readable ',(property-readable object)
26                           :writable ',(property-writable object)
27                           :gname ',(gobject-property-gname object)
28                           :type ',(gobject-property-type object)))
29
30 (defmethod make-load-form ((object cffi-property) &optional env)
31   (declare (ignore env))
32   `(make-cffi-property :name ',(property-name object)
33                        :accessor-name ',(property-accessor-name object)
34                        :readable ',(property-readable object)
35                        :writable ',(property-writable object)
36                        :type ',(cffi-property-type object)
37                        :reader ',(cffi-property-reader object)
38                        :writer ',(cffi-property-writer object)))
39
40 (defun parse-gobject-property (spec)
41   (destructuring-bind (name accessor-name gname type readable writable) spec
42       (make-gobject-property :name name
43                              :accessor-name accessor-name
44                              :gname gname
45                              :type type
46                              :readable readable
47                              :writable writable)))
48
49 (defun parse-cffi-property (spec)
50   (destructuring-bind (name accessor-name type reader writer) spec
51     (make-cffi-property :name name
52                         :accessor-name accessor-name
53                         :type type
54                         :reader reader
55                         :writer writer
56                         :readable (not (null reader))
57                         :writable (not (null writer)))))
58
59 (defun parse-property (spec)
60   (cond
61     ((eq (first spec) :cffi) (parse-cffi-property (rest spec)))
62     (t (parse-gobject-property spec))))
63
64 (defun property->method-arg (property)
65   (when (or (gobject-property-p property)
66             (and (cffi-property-p property)
67                  (property-writable property)))
68     (let ((name (property-name property)))
69       `(,name nil ,(name->supplied-p name)))))
70
71 (defun gobject-property->arg-push (property)
72   (assert (typep property 'gobject-property))
73   (with-slots (name type gname) property
74     `(when ,(name->supplied-p name)
75        (push ,gname arg-names)
76        (push ,type arg-types)
77        (push ,name arg-values))))
78
79 (defun cffi-property->initarg (property)
80   (assert (typep property 'cffi-property))
81   (when (property-writable property)
82     (with-slots (accessor-name name type writer) property
83       `(when ,(name->supplied-p name)
84          (setf (,accessor-name object) ,name)))))
85
86 (defun accessor-name (class-name property-name)
87   (intern (format nil "~A-~A" (symbol-name class-name)
88                   (lispify-name property-name))
89           *lisp-name-package*))
90
91 (defgeneric property->reader (class property))
92 (defgeneric property->writer (class property))
93
94 (defmethod property->reader (class (property gobject-property))
95   (with-slots (accessor-name type gname) property
96    `(defmethod ,accessor-name ((object ,class))
97       (g-object-call-get-property object ,gname ,type))))
98
99 (defmethod property->reader (class (property cffi-property))
100   (with-slots (accessor-name type reader) property
101     (etypecase reader
102       (string `(defmethod ,accessor-name ((object ,class))
103                  (foreign-funcall ,reader g-object object ,type)))
104       (symbol `(defmethod ,accessor-name ((object ,class))
105                  (funcall ',reader object))))))
106
107 (defmethod property->writer (class (property gobject-property))
108   (with-slots (accessor-name type gname) property
109     `(defmethod (setf ,accessor-name) (new-value (object ,class))
110        (g-object-call-set-property object ,gname new-value ,type)
111        new-value)))
112
113 (defmethod property->writer (class (property cffi-property))
114   (with-slots (accessor-name type writer) property
115     (etypecase writer
116       (string `(defmethod (setf ,accessor-name) (new-value (object ,class))
117                  (foreign-funcall ,writer g-object object ,type new-value :void)
118                  new-value))
119       (symbol `(defmethod (setf ,accessor-name) (new-value (object ,class))
120                  (funcall ',writer object new-value)
121                  new-value)))))
122
123 (defun property->accessors (class property export)
124   (append (when (property-readable property)
125             (list (property->reader class property)))
126           (when (property-writable property)
127             (list (property->writer class property)))
128           (when export
129             (list `(export ',(property-accessor-name property)
130                            (find-package ,(package-name (symbol-package (property-accessor-name property)))))))))
131
132 (defun interface->lisp-class-name (interface)
133   (etypecase interface
134     (symbol interface)
135     (string (or (gethash interface *known-interfaces*)
136                 (error "Unknown interface ~A" interface)))))
137
138 (defun type-initializer-call (type-initializer)
139   (etypecase type-initializer
140     (string `(if (foreign-symbol-pointer ,type-initializer)
141                  (foreign-funcall-pointer
142                   (foreign-symbol-pointer ,type-initializer) ()
143                   g-type)
144                  (warn "Type initializer '~A' is not available" ,type-initializer)))
145     (symbol `(funcall ',type-initializer))))
146
147 (defun meta-property->slot (class-name property)
148   `(,(property-name property)
149      :allocation ,(if (gobject-property-p property) :gobject-property :gobject-fn)
150      :g-property-type ,(if (gobject-property-p property) (gobject-property-type property) (cffi-property-type property))
151      :accessor ,(intern (format nil "~A-~A" (symbol-name class-name) (property-name property)) (symbol-package class-name))
152      ,@(when (if (gobject-property-p property)
153                  t
154                  (not (null (cffi-property-writer property))))
155              `(:initarg
156                ,(intern (string-upcase (property-name property)) (find-package :keyword))))
157      ,@(if (gobject-property-p property)
158            `(:g-property-name ,(gobject-property-gname property))
159            `(:g-getter ,(cffi-property-reader property)
160                        :g-setter ,(cffi-property-writer property)))))
161
162 (defmacro define-g-object-class (g-type-name name
163                                  (&key (superclass 'g-object)
164                                        (export t)
165                                        interfaces
166                                        type-initializer)
167                                  (&rest properties))
168   (setf properties (mapcar #'parse-property properties))
169   `(progn
170      (defclass ,name (,@(when (and superclass (not (eq superclass 'g-object))) (list superclass)) ,@(mapcar #'interface->lisp-class-name interfaces))
171        (,@(mapcar (lambda (property) (meta-property->slot name property)) properties))
172        (:metaclass gobject-class)
173        (:g-type-name . ,g-type-name)
174        ,@(when type-initializer
175                (list `(:g-type-initializer . ,type-initializer))))
176      ,@(when export
177              (cons `(export ',name (find-package ,(package-name (symbol-package name))))
178                    (mapcar (lambda (property)
179                              `(export ',(intern (format nil "~A-~A" (symbol-name name) (property-name property)) (symbol-package name))
180                                       (find-package ,(package-name (symbol-package name)))))
181                            properties)))))
182
183 (defmacro define-g-interface (g-type-name name (&key (export t) type-initializer) &body properties)
184   (setf properties (mapcar #'parse-property properties))
185   `(progn
186      (defclass ,name ()
187        (,@(mapcar (lambda (property) (meta-property->slot name property)) properties))
188        (:metaclass gobject-class)
189        (:g-type-name . ,g-type-name)
190        (:g-interface-p . t)
191        ,@(when type-initializer
192                (list `(:g-type-initializer . ,type-initializer))))
193      ,@(when export
194              (cons `(export ',name (find-package ,(package-name (symbol-package name))))
195                    (mapcar (lambda (property)
196                              `(export ',(intern (format nil "~A-~A" (symbol-name name) (property-name property)) (symbol-package name))
197                                       (find-package ,(package-name (symbol-package name)))))
198                            properties)))
199      (eval-when (:compile-toplevel :load-toplevel :execute)
200        (setf (gethash ,g-type-name *known-interfaces*) ',name))))
201
202 (defun starts-with (name prefix)
203   (and prefix (> (length name) (length prefix)) (string= (subseq name 0 (length prefix)) prefix)))
204
205 (defun strip-start (name prefix)
206   (if (starts-with name prefix)
207       (subseq name (length prefix))
208       name))
209
210 (defun lispify-name (name)
211   (with-output-to-string (stream)
212     (loop for c across (strip-start name *strip-prefix*)
213        for firstp = t then nil
214        do (when (and (not firstp) (upper-case-p c)) (write-char #\- stream))
215        do (write-char (char-upcase c) stream))))
216
217 (defun g-name->name (name)
218   (or (second (assoc name *lisp-name-exceptions* :test 'equal))
219       (intern (string-upcase (lispify-name name)) *lisp-name-package*)))
220
221 (defun property->property-definition (class-name property)
222   (let ((name (g-name->name (g-class-property-definition-name property)))
223         (accessor-name (accessor-name class-name (g-class-property-definition-name property)))
224         (g-name (g-class-property-definition-name property))
225         (type (gtype-name (g-class-property-definition-type property)))
226         (readable (g-class-property-definition-readable property))
227         (writable (and (g-class-property-definition-writable property)
228                        (not (g-class-property-definition-constructor-only property)))))
229     `(,name ,accessor-name ,g-name ,type ,readable ,writable)))
230
231 (defun probable-type-init-name (type-name)
232   (with-output-to-string (stream)
233     (iter (for c in-string type-name)
234           (for prev-c previous c)
235           (when (and (not (first-iteration-p))
236                      (upper-case-p c)
237                      (not (upper-case-p prev-c))
238                      (not (char= prev-c #\_)))
239             (write-char #\_ stream))
240           (write-char (char-downcase c) stream))
241     (write-string "_get_type" stream)))
242
243 (defun get-g-class-definition (type &optional lisp-name-package)
244   (when (and (stringp type) (null (ignore-errors (gtype type))))
245     (let ((type-init-name (probable-type-init-name type)))
246       (when (foreign-symbol-pointer type-init-name)
247         (foreign-funcall-pointer (foreign-symbol-pointer type-init-name) () :int))))
248   (when *generated-types*
249     (setf (gethash (gtype-name (gtype type)) *generated-types*) t))
250   (let* ((*lisp-name-package* (or lisp-name-package *lisp-name-package* *package*))
251          (g-type (gtype type))
252          (g-name (gtype-name g-type))
253          (name (g-name->name g-name))
254          (superclass-g-type (g-type-parent g-type))
255          (superclass-name (g-name->name (gtype-name superclass-g-type)))
256          (interfaces (g-type-interfaces g-type))
257          (properties (class-properties g-type))
258          (type-init-name (probable-type-init-name g-name))
259          (own-properties
260           (sort (copy-list (remove g-type properties :key #'g-class-property-definition-owner-type :test-not #'g-type=))
261                 #'string< :key #'g-class-property-definition-name)))
262     `(define-g-object-class ,g-name ,name 
263          (:superclass ,superclass-name
264                       :export t
265                       :interfaces (,@(sort (mapcar #'gtype-name interfaces) 'string<))
266                       ,@(when (and (foreign-symbol-pointer type-init-name)
267                                    (not (null-pointer-p (foreign-symbol-pointer type-init-name))))
268                               `(:type-initializer ,type-init-name)))
269        (,@(mapcar (lambda (property)
270                     (property->property-definition name property))
271                   own-properties)
272           ,@(cdr (find g-name *additional-properties* :key 'car :test 'string=))))))
273
274 (defun get-g-interface-definition (interface &optional lisp-name-package)
275   (when (and (stringp interface) (null (ignore-errors (gtype interface))))
276     (let ((type-init-name (probable-type-init-name interface)))
277       (when (foreign-symbol-pointer type-init-name)
278         (foreign-funcall-pointer (foreign-symbol-pointer type-init-name) () :int))))
279   (when *generated-types*
280     (setf (gethash (gtype-name (gtype interface)) *generated-types*) t))
281   (let* ((*lisp-name-package* (or lisp-name-package *lisp-name-package* *package*))
282          (type (gtype interface))
283          (g-name (gtype-name type))
284          (name (g-name->name g-name))
285          (properties (sort (copy-list (interface-properties type))
286                            #'string< :key #'g-class-property-definition-name))
287          (probable-type-initializer (probable-type-init-name g-name)))
288     `(define-g-interface ,g-name ,name
289          (:export t
290                   ,@(when (foreign-symbol-pointer probable-type-initializer)
291                           `(:type-initializer ,probable-type-initializer)))
292        ,@(append (mapcar (lambda (property)
293                            (property->property-definition name property))
294                          properties)
295                  (cdr (find g-name *additional-properties* :key 'car :test 'string=))))))
296
297 (defun get-g-class-definitions-for-root-1 (type)
298   (unless (member (gtype type) *generation-exclusions* :test 'g-type=)
299     (iter (when (first-iteration-p)
300             (unless (and *generated-types*
301                          (gethash (gtype-name (gtype type)) *generated-types*))
302               (appending (list (get-g-class-definition type)))))
303           (for child-type in (sort (copy-list (g-type-children type)) #'string< :key #'gtype-name))
304           (appending (get-g-class-definitions-for-root-1 child-type)))))
305
306 (defun get-g-class-definitions-for-root (type)
307   (setf type (gtype type))
308   (get-g-class-definitions-for-root-1 type))
309
310 (defvar *referenced-types*)
311
312 (defun class-or-interface-properties (type)
313   (setf type (gtype type))
314   (cond 
315     ((g-type= (g-type-fundamental type) (gtype +g-type-object+)) (class-properties type))
316     ((g-type= (g-type-fundamental type) (gtype +g-type-interface+)) (interface-properties type))))
317
318 (defun get-shallow-referenced-types (type)
319   (setf type (gtype type))
320   (remove-duplicates (sort (loop
321                               for property in (class-or-interface-properties type)
322                               when (g-type= type (g-class-property-definition-owner-type property))
323                               collect (g-class-property-definition-type property))
324                            #'string<
325                            :key #'gtype-name)
326                      :test 'equal))
327
328 (defun get-referenced-types-1 (type)
329   (setf type (gtype type))
330   (loop
331      for property-type in (sort (copy-list (get-shallow-referenced-types type)) #'string> :key #'gtype-name)
332      do (pushnew property-type *referenced-types* :test 'g-type=))
333   (loop
334      for type in (sort (copy-list (g-type-children type)) #'string< :key #'gtype-name)
335      do (get-referenced-types-1 type)))
336
337 (defun get-referenced-types (root-type)
338   (let (*referenced-types*)
339     (get-referenced-types-1 (gtype root-type))
340     *referenced-types*))
341
342 (defun filter-types-by-prefix (types prefix)
343   (remove-if-not
344    (lambda (type)
345      (starts-with (gtype-name (gtype type)) prefix))
346    types))
347
348 (defun filter-types-by-fund-type (types fund-type)
349   (setf fund-type (gtype fund-type))
350   (remove-if-not
351    (lambda (type)
352      (equal (g-type-fundamental (gtype type)) fund-type))
353    types))
354
355 (defmacro define-g-enum (g-name name (&key (export t) type-initializer) &body values)
356   "Defines a GEnum type for enumeration. Generates corresponding CFFI definition.
357
358 Example:
359 @begin{pre}
360 \(define-g-enum \"GdkGrabStatus\" grab-status () :success :already-grabbed :invalid-time :not-viewable :frozen)
361 \(define-g-enum \"GdkExtensionMode\" gdk-extension-mode (:export t :type-initializer \"gdk_extension_mode_get_type\")
362   (:none 0) (:all 1) (:cursor 2))
363 @end{pre}
364 @arg[g-name]{a string. Specifies the GEnum name}
365 @arg[name]{a symbol. Names the enumeration type.}
366 @arg[export]{a boolean. If true, @code{name} will be exported.}
367 @arg[type-initializer]{a @code{NIL} or a string or a function designator.
368
369 If non-@code{NIL}, specifies the function that initializes the type: string specifies a C function that returns the GType value and function designator specifies the Lisp function.}
370 @arg[values]{values for enum. Each value is a keyword or a list @code{(keyword integer-value)}. @code{keyword} corresponds to Lisp value of enumeration, and @code{integer-value} is an C integer for enumeration item. If @code{integer-value} is not specified, it is generated automatically (see CFFI manual)}"
371   `(progn
372      (defcenum ,name ,@values)
373      (register-enum-type ,g-name ',name)
374      ,@(when export
375              (list `(export ',name (find-package ,(package-name (symbol-package name))))))
376      ,@(when type-initializer
377              (list `(at-init () ,(type-initializer-call type-initializer))))))
378
379 (defun enum-value->definition (enum-value)
380   (let ((value-name (intern (lispify-name (enum-item-nick enum-value))
381                             (find-package :keyword)))
382         (numeric-value (enum-item-value enum-value)))
383     `(,value-name ,numeric-value)))
384
385 (defun get-g-enum-definition (type &optional lisp-name-package)
386   (when (and (stringp type) (null (gtype type)))
387     (let ((type-init-name (probable-type-init-name type)))
388       (when (foreign-symbol-pointer type-init-name)
389         (foreign-funcall-pointer (foreign-symbol-pointer type-init-name) () :int))))
390   (when *generated-types*
391     (setf (gethash (gtype-name (gtype type)) *generated-types*) t))
392   (let* ((*lisp-name-package* (or lisp-name-package *lisp-name-package* *package*))
393          (g-type (gtype type))
394          (g-name (gtype-name g-type))
395          (name (g-name->name g-name))
396          (items (get-enum-items g-type))
397          (probable-type-initializer (probable-type-init-name g-name)))
398     `(define-g-enum ,g-name ,name
399          (:export t
400                   ,@(when (foreign-symbol-pointer probable-type-initializer)
401                           (list :type-initializer
402                                 probable-type-initializer)))
403        ,@(mapcar #'enum-value->definition items))))
404
405 (defmacro define-g-flags (g-name name (&key (export t) type-initializer) &body values)
406   "Defines a GFlags type for enumeration that can combine its values. Generates corresponding CFFI definition. Values of this type are lists of keywords that are combined.
407
408 Example:
409 @begin{pre}
410 \(define-g-flags \"GdkWindowState\" window-state ()
411   (:withdrawn 1)
412   (:iconified 2) (:maximized 4) (:sticky 8) (:fullscreen 16)
413   (:above 32) (:below 64))
414 @end{pre}
415 @arg[g-name]{a string. Specifies the GEnum name}
416 @arg[name]{a symbol. Names the enumeration type.}
417 @arg[export]{a boolean. If true, @code{name} will be exported.}
418 @arg[type-initializer]{a @code{NIL} or a string or a function designator.
419
420 If non-@code{NIL}, specifies the function that initializes the type: string specifies a C function that returns the GType value and function designator specifies the Lisp function.}
421 @arg[values]{values for flags. Each value is a keyword or a list @code{(keyword integer-value)}. @code{keyword} corresponds to Lisp value of a flag, and @code{integer-value} is an C integer for flag. If @code{integer-value} is not specified, it is generated automatically (see CFFI manual)}"
422   `(progn
423      (defbitfield ,name ,@values)
424      (register-flags-type ,g-name ',name)
425      ,@(when export
426              (list `(export ',name (find-package ,(package-name (symbol-package name))))))
427      ,@(when type-initializer
428              (list `(at-init () ,(type-initializer-call type-initializer))))))
429
430 (defun flags-value->definition (flags-value)
431   (let ((value-name (intern (lispify-name (flags-item-nick flags-value))
432                             (find-package :keyword)))
433         (numeric-value (flags-item-value flags-value)))
434     `(,value-name ,numeric-value)))
435
436 (defun get-g-flags-definition (type &optional lisp-name-package)
437   (when (and (stringp type) (null (gtype type)))
438     (let ((type-init-name (probable-type-init-name type)))
439       (when (foreign-symbol-pointer type-init-name)
440         (foreign-funcall-pointer (foreign-symbol-pointer type-init-name) () :int))))
441   (when *generated-types*
442     (setf (gethash (gtype-name (gtype type)) *generated-types*) t))
443   (let* ((*lisp-name-package* (or lisp-name-package *lisp-name-package* *package*))
444          (g-type (gtype type))
445          (g-name (gtype-name g-type))
446          (name (g-name->name g-name))
447          (items (get-flags-items g-type))
448          (probable-type-initializer (probable-type-init-name g-name)))
449     `(define-g-flags ,g-name ,name
450          (:export t
451                   ,@(when (foreign-symbol-pointer probable-type-initializer)
452                           (list :type-initializer
453                                 probable-type-initializer)))
454        ,@(mapcar #'flags-value->definition items))))
455
456 (defun maybe-call-type-init (type)
457   (when (and (stringp type) (null (gtype type)))
458     (let ((type-init-name (probable-type-init-name type)))
459       (when (foreign-symbol-pointer type-init-name)
460         (foreign-funcall-pointer (foreign-symbol-pointer type-init-name) () :int)))))
461
462 (defun get-g-type-definition (type &optional lisp-name-package)
463   (maybe-call-type-init type)
464   (cond
465     ((g-type-is-a type (gtype +g-type-enum+)) (get-g-enum-definition type lisp-name-package))
466     ((g-type-is-a type (gtype +g-type-flags+)) (get-g-flags-definition type lisp-name-package))
467     ((g-type-is-a type (gtype +g-type-interface+)) (get-g-interface-definition type lisp-name-package))
468     ((g-type-is-a type (gtype +g-type-object+)) (get-g-class-definition type lisp-name-package))
469     (t (error "Do not know how to automatically generate type definition for ~A type ~A"
470               (gtype-name (g-type-fundamental type))
471               (or (ignore-errors (gtype-name (gtype type))) type)))))
472
473 (defun generate-types-hierarchy-to-file (file root-type &key include-referenced prefix package exceptions prologue interfaces enums flags objects exclusions additional-properties)
474   (if (not (streamp file))
475       (with-open-file (stream file :direction :output :if-exists :supersede)
476         (generate-types-hierarchy-to-file stream root-type
477                                           :prefix prefix
478                                           :package package
479                                           :exceptions exceptions
480                                           :prologue prologue
481                                           :include-referenced include-referenced
482                                           :interfaces interfaces
483                                           :enums enums
484                                           :flags flags
485                                           :objects objects
486                                           :exclusions exclusions
487                                           :additional-properties additional-properties))
488       (let* ((*generation-exclusions* (mapcar #'gtype exclusions))
489              (*lisp-name-package* (or package *package*))
490              (*package* *lisp-name-package*)
491              (*strip-prefix* (or prefix ""))
492              (*lisp-name-exceptions* exceptions)
493              (*print-case* :downcase)
494              (*additional-properties* additional-properties)
495              (*generated-types* (make-hash-table :test 'equalp))
496              (referenced-types (and include-referenced
497                                     (filter-types-by-prefix
498                                      (get-referenced-types root-type)
499                                      prefix))))
500         (setf exclusions (mapcar #'gtype exclusions))
501         (when prologue
502           (write-string prologue file)
503           (terpri file))
504         (when include-referenced
505           (loop
506              for interface in interfaces
507              do (loop
508                    for referenced-type in (get-shallow-referenced-types interface)
509                    do (pushnew referenced-type referenced-types :test 'g-type=)))
510           (loop
511              for object in objects
512              do (loop
513                    for referenced-type in (get-shallow-referenced-types object)
514                    do (pushnew referenced-type referenced-types :test 'g-type=)))
515           (loop
516              for enum-type in (filter-types-by-fund-type
517                                referenced-types "GEnum")
518              for def = (get-g-enum-definition enum-type)
519              unless (member enum-type exclusions :test 'g-type=)
520              do (format file "~S~%~%" def))
521             
522           (loop
523              for flags-type in (filter-types-by-fund-type
524                                 referenced-types "GFlags")
525              for def = (get-g-flags-definition flags-type)
526              unless (member flags-type exclusions :test 'g-type=)
527              do (format file "~S~%~%" def)))
528         (loop
529            with auto-enums = (and include-referenced
530                                   (filter-types-by-fund-type
531                                    referenced-types "GEnum"))
532            for enum in enums
533            for def = (get-g-enum-definition enum)
534            unless (find enum auto-enums :test 'g-type=)
535            do (format file "~S~%~%" def))
536         (loop
537            with auto-flags = (and include-referenced
538                                   (filter-types-by-fund-type
539                                    referenced-types "GFlags"))
540            for flags-type in flags
541            for def = (get-g-flags-definition flags-type)
542            unless (find flags-type auto-flags :test 'g-type=)
543            do (format file "~S~%~%" def))
544         (loop
545            for interface in interfaces
546            for def = (get-g-interface-definition interface)
547            do (format file "~S~%~%" def))
548         (loop
549            for def in (get-g-class-definitions-for-root root-type)
550            do (format file "~S~%~%" def))
551         (iter (for object in objects)
552               (unless (gethash (gtype-name (gtype object)) *generated-types*)
553                 (for def = (get-g-class-definition object))
554                 (format file "~S~%~%" def))))))