Commit | Line | Data |
---|---|---|
abdf50aa MW |
1 | ;;; -*-lisp-*- |
2 | ;;; | |
3 | ;;; Output driver for SOD translator | |
4 | ;;; | |
5 | ;;; (c) 2009 Straylight/Edgeware | |
6 | ;;; | |
7 | ||
8 | ;;;----- Licensing notice --------------------------------------------------- | |
9 | ;;; | |
10 | ;;; This file is part of the Simple Object Definition system. | |
11 | ;;; | |
12 | ;;; SOD is free software; you can redistribute it and/or modify | |
13 | ;;; it under the terms of the GNU General Public License as published by | |
14 | ;;; the Free Software Foundation; either version 2 of the License, or | |
15 | ;;; (at your option) any later version. | |
16 | ;;; | |
17 | ;;; SOD is distributed in the hope that it will be useful, | |
18 | ;;; but WITHOUT ANY WARRANTY; without even the implied warranty of | |
19 | ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
20 | ;;; GNU General Public License for more details. | |
21 | ;;; | |
22 | ;;; You should have received a copy of the GNU General Public License | |
23 | ;;; along with SOD; if not, write to the Free Software Foundation, | |
24 | ;;; Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | |
25 | ||
26 | (cl:in-package #:sod) | |
27 | ||
28 | ;;;-------------------------------------------------------------------------- | |
29 | ;;; Utilities. | |
30 | ||
31 | (defun banner (title output &key (blank-line-p t)) | |
32 | (format output "~&~%/*----- ~A ~A*/~%" | |
33 | title | |
34 | (make-string (- 77 2 5 1 (length title) 1 2) | |
35 | :initial-element #\-)) | |
36 | (when blank-line-p | |
37 | (terpri output))) | |
38 | ||
39 | ;;;-------------------------------------------------------------------------- | |
40 | ;;; Header output. | |
41 | ||
42 | (defun write-module-header (module) | |
43 | (let* ((file (merge-pathnames (make-pathname :type "H" :case :common) | |
44 | (module-name module))) | |
45 | (fakename (make-pathname :name (pathname-name file) | |
46 | :type (pathname-type file)))) | |
47 | (with-open-file (uoutput file | |
48 | :direction :output | |
49 | :if-exists :supersede | |
50 | :if-does-not-exist :create) | |
51 | (let ((output (make-instance 'position-aware-output-stream | |
52 | :stream uoutput | |
53 | :file fakename))) | |
54 | ||
55 | ;; Format the header and guards. | |
56 | (format output "~ | |
57 | /* -*-c-*- | |
58 | * | |
59 | * Header file generated by SOD for ~A | |
60 | */ | |
61 | ||
62 | #ifndef ~A | |
63 | #define ~:*~A | |
64 | ||
65 | #ifdef __cplusplus | |
66 | extern \"C\" { | |
67 | #endif~%" | |
68 | (namestring (module-name module)) | |
69 | (or (getf (module-plist module) 'include-guard) | |
70 | (with-output-to-string (guard) | |
71 | (let ((name (namestring file)) | |
72 | (uscore t)) | |
73 | (dotimes (i (length name)) | |
74 | (let ((ch (char name i))) | |
75 | (cond ((alphanumericp ch) | |
76 | (write-char (char-upcase ch) guard) | |
77 | (setf uscore nil)) | |
78 | ((not uscore) | |
79 | (write-char #\_ guard) | |
80 | (setf uscore t))))))))) | |
81 | ||
82 | ;; Forward declarations of all the structures and types. Nothing | |
83 | ;; interesting gets said here; this is just so that the user code | |
84 | ;; can talk meainingfully about the things we're meant to be | |
85 | ;; defining here. | |
86 | ;; | |
87 | ;; FIXME | |
88 | ||
89 | ;; The user fragments. | |
90 | (when (module-header-fragments module) | |
91 | (banner "User code" output) | |
92 | (dolist (frag (module-header-fragments module)) | |
93 | (write-fragment frag output))) | |
94 | ||
95 | ;; The definitions of the necessary structures. | |
96 | ;; | |
97 | ;; FIXME | |
98 | ||
99 | ;; The definitions of the necessary direct-methods. | |
100 | ;; | |
101 | ;; FIXME | |
102 | ||
103 | ;; The trailer section. | |
104 | (banner "That's all, folks" output) | |
105 | (format output "~ | |
106 | #ifdef __cplusplus | |
107 | } | |
108 | #endif | |
109 | ||
110 | #endif~%"))))) | |
111 | ||
112 | ;;;-------------------------------------------------------------------------- | |
113 | ;;; Source output. | |
114 | ||
115 | (defun write-module-source (module) | |
116 | (let* ((file (merge-pathnames (make-pathname :type "C" :case :common) | |
117 | (module-name module))) | |
118 | (fakename (make-pathname :name (pathname-name file) | |
119 | :type (pathname-type file)))) | |
120 | (with-open-file (uoutput file | |
121 | :direction :output | |
122 | :if-exists :supersede | |
123 | :if-does-not-exist :create) | |
124 | (let ((output (make-instance 'position-aware-output-stream | |
125 | :stream uoutput | |
126 | :file fakename))) | |
127 | ||
128 | ;; Format the header. | |
129 | (format output "~ | |
130 | /* -*-c-*- | |
131 | * | |
132 | * Source file generated by SOD for ~A | |
133 | */~%" | |
134 | (namestring (module-name module))) | |
135 | ||
136 | ;; The user fragments. | |
137 | (when (module-source-fragments module) | |
138 | (banner "User code" output) | |
139 | (dolist (frag (module-source-fragments module)) | |
140 | (write-fragment frag output))) | |
141 | ||
142 | ;; The definitions of the necessary tables. | |
143 | ;; | |
144 | ;; FIXME | |
145 | ||
146 | ;; The definitions of the necessary effective-methods. | |
147 | ;; | |
148 | ;; FIXME | |
149 | ||
150 | ;; The trailer section. | |
151 | (banner "That's all, folks" output :blank-line-p nil))))) | |
152 | ||
153 | ;;;----- That's all, folks -------------------------------------------------- |