From: Nathan Baum
Subject: CLISP always outputs a newline when it exits
Date: 
Message-ID: <1168248806.317113.148260@38g2000cwa.googlegroups.com>
CLISP always outputs a newline when it exits. This is extremely wrong
if I'm using it in a pipeline and need precise control over what gets
output.

I can hack up a fix by doing:

  (push (lambda () (setf *terminal-io* (make-broadcast-stream)))
        *fini-hooks*)

But that seems a bit nasty. Is there a better method I've overlooked?

From: Pascal Bourguignon
Subject: Re: CLISP always outputs a newline when it exits
Date: 
Message-ID: <87zm8t4x0l.fsf@thalassa.informatimago.com>
"Nathan Baum" <···········@btinternet.com> writes:

> CLISP always outputs a newline when it exits. This is extremely wrong
> if I'm using it in a pipeline and need precise control over what gets
> output.
>
> I can hack up a fix by doing:
>
>   (push (lambda () (setf *terminal-io* (make-broadcast-stream)))
>         *fini-hooks*)
>
> But that seems a bit nasty. Is there a better method I've overlooked?

Yes.  When I was younger, I tended to say like you.  But happily, I've
been corrected by the fine elders of c.l.l.  In your last messages,
you've affirmed about clisp things that are false.  Calm down, and ask
more questions.  Explain exactly what you do to get the results you
get, and if they're not what you want, _ask_ how to do what you want.

Here is how you can write a clisp script.  See how the output of this
script is exacly 0 byte!  If you get different results, you should
report informations about your environment (OS?) and your version of
clisp, and what you do to get the unwanted result.


[···@thalassa tmp]$ chmod 755 clisp-script 
[···@thalassa tmp]$ ./clisp-script  > a
[···@thalassa tmp]$ ls -l a
-rwxr-xr-x    1 pjb      pjb             0 Jan  8 11:36 a*
[···@thalassa tmp]$ cat clisp-script 
#!/usr/local/bin/clisp -ansi -q   -Kfull  -E iso-8859-1
;;;; -*- mode:lisp -*-
(ext:quit 0)
[···@thalassa tmp]$ /usr/local/bin/clisp  --version
GNU CLISP 2.41 (2006-10-13) (built 3374281823) (memory 3374283595)
Software: GNU C 3.3 20030226 (prerelease) (SuSE Linux) 
gcc -g -O2 -W -Wswitch -Wcomment -Wpointer-arith -Wimplicit -Wreturn-type -Wmissing-declarations -Wno-sign-compare -O2 -fexpensive-optimizations -falign-functions=4 -DUNICODE -DDYNAMIC_FFI -I. -x none libcharset.a libavcall.a libcallback.a -lreadline -lncurses -ldl  -liconv -lsigsegv -L/usr/X11R6/lib
SAFETY=0 HEAPCODES LINUX_NOEXEC_HEAPCODES GENERATIONAL_GC SPVW_BLOCKS SPVW_MIXED TRIVIALMAP_MEMORY
libsigsegv 2.4
libiconv 1.11
libreadline 5.2
Features: 
(READLINE REGEXP SYSCALLS I18N LOOP COMPILER CLOS MOP CLISP ANSI-CL COMMON-LISP
 LISP=CL INTERPRETER SOCKETS GENERIC-STREAMS LOGICAL-PATHNAMES SCREEN FFI
 GETTEXT UNICODE BASE-CHAR=CHARACTER PC386 UNIX)
C Modules: (clisp i18n syscalls regexp readline)
Installation directory: /usr/local/languages/clisp-2.41-pjb1-mit-clx/lib/clisp/
User language: ENGLISH
Machine: I686 (I686) thalassa.informatimago.com [62.93.174.79]
[···@thalassa tmp]$ 


-- 
__Pascal Bourguignon__                     http://www.informatimago.com/
Cats meow out of angst
"Thumbs! If only we had thumbs!
We could break so much!"
From: Nathan Baum
Subject: Re: CLISP always outputs a newline when it exits
Date: 
Message-ID: <1168264281.531192.228760@s80g2000cwa.googlegroups.com>
Pascal Bourguignon wrote:
> "Nathan Baum" <···········@btinternet.com> writes:
>
> > CLISP always outputs a newline when it exits. This is extremely wrong
> > if I'm using it in a pipeline and need precise control over what gets
> > output.
> >
> > I can hack up a fix by doing:
> >
> >   (push (lambda () (setf *terminal-io* (make-broadcast-stream)))
> >         *fini-hooks*)
> >
> > But that seems a bit nasty. Is there a better method I've overlooked?
>
> Yes.  When I was younger, I tended to say like you.  But happily, I've
> been corrected by the fine elders of c.l.l.  In your last messages,
> you've affirmed about clisp things that are false. Calm down, and ask
> more questions.  Explain exactly what you do to get the results you
> get, and if they're not what you want, _ask_ how to do what you want.

