port-position on custom ports give wrong answers

Bug #251642 reported by Michael D. Adams
2
Affects Status Importance Assigned to Milestone
Ikarus Scheme
Fix Committed
Low
Abdulaziz Ghuloum

Bug Description

I think you got some of the arithmetic in accounting for custom port buffers backwards.

$ ./src/ikarus -b ./scheme/ikarus.boot
Ikarus Scheme version 0.0.3+ (revision 1549, build 2008-07-23)
> (define p (let ([pos 0]) (make-custom-binary-input-port "foo" (lambda (bv s c) (set! pos (+ pos c)) c) (lambda () pos) (lambda (x) (set! pos x)) #f)))
> (port-position p)
0
> (get-u8 p)
255
> (port-position p)
257

The last result should have been 1.

Related branches

Revision history for this message
Abdulaziz Ghuloum (aghuloum) wrote : Re: [Bug 251642] [NEW] port-position on custom ports give wrong answers

On Jul 24, 2008, at 3:05 PM, Michael D. Adams wrote:

> I think you got some of the arithmetic in accounting for custom port
> buffers backwards.

I agree that this is incorrect, but what's the correct behavior?

On the one hand, the IO system can fully keep track of the position
since it knows how many bytes have been read into the buffer and how
many bytes have been consumed by get-u8, so, the port position is
always known. (this is how the file-based ports know their position;
they never use lseek or whatever to compute the current position)
So, can port-position simply bypass the given procedure and always
return some internally computed value?

Either way, we can get this to work for binary ports since the given
procedure is required to return an integer and with some arithmetic
we can get the right answer. But what about textual ports? Since
the get-position procedure may return "a single value" without any
restrictions on what that value may be, we cannot use that value to
compute the actual position of the port. It seems that we cannot
buffer custom textual ports. But we have to buffer at least one
character to support lookahead-char! In that case, we have to get
the port position before we do a lookahead-char, cache it just in
case we get asked for it, and throw it away when we do a get-char.
So, can the implementation call the supplied get-position procedure
before lookahead-char and even if the user did not call port-positon?

Any ideas for how to resolve this interesting problem?

Revision history for this message
Abdulaziz Ghuloum (aghuloum) wrote :

Example: no implementation of R6RS runs the following program:

#!r6rs
(import (rnrs))
(let ([p
       (let ([pos 0])
         (define-record-type P (fields pos))
         (make-custom-textual-input-port "foo"
           (lambda (s i c) (set! pos (+ pos c)) c)
           (lambda () (make-P pos))
           (lambda (x) (set! pos (P-pos x)))
           (lambda () (display "done\n"))))])
  (lookahead-char p)
  (port-position p))

Revision history for this message
Abdulaziz Ghuloum (aghuloum) wrote :

Counting is fixed in revision 1553, though all issues are still standing.

Revision history for this message
Michael D. Adams (mdmkolbe) wrote :

Yes, the custom ports interface has problems. For binary custom ports where both get-position and set-position are provided it is possible (though ikcy) to work around the problems. This is one area that you, Kent, and Will Clinger agree on. You just kind of have to work make it work where you can and not worry about the rest.

Revision history for this message
Abdulaziz Ghuloum (aghuloum) wrote :

Closing since I fixed it for the simple case that you mentioned.

Changed in ikarus:
assignee: nobody → aghuloum
importance: Undecided → Low
status: New → Fix Committed
Changed in ikarus:
milestone: none → 0.0.4
To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.