1. [SOLVED] Fresh pair of eyes?
- Posted by petelomax Feb 15, 2017
- 1196 views
- Last edited Feb 16, 2017
There is a bug somewhere in the Phix file buffer handling, which I have replicated (in OE-compatible hll) as follows:
constant -- BUFFERSIZE = 8192 BUFFERSIZE = 16 sequence cbuffer = repeat('Z',32) -- bit settings for fmode: constant F_CLOSED = #00, -- file is closed/available for re-use F_WRITE = #02, -- file has write permission F_BINARY = #04, -- binary mode F_DIRTY = #08 -- write cache flag atom frealposn -- actual file position. NB when F_DIRTY is set, this must exactly -- correspond to fbuffer[1]. atom fmode, fposn, fend sequence fbuffer -- If fmode has the F_DIRTY bit set, then frealposn corresponds to the start -- of fbuffer, otherwise it corresponds to the fend of the fbuffer. -- A fposn of 1 and fend of 0 is the standard "empty" state. procedure h_open() fbuffer = repeat(' ',BUFFERSIZE) fmode = F_BINARY+F_WRITE fposn = 1 fend = 0 frealposn = 0 end procedure procedure flushfidx() if fend then for i=1 to fend do cbuffer[frealposn+i] = fbuffer[i] end for frealposn += fend end if end procedure procedure h_close() -- -- Close and flush out any still-buffered characters. -- -- if fn>=3 then --DEV: -- if fmode then -- if fmode!=F_CLOSED then if and_bits(fmode,F_DIRTY) then flushfidx() end if fmode = F_CLOSED -- clear mode, mark as closed -- end if -- end if end procedure function h_seek(atom pos) integer fposn2 if and_bits(fmode,F_DIRTY) then -- realposn corresponds to the \\start\\ of the buffer, -- and we can extend/write beyond fend upto BUFFERSIZE. fposn2 = pos-frealposn+1 if fposn2>=1 and fposn2<=BUFFERSIZE and fposn2<=fend+1 then fposn = fposn2 return 0 end if fmode -= F_DIRTY flushfidx() else -- realposn corresponds to the \\end\\ of the buffer, but -- in this case fend is the hard limit of readable bytes. fposn2 = pos-(frealposn-fend)+1 if fposn2>=1 and fposn2<=fend then fposn = fposn2 return 0 end if end if fend = 0 fposn = 1 frealposn = pos return 0 end function procedure h_puts(sequence x) integer lx, newend integer fend2 integer fposn2 fposn2 = fposn fend2 = fend if not and_bits(fmode,F_DIRTY) then fmode = or_bits(fmode,F_DIRTY) fposn2 = 1 fend2 = 0 end if lx = length(x) -- will it fit in the buffer? newend = fposn2+lx-1 if newend<=BUFFERSIZE then fbuffer[fposn2..newend] = x fposn2 += lx fposn = fposn2 if newend>fend2 then fend = newend end if else if fend2 then fmode -= F_DIRTY flushfidx() fend = 0 fposn = 1 end if for i=1 to lx do cbuffer[frealposn+i] = x[i] end for frealposn += lx end if end procedure sequence trace3 = join({ "X", " ", "=", " ", " ", " ",},"\r\n") h_open() h_puts(trace3) if h_seek(3)!=SEEK_OK then ?9/0 end if h_puts(trace3) h_close() ?cbuffer
The above (wrongly) prints
"X\r\n \r\n=\r\n \r\n \r\n X\r\n \r\n=\r\n \r\n \r\n "
but if I change BUFFERSIZE to 8192 i get:
"X\r\nX\r\n \r\n=\r\n \r\n \r\n ZZZZZZZZZZZZZ"
which is correct, the second X being 3 bytes on from the first as desired.
I should really be able to fix this in my sleep, but you know how it goes sometimes...
(Maybe my need for some "deep understanding" of the logic error, rather than just making it work, is creating a mental block.)
Any help appreciated,
Pete
2. Re: Fresh pair of eyes?
- Posted by bugmagnet Feb 16, 2017
- 1169 views
You could euc it to C and then run a static check tool, like cppcheck, over it the result.
Bugmagnet
3. Re: Fresh pair of eyes?
- Posted by petelomax Feb 16, 2017
- 1168 views
- Last edited Feb 17, 2017
I knew it would be something trivial.
In flushfidx():
-- frealposn += fend frealposn += fposn
EDIT: spoke a bit too soon, more like
frealposn += fend -- frealposn += fposn if fposn<=fend then --(seek) integer back = fend-fposn+1 frealposn -= back end if