This isn't false. I can see where the newline is appended in the source
for the version of CLISP I'm using:

    ...
    funcall(L(fresh_line),0);   /* (FRESH-LINE [*standard-output*]) */
    pushSTACK(var_stream(S(error_output),strmflags_wr_ch_B));
    funcall(L(fresh_line),1);   /* (FRESH-LINE *error-output*) */
    pushSTACK(Symbol_value(S(terminal_io)));
    funcall(L(fresh_line),1);   /* (FRESH-LINE *terminal-io*) */
    ...

This code is always executed upon CLISP shutdown.

However, because *standard-output* and *error-output* are synonym
streams for *terminal-io*, rebinding it has the effect of bypassing
these calls to (fresh-line).

> Here is how you can write a clisp script.  See how the output of this
> script is exacly 0 byte!  If you get different results, you should
> report informations about your environment (OS?) and your version of
> clisp, and what you do to get the unwanted result.

CLISP always appends a newline if any other output was produced and the
last character output wasn't a newline. So it's as though it does
(fresh-line *terminal-io*). So yes, your no-output-producing script
produces no additional output, but it is a rather useless script in
most pipelines. ;-)

#!/usr/bin/clisp -q -E iso-8859-1 -ansi -Kfull
(princ "hello")

Linux localhost 2.6.17-gentoo-r8 #11 PREEMPT Thu Jan 4 16:52:02 UTC
2007 i686 AMD Athlon(tm) XP 2000+ AuthenticAMD GNU/Linux

GNU CLISP 2.41 (2006-10-13) (built 3376703777) (memory 3377238229)
Software: GNU C 4.1.1 (Gentoo 4.1.1-r1)
gcc -O3 -march=athlon -pipe -msse -mmmx -mfpmath=sse -W -Wswitch
-Wcomment -Wpointer-arith -Wimplicit -Wreturn-type
-Wmissing-declarations -Wno-sign-compare -O2 -fexpensive-optimizations
-falign-functions=4 -DUNICODE -DDYNAMIC_FFI -I. -x none libcharset.a
libavcall.a libcallback.a /usr/lib/libreadline.so -lncurses -ldl
-L/usr/lib -lsigsegv -L/usr/lib -lc
SAFETY=0 HEAPCODES LINUX_NOEXEC_HEAPCODES GENERATIONAL_GC SPVW_BLOCKS
SPVW_MIXED TRIVIALMAP_MEMORY
libsigsegv 2.4
libreadline 5.1
Features:
(CL-PPCRE SPLIT-SEQUENCE ASDF READLINE REGEXP SYSCALLS I18N LOOP
COMPILER CLOS MOP CLISP ANSI-CL COMMON-LISP LISP=CL INTERPRETER SOCKETS
GENERIC-STREAMS
 LOGICAL-PATHNAMES SCREEN FFI GETTEXT UNICODE BASE-CHAR=CHARACTER PC386
UNIX)
C Modules: (clisp i18n syscalls regexp readline)
Installation directory: /usr/lib/clisp/
User language: ENGLISH
Machine: I686 (I686) localhost [127.0.0.1]


>
> [···@thalassa tmp]$ chmod 755 clisp-script
> [···@thalassa tmp]$ ./clisp-script  > a
> [···@thalassa tmp]$ ls -l a
> -rwxr-xr-x    1 pjb      pjb             0 Jan  8 11:36 a*
> [···@thalassa tmp]$ cat clisp-script
> #!/usr/local/bin/clisp -ansi -q   -Kfull  -E iso-8859-1
> ;;;; -*- mode:lisp -*-
> (ext:quit 0)
> [···@thalassa tmp]$ /usr/local/bin/clisp  --version
> GNU CLISP 2.41 (2006-10-13) (built 3374281823) (memory 3374283595)
> Software: GNU C 3.3 20030226 (prerelease) (SuSE Linux)
> gcc -g -O2 -W -Wswitch -Wcomment -Wpointer-arith -Wimplicit -Wreturn-type -Wmissing-declarations -Wno-sign-compare -O2 -fexpensive-optimizations -falign-functions=4 -DUNICODE -DDYNAMIC_FFI -I. -x none libcharset.a libavcall.a libcallback.a -lreadline -lncurses -ldl  -liconv -lsigsegv -L/usr/X11R6/lib
> SAFETY=0 HEAPCODES LINUX_NOEXEC_HEAPCODES GENERATIONAL_GC SPVW_BLOCKS SPVW_MIXED TRIVIALMAP_MEMORY
> libsigsegv 2.4
> libiconv 1.11
> libreadline 5.2
> Features:
> (READLINE REGEXP SYSCALLS I18N LOOP COMPILER CLOS MOP CLISP ANSI-CL COMMON-LISP
>  LISP=CL INTERPRETER SOCKETS GENERIC-STREAMS LOGICAL-PATHNAMES SCREEN FFI
>  GETTEXT UNICODE BASE-CHAR=CHARACTER PC386 UNIX)
> C Modules: (clisp i18n syscalls regexp readline)
> Installation directory: /usr/local/languages/clisp-2.41-pjb1-mit-clx/lib/clisp/
> User language: ENGLISH
> Machine: I686 (I686) thalassa.informatimago.com [62.93.174.79]
> [···@thalassa tmp]$
>
>
> --
> __Pascal Bourguignon__                     http://www.informatimago.com/
> Cats meow out of angst
> "Thumbs! If only we had thumbs!
> We could break so much!"
From: Pascal Bourguignon
Subject: Re: CLISP always outputs a newline when it exits
Date: 
Message-ID: <87mz4t4ndc.fsf@thalassa.informatimago.com>
"Nathan Baum" <···········@btinternet.com> writes:

