X-Git-Url: https://git.distorted.org.uk/~mdw/sod/blobdiff_plain/048d0b2d143b6a491ac73eed6ab972e97774391c..8eb242b160e163a1cfc6e810aeda4788116bba1a:/src/module-output.lisp diff --git a/src/module-output.lisp b/src/module-output.lisp index b093b82..c3c61d6 100644 --- a/src/module-output.lisp +++ b/src/module-output.lisp @@ -7,7 +7,7 @@ ;;;----- 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 @@ -65,6 +65,20 @@ (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. @@ -73,15 +87,17 @@ "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 ((*print-right-margin* 77) + (*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 (or (stream-pathname stream) - #p""))))) - (hook-output module reason sequencer) - (invoke-sequencer-items sequencer stream))) + :file (stream-pathname stream))))) + (with-module-environment (module) + (hook-output module reason sequencer) + (invoke-sequencer-items sequencer stream)))) ;;;-------------------------------------------------------------------------- ;;; Output implementation. @@ -112,14 +128,16 @@ (: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%" @@ -161,12 +179,14 @@ :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%" @@ -180,4 +200,33 @@ ((: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 --------------------------------------------------