Re: How to avoid new line from stream

Max Zettlmeißl via clisp-list <[email protected]> Fri, 3 Aug 2018 14:15:00 +0200
Newsgroups gmane.lisp.clisp.general
Message-ID <CACjvM=d=e2B++wZ98HaDfO15jiKXFge9RXNJ5XpxAPBuQYPfiA@mail.gmail.com>
On Fri, Aug 3, 2018 at 11:36 AM, Jean Louis <[email protected]> wrote:
>
> Thank you.
>
> I found one reference here:
> https://rosettacode.org/wiki/Read_a_file_character_by_character/UTF8#Common_Lisp
>
> Right now it is working this way.
>
> (defun slurp-stream-io-command2 (command string)
>   "Returns the output of a command to which string
> has been fed, very usable for markdown, emacs Org
> mode processing and similar"
>   (let* ((stream (make-pipe-io-stream command :external-format "utf-8"))
>          (in (two-way-stream-input-stream stream))
>          (out (two-way-stream-output-stream stream))
>          (result ""))
>     (princ string out)
>     (finish-output out)
>     (close out)
>     (setf result (with-output-to-string (var)
>                    (loop for c = (read-char in nil)
>                       while c
>                       do (format var "~a" c))))
>     (finish-output in)
>     (close in)
>     (close stream)
>     result))

I took a closer look at make-pipe-io-stream and most of the things
your are doing are superfluous or even nonsensical.
As you can see in the CLISP documentation, the primary value returned
by make-pipe-io-stream is a bidirectional stream.
(https://clisp.sourceforge.io/impnotes/shell.html#pipe)
If you wanted to access the input and output streams separately, you
would use multiple-value-bind, but in your case there is no reason to
do so.
Your example does not apply exactly to this situation, since streams
connected to files behave differently from network streams or pipes,
where it is very uncertain if and when output will be available.
Personally I would choose a better name for the function, but here is
how you could write it in a better way:

(defun slurp-stream-io (command input)
  (with-open-stream (stream (make-pipe-io-stream command :buffered nil))
    (princ input stream)
    (with-output-to-string (output)
      (loop
         do (write-char (read-char stream) output)
         while (listen stream)))))

It blocks until the first character is received from the command.

I don't see any reason to use slurp-stream-io-command over run-program.
Your intent would be transported way more clearly by run-program.
(https://clisp.sourceforge.io/impnotes/shell.html#run-prog)
Additionally it is more customizable than make-pipe-io-stream e.g.
when you want to supply arguments to the program which you invoke.

(defun slurp-stream-io-1 (command input)
  (with-open-stream (stream (run-program command
                                         :input :stream
                                         :output :stream))
    (princ input stream)
    (finish-output stream)
    (with-output-to-string (output)
      (loop
         do (write-char (read-char stream) output)
         while (listen stream)))))

Happy hacking.

------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
clisp-list mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/clisp-list