3 (defun named-xml-element-child (element name
)
5 (and (s-xml::xml-element-p x
)
6 (equal (s-xml::xml-element-name x
) name
)))
7 (s-xml::xml-element-children element
)))
9 (defun is-field-element-p (element)
10 (equal (s-xml:xml-element-name element
) 'GIR-CORE
::|field|
))
12 (defun is-callback-element-p (element)
13 (equal (s-xml:xml-element-name element
) 'GIR-CORE
::|callback|
))
15 (defun is-object-record (record)
16 (let* ((record-string (string record
))
17 (record-string-len (length record-string
)))
19 (and (> record-string-len
6)
20 (string= "OBJECT" (string-upcase (subseq record-string
(- record-string-len
6))))))))
22 (defun parse-function-types (outs method
)
24 (named-xml-element-child method
'GIR-CORE
:|return-value|
))
26 (named-xml-element-child method
'GIR-CORE
:|parameters|
)))
27 (let ((return-type (first (xml-element-children return-value
))))
28 (format outs
" ~A~%" (resolve-type (s-xml:xml-element-attribute return-type
'GIR-C
::|type|
))))
29 (when (s-xml::xml-element-p parameters
)
31 (for parameter in
(s-xml:xml-element-children parameters
))
32 (format outs
"~&~T( ~A " (s-xml:xml-element-attribute parameter
:|name|
))
34 (resolve-type (xml-element-attribute (car (s-xml:xml-element-children parameter
)) 'GIR-C
::|type|
)))))))
36 (defun parse-signal-types (outs gsignal
)
37 (let ((name (s-xml:xml-element-attribute gsignal
:|name|
)))
38 (format outs
"~%; ----------------- ~A ----------------~%" name
)
39 (format outs
"(defmacro make-~A (name &rest body) ~%" (lispize name
))
40 (format outs
"~T(defcallback ,name ")
41 (let ((return-value (named-xml-element-child gsignal
'GIR-CORE
::|return-value|
)))
42 (let ((return-type (first (xml-element-children return-value
))))
43 (format outs
"~&~T~A" (resolve-type (s-xml:xml-element-attribute return-type
'GIR-C
::|type|
))))
46 (for item in
(s-xml:xml-element-children gsignal
))
47 (when (s-xml::xml-element-p item
)
48 (case (s-xml:xml-element-name item
)
49 (GIR-CORE::|parameters|
51 (for parameter in
(s-xml:xml-element-children item
))
52 (format outs
"( ~A " (s-xml:xml-element-attribute parameter
:|name|
))
54 (resolve-type (xml-element-attribute (car (s-xml:xml-element-children parameter
)) 'GIR-C
::|type|
))))))))
56 (format outs
"~%~T,@body))~%")))
60 (defun parse-record (outs record
)
61 (let ((c-type (s-xml:xml-element-attribute record
'GIR-C
::|type|
))
62 (name (s-xml:xml-element-attribute record
:|name|
)))
63 ;; we punt on object records (I think they are meant to be opaque)
64 (add-type name
:struct
)
65 ;; if the struct is actually an object type, we aren't interested (they are supposed to be opaque!?)
66 (unless (is-object-record name
)
68 ((fields (remove-if-not #'is-field-element-p
(s-xml::xml-element-children record
)))
69 (callbacks (remove-if-not #'is-callback-element-p
(s-xml::xml-element-children record
))))
70 (format outs
"~%; ----------------- ~A ----------------~%" name
)
71 (when (or (not (zerop (length fields
))) (not (zerop (length callbacks
))))
72 (format outs
"~%; ----------------- ~A : fields ----------------~%" name
)
73 (when (not (zerop (length fields
)))
74 (format outs
"~%(defcstruct ~A ~%" name
)
77 (format outs
"~&~T(~A ~A)"
78 (lispize (s-xml:xml-element-attribute field
:|name|
))
79 (resolve-type (s-xml:xml-element-attribute
80 (named-xml-element-child field
'GIR-CORE
:|type|
)
83 (when (not (zerop (length callbacks
)))
84 (format outs
"~%; ----------------- ~A : methods ----------------~%" name
)
86 (for method in callbacks
)
87 (let ((name (s-xml:xml-element-attribute method
:|name|
)))
88 (format outs
"(defcfun (~S ~A) " name
(lispize name
))
89 (parse-function-types outs method
)
90 (format outs
")~%~%")))))))))
94 (defun parse-function (outs function
)
95 (let ((c-identifier (s-xml:xml-element-attribute function
'GIR-C
::|identifier|
))
96 (name (s-xml:xml-element-attribute function
:|name|
)))
97 (format outs
"~%; ----------------- Function: ~A ---------------- " name
)
98 (format outs
"~%(defcfun (~S ~A)" c-identifier
(lispize name
))
99 (parse-function-types outs function
)
100 (format outs
")~%")))
102 (defun parse-constructor (outs constructor
)
103 (let ((c-identifier (s-xml:xml-element-attribute constructor
'GIR-C
::|identifier|
))
104 (name (s-xml:xml-element-attribute constructor
:|name|
)))
105 (format outs
"~%; ----------------- Constructor: ~A ---------------- " (lispize c-identifier
))
106 (format outs
"~%(defcfun (~S ~A) " c-identifier
(lispize c-identifier
))
107 (parse-function-types outs constructor
)
108 (format outs
")~%")))
110 ;; callbacks associated with the records are actually methods
113 (defun parse-enum-members (outs enum
)
115 (for member in
(s-xml:xml-element-children enum
))
116 (when (eql (s-xml:xml-element-name member
) 'GIR-CORE
::|member|
)
117 (format outs
"~&~T(:~A ~S)"
118 (string-upcase (s-xml:xml-element-attribute member
:|name|
))
119 (parse-integer (s-xml:xml-element-attribute member
:|value|
))))))
121 (defun parse-enumeration (outs enum
)
122 (let ((c-type (s-xml:xml-element-attribute enum
'GIR-C
::|type|
))
123 (name (s-xml:xml-element-attribute enum
:|name|
)))
124 (format outs
"~%; ----------------- Enumeration: ~A ----------------~%" (lispize c-type
))
125 (add-type (string c-type
) :unsigned-int
)
126 (format outs
"(defcenum ~A " name
)
127 (parse-enum-members outs enum
)
128 (format outs
")~%")))
130 (defun parse-bitfield (outs bitfield
)
131 (let ((c-type (s-xml:xml-element-attribute bitfield
'GIR-C
::|type|
))
132 (name (s-xml:xml-element-attribute bitfield
:|name|
)))
133 (format outs
"~%; ----------------- ~A ----------------~%" (lispize c-type
))
134 (format outs
"(defcenum ~A " name
)
135 (add-type (string c-type
) :unsigned-int
)
136 (parse-enum-members outs bitfield
)
137 (format outs
")~%")))
139 (defun parse-class (outs gclass
)
141 (for method in
(s-xml:xml-element-children gclass
))
142 (when (s-xml::xml-element-p method
)
143 (case (s-xml:xml-element-name method
)
144 (GIR-CORE::|constructor|
(parse-constructor outs method
))
145 (GIR-CORE::|method|
(parse-function outs method
))
146 (GIR-CORE::|callback|
(parse-signal-types outs method
))))))
148 (defun parse-boxed (outs boxed
)
150 (for method in
(s-xml:xml-element-children boxed
))
151 (when (s-xml::xml-element-p method
)
152 (case (s-xml:xml-element-name method
)
153 (GIR-CORE::|constructor|
(parse-constructor outs method
))
154 (GIR-CORE::|method|
(parse-function outs method
))
155 (GIR-CORE::|callback|
(parse-signal-types outs method
))))))
157 (defun parse-callback (outs callback
)
158 (let ((name (s-xml:xml-element-attribute callback
:|name|
)))
159 (add-type name
:pointer
)
160 (parse-signal-types outs callback
)))
162 (defparameter *gir-top-level-type-elements
*
164 '((GIR-CORE::|bitfield| . parse-bitfield
)
165 (GIR-CORE::|enumeration| . parse-enumeration
)
166 (GIR-CORE::|record| . parse-record
)))
168 (defparameter *gir-top-level-function-elements
*
170 '((GIR-CORE::|callback| . parse-callback
)
171 (GIR-CORE::|function| . parse-function
)
172 (GIR-CORE::|class| . parse-class
)
173 (GIR-GLIB::|boxed| . parse-boxed
)))
176 (defun parse-element (outs elements entry
)
177 (let ((name (s-xml:xml-element-name entry
)))
178 (let ((fun (cdr (assoc name elements
))))
180 (funcall fun outs entry
)))))
183 (defun parse-namespace (outs namespace elements
)
184 (let ((namespace-name
185 (alexandria::make-keyword
186 (string-upcase (s-xml:xml-element-attribute namespace
:|name|
)))))
187 ;; (format outs "(defpackage ~S (:use :common-lisp :cffi :iterate))~%~%" namespace-name)
188 (format outs
"(in-package ~S)~%" namespace-name
)
190 (for entry in
(xml-element-children namespace
))
191 (parse-element outs elements entry
))))
193 (defun parse-repository (outs repository elements
)
195 (for namespace in
(s-xml:xml-element-children repository
))
196 (parse-namespace outs namespace elements
)))