> Pascal Bourguignon wrote:
>> "Nathan Baum" <···········@btinternet.com> writes:
>>
>> > CLISP always outputs a newline when it exits. This is extremely wrong
>> > if I'm using it in a pipeline and need precise control over what gets
>> > output.
>> >
>> > I can hack up a fix by doing:
>> >
>> >   (push (lambda () (setf *terminal-io* (make-broadcast-stream)))
>> >         *fini-hooks*)
>> >
>> > But that seems a bit nasty. Is there a better method I've overlooked?
>>
>> Yes.  When I was younger, I tended to say like you.  But happily, I've
>> been corrected by the fine elders of c.l.l.  In your last messages,
>> you've affirmed about clisp things that are false. Calm down, and ask
>> more questions.  Explain exactly what you do to get the results you
>> get, and if they're not what you want, _ask_ how to do what you want.
>
> This isn't false. I can see where the newline is appended in the source
> for the version of CLISP I'm using:
>
>     ...
>     funcall(L(fresh_line),0);   /* (FRESH-LINE [*standard-output*]) */
>     pushSTACK(var_stream(S(error_output),strmflags_wr_ch_B));
>     funcall(L(fresh_line),1);   /* (FRESH-LINE *error-output*) */
>     pushSTACK(Symbol_value(S(terminal_io)));
>     funcall(L(fresh_line),1);   /* (FRESH-LINE *terminal-io*) */
>     ...
>
> This code is always executed upon CLISP shutdown.

Not always.  It's only executed on TEXT streams.

Any good unix filter processing TEXT will always terminate each line
with a newline. (And always did expect a newline on all lines, even
the last one).


> [...] So yes, your no-output-producing script
> produces no additional output, but it is a rather useless script in
> most pipelines. ;-)

Look how it becomes much easier when you say what you want!


[···@thalassa tmp]$ ./clisp-script < /dev/null | wc -c
      0
[···@thalassa tmp]$ echo -n abc | ./clisp-script | wc -c
      3
[···@thalassa tmp]$ echo    abc | ./clisp-script | wc -c
      4

What you want is to write a binary filter.

You should not use the default *standard-input* and *standard-output*
lisp streams when you want to process unix flows, that are sequences
of _bytes_, not sequences of newline-terminated lines of text.

In this case, you must hook a binary lisp stream on the stdin and
stdout:


