A C fragment is aware of its original location, and will bear proper #line
markers when written out."))
-(defun output-c-excursion (stream location thunk)
- "Invoke THUNK surrounding it by writing #line markers to STREAM.
+(defun output-c-excursion (stream location func)
+ "Invoke FUNC surrounding it by writing #line markers to STREAM.
The first marker describes LOCATION; the second refers to the actual
output position in STREAM. If LOCATION doesn't provide a line number then
no markers are output after all. If the output stream isn't
- position-aware then no final marker is output."
-
- (let* ((location (file-location location))
- (line (file-location-line location))
- (filename (file-location-filename location)))
- (cond (line
- (when (typep stream 'position-aware-stream)
- (format stream "~&#line ~D~@[ ~S~]~%" line filename))
- (funcall thunk)
- (when (typep stream 'position-aware-stream)
- (fresh-line stream)
- (format stream "#line ~D ~S~%"
- (1+ (position-aware-stream-line stream))
- (let ((path (stream-pathname stream)))
- (if path (namestring path) "<sod-output>")))))
- (t
- (funcall thunk)))))
+ position-aware then no final marker is output.
+
+ FUNC is passed the output stream as an argument. Complicated games may be
+ played with interposed streams. Try not to worry about it."
+
+ (flet ((doit (stream)
+ (let* ((location (file-location location))
+ (line (file-location-line location))
+ (filename (file-location-filename location)))
+ (cond (line
+ (when (typep stream 'position-aware-stream)
+ (format stream "~&#line ~D~@[ ~S~]~%" line filename))
+ (funcall func stream)
+ (when (typep stream 'position-aware-stream)
+ (fresh-line stream)
+ (format stream "#line ~D ~S~%"
+ (1+ (position-aware-stream-line stream))
+ (let ((path (stream-pathname stream)))
+ (if path (namestring path)
+ "<sod-output>")))))
+ (t
+ (funcall func stream))))))
+ (print-ugly-stuff stream #'doit)))
(defmethod print-object ((fragment c-fragment) stream)
(let ((text (c-fragment-text fragment))
(prin1 (subseq text 0 37) stream)
(write-string "..." stream))))
(output-c-excursion stream location
- (lambda () (write-string text stream))))))
+ (lambda (stream) (write-string text stream))))))
(defmethod make-load-form ((fragment c-fragment) &optional environment)
(make-load-form-saving-slots fragment :environment environment))
(,print))
(,print)))))
+(export 'print-ugly-stuff)
+(defun print-ugly-stuff (stream func)
+ "Print not-pretty things to the stream underlying STREAM.
+
+ The Lisp pretty-printing machinery, notably `pprint-logical-block', may
+ interpose additional streams between its body and the original target
+ stream. This makes it difficult to make use of the underlying stream's
+ special features, whatever they might be."
+
+ ;; This is unpleasant. Hacky hacky.
+ #.(or #+sbcl '(if (typep stream 'sb-pretty:pretty-stream)
+ (let ((target (sb-pretty::pretty-stream-target stream)))
+ (pprint-newline :mandatory stream)
+ (funcall func target))
+ (funcall func stream))
+ #+cmu '(if (typep stream 'pp:pretty-stream)
+ (let ((target (pp::pretty-stream-target stream)))
+ (pprint-newline :mandatory stream)
+ (funcall func target))
+ (funcall func stream))
+ '(funcall func stream)))
+
;;;--------------------------------------------------------------------------
;;; Iteration macros.