;;;----- Licensing notice ---------------------------------------------------
;;;
-;;; This file is part of the Sensble Object Design, an object system for C.
+;;; This file is part of the Sensible Object Design, an object system for C.
;;;
;;; SOD is free software; you can redistribute it and/or modify
;;; it under the terms of the GNU General Public License as published by
(merge-pathnames (make-pathname :type type :case :common)
(module-name module)))
+(defvar *done-one-off-output* nil
+ "A list of tokens for things which should appear at most once in output.")
+
+(export 'one-off-output)
+(defun one-off-output (token sequencer item-name function)
+ "Arrange to output a thing at most once.
+
+ If there has been no previous call to `one-off-output' with the given
+ TOKEN during this output run, then arrange to call FUNCTION when the item
+ called ITEM-NAME is traversed. Otherwise do nothing."
+ (unless (member token *done-one-off-output*)
+ (push token *done-one-off-output*)
+ (add-sequencer-item-function sequencer item-name function)))
+
;;;--------------------------------------------------------------------------
;;; Main output interface.
"Write the MODULE to STREAM, giving the output machinery the REASON.
This is the top-level interface for producing output."
- (let ((sequencer (make-instance 'sequencer))
+ (let ((*done-one-off-output* nil)
+ (sequencer (make-instance 'sequencer))
(stream (if (typep stream 'position-aware-output-stream)
stream
(make-instance 'position-aware-output-stream
:stream stream
:file (stream-pathname stream)))))
- (hook-output module reason sequencer)
- (invoke-sequencer-items sequencer stream)))
+ (with-module-environment (module)
+ (hook-output module reason sequencer)
+ (invoke-sequencer-items sequencer stream))))
;;;--------------------------------------------------------------------------
;;; Output implementation.
(:prologue
(:guard :start)
(:typedefs :start) :typedefs (:typedefs :end)
- (:includes :start) :includes (:includes :end)
- (:classes :start) :classes (:classes :end)
+ (:includes :start) :includes :early-decls (:includes :end)
+ (:early-user :start) :early-user (:early-user :end)
+ (:classes :start) (:classes :end)
+ (:user :start) :user (:user :end)
(:guard :end)
:epilogue)
(:prologue
(format stream "~
-/* -*-c-*-
+/* -*- mode: c; indent-tabs-mode: nil -*-
*
* Header file generated by SOD for ~A
*/~2%"
:constraint
(:prologue
(:includes :start) :includes (:includes :end)
+ (:early-user :start) :early-user (:early-user :end)
(:classes :start) (:classes :end)
+ (:user :start) :user (:user :end)
:epilogue)
(:prologue
(format stream "~
-/* -*-c-*-
+/* -*- mode: c; indent-tabs-mode: nil -*-
*
* Implementation file generated by SOD for ~A
*/~2%"
((:includes :end)
(terpri stream))))
+;;;--------------------------------------------------------------------------
+;;; Output types.
+
+(defvar *output-types* nil
+ "List of known output types.")
+
+(export 'declare-output-type)
+(defun declare-output-type (reason pathname)
+ "Record that REASON is a valid user-level output type.
+
+ The output file name will be constructed by merging the module's pathname
+ with PATHNAME."
+ (setf (get reason 'output-type) pathname))
+
+(export 'output-type-pathname)
+(defun output-type-pathname (reason)
+ "Return the PATHNAME template for the output type REASON.
+
+ Report an error if there is no such output type."
+ (or (get reason 'output-type)
+ (error "Unknown output type `~(~A~)'" reason)))
+
+(define-clear-the-decks reset-output-types
+ "Clear out the registered output types."
+ (dolist (reason *output-types*) (remprop reason 'output-type))
+ (setf *output-types* nil)
+ (declare-output-type :c (make-pathname :type "C" :case :common))
+ (declare-output-type :h (make-pathname :type "H" :case :common)))
+
;;;----- That's all, folks --------------------------------------------------