#!/usr/local/bin/clisp -ansi -q   -Kfull  -E iso-8859-1
;;;; -*- mode:lisp -*-
(let ((*standard-input* 
       (EXT:MAKE-STREAM :INPUT  :ELEMENT-TYPE '(UNSIGNED-BYTE 8)))
      (*standard-output*
       (EXT:MAKE-STREAM :OUTPUT :ELEMENT-TYPE '(UNSIGNED-BYTE 8))))
      ;; Better leave *error-output* as a text stream!
  (loop
     :for byte = (read-byte *standard-input* nil nil)
     :while byte
     :do (write-byte byte *standard-output*)))
(ext:quit 0)



-- 
__Pascal Bourguignon__                     http://www.informatimago.com/
Our enemies are innovative and resourceful, and so are we. They never
stop thinking about new ways to harm our country and our people, and
neither do we. -- Georges W. Bush
From: Kaz Kylheku
Subject: Re: CLISP always outputs a newline when it exits
Date: 
Message-ID: <1168278450.160745.145820@51g2000cwl.googlegroups.com>
Pascal Bourguignon wrote:
> Any good unix filter processing TEXT will always terminate each line
> with a newline. (And always did expect a newline on all lines, even
> the last one).

In fact, in ANSI C, the behavior is undefined if the last character
written to a text stream is not a newline.

7.9.2:

... Whether the last line requires a terminating new-line character is
implementation-defined.

[ I.e., if the implementation decides to require it, and the programmer
doesn't supply it,
  the unsatisified requirement causes undefined behavior. ]

... Data read in from a text stream will necessarily compare equal to
the data
that were earlier written out to that stream only if: the data consist
only of printing
characters and the control characters horizontal tab and new-line; no
new-line character is
immediately preceded by space characters; and the last character is a
new-line character.
From: Nathan Baum
Subject: Re: CLISP always outputs a newline when it exits
Date: 
Message-ID: <1168293378.871459.196850@51g2000cwl.googlegroups.com>
Kaz Kylheku wrote:
> Pascal Bourguignon wrote:
> > Any good unix filter processing TEXT will always terminate each line
> > with a newline. (And always did expect a newline on all lines, even
> > the last one).
>
> In fact, in ANSI C, the behavior is undefined if the last character
> written to a text stream is not a newline.
>
> 7.9.2:
>
> ... Whether the last line requires a terminating new-line character is
> implementation-defined.
>
> [ I.e., if the implementation decides to require it, and the programmer
> doesn't supply it,
>   the unsatisified requirement causes undefined behavior. ]
>
> ... Data read in from a text stream will necessarily compare equal to
> the data
> that were earlier written out to that stream only if: the data consist
> only of printing
> characters and the control characters horizontal tab and new-line; no
> new-line character is
> immediately preceded by space characters; and the last character is a
> new-line character.

I did some research to see if UNIX defined this behavior. It seems
obvious that this and similar constraints (possible limits on line
length, whitespace at the end of a line might be removed) are to allow
for operating systems which enforce record-based file formats, of which
UNIX is not.

My research came up empty, with no clear signal either way, but
something interesting I did notice is that you can't even trust
-binary- streams in ANSI C:

7.19.2 (ISO/IEC 9899:1999)
  [A binary] stream may, however, have an implementation-defined
  number of null characters appended to the end of the stream.

This pretty much means any binary format which isn't self-terminating
(e.g. length specified in the header, or is terminated by a magic
number) is impossible to read without depending upon
implementation-defined behavior.
From: Nathan Baum
Subject: Re: CLISP always outputs a newline when it exits
Date: 
Message-ID: <1168299380.160415.274760@s80g2000cwa.googlegroups.com>
Pascal Bourguignon wrote:
> "Nathan Baum" <···········@btinternet.com> writes:
>
> > Pascal Bourguignon wrote:
> >> "Nathan Baum" <···········@btinternet.com> writes:
> >>
> >> > CLISP always outputs a newline when it exits. This is extremely wrong
> >> > if I'm using it in a pipeline and need precise control over what gets
> >> > output.
> >> >
> >> > I can hack up a fix by doing:
> >> >
> >> >   (push (lambda () (setf *terminal-io* (make-broadcast-stream)))
> >> >         *fini-hooks*)
> >> >
> >> > But that seems a bit nasty. Is there a better method I've overlooked?
> >>
> >> Yes.  When I was younger, I tended to say like you.  But happily, I've
> >> been corrected by the fine elders of c.l.l.  In your last messages,
> >> you've affirmed about clisp things that are false. Calm down, and ask
> >> more questions.  Explain exactly what you do to get the results you
> >> get, and if they're not what you want, _ask_ how to do what you want.
> >
> > This isn't false. I can see where the newline is appended in the source
> > for the version of CLISP I'm using:
> >
> >     ...
> >     funcall(L(fresh_line),0);   /* (FRESH-LINE [*standard-output*]) */
> >     pushSTACK(var_stream(S(error_output),strmflags_wr_ch_B));
> >     funcall(L(fresh_line),1);   /* (FRESH-LINE *error-output*) */
> >     pushSTACK(Symbol_value(S(terminal_io)));
> >     funcall(L(fresh_line),1);   /* (FRESH-LINE *terminal-io*) */
> >     ...
> >
> > This code is always executed upon CLISP shutdown.
>
> Not always.  It's only executed on TEXT streams.

Nothing in the source suggests it checks the element type of the
streams before executing the code. In fact, CLISP will fall over if any
of those streams are not a character output stream upon exiting,
because it will try to FRESH-LINE anyway even though that's not
possible on a byte stream. This strongly suggests the code is executed
on any kind of stream.

$ cat clisp.script
#!/usr/bin/clisp
(setf *standard-output*  (EXT:MAKE-STREAM :OUTPUT :ELEMENT-TYPE
'(UNSIGNED-BYTE 8)))
$ ./clisp.script
*** - The value of *STANDARD-OUTPUT* was not an appropriate stream:
       #<OUTPUT UNBUFFERED FILE-STREAM (UNSIGNED-BYTE 8) #P"/dev/fd/1">
      . It has been changed to #<IO SYNONYM-STREAM *TERMINAL-IO*>.

> Any good unix filter processing TEXT will always terminate each line
> with a newline. (And always did expect a newline on all lines, even
> the last one).

'Course, it's logically impossible for a UNIX filter to fail to put a
newline on any line other than the last one. ;-)

But, actually, several good UNIX filters don't automatically terminate
the final line with a newline. tr and sed, for example, only terminate
their output with a newline if the input was terminated with a newline:

  $ printf foo | tr o q
  fqq$ printf foo | sed s/o/q/
  fqo$

(At least, *I* think sed is a good UNIX filter. YMMV. :p)

Some filters -do- always add newlines: sort and uniq, for example.
That's not totally wrong in the context, although I wouldn't complain
if they omitted the terminating newline from output if it was also
omitted from input.

> > [...] So yes, your no-output-producing script
> > produces no additional output, but it is a rather useless script in
> > most pipelines. ;-)
>
> Look how it becomes much easier when you say what you want!
>
>
> [···@thalassa tmp]$ ./clisp-script < /dev/null | wc -c
>       0
> [···@thalassa tmp]$ echo -n abc | ./clisp-script | wc -c
>       3
> [···@thalassa tmp]$ echo    abc | ./clisp-script | wc -c
>       4
>
> What you want is to write a binary filter.
>
> You should not use the default *standard-input* and *standard-output*
> lisp streams when you want to process unix flows, that are sequences
> of _bytes_, not sequences of newline-terminated lines of text.
>
> In this case, you must hook a binary lisp stream on the stdin and
> stdout:
>
>
> #!/usr/local/bin/clisp -ansi -q   -Kfull  -E iso-8859-1
> ;;;; -*- mode:lisp -*-
> (let ((*standard-input*
>        (EXT:MAKE-STREAM :INPUT  :ELEMENT-TYPE '(UNSIGNED-BYTE 8)))
>       (*standard-output*
>        (EXT:MAKE-STREAM :OUTPUT :ELEMENT-TYPE '(UNSIGNED-BYTE 8))))
>       ;; Better leave *error-output* as a text stream!
>   (loop
>      :for byte = (read-byte *standard-input* nil nil)
>      :while byte
>      :do (write-byte byte *standard-output*)))
> (ext:quit 0)

Ah-ha. That works; but not for the reason you say.

It isn't because the element type of the stream is (UNSIGNED-BYTE 8),
but rather because nothing is output to the top-level values of
*standard-output*, *error-output* or *terminal-io*; the result being
that when FRESH-LINE is called on them, they don't think a newline
needs to be output.

This is easily proven by replacing *-byte with *-char and
(UNSIGNED-BYTE 8) with CHARACTER: the script still doesn't append a
newline.

You are right, of course, that I don't want to (indeed, can't,
generally speaking) write a binary filter using character streams. When
it came to actually sending binary data, I would have done what you
said, and the problem would have solved itself, although I'd be none
the wiser.

>
>
>
> --
> __Pascal Bourguignon__                     http://www.informatimago.com/
> Our enemies are innovative and resourceful, and so are we. They never
> stop thinking about new ways to harm our country and our people, and
> neither do we. -- Georges W. Bush
From: Barry Margolin
Subject: Re: CLISP always outputs a newline when it exits
Date: 
Message-ID: <barmar-C81B61.21280208012007@comcast.dca.giganews.com>
In article <························@s80g2000cwa.googlegroups.com>,
 "Nathan Baum" <···········@btinternet.com> wrote:

> Some filters -do- always add newlines: sort and uniq, for example.
> That's not totally wrong in the context, although I wouldn't complain
> if they omitted the terminating newline from output if it was also
> omitted from input.

The distinction is generally between filters that process lines and 
those that just process characters.  Grep is another example of a 
line-based filter.  But tr doesn't need to deal with lines, so it 
doesn't really care how the file ends, and it simply copies the original 
ending to the output.

A common behavior of many line-based filter implementations is that they 
may ignore the last line of the input if it doesn't end in newline.

In the case of sort, it seems just as "correct" for it to omit the 
newline after the repositioned last line.  E.g. if the input was 
"b\nc\na" the result could be "ab\nc\n"!

-- 
Barry Margolin, ······@alum.mit.edu
Arlington, MA
*** PLEASE post questions in newsgroups, not directly to me ***
*** PLEASE don't copy me on replies, I'll read them in the group ***
From: Pascal Bourguignon
Subject: Re: CLISP always outputs a newline when it exits
Date: 
Message-ID: <87vejh2hlm.fsf@thalassa.informatimago.com>
"Nathan Baum" <···········@btinternet.com> writes:

> $ cat clisp.script
> #!/usr/bin/clisp
> (setf *standard-output*  (EXT:MAKE-STREAM :OUTPUT :ELEMENT-TYPE
> '(UNSIGNED-BYTE 8)))
> $ ./clisp.script
> *** - The value of *STANDARD-OUTPUT* was not an appropriate stream:
>        #<OUTPUT UNBUFFERED FILE-STREAM (UNSIGNED-BYTE 8) #P"/dev/fd/1">
>       . It has been changed to #<IO SYNONYM-STREAM *TERMINAL-IO*>.


I showed you how to do it correctly.  Why are you doing it wrong?  Are
you a troll?


>> Any good unix filter processing TEXT will always terminate each line
>> with a newline. (And always did expect a newline on all lines, even
>> the last one).
>
> 'Course, it's logically impossible for a UNIX filter to fail to put a
> newline on any line other than the last one. ;-)
>
> But, actually, several good UNIX filters don't automatically terminate
> the final line with a newline. tr and sed, for example, only terminate
> their output with a newline if the input was terminated with a newline:
>
>   $ printf foo | tr o q
>   fqq$ printf foo | sed s/o/q/
>   fqo$
>
> (At least, *I* think sed is a good UNIX filter. YMMV. :p)

They did not always behave like this.  Old versions would hang
indefinitely if the last line of input wasn't line-terminated.  Why do
you think the standard specifies undefined behavior?


>> #!/usr/local/bin/clisp -ansi -q   -Kfull  -E iso-8859-1
>> ;;;; -*- mode:lisp -*-
>> (let ((*standard-input*
>>        (EXT:MAKE-STREAM :INPUT  :ELEMENT-TYPE '(UNSIGNED-BYTE 8)))
>>       (*standard-output*
>>        (EXT:MAKE-STREAM :OUTPUT :ELEMENT-TYPE '(UNSIGNED-BYTE 8))))
>>       ;; Better leave *error-output* as a text stream!
>>   (loop
>>      :for byte = (read-byte *standard-input* nil nil)
>>      :while byte
>>      :do (write-byte byte *standard-output*)))
>> (ext:quit 0)
>
> Ah-ha. That works; but not for the reason you say.

Yes for the exact reason I say.

clisp didn't call fresh-line on these streams made explicitely binary.


> It isn't because the element type of the stream is (UNSIGNED-BYTE 8),
> but rather because nothing is output to the top-level values of
> *standard-output*, *error-output* or *terminal-io*; the result being
> that when FRESH-LINE is called on them, they don't think a newline
> needs to be output.

If you write on these text streams, as the POSIX standard mandates,
they will be line terminated.  Or do you want to break standard?  Are
you a *Microsoft* troll?


> This is easily proven by replacing *-byte with *-char and
> (UNSIGNED-BYTE 8) with CHARACTER: the script still doesn't append a
> newline.

I showed you how to do it right.  Why would you want to do it wrong?


> You are right, of course, that I don't want to (indeed, can't,
> generally speaking) write a binary filter using character streams. When
> it came to actually sending binary data, I would have done what you
> said, and the problem would have solved itself, although I'd be none
> the wiser.

In conclusion, there is nothing wrong with clisp, on the contrary, it
even respects fine points of the posix standard, while not all C unix
tools do.


-- 
__Pascal Bourguignon__                     http://www.informatimago.com/

Nobody can fix the economy.  Nobody can be trusted with their finger
on the button.  Nobody's perfect.  VOTE FOR NOBODY.
From: Nathan Baum
Subject: Re: CLISP always outputs a newline when it exits
Date: 
Message-ID: <1168303399.531764.90500@11g2000cwr.googlegroups.com>
Pascal Bourguignon wrote:
> "Nathan Baum" <···········@btinternet.com> writes:
>
> > $ cat clisp.script
> > #!/usr/bin/clisp
> > (setf *standard-output*  (EXT:MAKE-STREAM :OUTPUT :ELEMENT-TYPE
> > '(UNSIGNED-BYTE 8)))
> > $ ./clisp.script
> > *** - The value of *STANDARD-OUTPUT* was not an appropriate stream:
> >        #<OUTPUT UNBUFFERED FILE-STREAM (UNSIGNED-BYTE 8) #P"/dev/fd/1">
> >       . It has been changed to #<IO SYNONYM-STREAM *TERMINAL-IO*>.
>
> I showed you how to do it correctly.  Why are you doing it wrong?  Are
> you a troll?

You said CLISP only called fresh-line on text streams. I showed you
that it also called them on binary streams.

Rather than admitting that you were wrong, you prefer to pretend that
you were right and accuse me of being a troll? Why are you doing it
wrong? Are you a troll?

>
> >> Any good unix filter processing TEXT will always terminate each line
> >> with a newline. (And always did expect a newline on all lines, even
> >> the last one).
> >
> > 'Course, it's logically impossible for a UNIX filter to fail to put a
> > newline on any line other than the last one. ;-)
> >
> > But, actually, several good UNIX filters don't automatically terminate
> > the final line with a newline. tr and sed, for example, only terminate
> > their output with a newline if the input was terminated with a newline:
> >
> >   $ printf foo | tr o q
> >   fqq$ printf foo | sed s/o/q/
> >   fqo$
> >
> > (At least, *I* think sed is a good UNIX filter. YMMV. :p)
>
> They did not always behave like this.  Old versions would hang
> indefinitely if the last line of input wasn't line-terminated.  Why do
> you think the standard specifies undefined behavior?

I already said why the standard specifies undefined behavior. Certainly
not so that badly written programs could hang indefinitely waiting for
the end of the file to magically turn into a newline.

> >> #!/usr/local/bin/clisp -ansi -q   -Kfull  -E iso-8859-1
> >> ;;;; -*- mode:lisp -*-
> >> (let ((*standard-input*
> >>        (EXT:MAKE-STREAM :INPUT  :ELEMENT-TYPE '(UNSIGNED-BYTE 8)))
> >>       (*standard-output*
> >>        (EXT:MAKE-STREAM :OUTPUT :ELEMENT-TYPE '(UNSIGNED-BYTE 8))))
> >>       ;; Better leave *error-output* as a text stream!
> >>   (loop
> >>      :for byte = (read-byte *standard-input* nil nil)
> >>      :while byte
> >>      :do (write-byte byte *standard-output*)))
> >> (ext:quit 0)
> >
> > Ah-ha. That works; but not for the reason you say.
>
> Yes for the exact reason I say.
>
> clisp didn't call fresh-line on these streams made explicitely binary.

Clearly not. But you were saying that's because those streams are
binary, whilst that simply isn't the case. It's because no output was
sent to the top-level *standard-output*.

> > It isn't because the element type of the stream is (UNSIGNED-BYTE 8),
> > but rather because nothing is output to the top-level values of
> > *standard-output*, *error-output* or *terminal-io*; the result being
> > that when FRESH-LINE is called on them, they don't think a newline
> > needs to be output.
>
> If you write on these text streams, as the POSIX standard mandates,
> they will be line terminated.  Or do you want to break standard?  Are
> you a *Microsoft* troll?

Please show me where the POSIX standard mandates that you must put a
newline at the end of a text stream, and then explain why POSIX
"printf" is defined not to do that unless you explicitly request it.

> > This is easily proven by replacing *-byte with *-char and
> > (UNSIGNED-BYTE 8) with CHARACTER: the script still doesn't append a
> > newline.
>
> I showed you how to do it right.  Why would you want to do it wrong?

Do what right?

If I wanted to implement POSIX printf in CLISP, where the terminating
newline is -not- compulsory, I would have to either do the printing
using a character stream created using make-stream, or rebind
*terminal-io* before the script exits.

You evidently consider both of those ways to be automatically wrong,
even though there's no other way to implement POSIX printf in CLISP.
Presumably, wanting to implement POSIX printf in CLISP would be
automatically wrong, no matter what.

> > You are right, of course, that I don't want to (indeed, can't,
> > generally speaking) write a binary filter using character streams. When
> > it came to actually sending binary data, I would have done what you
> > said, and the problem would have solved itself, although I'd be none
> > the wiser.
>
> In conclusion, there is nothing wrong with clisp, on the contrary, it
> even respects fine points of the posix standard, while not all C unix
> tools do.

Even if the POSIX standard does mandate a newline at the end of a text
stream, which I very much doubt, CLISP -doesn't- always respect that,
because it doesn't always append a newline.

> __Pascal Bourguignon__                     http://www.informatimago.com/
>
> Nobody can fix the economy.  Nobody can be trusted with their finger
> on the button.  Nobody's perfect.  VOTE FOR NOBODY.
From: Pascal Bourguignon
Subject: Re: CLISP always outputs a newline when it exits
Date: 
Message-ID: <87mz4s2zb5.fsf@thalassa.informatimago.com>
"Nathan Baum" <···········@btinternet.com> writes:

> Pascal Bourguignon wrote:
>> "Nathan Baum" <···········@btinternet.com> writes:
>>
>> > $ cat clisp.script
>> > #!/usr/bin/clisp
>> > (setf *standard-output*  (EXT:MAKE-STREAM :OUTPUT :ELEMENT-TYPE
>> > '(UNSIGNED-BYTE 8)))
>> > $ ./clisp.script
>> > *** - The value of *STANDARD-OUTPUT* was not an appropriate stream:
>> >        #<OUTPUT UNBUFFERED FILE-STREAM (UNSIGNED-BYTE 8) #P"/dev/fd/1">
>> >       . It has been changed to #<IO SYNONYM-STREAM *TERMINAL-IO*>.
>>
>> I showed you how to do it correctly.  Why are you doing it wrong?  Are
>> you a troll?
>
> You said CLISP only called fresh-line on text streams. I showed you
> that it also called them on binary streams.

Misunderstanding.  I was speaking of lisp streams, not of stdin
stdout.  Once you call ext:make-stream :input, there are two lisp
strings hooked on stdin, the normal *standard-input* text stream, and
the newly created binary stream.  FRESH-LINE will rightfully be called
on *standard-input* if you don't finish a line.  But there's no
reason, since you won't be using the text stream, only the binary
stream.


>> >> #!/usr/local/bin/clisp -ansi -q   -Kfull  -E iso-8859-1
>> >> ;;;; -*- mode:lisp -*-
>> >> (let ((*standard-input*
>> >>        (EXT:MAKE-STREAM :INPUT  :ELEMENT-TYPE '(UNSIGNED-BYTE 8)))
>> >>       (*standard-output*
>> >>        (EXT:MAKE-STREAM :OUTPUT :ELEMENT-TYPE '(UNSIGNED-BYTE 8))))
>> >>       ;; Better leave *error-output* as a text stream!
>> >>   (loop
>> >>      :for byte = (read-byte *standard-input* nil nil)
>> >>      :while byte
>> >>      :do (write-byte byte *standard-output*)))
>> >> (ext:quit 0)
>> >
>> > Ah-ha. That works; but not for the reason you say.
>>
>> Yes for the exact reason I say.
>>
>> clisp didn't call fresh-line on these streams made explicitely binary.
>
> Clearly not. But you were saying that's because those streams are
> binary, whilst that simply isn't the case. It's because no output was
> sent to the top-level *standard-output*.

What does the default *standard-output* has to do with that?  We have
stdin and stdout and these binary streams, and we run the filter and
don't get spurrious bytes added.  What more do you want?

>> > This is easily proven by replacing *-byte with *-char and
>> > (UNSIGNED-BYTE 8) with CHARACTER: the script still doesn't append a
>> > newline.
>>
>> I showed you how to do it right.  Why would you want to do it wrong?
>
> Do what right?
>
> If I wanted to implement POSIX printf in CLISP, where the terminating
> newline is -not- compulsory, I would have to either do the printing
> using a character stream created using make-stream, or rebind
> *terminal-io* before the script exits.

If you wanted to implement printf, you'd have to use a BINARY stream!
C and POSIX have no notion of character files.  They only know BYTE files.


-- 
__Pascal Bourguignon__                     http://www.informatimago.com/

This is a signature virus.  Add me to your signature and help me to live.
From: Novus
Subject: Re: CLISP always outputs a newline when it exits
Date: 
Message-ID: <2007010823373116807-novus@ngoqdeorg>
On 2007-01-08 19:01:41 -0500, Pascal Bourguignon <···@informatimago.com> said:

> If you write on these text streams, as the POSIX standard mandates,
> they will be line terminated.  Or do you want to break standard?  Are
> you a *Microsoft* troll?

I was with you until that paragraph. I'm gonna have to call BS
on your POSIX statement though. Unless you can site the relevant
portion of the standard.

Novus
From: Pascal Bourguignon
Subject: Re: CLISP always outputs a newline when it exits
Date: 
Message-ID: <87irfg2zac.fsf@thalassa.informatimago.com>
Novus <·····@ngoqde.org> writes:

> On 2007-01-08 19:01:41 -0500, Pascal Bourguignon <···@informatimago.com> said:
>
>> If you write on these text streams, as the POSIX standard mandates,
>> they will be line terminated.  Or do you want to break standard?  Are
>> you a *Microsoft* troll?
>
> I was with you until that paragraph. I'm gonna have to call BS
> on your POSIX statement though. Unless you can site the relevant
> portion of the standard.

They were both cited in this thread.

-- 
__Pascal Bourguignon__                     http://www.informatimago.com/

This is a signature virus.  Add me to your signature and help me to live.
From: parnell
Subject: CLISP and FFI with saved executables
Date: 
Message-ID: <1168291605.631332.87780@v33g2000cwv.googlegroups.com>
I realize this is slightly off topic but I cannot seem to get anyone to
add me to the clisp-list mailing list to ask this question:


I would like to deliver a stand alone application that uses the clsql
libraries on (WinXP/2003 server, CLISP 2.41, CLSQL 3.8.0).  My
application works fine when I compile and run it from a repl session
but when I create the executable like so:


(ext:saveinitmem "y:\\appz\\hisexecshares\\hisexecshares.exe"
                          :init-function #'his-exe-main
                          :NORC t
                          :script nil
                          :executable t
                          :quiet t)


And then run it like so:

Y:\appz\hisexecshares>hisexecshares.exe 2007-01-04

I get the following errors:


"2007-01-04"

WARNING: FFI::FOREIGN-CALL-OUT: no dynamic object named
"SQLAllocHandle" in library

          :DEFAULT



         Skip foreign object creation

*** - FFI::FOREIGN-CALL-OUT: #<INVALID FOREIGN-POINTER #x00000000>
comes from a previous

      Lisp session and is invalid

This is my main function in case that helps:


(defun his-exe-main ()
  (let ((date (first ext:*args*)))
    (print date)
    (cffi:define-foreign-library clsql_uffi
                                 (t (:default "clsql_uffi")))
    (cffi:use-foreign-library clsql_uffi)
    (setf clsql:*default-database-type* :odbc)
    (clsql:initialize-database-type)
    (clsql:connect '("name of odbc connection and username password
here" :if-exists :WARN-OLD)

    (clsql:enable-sql-reader-syntax)
        (read-oats-csv date "C:\\Oats\\")))

 

Any help would be appricated.

 

Thanks,

 

Parnell
From: Sam Steingold
Subject: Re: CLISP and FFI with saved executables
Date: 
Message-ID: <m3irfgx6s0.fsf@loiso.podval.org>
> * parnell <·············@ebava-pncvgny.pbz> [2007-01-08 13:26:45 -0800]:
>
> I realize this is slightly off topic but I cannot seem to get anyone to
> add me to the clisp-list mailing list to ask this question:
>
>
> I would like to deliver a stand alone application that uses the clsql
> libraries on (WinXP/2003 server, CLISP 2.41, CLSQL 3.8.0).  My
> application works fine when I compile and run it from a repl session
> but when I create the executable like so:
>
>
> (ext:saveinitmem "y:\\appz\\hisexecshares\\hisexecshares.exe"
>                           :init-function #'his-exe-main
>                           :NORC t
>                           :script nil
>                           :executable t
>                           :quiet t)
>
>
> And then run it like so:
>
> Y:\appz\hisexecshares>hisexecshares.exe 2007-01-04
>
> I get the following errors:
>
>
> "2007-01-04"
>
> WARNING: FFI::FOREIGN-CALL-OUT: no dynamic object named
> "SQLAllocHandle" in library
>
>           :DEFAULT
>
>
>
>          Skip foreign object creation
>
> *** - FFI::FOREIGN-CALL-OUT: #<INVALID FOREIGN-POINTER #x00000000>
> comes from a previous Lisp session and is invalid

IIRC, this is a bug the FFI wrapper code (CFFI?) that somehow manages to
create the foreign functions without recording the DLL where the C
counterpart is located, the result being that CLISP cannot re-create the
functions when it starts up from the image.

-- 
Sam Steingold (http://sds.podval.org/) on Fedora Core release 6 (Zod)
http://openvotingconsortium.org http://camera.org http://pmw.org.il
http://israelunderattack.slide.com http://thereligionofpeace.com
If you're being passed on the right, you're in the wrong lane.