chiark / gitweb /
Lots more has happened.
[sod] / module-output.lisp
CommitLineData
ddee4bb1
MW
1;;; -*-lisp-*-
2;;;
3;;; Output handling for modules
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(defun guard-name (filename)
40 "Return a sensible inclusion guard name for FILENAME."
41 (with-output-to-string (guard)
42 (let* ((pathname (make-pathname :name (pathname-name filename)
43 :type (pathname-type filename)))
44 (name (namestring pathname))
45 (uscore t))
46 (dotimes (i (length name))
47 (let ((ch (char name i)))
48 (cond ((alphanumericp ch)
49 (write-char (char-upcase ch) guard)
50 (setf uscore nil))
51 ((not uscore)
52 (write-char #\_ guard)
53 (setf uscore t))))))))
54
55;;;--------------------------------------------------------------------------
56;;; Driving output.
57
58(defun guess-output-file (module type)
59 (merge-pathnames (make-pathname :type type :case :common)
60 (module-name module)))
61
62(defun output-module (module reason stream)
63 (let ((sequencer (make-instance 'sequencer)))
64 (add-output-hooks module reason sequencer)
65 (invoke-sequencer-items sequencer stream)))
66
67;;;--------------------------------------------------------------------------
68;;; Main output protocol implementation.
69
70(defmethod add-output-hooks progn ((module module) reason sequencer)
71 (dolist (item (module-items module))
72 (add-output-hooks item reason sequencer)))
73
74;;;--------------------------------------------------------------------------
75;;; Header output.
76
77(defmethod add-output-hooks progn
78 ((module module) (reason (eql :h)) sequencer)
79 (sequence-output (stream sequencer)
80 :constraint (:prologue
81 (:guard :start)
82 (:typedefs :start) :typedefs (:typedefs :end)
83 (:includes :start) :includes (:includes :end)
84 (:classes :start) (:classes :end)
85 (:guard :end)
86 :epilogue)
87
88 (:prologue
89 (format stream "~
90/* -*-c-*-
91 *
92 * Header file generated by SOD for ~A
93 */~2%"
94 (namestring (module-name module))))
95
96 ((:guard :start)
97 (format stream "~
98#ifndef ~A
99#define ~:*~A
100
101#ifdef __cplusplus
102 extern \"C\" {
103#endif~2%"
104 (or (get-property (module-pset module) :guard :id)
105 (guard-name (or (stream-pathname stream)
106 (guess-output-file module "H"))))))
107 ((:guard :end)
108 (banner "That's all, folks" stream)
109 (format stream "~
110#ifdef __cplusplus
111 }
112#endif
113
114#endif~%"))
115
116 ((:typedefs :start)
117 (banner "Forward type declarations" stream))
118 ((:typedefs :end)
119 (terpri stream))
120
121 ((:includes :start)
122 (banner "External header files" stream))
123 ((:includes :end)
124 (terpri stream))))
125
126;;;----- That's all, folks --------------------------------------------------