diff --git a/ChangeLog b/ChangeLog index a0139f5..cd3f3e7 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,25 @@ +2013-01-31 Mirko Vukovic + + * examples.lisp: Updated and cleaned up examples + + * gnuplot-interface.lisp (echo-command, gnuplot-echo-command + *command-copy*): Removed these commands and special variable. + Command echoing is now handled with the + with-captured-gnuplot-input macro + (with-captured-gnuplot-input): New macro that replaces the + functionality of echo commands + + + * gnuplot-interface.asd (#:gnuplot-interface): Removed + "gnuplot-interface" from the components list. The streams in that + file are out of date + + * gnuplot-interface.lisp (command): Enabled + `get-output-stream-string' to clear the echo buffer. This buffer + would overflow after plotting large data sets. I may want to + reconsider stream architecture. Maybe I should disable the echo, + and enable it only when required. + 2013-01-11 Mirko Vukovic * gnuplot-interface.lisp (send-line): Modified to only send line, diff --git a/examples.lisp b/examples.lisp index cb5b7da..b974778 100755 --- a/examples.lisp +++ b/examples.lisp @@ -1,5 +1,5 @@ ;; Mirko Vukovic -;; Time-stamp: <2011-10-04 12:47:59 examples.lisp> +;; Time-stamp: <2013-01-31 13:54:25Eastern Standard Time examples.lisp> ;; ;; Copyright 2011 Mirko Vukovic ;; Distributed under the terms of the GNU General Public License @@ -29,16 +29,11 @@ "Example of a plot with inlined data. This example also illustrates the use of sending a line break" (send-line "plot '-' with lines") - (send-line (format nil "~%")) (send-line "5") - (send-line (format nil "~%")) (send-line "12") - (send-line-break) (send-line "-8") - (send-line-break) (send-line "e") - (send-line-break) - (send-line-break)) + (finish-output *command*)) (defun plot-fun (numbers function) "Given a list of numbers `numbers' and a `function', generate a @@ -46,22 +41,16 @@ plot This example shows how to make a plot of x vs y using the inlined data" (send-line "plot '-' using 1:2 with lines") - (send-line-break) (dolist (x numbers) - (send-line (format nil "~a ~a" x (funcall function x))) - (send-line-break)) - (send-line "e") - (send-line-break) - (send-line-break)) + (send-line (format nil "~a ~a" x (funcall function x)))) + (send-line #\e) + (finish-output *command*)) (defun plot-combo (numbers function) "This example builds upon `plot-fun'. Along with the function plot, it overplots gnuplot's cos(x)" - (send-line "plot '-' using 1:2 with lines") + (send-line "plot '-' using 1:2 with lines" t) (send-line ", cos(x)") - (send-line-break) (dolist (x numbers) - (send-line (format nil "~a ~a" x (funcall function x))) - (send-line-break)) - (send-line "e") - (send-line-break) - (send-line-break)) \ No newline at end of file + (send-line (format nil "~a ~a" x (funcall function x)))) + (send-line #\e) + (finish-output *command*)) diff --git a/gnuplot-interface-package-def.lisp b/gnuplot-interface-package-def.lisp index 7ff436d..9eda200 100644 --- a/gnuplot-interface-package-def.lisp +++ b/gnuplot-interface-package-def.lisp @@ -20,10 +20,12 @@ :reset :gnuplot-reset :stop :stop-gnuplot :command :gnuplot-command - :echo-command :gnuplot-echo-command - - :send-line :finish-command :send-line-to-gnuplot - :send-line-break :send-line-break-to-gnuplot + + ;; low level commands + :send-command :send-line :finish-command :send-line-break + + ;; debugging + :with-captured-gnuplot-input :*gnuplot-input-string* :*terminal* :normalize-namestring) diff --git a/gnuplot-interface.asd b/gnuplot-interface.asd index 0f6cd98..474aa2b 100644 --- a/gnuplot-interface.asd +++ b/gnuplot-interface.asd @@ -4,7 +4,7 @@ :serial t :components ((:file "gnuplot-interface-package-def") (:file "gnuplot-interface") - (:file "gnuplot-windows") + #+skip(:file "gnuplot-windows") (:file "examples")) :depends-on (:alexandria #+skip-external-program :external-program)) diff --git a/gnuplot-interface.lisp b/gnuplot-interface.lisp index 43706aa..6fbf725 100644 --- a/gnuplot-interface.lisp +++ b/gnuplot-interface.lisp @@ -1,5 +1,5 @@ ;; Mirko Vukovic -;; Time-stamp: <2013-01-11 14:00:45Eastern Standard Time gnuplot-interface.lisp> +;; Time-stamp: <2013-01-31 13:57:18Eastern Standard Time gnuplot-interface.lisp> ;; ;; Copyright 2011 Mirko Vukovic ;; Distributed under the terms of the GNU General Public License @@ -29,7 +29,7 @@ gnuplot") (defparameter *gnuplot-input* nil "lisp output to the gnuplot stream") (defparameter *io* nil "gnuplot bidirectional stream") (defparameter *error* nil "gnuplot error stream") ;; not used -(defparameter *command-copy* (make-string-output-stream) +#+skip(defparameter *command-copy* (make-string-output-stream) "Receives a copy of gnuplot commands") (defparameter *command* nil "Stream used to send commands") @@ -82,7 +82,7 @@ START-GNUPLOT") "Start gnuplot executable and initialize input stream. Also create the *command* broadcast stream. " - (setf *command-copy* (make-string-output-stream)) + #+skip(setf *command-copy* (make-string-output-stream)) ;;; I currently use native facilities for starting the gnuplot ;;; process. Note that in SBCL I set :WAIT to NIL and in CLISP I set @@ -118,8 +118,7 @@ the *command* broadcast stream. :output :stream) *gnuplot-input* (external-program:process-input-stream *gnuplot*) *gnuplot-output* (external-program:process-output-stream *gnuplot*)) - (setf *command* - (make-broadcast-stream *gnuplot-input* *command-copy*)) + (setf *command* *gnuplot-input*) (values)) @@ -139,15 +138,30 @@ the *command* broadcast stream. (close *gnuplot-input*) ;;(close *io*) (close *command*) - (close *command-copy*)))) + #+skip(close *command-copy*)))) (defun stop () "Alias for STOP-GNUPLOT" (stop-gnuplot)) +(defparameter *gnuplot-input-string* "" + "Stores command string sent to gnuplot" ) + +(defmacro with-captured-gnuplot-input (&body body) + "Execute body while capturing commands sent to *command* into +*gnuplot-input-string*" + `(let* ((copy-stream (make-string-output-stream)) + (command-stream (make-broadcast-stream *gnuplot-input* + copy-stream))) + (let ((*command* command-stream)) + (unwind-protect + ,@body + (setf *gnuplot-input-string* (get-output-stream-string copy-stream)) + (close copy-stream))))) + (defun command (&rest command-and-args) "Pass `command-and-args' to the *command* stream" -#| (get-output-stream-string *command-copy*)|# + #+skip(get-output-stream-string *command-copy*) (when command-and-args (apply #'format *command* command-and-args) (format *command* "~%") @@ -164,16 +178,19 @@ Do not send line return Do not attempt to flush the buffer" (princ string *command*)) -(defun send-line (string) +(defun send-line (string &optional continuation) "Pass a single line to the gnuplot stream Send a line return + +If CONTINUATION is T also append the \ character Do not attempt to flush the buffer This command is used to pass complex, multi-line input to gnuplot." (princ string *command*) - (princ (format nil "~%") *command*) - #+skip(finish-output *command*)) + (when continuation (princ #\\ *command*)) + (princ " +" *command*)) @@ -181,8 +198,8 @@ This command is used to pass complex, multi-line input to gnuplot." "Send a line break. Do not attempt to flush the buffer" - (princ (format nil "~%") *command*) - #+skip(finish-output *command*)) + (princ (format nil " +") *command*)) (defun flush-buffer () "Flush buffer" @@ -190,7 +207,8 @@ Do not attempt to flush the buffer" (defun finish-command () "Send line-break and flush stream" - (princ (format nil "~%") *command*) + (princ " +" *command*) (finish-output *command*)) @@ -200,11 +218,11 @@ Do not attempt to flush the buffer" (send-line-break)) -(defun echo-command () +#+skip(defun echo-command () "Return the last command sent to " (get-output-stream-string *command-copy*)) -(defun gnuplot-echo-command () +#+skip(defun gnuplot-echo-command () (echo-command)) (defun init-gnuplot () @@ -227,7 +245,7 @@ Do not attempt to flush the buffer" *io* nil *windows* nil *windows-history* nil - *command-copy* nil + ;;*command-copy* nil *command* nil ))