1 | ;;;; build-gtk.jl -- translate guile-gtk .defs file to rep C code |
---|
2 | ;;; Copyright (C) 1999 John Harper <john@dcs.warwick.ac.uk> |
---|
3 | ;;; $Id: build-gtk.jl,v 1.1.1.2 2003-01-05 00:30:07 ghudson Exp $ |
---|
4 | ;;; |
---|
5 | ;;; This program is free software; you can redistribute it and/or modify |
---|
6 | ;;; it under the terms of the GNU General Public License as published by |
---|
7 | ;;; the Free Software Foundation; either version 2, or (at your option) |
---|
8 | ;;; any later version. |
---|
9 | ;;; |
---|
10 | ;;; This program is distributed in the hope that it will be useful, |
---|
11 | ;;; but WITHOUT ANY WARRANTY; without even the implied warranty of |
---|
12 | ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
---|
13 | ;;; GNU General Public License for more details. |
---|
14 | ;;; |
---|
15 | ;;; You should have received a copy of the GNU General Public License |
---|
16 | ;;; along with this software; see the file COPYING. If not, write to |
---|
17 | ;;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. |
---|
18 | |
---|
19 | (provide 'build-gtk) |
---|
20 | |
---|
21 | (setq debug-on-error '(bad-arg invalid-function missing-arg)) |
---|
22 | |
---|
23 | ;; Notes: |
---|
24 | |
---|
25 | ;; This assumes that the `sed-fix-defs' sed script has been run over all |
---|
26 | ;; input files (to convert schemey things to their lispy equivalents) |
---|
27 | |
---|
28 | ;; Todo: |
---|
29 | ;; * doesn't check for `listable' type-property |
---|
30 | ;; * guile-gtk `struct' and `ptype' types |
---|
31 | ;; * not possible to wrap functions returning vector types |
---|
32 | |
---|
33 | ;; WARNING: This makes some pretty gruesome assumptions. [where?] |
---|
34 | |
---|
35 | |
---|
36 | ;; Configuration |
---|
37 | |
---|
38 | ;; Alist of (TYPE ["C-TYPE" | DECL-FUNC] ["REP2GTK" | FROM-REP-FUNC] |
---|
39 | ;; ["GTK2REP" | TO-REP-FUNC] ["PRED-NAME" | PRED-FUNC] |
---|
40 | ;; . OPTION-ALIST) |
---|
41 | |
---|
42 | ;; The required functions are called as: |
---|
43 | |
---|
44 | ;; (DECL-FUNC TYPE TYPE-INFO) |
---|
45 | ;; (FROM-REP-FUNC OUTPUT-STREAM TYPE "REP-VAR" TYPE-INFO OPTIONS) |
---|
46 | ;; (TO-REP-FUNC OUTPUT-STREAM TYPE "GTK-VAR" TYPE-INFO OPTIONS) |
---|
47 | ;; (PRED-FUNC OUTPUT-STREAM TYPE "REP-VAR" TYPE-INFO OPTIONS) |
---|
48 | |
---|
49 | ;; The options in the OPTION-ALIST may be: |
---|
50 | |
---|
51 | ;; (c2args . EMIT-ARG-FUNC) |
---|
52 | ;; (finish . FINISH-ARG-FUNC) |
---|
53 | ;; (listable . BOOLEAN) |
---|
54 | |
---|
55 | ;; with: |
---|
56 | |
---|
57 | ;; (EMIT-ARG-FUNC OUTPUT TYPE "GTK-VAR" OPTIONS) |
---|
58 | ;; (FINISH-ARG-FUNC OUTPUT TYPE "GTK-VAR" "REP-VAR" OPTIONS) |
---|
59 | |
---|
60 | (defvar gtk-type-alist nil) |
---|
61 | |
---|
62 | (defun define-type (type c-type rep-to-gtk gtk-to-rep type-pred . options) |
---|
63 | (setq gtk-type-alist (cons (list* type c-type rep-to-gtk |
---|
64 | gtk-to-rep type-pred options) |
---|
65 | gtk-type-alist))) |
---|
66 | |
---|
67 | |
---|
68 | ;; Work variables |
---|
69 | |
---|
70 | (defvar gtk-enums nil |
---|
71 | "List of (ENUM-NAME . ENUM-DEF) for all parsed enums defs") |
---|
72 | |
---|
73 | (defvar gtk-string-enums nil |
---|
74 | "List of (ENUM-NAME . ENUM-DEF) for all parsed enums defs") |
---|
75 | |
---|
76 | (defvar gtk-flags nil |
---|
77 | "List of (ENUM-NAME . ENUM-DEF) for all parsed flags defs") |
---|
78 | |
---|
79 | (defvar gtk-boxed nil |
---|
80 | "List of (BOXED-NAME . BOXED-DEF)") |
---|
81 | |
---|
82 | (defvar gtk-objects nil |
---|
83 | "List of (OBJECT-NAME . OBJECT-DEF)") |
---|
84 | |
---|
85 | (defvar gtk-functions nil |
---|
86 | "List of (FUNCTION-NAME . FUNCTION-DEF)") |
---|
87 | |
---|
88 | (defvar gtk-options nil |
---|
89 | "List of (OPTION VALUE)") |
---|
90 | |
---|
91 | (defvar gtk-subrs nil |
---|
92 | "List of C-NAME.") |
---|
93 | |
---|
94 | ;; similar for imported files |
---|
95 | (defvar gtk-imported-enums nil) |
---|
96 | (defvar gtk-imported-string-enums nil) |
---|
97 | (defvar gtk-imported-flags nil) |
---|
98 | (defvar gtk-imported-boxed nil) |
---|
99 | (defvar gtk-imported-objects nil) |
---|
100 | |
---|
101 | ;; t when importing secondary definitions |
---|
102 | (defvar gtk-importing nil) |
---|
103 | |
---|
104 | (defmacro gtk-get-options (name options) |
---|
105 | `(cdr (assq ,name ,options))) |
---|
106 | |
---|
107 | (defmacro gtk-get-option (name options) |
---|
108 | `(car (gtk-get-options ,name ,options))) |
---|
109 | |
---|
110 | (defvar gtk-hyphen-map |
---|
111 | (let |
---|
112 | ((map (make-string (1+ ?_))) |
---|
113 | (i 0)) |
---|
114 | (while (< i ?_) |
---|
115 | (aset map i i) |
---|
116 | (setq i (1+ i))) |
---|
117 | (aset map i ?-) |
---|
118 | map)) |
---|
119 | |
---|
120 | (defvar gtk-unhyphen-map |
---|
121 | (let |
---|
122 | ((map (make-string (1+ ?-))) |
---|
123 | (i 0)) |
---|
124 | (while (< i ?-) |
---|
125 | (aset map i i) |
---|
126 | (setq i (1+ i))) |
---|
127 | (aset map i ?_) |
---|
128 | map)) |
---|
129 | |
---|
130 | (defvar gtk-emitted-composite-helpers nil) |
---|
131 | |
---|
132 | |
---|
133 | ;; Entry point |
---|
134 | |
---|
135 | (defun build-gtk (defs-file-name output-file-name) |
---|
136 | (let |
---|
137 | ((gtk-enums nil) |
---|
138 | (gtk-string-enums nil) |
---|
139 | (gtk-flags nil) |
---|
140 | (gtk-boxed nil) |
---|
141 | (gtk-objects nil) |
---|
142 | (gtk-functions nil) |
---|
143 | (gtk-options nil) |
---|
144 | (gtk-subrs nil) |
---|
145 | (gtk-imported-enums nil) |
---|
146 | (gtk-imported-string-enums nil) |
---|
147 | (gtk-imported-flags nil) |
---|
148 | (gtk-imported-boxed nil) |
---|
149 | (gtk-imported-objects nil) |
---|
150 | (gtk-importing nil) |
---|
151 | (gtk-emitted-composite-helpers nil)) |
---|
152 | (let |
---|
153 | ((defs-file (open-file defs-file-name 'read))) |
---|
154 | (or defs-file (error "Can't open input file: %s" defs-file-name)) |
---|
155 | (unwind-protect |
---|
156 | (parse-gtk defs-file) |
---|
157 | (close-file defs-file))) |
---|
158 | (setq gtk-enums (nreverse gtk-enums)) |
---|
159 | (setq gtk-string-enums (nreverse gtk-string-enums)) |
---|
160 | (setq gtk-flags (nreverse gtk-flags)) |
---|
161 | (setq gtk-boxed (nreverse gtk-boxed)) |
---|
162 | (setq gtk-objects (nreverse gtk-objects)) |
---|
163 | (setq gtk-functions (nreverse gtk-functions)) |
---|
164 | (let |
---|
165 | ((output-file (open-file output-file-name 'write))) |
---|
166 | (or output-file (error "Can't open output file: %s" output-file-name)) |
---|
167 | (unwind-protect |
---|
168 | (let |
---|
169 | ((standard-output output-file)) |
---|
170 | (output-gtk output-file)) |
---|
171 | (close-file output-file))))) |
---|
172 | |
---|
173 | (defun build-gtk-batch () |
---|
174 | (or (= (length command-line-args) 2) (error "usage: INPUT OUTPUT")) |
---|
175 | (let |
---|
176 | ((in (car command-line-args)) |
---|
177 | (out (nth 1 command-line-args))) |
---|
178 | (setq command-line-args (nthcdr 2 command-line-args)) |
---|
179 | (build-gtk in out))) |
---|
180 | |
---|
181 | |
---|
182 | ;; Parsing |
---|
183 | |
---|
184 | (defun parse-gtk (input) |
---|
185 | (condition-case nil |
---|
186 | (while t |
---|
187 | (let |
---|
188 | ((def (read input))) |
---|
189 | ;;(format standard-error "read: %S\n" def) |
---|
190 | (when def |
---|
191 | (or (consp def) (error "Definition isn't a list")) |
---|
192 | (cond |
---|
193 | ((memq (car def) '(include import)) |
---|
194 | (let |
---|
195 | ((file (open-file (expand-file-name (nth 1 def) |
---|
196 | (file-name-directory |
---|
197 | (file-binding input))) |
---|
198 | 'read))) |
---|
199 | (or file (error "Can't open input file: %s" (nth 1 def))) |
---|
200 | (unwind-protect |
---|
201 | (let ((gtk-importing (if (eq (car def) 'import) |
---|
202 | t |
---|
203 | gtk-importing))) |
---|
204 | (parse-gtk file)) |
---|
205 | (close-file file)))) |
---|
206 | ((eq (car def) 'define-enum) |
---|
207 | (let* |
---|
208 | ((name (nth 1 def)) |
---|
209 | (body (nthcdr 2 def)) |
---|
210 | (cell (or (assq name gtk-enums) |
---|
211 | (assq name gtk-imported-enums)))) |
---|
212 | (if cell |
---|
213 | (rplacd cell body) |
---|
214 | (if (not gtk-importing) |
---|
215 | (setq gtk-enums (cons (cons name body) gtk-enums)) |
---|
216 | (setq gtk-imported-enums |
---|
217 | (cons (cons name body) gtk-imported-enums)))))) |
---|
218 | ((eq (car def) 'define-string-enum) |
---|
219 | (let* |
---|
220 | ((name (nth 1 def)) |
---|
221 | (body (nthcdr 2 def)) |
---|
222 | (cell (or (assq name gtk-string-enums) |
---|
223 | (assq name gtk-imported-string-enums)))) |
---|
224 | (if cell |
---|
225 | (rplacd cell body) |
---|
226 | (if (not gtk-importing) |
---|
227 | (setq gtk-string-enums (cons (cons name body) |
---|
228 | gtk-string-enums)) |
---|
229 | (setq gtk-imported-string-enums |
---|
230 | (cons (cons name body) |
---|
231 | gtk-imported-string-enums)))))) |
---|
232 | ((eq (car def) 'define-flags) |
---|
233 | (let* |
---|
234 | ((name (nth 1 def)) |
---|
235 | (body (nthcdr 2 def)) |
---|
236 | (cell (or (assq name gtk-flags) |
---|
237 | (assq name gtk-imported-flags)))) |
---|
238 | (if cell |
---|
239 | (rplacd cell body) |
---|
240 | (if (not gtk-importing) |
---|
241 | (setq gtk-flags (cons (cons name body) gtk-flags)) |
---|
242 | (setq gtk-imported-flags |
---|
243 | (cons (cons name body) gtk-imported-flags)))))) |
---|
244 | ((eq (car def) 'define-boxed) |
---|
245 | (let |
---|
246 | ((cell (or (assq (nth 1 def) gtk-boxed) |
---|
247 | (assq (nth 1 def) gtk-imported-boxed)))) |
---|
248 | (if cell |
---|
249 | (rplacd cell (nthcdr 2 def)) |
---|
250 | (if (not gtk-importing) |
---|
251 | (setq gtk-boxed (cons (cdr def) gtk-boxed)) |
---|
252 | (setq gtk-imported-boxed |
---|
253 | (cons (cdr def) gtk-imported-boxed)))))) |
---|
254 | ((eq (car def) 'define-object) |
---|
255 | (let* |
---|
256 | ((name (nth 1 def)) |
---|
257 | (super (nth 2 def)) |
---|
258 | (attrs (nthcdr 3 def)) |
---|
259 | (cell (or (assq name gtk-objects) |
---|
260 | (assq name gtk-imported-objects)))) |
---|
261 | (when (car super) |
---|
262 | (setq attrs (cons (cons 'super (car super)) attrs))) |
---|
263 | (if cell |
---|
264 | (rplacd cell attrs) |
---|
265 | (if (not gtk-importing) |
---|
266 | (setq gtk-objects |
---|
267 | (cons (cons name attrs) gtk-objects)) |
---|
268 | (setq gtk-imported-objects |
---|
269 | (cons (cons name attrs) gtk-imported-objects)))))) |
---|
270 | ((eq (car def) 'define-func) |
---|
271 | (unless gtk-importing |
---|
272 | (let |
---|
273 | ((cell (assq (nth 1 def) gtk-functions))) |
---|
274 | (if cell |
---|
275 | (rplacd cell (nthcdr 2 def)) |
---|
276 | (setq gtk-functions (cons (cdr def) gtk-functions)))))) |
---|
277 | ((eq (car def) 'define-type) |
---|
278 | (eval def)) |
---|
279 | ((eq (car def) 'options) |
---|
280 | (unless gtk-importing |
---|
281 | (mapc (lambda (cell) |
---|
282 | (let |
---|
283 | ((value (assq (car cell) gtk-options))) |
---|
284 | (if value |
---|
285 | (rplacd value (nconc (cdr value) |
---|
286 | (list (nth 1 cell)))) |
---|
287 | (setq gtk-options (cons cell gtk-options))))) |
---|
288 | (cdr def)))) |
---|
289 | ((eq (car def) 'add-options) |
---|
290 | (unless gtk-importing |
---|
291 | (let |
---|
292 | ((value (assq (nth 1 def) gtk-options))) |
---|
293 | (if value |
---|
294 | (rplacd value (nconc (cdr value) (nthcdr 2 def))) |
---|
295 | (setq gtk-options (cons (cdr def) gtk-options)))))) |
---|
296 | (t |
---|
297 | (gtk-warning "Ignoring `%S'" def)))))) |
---|
298 | (end-of-stream))) |
---|
299 | |
---|
300 | |
---|
301 | ;; Code generation |
---|
302 | |
---|
303 | (defmacro @ args |
---|
304 | (list* 'format 'output args)) |
---|
305 | |
---|
306 | (defun output-header (output) |
---|
307 | (@ "/* Automatically generated by build-gtk, DO NOT EDIT! */\n\n") |
---|
308 | (when (gtk-get-options 'includes gtk-options) |
---|
309 | (mapc (lambda (opt) |
---|
310 | (@ "%s\n" opt)) |
---|
311 | (gtk-get-options 'includes gtk-options))) |
---|
312 | (@ "#include <rep.h>\n") |
---|
313 | (@ "#include \"rep-gtk.h\"\n\n")) |
---|
314 | |
---|
315 | (defun output-footer (output) |
---|
316 | (let* |
---|
317 | ((feature (gtk-get-option 'provide gtk-options)) |
---|
318 | (aliases (gtk-get-options 'alias gtk-options)) |
---|
319 | (init (gtk-get-option 'init-func gtk-options))) |
---|
320 | (when feature |
---|
321 | (@ "\nrepv\nrep_dl_init \(void\)\n{\n") |
---|
322 | (@ " repv s = rep_push_structure \(\"%s\"\);\n" feature) |
---|
323 | (mapc (lambda (a) |
---|
324 | (@ " /* ::alias:%s %s:: */\n" a feature) |
---|
325 | (@ " rep_alias_structure \(\"%s\"\);\n" a)) aliases) |
---|
326 | (when init |
---|
327 | (@ "\n %s \(\);\n\n" init)) |
---|
328 | (@ " return rep_pop_structure \(s\);\n") |
---|
329 | (@ "}\n")))) |
---|
330 | |
---|
331 | (defun output-imported-enums (output) |
---|
332 | (when gtk-imported-enums |
---|
333 | (@ "\f\n/* Imported enums */\n\n") |
---|
334 | (mapc (lambda (enum) |
---|
335 | (let* |
---|
336 | ((cname (gtk-canonical-name (symbol-name (car enum))))) |
---|
337 | (@ "extern sgtk_enum_info sgtk_%s_info;\n" cname))) |
---|
338 | gtk-imported-enums) |
---|
339 | (@ "\n"))) |
---|
340 | |
---|
341 | (defun output-enums (output) |
---|
342 | (when gtk-enums |
---|
343 | (@ "\f\n/* Enums definitions */\n\n") |
---|
344 | (mapc (lambda (enum) |
---|
345 | (let* |
---|
346 | ((name (car enum)) |
---|
347 | (cname (gtk-canonical-name (symbol-name name))) |
---|
348 | (values (cdr enum))) |
---|
349 | ;; write literal names |
---|
350 | (@ "static sgtk_enum_literal _%s_literals[%d] = {\n" |
---|
351 | cname (length values)) |
---|
352 | (mapc (lambda (cell) |
---|
353 | (@ " { \"%s\", %s },\n" (car cell) (nth 1 cell))) |
---|
354 | values) |
---|
355 | (@ "};\n") |
---|
356 | ;; write type info struct |
---|
357 | (@ "sgtk_enum_info sgtk_%s_info = {\n" cname) |
---|
358 | (@ " { \"%s\", G_TYPE_ENUM }, %d, _%s_literals,\n" |
---|
359 | name (length values) cname) |
---|
360 | (@ "};\n\n"))) |
---|
361 | gtk-enums))) |
---|
362 | |
---|
363 | (defun output-imported-string-enums (output) |
---|
364 | (when gtk-imported-string-enums |
---|
365 | (@ "\f\n/* Imported string enums */\n\n") |
---|
366 | (mapc (lambda (enum) |
---|
367 | (let* |
---|
368 | ((cname (gtk-canonical-name (symbol-name (car enum))))) |
---|
369 | (@ "extern sgtk_string_enum_info sgtk_%s_info;\n" cname))) |
---|
370 | gtk-imported-string-enums) |
---|
371 | (@ "\n"))) |
---|
372 | |
---|
373 | (defun output-string-enums (output) |
---|
374 | (when gtk-string-enums |
---|
375 | (@ "\f\n/* String enums definitions */\n\n") |
---|
376 | (mapc (lambda (enum) |
---|
377 | (let* |
---|
378 | ((name (car enum)) |
---|
379 | (cname (gtk-canonical-name (symbol-name name))) |
---|
380 | (values (cdr enum))) |
---|
381 | ;; write literal names |
---|
382 | (@ "static sgtk_senum_literal _%s_literals[%d] = {\n" |
---|
383 | cname (length values)) |
---|
384 | (mapc (lambda (cell) |
---|
385 | (@ " { \"%s\", %s },\n" (car cell) (nth 1 cell))) |
---|
386 | values) |
---|
387 | (@ "};\n") |
---|
388 | ;; write type info struct |
---|
389 | (@ "sgtk_senum_info sgtk_%s_info = {\n" cname) |
---|
390 | (@ " { \"%s\", G_TYPE_INVALID }, %d, _%s_literals,\n" |
---|
391 | name (length values) cname) |
---|
392 | (@ "};\n\n"))) |
---|
393 | gtk-string-enums))) |
---|
394 | |
---|
395 | (defun output-imported-flags (output) |
---|
396 | (when gtk-imported-flags |
---|
397 | (@ "\f\n/* Imported flags */\n\n") |
---|
398 | (mapc (lambda (flag) |
---|
399 | (let* |
---|
400 | ((cname (gtk-canonical-name (symbol-name (car flag))))) |
---|
401 | (@ "extern sgtk_enum_info sgtk_%s_info;\n" cname))) |
---|
402 | gtk-imported-flags) |
---|
403 | (@ "\n"))) |
---|
404 | |
---|
405 | (defun output-flags (output) |
---|
406 | (when gtk-flags |
---|
407 | (@ "\f\n/* Flags definitions */\n\n") |
---|
408 | (mapc (lambda (flag) |
---|
409 | (let* |
---|
410 | ((name (car flag)) |
---|
411 | (cname (gtk-canonical-name (symbol-name name))) |
---|
412 | (values (cdr flag))) |
---|
413 | ;; write literal names |
---|
414 | (@ "static sgtk_enum_literal _%s_literals[%d] = {\n" |
---|
415 | cname (length values)) |
---|
416 | (mapc (lambda (cell) |
---|
417 | (@ " { \"%s\", %s },\n" (car cell) (nth 1 cell))) |
---|
418 | values) |
---|
419 | (@ "};\n") |
---|
420 | ;; write type info struct |
---|
421 | (@ "sgtk_enum_info sgtk_%s_info = {\n" cname) |
---|
422 | (@ " { \"%s\", G_TYPE_FLAGS }, %d, _%s_literals,\n" |
---|
423 | name (length values) cname) |
---|
424 | (@ "};\n\n"))) |
---|
425 | gtk-flags))) |
---|
426 | |
---|
427 | (defun output-imported-boxed (output) |
---|
428 | (when gtk-imported-boxed |
---|
429 | (@ "\f\n/* Imported boxed structures */\n\n") |
---|
430 | (mapc (lambda (boxed) |
---|
431 | (let* |
---|
432 | ((cname (gtk-canonical-name (symbol-name (car boxed))))) |
---|
433 | (@ "extern sgtk_boxed_info sgtk_%s_info;\n" cname))) |
---|
434 | gtk-imported-boxed) |
---|
435 | (@ "\n"))) |
---|
436 | |
---|
437 | (defun output-boxed (output) |
---|
438 | (when gtk-boxed |
---|
439 | (@ "\f\n/* Boxed structure definitions */\n\n") |
---|
440 | (mapc (lambda (boxed) |
---|
441 | (let* |
---|
442 | ((name (car boxed)) |
---|
443 | (cname (gtk-canonical-name (symbol-name name))) |
---|
444 | (attrs (cdr boxed)) |
---|
445 | (conv (car (cdr (assq 'conversion attrs))))) |
---|
446 | (when conv |
---|
447 | (@ "repv %s (repv);\n" conv)) |
---|
448 | (@ "sgtk_boxed_info sgtk_%s_info = {\n" cname) |
---|
449 | (@ " { \"%s\", G_TYPE_BOXED, %s },\n" name (or conv "NULL")) |
---|
450 | (@ " (void *(*)(void*))%s,\n" |
---|
451 | (or (car (cdr (assq 'copy attrs))) "NULL")) |
---|
452 | (@ " (void (*)(void*))%s,\n" |
---|
453 | (or (car (cdr (assq 'free attrs))) "NULL")) |
---|
454 | (@ " %s\n" |
---|
455 | (or (car (cdr (assq 'size attrs))) 0)) |
---|
456 | (@ "};\n\n"))) |
---|
457 | gtk-boxed))) |
---|
458 | |
---|
459 | (defun output-imported-objects (output) |
---|
460 | (when gtk-imported-objects |
---|
461 | (@ "\f\n/* Imported GTK objects */\n\n") |
---|
462 | (mapc (lambda (obj) |
---|
463 | (let* |
---|
464 | ((cname (gtk-canonical-name (symbol-name (car obj))))) |
---|
465 | (@ "extern sgtk_object_info sgtk_%s_info;\n" cname))) |
---|
466 | gtk-imported-objects) |
---|
467 | (@ "\n"))) |
---|
468 | |
---|
469 | (defun output-objects (output) |
---|
470 | (when gtk-objects |
---|
471 | (@ "\f\n/* GTK object definitions */\n\n") |
---|
472 | (mapc (lambda (obj) |
---|
473 | (let* |
---|
474 | ((name (car obj)) |
---|
475 | (cname (gtk-canonical-name (symbol-name name)))) |
---|
476 | (@ "sgtk_object_info sgtk_%s_info = {\n" cname) |
---|
477 | (@ " { \"%s\", G_TYPE_OBJECT }, %s_get_type\n" name cname) |
---|
478 | (@ "};\n\n"))) gtk-objects))) |
---|
479 | |
---|
480 | (defun output-type-info (output) |
---|
481 | (when (or gtk-enums gtk-flags gtk-boxed gtk-objects) |
---|
482 | (@ "\f\n/* Vector of all type information */\n\n") |
---|
483 | (@ "static sgtk_type_info *_type_infos[] = {\n") |
---|
484 | (mapc (lambda (lst) |
---|
485 | (mapc (lambda (type) |
---|
486 | (@ " (sgtk_type_info*)&sgtk_%s_info,\n" |
---|
487 | (gtk-canonical-name (symbol-name (car type))))) |
---|
488 | lst)) |
---|
489 | (list gtk-enums gtk-string-enums gtk-flags gtk-boxed gtk-objects)) |
---|
490 | (@ " NULL\n};\n\n"))) |
---|
491 | |
---|
492 | (defun output-functions (output) |
---|
493 | (@ "\f\n/* Defuns */\n\n") |
---|
494 | (mapc (lambda (fun) |
---|
495 | (let |
---|
496 | ;; send output to a temporary buffer to allow helper |
---|
497 | ;; functions to be emitted asynchronously |
---|
498 | ((temporary-stream (make-string-output-stream))) |
---|
499 | (output-function fun temporary-stream) |
---|
500 | (write output (get-output-stream-string temporary-stream)))) |
---|
501 | gtk-functions) |
---|
502 | (@ "\n\n")) |
---|
503 | |
---|
504 | (defun output-subrs (output) |
---|
505 | (@ "\f\n/* Initialisation */\n\n") |
---|
506 | (let |
---|
507 | ((init-func (gtk-get-option 'init-func gtk-options)) |
---|
508 | (other-inits (gtk-get-options 'other-inits gtk-options)) |
---|
509 | (extra-init (gtk-get-options 'extra-init-code gtk-options)) |
---|
510 | (system-init (gtk-get-options 'system-init-code gtk-options))) |
---|
511 | (when init-func |
---|
512 | (@ "void\n%s (void)\n{\n" init-func) |
---|
513 | (@ " static int done;\n if (!done)\n {\n") |
---|
514 | (@ " done = 1;\n") |
---|
515 | (mapc (lambda (func) |
---|
516 | (@ " %s ();\n" func)) other-inits) |
---|
517 | (when (or gtk-enums gtk-string-enums gtk-flags gtk-boxed gtk-objects) |
---|
518 | (@ " sgtk_register_type_infos (_type_infos);\n")) |
---|
519 | (mapc (lambda (cname) |
---|
520 | (@ " rep_ADD_SUBR(S%s);\n" cname)) (nreverse gtk-subrs)) |
---|
521 | (mapc (lambda (code) |
---|
522 | (declare (unused code)) |
---|
523 | (@ " %s\n")) extra-init) |
---|
524 | (when system-init |
---|
525 | (@ " {\n") |
---|
526 | (@ " char *tem = getenv (\"REP_GTK_DONT_INITIALIZE\");\n") |
---|
527 | (@ " if (tem == 0 || atoi (tem) == 0) {\n") |
---|
528 | (mapc (lambda (code) |
---|
529 | (@ " %s\n" code)) system-init) |
---|
530 | (@ " }\n") |
---|
531 | (@ " }\n")) |
---|
532 | (@ " \}\n\}\n")))) |
---|
533 | |
---|
534 | (defun output-gtk (output) |
---|
535 | (output-header output) |
---|
536 | (output-imported-enums output) |
---|
537 | (output-imported-string-enums output) |
---|
538 | (output-imported-flags output) |
---|
539 | (output-imported-boxed output) |
---|
540 | (output-imported-objects output) |
---|
541 | (output-enums output) |
---|
542 | (output-string-enums output) |
---|
543 | (output-flags output) |
---|
544 | (output-boxed output) |
---|
545 | (output-objects output) |
---|
546 | (output-functions output) |
---|
547 | (output-field-functions gtk-boxed output) |
---|
548 | (output-field-functions gtk-objects output) |
---|
549 | (output-type-info output) |
---|
550 | (output-subrs output) |
---|
551 | (output-footer output)) |
---|
552 | |
---|
553 | |
---|
554 | ;; Type management |
---|
555 | |
---|
556 | (defun gtk-outer-type (type) |
---|
557 | (while (consp type) |
---|
558 | (setq type (car type))) |
---|
559 | type) |
---|
560 | |
---|
561 | (defun gtk-inner-type (type) |
---|
562 | (while (consp (car type)) |
---|
563 | (setq type (car type))) |
---|
564 | (nth 1 type)) |
---|
565 | |
---|
566 | (defun gtk-composite-type-mode (type) |
---|
567 | (while (consp (car type)) |
---|
568 | (setq type (car type))) |
---|
569 | (case (car type) |
---|
570 | ((ret) 'out) |
---|
571 | ((fvec) (or (nth 3 type) 'in)) |
---|
572 | (t (or (nth 2 type) 'in)))) |
---|
573 | |
---|
574 | (defun gtk-composite-type-len (type) |
---|
575 | (while (consp (car type)) |
---|
576 | (setq type (car type))) |
---|
577 | (case (car type) |
---|
578 | ((ret) 1) |
---|
579 | ((fvec) (nth 2 type)) |
---|
580 | (t nil))) |
---|
581 | |
---|
582 | (defun gtk-type-info (type) |
---|
583 | (let* |
---|
584 | ((actual-type (gtk-outer-type type)) |
---|
585 | (typage (cond ((or (assq actual-type gtk-enums) |
---|
586 | (assq actual-type gtk-imported-enums)) |
---|
587 | (assq 'enum gtk-type-alist)) |
---|
588 | ((or (assq actual-type gtk-string-enums) |
---|
589 | (assq actual-type gtk-imported-string-enums)) |
---|
590 | (assq 'senum gtk-type-alist)) |
---|
591 | ((or (assq actual-type gtk-flags) |
---|
592 | (assq actual-type gtk-imported-flags)) |
---|
593 | (assq 'flags gtk-type-alist)) |
---|
594 | ((or (assq actual-type gtk-boxed) |
---|
595 | (assq actual-type gtk-imported-boxed)) |
---|
596 | (assq 'boxed gtk-type-alist)) |
---|
597 | ((or (assq actual-type gtk-objects) |
---|
598 | (assq actual-type gtk-imported-objects)) |
---|
599 | (assq 'object gtk-type-alist)) |
---|
600 | (t |
---|
601 | (assq actual-type gtk-type-alist))))) |
---|
602 | (or typage (error "Unknown type: %s" type)))) |
---|
603 | |
---|
604 | (defmacro gtk-typage-prop (typage prop) |
---|
605 | `(cdr (assq ,prop (nthcdr 5 ,typage)))) |
---|
606 | |
---|
607 | (defun gtk-type-decl (type typage) |
---|
608 | (let |
---|
609 | ((decl (nth 1 typage))) |
---|
610 | (if (functionp decl) |
---|
611 | (funcall decl type typage) |
---|
612 | decl))) |
---|
613 | |
---|
614 | (defmacro gtk-type-fromrep (typage) |
---|
615 | `(nth 2 ,typage)) |
---|
616 | |
---|
617 | (defmacro gtk-type-torep (typage) |
---|
618 | `(nth 3 ,typage)) |
---|
619 | |
---|
620 | (defmacro gtk-type-pred (typage) |
---|
621 | `(nth 4 ,typage)) |
---|
622 | |
---|
623 | (defun gtk-type-prop (type prop) |
---|
624 | (gtk-typage-prop (gtk-type-info type) prop)) |
---|
625 | |
---|
626 | |
---|
627 | ;; Function arg helpers |
---|
628 | |
---|
629 | (defmacro gtk-get-arg-options (option arg) |
---|
630 | `(assq ,option (nthcdr 2 ,arg))) |
---|
631 | |
---|
632 | (defun gtk-arg-optional-p (arg) |
---|
633 | (nth 1 (gtk-get-arg-options '= arg))) |
---|
634 | |
---|
635 | (defmacro gtk-arg-type (arg) |
---|
636 | `(car ,arg)) |
---|
637 | |
---|
638 | (defmacro gtk-arg-name (arg) |
---|
639 | `(symbol-name (nth 1 ,arg))) |
---|
640 | |
---|
641 | |
---|
642 | ;; Type output functions |
---|
643 | |
---|
644 | (defun output-complex-type (type typage) |
---|
645 | (declare (unused typage)) |
---|
646 | (setq type (gtk-outer-type type)) |
---|
647 | (if (or (assq type gtk-enums) (assq type gtk-imported-enums) |
---|
648 | (assq type gtk-flags) (assq type gtk-imported-flags)) |
---|
649 | (symbol-name type) |
---|
650 | (format nil "%s*" type))) |
---|
651 | |
---|
652 | (define (output-rep-to-static x) |
---|
653 | (lambda (output type rep-var typage) |
---|
654 | (setq type (gtk-outer-type type)) |
---|
655 | (let ((name (gtk-canonical-name (symbol-name type)))) |
---|
656 | (@ "\(%s\) sgtk_rep_to_%s \(%s, &sgtk_%s_info\)" |
---|
657 | (gtk-type-decl type typage) x rep-var name)))) |
---|
658 | |
---|
659 | (define (output-static-to-rep x) |
---|
660 | (lambda (output type gtk-var typage) |
---|
661 | (declare (unused typage)) |
---|
662 | (setq type (gtk-outer-type type)) |
---|
663 | (let ((name (gtk-canonical-name (symbol-name type)))) |
---|
664 | (@ "sgtk_%s_to_rep \(%s, &sgtk_%s_info\)" x gtk-var name)))) |
---|
665 | |
---|
666 | (define (output-static-pred x) |
---|
667 | (lambda (output type rep-var typage) |
---|
668 | (declare (unused typage)) |
---|
669 | (@ "sgtk_valid_%s \(%s, &sgtk_%s_info\)" |
---|
670 | x rep-var (gtk-canonical-name (symbol-name type))))) |
---|
671 | |
---|
672 | (define output-rep-to-enum (output-rep-to-static 'enum)) |
---|
673 | (define output-enum-to-rep (output-static-to-rep 'enum)) |
---|
674 | (define output-enum-pred (output-static-pred 'enum)) |
---|
675 | |
---|
676 | (define output-rep-to-senum (output-rep-to-static 'senum)) |
---|
677 | (define output-senum-to-rep (output-static-to-rep 'senum)) |
---|
678 | (define output-senum-pred (output-static-pred 'senum)) |
---|
679 | |
---|
680 | (define output-rep-to-flags (output-rep-to-static 'flags)) |
---|
681 | (define output-flags-to-rep (output-static-to-rep 'flags)) |
---|
682 | (define output-flags-pred (output-static-pred 'flags)) |
---|
683 | |
---|
684 | (defun output-rep-to-boxed (output type rep-var typage) |
---|
685 | (declare (unused typage)) |
---|
686 | (setq type (gtk-outer-type type)) |
---|
687 | (@ "\(%s*\) sgtk_rep_to_boxed \(%s\)" type rep-var)) |
---|
688 | |
---|
689 | (defun output-boxed-to-rep (output type gtk-var typage) |
---|
690 | (declare (unused typage)) |
---|
691 | (let* |
---|
692 | ((base-type (gtk-outer-type type)) |
---|
693 | (name (gtk-canonical-name (symbol-name base-type))) |
---|
694 | (copy (if (assq 'copy (cdr type)) |
---|
695 | (gtk-get-option 'copy (cdr type)) |
---|
696 | t))) |
---|
697 | (@ "sgtk_boxed_to_rep \(%s, &sgtk_%s_info, %d\)" |
---|
698 | gtk-var name (if copy 1 0)))) |
---|
699 | |
---|
700 | (defun output-boxed-pred (output type rep-var typage) |
---|
701 | (declare (unused typage)) |
---|
702 | (@ "sgtk_valid_boxed \(%s, &sgtk_%s_info\)" |
---|
703 | rep-var (gtk-canonical-name (symbol-name type)))) |
---|
704 | |
---|
705 | (defun output-rep-to-object (output type rep-var typage) |
---|
706 | (declare (unused typage)) |
---|
707 | (setq type (gtk-outer-type type)) |
---|
708 | (@ "\(%s*\) sgtk_get_gobj \(%s\)" type rep-var)) |
---|
709 | |
---|
710 | (defun output-object-to-rep (output type gtk-var typage) |
---|
711 | (declare (unused typage)) |
---|
712 | (setq type (gtk-outer-type type)) |
---|
713 | (@ "sgtk_wrap_gobj \(\(GObject*\) %s\)" gtk-var)) |
---|
714 | |
---|
715 | (defun output-object-pred (output type rep-var typage) |
---|
716 | (declare (unused typage)) |
---|
717 | (@ "sgtk_is_a_gobj \(%s_get_type \(\), %s\)" |
---|
718 | (gtk-canonical-name (symbol-name type)) rep-var)) |
---|
719 | |
---|
720 | (defun output-rep-to-full-callback (output type rep-var typage options) |
---|
721 | (declare (unused typage type)) |
---|
722 | (let |
---|
723 | ((protect (gtk-get-option 'protection options))) |
---|
724 | (cond ((eq protect '*result*) |
---|
725 | (@ "sgtk_new_protect \(%s\)" rep-var)) |
---|
726 | ((and (not (eq protect t)) |
---|
727 | (not (eq protect nil))) |
---|
728 | (@ "sgtk_protect \(p_%s, %s\)" protect rep-var)) |
---|
729 | (t |
---|
730 | (@ "sgtk_protect \(Qt, %s\)" rep-var))))) |
---|
731 | |
---|
732 | (defun output-full-callback-args (output type var options) |
---|
733 | (declare (unused typage type options)) |
---|
734 | (@ "0, sgtk_callback_marshal, (gpointer)%s, sgtk_callback_destroy" var)) |
---|
735 | |
---|
736 | (defun output-full-callback-finish (output type g-var r-var options) |
---|
737 | (declare (unused typage type r-var)) |
---|
738 | (let |
---|
739 | ((protect (gtk-get-option 'protection options))) |
---|
740 | (when (eq protect '*result*) |
---|
741 | (@ " sgtk_set_protect \(pr_ret, %s\);\n" g-var)))) |
---|
742 | |
---|
743 | (defun output-rep-to-gclosure (output type rep-var typage options) |
---|
744 | (declare (unused typage type)) |
---|
745 | (let |
---|
746 | ((protect (gtk-get-option 'protection options))) |
---|
747 | (cond ((eq protect '*result*) |
---|
748 | (@ "sgtk_new_gclosure \(%s\)" rep-var)) |
---|
749 | ((and (not (eq protect t)) |
---|
750 | (not (eq protect nil))) |
---|
751 | (@ "sgtk_gclosure \(p_%s, %s\)" protect rep-var)) |
---|
752 | (t |
---|
753 | (@ "sgtk_gclosure \(Qt, %s\)" rep-var))))) |
---|
754 | |
---|
755 | (defun output-gclosure-finish (output type g-var r-var options) |
---|
756 | (declare (unused typage type r-var)) |
---|
757 | (let |
---|
758 | ((protect (gtk-get-option 'protection options))) |
---|
759 | (when (eq protect '*result*) |
---|
760 | (@ " sgtk_set_gclosure \(pr_ret, %s\);\n" g-var)))) |
---|
761 | |
---|
762 | (defun output-rep-to-cvec (output type rep-var typage) |
---|
763 | (declare (unused typage)) |
---|
764 | (let* |
---|
765 | ((inner-type (gtk-inner-type type)) |
---|
766 | (inner-typage (gtk-type-info inner-type)) |
---|
767 | (decl (gtk-type-decl inner-type inner-typage)) |
---|
768 | (mode (gtk-composite-type-mode type))) |
---|
769 | (output-helper inner-type standard-output) |
---|
770 | (@ "sgtk_rep_to_cvec \(%s, %s, sizeof \(%s\)\)" |
---|
771 | rep-var |
---|
772 | (if (eq mode 'out) |
---|
773 | "0" |
---|
774 | (format nil "_sgtk_helper_fromrep_%s" inner-type)) |
---|
775 | decl))) |
---|
776 | |
---|
777 | (defun output-cvec-to-rep (output type gtk-var typage) |
---|
778 | (declare (unused typage)) |
---|
779 | (let* |
---|
780 | ((inner-type (gtk-inner-type type)) |
---|
781 | (inner-typage (gtk-type-info inner-type)) |
---|
782 | (decl (gtk-type-decl inner-type inner-typage))) |
---|
783 | (output-helper inner-type standard-output) |
---|
784 | (@ "sgtk_cvec_to_rep \(&%s, _sgtk_helper_torep_copy_%s, sizeof \(%s\)\)" |
---|
785 | gtk-var inner-type decl))) |
---|
786 | |
---|
787 | (defun output-cvec-pred (output type rep-var typage) |
---|
788 | (declare (unused typage)) |
---|
789 | (let* |
---|
790 | ((inner-type (gtk-inner-type type)) |
---|
791 | (mode (gtk-composite-type-mode type)) |
---|
792 | (len (gtk-composite-type-len type))) |
---|
793 | (output-helper inner-type standard-output) |
---|
794 | (if len |
---|
795 | (@ "sgtk_valid_complen \(%s, %s, %s\)" |
---|
796 | rep-var |
---|
797 | (if (eq mode 'out) |
---|
798 | ;; `out', so don't check inner validity |
---|
799 | "NULL" |
---|
800 | (concat "_sgtk_helper_valid_" (symbol-name inner-type))) |
---|
801 | len) |
---|
802 | (@ "sgtk_valid_composite \(%s, _sgtk_helper_valid_%s\)" |
---|
803 | rep-var inner-type)))) |
---|
804 | |
---|
805 | (defun output-cvec-args (output type var options) |
---|
806 | (declare (unused typage options)) |
---|
807 | (let* |
---|
808 | ((outer-type (gtk-outer-type type)) |
---|
809 | (inner-type (gtk-inner-type type)) |
---|
810 | (inner-typage (gtk-type-info inner-type)) |
---|
811 | (decl (gtk-type-decl inner-type inner-typage))) |
---|
812 | (cond ((eq outer-type 'cvec) |
---|
813 | (@ "%s.count, \(%s*\) %s.vec" var decl var)) |
---|
814 | ((eq outer-type 'cvecr) |
---|
815 | (@ "\(%s*\) %s.vec, %s.count" decl var var)) |
---|
816 | ((memq outer-type '(fvec ret tvec)) |
---|
817 | (@ "\(%s*\) %s.vec" decl var)) |
---|
818 | (t |
---|
819 | (gtk-warning "Don't know how to pass type %s" type))))) |
---|
820 | |
---|
821 | (defun output-cvec-finish (output type gtk-var rep-var options) |
---|
822 | (declare (unused typage options)) |
---|
823 | (let* |
---|
824 | ((inner-type (gtk-inner-type type)) |
---|
825 | (inner-typage (gtk-type-info inner-type)) |
---|
826 | (decl (gtk-type-decl inner-type inner-typage)) |
---|
827 | (mode (gtk-composite-type-mode type))) |
---|
828 | (@ " sgtk_cvec_finish \(&%s, %s, %s, sizeof \(%s\)\);\n" |
---|
829 | gtk-var rep-var |
---|
830 | (if (eq mode 'in) |
---|
831 | "0" |
---|
832 | (format nil "_sgtk_helper_torep_nocopy_%s" inner-type)) |
---|
833 | decl))) |
---|
834 | |
---|
835 | (defun output-rep-to-list (output type rep-var typage) |
---|
836 | (declare (unused typage)) |
---|
837 | (let |
---|
838 | ((outer-type (gtk-outer-type type)) |
---|
839 | (inner-type (gtk-inner-type type))) |
---|
840 | (output-helper inner-type standard-output) |
---|
841 | (@ "sgtk_rep_to_%s \(%s, _sgtk_helper_fromrep_%s\)" |
---|
842 | outer-type rep-var inner-type))) |
---|
843 | |
---|
844 | (defun output-list-to-rep (output type gtk-var typage) |
---|
845 | (declare (unused typage)) |
---|
846 | (let |
---|
847 | ((outer-type (gtk-outer-type type)) |
---|
848 | (inner-type (gtk-inner-type type))) |
---|
849 | (output-helper inner-type standard-output) |
---|
850 | (@ "sgtk_%s_to_rep \(%s, _sgtk_helper_torep_copy_%s\)" |
---|
851 | outer-type gtk-var inner-type))) |
---|
852 | |
---|
853 | (defun output-list-finish (output type gtk-var rep-var options) |
---|
854 | (declare (unused typage options)) |
---|
855 | (let |
---|
856 | ((outer-type (gtk-outer-type type)) |
---|
857 | (inner-type (gtk-inner-type type)) |
---|
858 | (mode (gtk-composite-type-mode type))) |
---|
859 | (@ " sgtk_%s_finish \(%s, %s, %s\);\n" |
---|
860 | outer-type gtk-var rep-var |
---|
861 | (if (eq mode 'in) |
---|
862 | "0" |
---|
863 | (format nil "_sgtk_helper_torep_nocopy_%s" inner-type))))) |
---|
864 | |
---|
865 | |
---|
866 | ;; Function generation |
---|
867 | |
---|
868 | (defun output-function (def output #!optional function-callback) |
---|
869 | (let* |
---|
870 | ((ret (nth 1 def)) |
---|
871 | (args (nth 2 def)) |
---|
872 | (options (nthcdr 3 def)) |
---|
873 | (fname (symbol-name (car def))) |
---|
874 | (rname (or (gtk-get-option 'scm-name options) |
---|
875 | (gtk-hyphenate-name fname))) |
---|
876 | (cname (gtk-unhyphenate-name rname)) |
---|
877 | (subrtype (if (or (> (length args) 5) |
---|
878 | (gtk-get-option 'rest-arg options)) |
---|
879 | 'n |
---|
880 | (length args)))) |
---|
881 | (setq gtk-subrs (cons cname gtk-subrs)) |
---|
882 | |
---|
883 | ;; output header |
---|
884 | (@ "DEFUN\(\"%s\", F%s, S%s, \(" rname cname cname) |
---|
885 | (if (eq subrtype 'n) |
---|
886 | (@ "repv args") |
---|
887 | (if (zerop subrtype) |
---|
888 | (@ "void") |
---|
889 | (let |
---|
890 | ((tem args)) |
---|
891 | (while tem |
---|
892 | (@ "repv p_%s%s" (gtk-arg-name (car tem)) (if (cdr tem) ", " "")) |
---|
893 | (setq tem (cdr tem)))))) |
---|
894 | (@ "\), rep_Subr%s\)\n{\n" (if (numberp subrtype) subrtype "N")) |
---|
895 | (unless (eq ret 'none) |
---|
896 | (@ " repv pr_ret;\n")) |
---|
897 | (when (eq subrtype 'n) |
---|
898 | (@ " repv ") |
---|
899 | (let |
---|
900 | ((tem args)) |
---|
901 | (while tem |
---|
902 | (@ "p_%s%s" (gtk-arg-name (car tem)) (if (cdr tem) ", " ";\n\n")) |
---|
903 | (setq tem (cdr tem))))) |
---|
904 | |
---|
905 | ;; output any gc roots required |
---|
906 | (mapc (lambda (arg) |
---|
907 | (when (or (gtk-get-arg-options 'protect-during arg) |
---|
908 | (gtk-type-prop (gtk-arg-type arg) 'finish)) |
---|
909 | (@ " rep_GC_root gc_%s;\n" (gtk-arg-name arg)))) args) |
---|
910 | |
---|
911 | ;; output arg/ret decls |
---|
912 | (mapc (lambda (arg) |
---|
913 | (let* |
---|
914 | ((type (gtk-arg-type arg)) |
---|
915 | (typage (gtk-type-info type)) |
---|
916 | (decl (gtk-type-decl type typage))) |
---|
917 | (if (stringp decl) |
---|
918 | (@ " %s c_%s;\n" decl (gtk-arg-name arg)) |
---|
919 | (gtk-warning |
---|
920 | "Don't know how to declare type: %s" type)))) args) |
---|
921 | (unless (eq ret 'none) |
---|
922 | (let* |
---|
923 | ((typage (gtk-type-info ret)) |
---|
924 | (decl (gtk-type-decl ret typage))) |
---|
925 | (cond |
---|
926 | ((stringp decl) |
---|
927 | (@ " %s cr_ret;\n" decl)) |
---|
928 | ((functionp decl) |
---|
929 | (funcall decl output ret "cr_ret" typage options)) |
---|
930 | (t |
---|
931 | (gtk-warning |
---|
932 | "Don't know how to declare type: %s" ret))))) |
---|
933 | (unless (and (null args) (eq ret 'none)) |
---|
934 | (@ "\n")) |
---|
935 | |
---|
936 | ;; break out the list of parameters |
---|
937 | (when (eq subrtype 'n) |
---|
938 | (let |
---|
939 | ((tem args) |
---|
940 | (i 1)) |
---|
941 | (while tem |
---|
942 | (@ " if \(!rep_CONSP\(args\)\)\n") |
---|
943 | (@ " p_%s = Qnil; \n" (gtk-arg-name (car tem))) |
---|
944 | (@ " else {\n") |
---|
945 | (@ (if (and (null (cdr tem)) (gtk-get-option 'rest-arg options)) |
---|
946 | " p_%s = args; args = Qnil;\n" |
---|
947 | " p_%s = rep_CAR(args); args = rep_CDR(args);\n") |
---|
948 | (gtk-arg-name (car tem))) |
---|
949 | (@ " }\n") |
---|
950 | (setq tem (cdr tem)) |
---|
951 | (setq i (1+ i))) |
---|
952 | (@ "\n"))) |
---|
953 | |
---|
954 | ;; output arg checks and conversions |
---|
955 | (let |
---|
956 | ((tem args) |
---|
957 | (i 1)) |
---|
958 | (while tem |
---|
959 | (let* |
---|
960 | ((type (gtk-arg-type (car tem))) |
---|
961 | (typage (gtk-type-info type)) |
---|
962 | (pred (gtk-type-pred typage)) |
---|
963 | (optional (gtk-arg-optional-p (car tem))) |
---|
964 | (type-options (gtk-get-options type gtk-options))) |
---|
965 | (when (gtk-get-option 'conversion type-options) |
---|
966 | (@ " p_%s = %s \(p_%s\);\n" |
---|
967 | (gtk-arg-name (car tem)) |
---|
968 | (gtk-get-option 'conversion type-options) |
---|
969 | (gtk-arg-name (car tem)))) |
---|
970 | (unless (or optional (null pred)) |
---|
971 | (when (gtk-get-arg-options 'null-ok (car tem)) |
---|
972 | (@ " if (p_%s != Qnil)\n " (gtk-arg-name (car tem)))) |
---|
973 | (@ " rep_DECLARE \(%d, p_%s, " i (gtk-arg-name (car tem))) |
---|
974 | (cond ((stringp pred) |
---|
975 | (@ "%s \(p_%s\)" pred (gtk-arg-name (car tem)))) |
---|
976 | ((functionp pred) |
---|
977 | (funcall pred output type |
---|
978 | (concat "p_" (gtk-arg-name (car tem))) |
---|
979 | typage options)) |
---|
980 | (t |
---|
981 | (gtk-warning "Don't know type predicate: %s" type))) |
---|
982 | (@ "\);\n")) |
---|
983 | (setq tem (cdr tem)) |
---|
984 | (setq i (1+ i))))) |
---|
985 | (when args |
---|
986 | (@ "\n")) |
---|
987 | |
---|
988 | ;; initialise gc roots |
---|
989 | (mapc (lambda (arg) |
---|
990 | (when (or (gtk-get-arg-options 'protect-during arg) |
---|
991 | (gtk-type-prop (gtk-arg-type arg) 'finish)) |
---|
992 | (@ " rep_PUSHGC \(gc_%s, p_%s\);\n" |
---|
993 | (gtk-arg-name arg) (gtk-arg-name arg)))) args) |
---|
994 | |
---|
995 | ;; output arg initialisations |
---|
996 | (mapc (lambda (arg) |
---|
997 | (let* |
---|
998 | ((type (gtk-arg-type arg)) |
---|
999 | (typage (gtk-type-info type)) |
---|
1000 | (from (gtk-type-fromrep typage)) |
---|
1001 | (optional (gtk-arg-optional-p arg))) |
---|
1002 | (when (gtk-get-arg-options 'null-ok arg) |
---|
1003 | (@ " if (p_%s == Qnil)\n c_%s = 0; \n else\n " |
---|
1004 | (gtk-arg-name arg) (gtk-arg-name arg))) |
---|
1005 | (when optional |
---|
1006 | (@ " if \(p_%s == Qnil\)\n c_%s = %s;\n else\n " |
---|
1007 | (gtk-arg-name arg) (gtk-arg-name arg) optional)) |
---|
1008 | (@ " c_%s = " (gtk-arg-name arg)) |
---|
1009 | (cond ((stringp from) |
---|
1010 | (@ "%s \(p_%s\)" from (gtk-arg-name arg))) |
---|
1011 | ((functionp from) |
---|
1012 | (funcall from output type |
---|
1013 | (concat "p_" (gtk-arg-name arg)) |
---|
1014 | typage options)) |
---|
1015 | (t |
---|
1016 | (gtk-warning |
---|
1017 | "Don't know how to convert repv to %s" type))) |
---|
1018 | (@ ";\n"))) args) |
---|
1019 | (when args |
---|
1020 | (@ "\n")) |
---|
1021 | |
---|
1022 | (if function-callback |
---|
1023 | (funcall function-callback output) |
---|
1024 | ;; output call |
---|
1025 | (@ " ") |
---|
1026 | (unless (eq ret 'none) |
---|
1027 | (@ "cr_ret = ")) |
---|
1028 | (@ "%s \(" fname) |
---|
1029 | (let |
---|
1030 | ((tem args)) |
---|
1031 | (while tem |
---|
1032 | (let |
---|
1033 | ((opt (gtk-type-prop (gtk-arg-type (car tem)) 'c2args))) |
---|
1034 | (if opt |
---|
1035 | (if (functionp opt) |
---|
1036 | (funcall opt output (gtk-arg-type (car tem)) |
---|
1037 | (concat "c_" (gtk-arg-name (car tem))) |
---|
1038 | options) |
---|
1039 | (gtk-warning "c2args function %s undefined" opt)) |
---|
1040 | (@ "c_%s" (gtk-arg-name (car tem))))) |
---|
1041 | (@ (if (cdr tem) ", " "")) |
---|
1042 | (setq tem (cdr tem)))) |
---|
1043 | (@ "\);\n\n")) |
---|
1044 | |
---|
1045 | ;; output ret conversion |
---|
1046 | (unless (eq ret 'none) |
---|
1047 | (let* |
---|
1048 | ((typage (gtk-type-info ret)) |
---|
1049 | (to (gtk-type-torep typage))) |
---|
1050 | (@ " pr_ret = ") |
---|
1051 | (cond ((stringp to) |
---|
1052 | (@ "%s \(cr_ret\)" to)) |
---|
1053 | ((functionp to) |
---|
1054 | (funcall to output ret "cr_ret" typage options)) |
---|
1055 | (t |
---|
1056 | (gtk-warning |
---|
1057 | "Don't know how to convert %s to repv" ret))) |
---|
1058 | (@ ";\n"))) |
---|
1059 | |
---|
1060 | ;; output `finish' options |
---|
1061 | (mapc (lambda (arg) |
---|
1062 | (let |
---|
1063 | ((opt (gtk-type-prop (gtk-arg-type arg) 'finish))) |
---|
1064 | (when opt |
---|
1065 | (if (functionp opt) |
---|
1066 | (funcall opt output (gtk-arg-type arg) |
---|
1067 | (concat "c_" (gtk-arg-name arg)) |
---|
1068 | (concat "p_" (gtk-arg-name arg)) |
---|
1069 | options) |
---|
1070 | (gtk-warning "finish function %s undefined" opt))))) args) |
---|
1071 | |
---|
1072 | ;; pop gc roots |
---|
1073 | (mapc (lambda (arg) |
---|
1074 | (when (or (gtk-get-arg-options 'protect-during arg) |
---|
1075 | (gtk-type-prop (gtk-arg-type arg) 'finish)) |
---|
1076 | (@ " rep_POPGC;\n" |
---|
1077 | (gtk-arg-name arg) (gtk-arg-name arg)))) args) |
---|
1078 | |
---|
1079 | ;; output return statement |
---|
1080 | (if (eq ret 'none) |
---|
1081 | (@ " return Qnil;\n") |
---|
1082 | (@ " return pr_ret;\n")) |
---|
1083 | |
---|
1084 | ;; footer |
---|
1085 | (@ "}\n\n"))) |
---|
1086 | |
---|
1087 | |
---|
1088 | ;; Field access functions |
---|
1089 | |
---|
1090 | (defun output-field-functions (type-list output) |
---|
1091 | (mapc (lambda (def) |
---|
1092 | (let |
---|
1093 | ((fields (cdr (assq 'fields (cdr def))))) |
---|
1094 | (when fields |
---|
1095 | (mapc #'(lambda (field) |
---|
1096 | (output-field-accessors |
---|
1097 | (car def) field output |
---|
1098 | (car (cdr (assq 'setter (nthcdr 2 field)))) |
---|
1099 | (car (cdr (assq 'getter (nthcdr 2 field)))))) |
---|
1100 | fields)) |
---|
1101 | (output-type-predicate (car def) output))) |
---|
1102 | type-list)) |
---|
1103 | |
---|
1104 | (defun output-field-accessors (datatype field output #!optional settable getter) |
---|
1105 | (let* |
---|
1106 | ((type (car field)) |
---|
1107 | (cdatatype (gtk-canonical-name (symbol-name datatype))) |
---|
1108 | (cfieldname (symbol-name (nth 1 field)))) |
---|
1109 | (output-function (list (intern (format nil "%s_%s" cdatatype cfieldname)) |
---|
1110 | type (list (list datatype 'obj))) |
---|
1111 | output |
---|
1112 | (lambda (output) |
---|
1113 | (if getter |
---|
1114 | (@ " cr_ret = %s (c_obj);\n" getter) |
---|
1115 | (@ " cr_ret = c_obj->%s;\n" cfieldname)))) |
---|
1116 | (when settable |
---|
1117 | (output-function (list (intern (format nil "%s_%s_set" |
---|
1118 | cdatatype cfieldname)) |
---|
1119 | 'none (list (list datatype 'obj) |
---|
1120 | (list type 'data))) |
---|
1121 | output |
---|
1122 | (lambda (output) |
---|
1123 | (@ " c_obj->%s = c_data;\n" cfieldname)))))) |
---|
1124 | |
---|
1125 | (defun output-type-predicate (type output) |
---|
1126 | (let* |
---|
1127 | ((typage (gtk-type-info type)) |
---|
1128 | (ctype (gtk-canonical-name (symbol-name type))) |
---|
1129 | (rtype (gtk-hyphenate-name ctype)) |
---|
1130 | (pred (gtk-type-pred typage))) |
---|
1131 | (cond ((stringp pred) |
---|
1132 | (setq pred (format nil "%s \(p_obj\)" pred))) |
---|
1133 | ((functionp pred) |
---|
1134 | (let |
---|
1135 | ((temporary-output (make-string-output-stream))) |
---|
1136 | (funcall pred temporary-output type "p_obj" typage nil) |
---|
1137 | (setq pred (get-output-stream-string temporary-output)))) |
---|
1138 | ((null pred) |
---|
1139 | (setq pred "1"))) |
---|
1140 | (@ "DEFUN\(\"%s-p\", F%s_p, S%s_p, \(repv p_obj\), rep_Subr1\)\n{\n" |
---|
1141 | rtype ctype ctype) |
---|
1142 | (@ " return \(%s\) ? Qt : Qnil;\n}\n\n" pred) |
---|
1143 | (setq gtk-subrs (cons (intern (format nil "%s_p" ctype)) gtk-subrs)))) |
---|
1144 | |
---|
1145 | |
---|
1146 | ;; Composite type helper functions |
---|
1147 | |
---|
1148 | (defun output-helper (type output) |
---|
1149 | (unless (memq type gtk-emitted-composite-helpers) |
---|
1150 | (setq gtk-emitted-composite-helpers |
---|
1151 | (cons type gtk-emitted-composite-helpers)) |
---|
1152 | (let* |
---|
1153 | ((typage (gtk-type-info type)) |
---|
1154 | (pred (gtk-type-pred typage)) |
---|
1155 | (decl (gtk-type-decl type typage)) |
---|
1156 | (from (gtk-type-fromrep typage)) |
---|
1157 | (to (gtk-type-torep typage))) |
---|
1158 | |
---|
1159 | ;; use some hackery to get from, to, and pred functions as strings |
---|
1160 | (cond ((stringp from) |
---|
1161 | (setq from (concat from " \(obj\)"))) |
---|
1162 | ((functionp from) |
---|
1163 | (let |
---|
1164 | ((temporary-output (make-string-output-stream))) |
---|
1165 | (funcall from temporary-output type "obj" typage nil) |
---|
1166 | (setq from (get-output-stream-string temporary-output))))) |
---|
1167 | (cond ((stringp to) |
---|
1168 | (setq to (format nil "%s \(*\(%s*\)mem\)" to decl))) |
---|
1169 | ((functionp to) |
---|
1170 | (let |
---|
1171 | ((temporary-output (make-string-output-stream))) |
---|
1172 | (funcall to temporary-output type |
---|
1173 | (format nil "\(*\(%s*\)mem\)" decl) typage nil) |
---|
1174 | (setq to (get-output-stream-string temporary-output))))) |
---|
1175 | (cond ((stringp pred) |
---|
1176 | (setq pred (format nil "%s \(obj\)" pred))) |
---|
1177 | ((functionp pred) |
---|
1178 | (let |
---|
1179 | ((temporary-output (make-string-output-stream))) |
---|
1180 | (funcall pred temporary-output type "obj" typage nil) |
---|
1181 | (setq pred (get-output-stream-string temporary-output)))) |
---|
1182 | ((null pred) |
---|
1183 | (setq pred "1"))) |
---|
1184 | |
---|
1185 | (unless (and (stringp decl) (stringp pred) (stringp from) (stringp to)) |
---|
1186 | (error "Can't create composite helper for %s" type)) |
---|
1187 | (@ "/* helpers for %s */\n" type) |
---|
1188 | (@ "static int\n_sgtk_helper_valid_%s \(repv obj\)\n" type) |
---|
1189 | (@ "\{\n return obj == Qnil || \(%s\);\n\}\n" pred) |
---|
1190 | (@ "static void\n_sgtk_helper_fromrep_%s \(repv obj, void *mem\)\n" type) |
---|
1191 | (@ "\{\n *\(%s*\)mem = %s;\n\}\n" decl from) |
---|
1192 | (@ "static repv\n_sgtk_helper_torep_copy_%s \(void *mem\)\n" type) |
---|
1193 | (@ "\{\n return %s;\n\}\n" to) |
---|
1194 | ;; XXX presumably there should be a difference between the |
---|
1195 | ;; XXX copy and no_copy variants!? |
---|
1196 | (@ "static repv\n_sgtk_helper_torep_nocopy_%s \(void *mem\)\n" type) |
---|
1197 | (@ "\{\n return %s;\n\}\n\n" to)))) |
---|
1198 | |
---|
1199 | |
---|
1200 | ;; Sundries |
---|
1201 | |
---|
1202 | (defun gtk-canonical-name (name) |
---|
1203 | (let |
---|
1204 | ((out nil) |
---|
1205 | (point 0)) |
---|
1206 | (while (string-match "[A-Z]+" name point) |
---|
1207 | (setq out (cons (substring name point (match-start)) out)) |
---|
1208 | (unless (zerop point) |
---|
1209 | (setq out (cons ?_ out))) |
---|
1210 | (setq out (cons (translate-string (substring |
---|
1211 | name (match-start) (match-end)) |
---|
1212 | downcase-table) out)) |
---|
1213 | (setq point (match-end))) |
---|
1214 | (if out |
---|
1215 | (progn |
---|
1216 | (setq out (cons (substring name point) out)) |
---|
1217 | (apply concat (nreverse out))) |
---|
1218 | name))) |
---|
1219 | |
---|
1220 | (defun gtk-hyphenate-name (name) |
---|
1221 | (if (string-match "_" name) |
---|
1222 | (translate-string (copy-sequence name) gtk-hyphen-map) |
---|
1223 | name)) |
---|
1224 | |
---|
1225 | (defun gtk-unhyphenate-name (name) |
---|
1226 | (if (string-match "-" name) |
---|
1227 | (translate-string (copy-sequence name) gtk-unhyphen-map) |
---|
1228 | name)) |
---|
1229 | |
---|
1230 | (defun gtk-warning (fmt . args) |
---|
1231 | (apply format standard-error fmt args) |
---|
1232 | (write standard-error ?\n)) |
---|
1233 | |
---|
1234 | |
---|
1235 | ;; initialisation |
---|
1236 | |
---|
1237 | (define-type 'type "GtkType" "sgtk_rep_to_type" |
---|
1238 | "sgtk_type_to_rep" "sgtk_valid_type") |
---|
1239 | |
---|
1240 | (define-type 'char "gchar" "sgtk_rep_to_char" |
---|
1241 | "sgtk_char_to_rep" "sgtk_valid_char") |
---|
1242 | |
---|
1243 | (define-type 'bool "int" "sgtk_rep_to_bool" "sgtk_bool_to_rep" nil) |
---|
1244 | |
---|
1245 | ;; XXX fix the validation functions |
---|
1246 | (define-type 'short "short" "sgtk_rep_to_int" "sgtk_int_to_rep" |
---|
1247 | "sgtk_valid_int" '(listable . t)) |
---|
1248 | (define-type 'ushort "gushort" "sgtk_rep_to_uint" "sgtk_uint_to_rep" |
---|
1249 | "sgtk_valid_uint" '(listable . t)) |
---|
1250 | |
---|
1251 | (define-type 'int "gint" "sgtk_rep_to_int" "sgtk_int_to_rep" |
---|
1252 | "sgtk_valid_int" '(listable . t)) |
---|
1253 | |
---|
1254 | (define-type 'uint "guint" "sgtk_rep_to_uint" "sgtk_uint_to_rep" |
---|
1255 | "sgtk_valid_uint" '(listable . t)) |
---|
1256 | |
---|
1257 | (define-type 'long "glong" "sgtk_rep_to_long" |
---|
1258 | "sgtk_long_to_rep" "sgtk_valid_long") |
---|
1259 | |
---|
1260 | (define-type 'ulong "gulong" "sgtk_rep_to_ulong" |
---|
1261 | "sgtk_ulong_to_rep" "sgtk_valid_ulong") |
---|
1262 | |
---|
1263 | (define-type 'float "gfloat" "sgtk_rep_to_float" |
---|
1264 | "sgtk_float_to_rep" "sgtk_valid_float") |
---|
1265 | |
---|
1266 | (define-type 'string "char*" "sgtk_rep_to_string" |
---|
1267 | "sgtk_string_to_rep" "sgtk_valid_string" '(listable . t)) |
---|
1268 | |
---|
1269 | (define-type 'enum output-complex-type output-rep-to-enum |
---|
1270 | output-enum-to-rep output-enum-pred) |
---|
1271 | |
---|
1272 | (define-type 'senum "char*" output-rep-to-senum |
---|
1273 | output-senum-to-rep output-senum-pred) |
---|
1274 | |
---|
1275 | (define-type 'flags output-complex-type output-rep-to-flags |
---|
1276 | output-flags-to-rep output-flags-pred) |
---|
1277 | |
---|
1278 | (define-type 'boxed output-complex-type output-rep-to-boxed |
---|
1279 | output-boxed-to-rep output-boxed-pred '(listable . t)) |
---|
1280 | |
---|
1281 | (define-type 'pointer "gpointer" "sgtk_rep_to_pointer" |
---|
1282 | "sgtk_pointer_to_rep" "sgtk_valid_pointer") |
---|
1283 | |
---|
1284 | (define-type 'object output-complex-type output-rep-to-object |
---|
1285 | output-object-to-rep output-object-pred '(listable . t)) |
---|
1286 | |
---|
1287 | (define-type 'static_string "const char*" nil |
---|
1288 | "sgtk_static_string_to_rep" nil '(listable . t)) |
---|
1289 | |
---|
1290 | (define-type 'full-callback "sgtk_protshell*" output-rep-to-full-callback nil |
---|
1291 | "sgtk_valid_function" (cons 'c2args output-full-callback-args) |
---|
1292 | (cons 'finish output-full-callback-finish)) |
---|
1293 | |
---|
1294 | (define-type 'gclosure "GClosure*" output-rep-to-gclosure nil |
---|
1295 | "sgtk_valid_function" (cons 'finish output-full-callback-finish)) |
---|
1296 | |
---|
1297 | (define-type 'file-descriptor "int" "sgtk_rep_to_fd" |
---|
1298 | "sgtk_fd_to_rep" "sgtk_valid_fd") |
---|
1299 | |
---|
1300 | (define-type 'list "GList*" output-rep-to-list output-list-to-rep |
---|
1301 | output-cvec-pred (cons 'finish output-list-finish)) |
---|
1302 | |
---|
1303 | (define-type 'slist "GSList*" output-rep-to-list output-list-to-rep |
---|
1304 | output-cvec-pred (cons 'finish output-list-finish)) |
---|
1305 | |
---|
1306 | (define-type 'cvec "sgtk_cvec" output-rep-to-cvec output-cvec-to-rep |
---|
1307 | output-cvec-pred (cons 'finish output-cvec-finish) |
---|
1308 | (cons 'c2args output-cvec-args)) |
---|
1309 | |
---|
1310 | (define-type 'cvecr "sgtk_cvec" output-rep-to-cvec output-cvec-to-rep |
---|
1311 | output-cvec-pred (cons 'finish output-cvec-finish) |
---|
1312 | (cons 'c2args output-cvec-args)) |
---|
1313 | |
---|
1314 | (define-type 'fvec "sgtk_cvec" output-rep-to-cvec output-cvec-to-rep |
---|
1315 | output-cvec-pred (cons 'finish output-cvec-finish) |
---|
1316 | (cons 'c2args output-cvec-args)) |
---|
1317 | |
---|
1318 | (define-type 'tvec "sgtk_cvec" output-rep-to-cvec output-cvec-to-rep |
---|
1319 | output-cvec-pred (cons 'finish output-cvec-finish) |
---|
1320 | (cons 'c2args output-cvec-args)) |
---|
1321 | |
---|
1322 | (define-type 'ret "sgtk_cvec" output-rep-to-cvec output-cvec-to-rep |
---|
1323 | output-cvec-pred (cons 'finish output-cvec-finish) |
---|
1324 | (cons 'c2args output-cvec-args)) |
---|
1325 | |
---|
1326 | (define-type 'double "gdouble" "sgtk_rep_to_double" |
---|
1327 | "sgtk_double_to_rep" "sgtk_valid_double") |
---|
1328 | |
---|
1329 | (define-type 'point "GdkPoint" "sgtk_rep_to_point" |
---|
1330 | "sgtk_point_to_rep" "sgtk_valid_point") |
---|
1331 | |
---|
1332 | (define-type 'rect "GdkRectangle" "sgtk_rep_to_rect" |
---|
1333 | "sgtk_rect_to_rep" "sgtk_valid_rect") |
---|
1334 | |
---|
1335 | (define-type 'SCM "repv" "" "" nil) |
---|