file-position and string-output-stream

Bug #1839040 reported by Douglas Katzman on 2019-08-05
6
This bug affects 1 person
Affects Status Importance Assigned to Milestone
SBCL
Undecided
Unassigned

Bug Description

FILE-POSITION sometimes crashes on string streams.
It also crashes or has non-obvious behavior in other lisp implementations, so apparently we're not the first to wonder what it's supposed to do.

* (defparameter *s* (make-string-output-stream))
*S*
* (dotimes (i 64) (write-char #\a *s*))
NIL
* (dotimes (i 64) (write-char #\b *s*))
NIL
* (file-position *s* 3)
3
* (file-position *s* 4)

debugger invoked on a TYPE-ERROR in thread
#<THREAD "main thread" RUNNING {10005084C3}>:
  The value
    -60
  is not of type
    SB-INT:INDEX
  when setting slot SB-IMPL::POINTER of structure SB-IMPL::STRING-OUTPUT-STREAM

I think our intent is probably the best among the implementations I tested: you can rewrite portions of the buffer, and GET-OUTPUT-STREAM-STRING will always give you the longest amount you've written or positioned to. It sometimes (or maybe most of the time) behaves that way.

Here are observations in other lisps for the sake of comparison:

CLISP seems to think FILE-POSITION means truncate. You can't set the position to a higher number than you've set it, and GET- returns data up to the the lesser value.

> (file-position *s* 3)
3
> (file-position *s* 4)
*** - FILE-POSITION: index 4 for "aaa" is out of range
The following restarts are available:
ABORT :R1 Abort main loop
Break 1 [5]> :r1
> (Get-output-stream-string *s*)
"aaa"

ECL seems to think it means truncate and/or extend, space-filling as necessary:
> (file-position *s* 3)
T
> (file-position *s* 4)
T
> (Get-output-stream-string *s*)
"aaa "
> (file-position *s* 10)
T
> (Get-output-stream-string *s*)
" "

CCL truncates and/or extends, but uses lingering data from previous output operations:
? (defparameter *s* (make-string-output-stream))
? (dotimes (i 10) (write-char (code-char (+ 64 i)) *s*))
? (get-output-stream-string *s*)
"@ABCDEFGHI"
? (file-position *s* 5)
? (Get-output-stream-string *s*)
"@ABCD"

Also (unrelatedly) I think CLEAR-OUTPUT ought to mean erase the buffer, but it doesn't.

Douglas Katzman (dougk) on 2019-08-05
description: updated
To post a comment you must log in.
This report contains Public information  Edit
Everyone can see this information.

Other bug subscribers