1. [SOLVED] Fresh pair of eyes?

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

new topic     » topic index » view message » categorize

2. Re: Fresh pair of eyes?

You could euc it to C and then run a static check tool, like cppcheck, over it the result.

Bugmagnet

new topic     » goto parent     » topic index » view message » categorize

3. Re: Fresh pair of eyes?

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 
new topic     » goto parent     » topic index » view message » categorize

Search



Quick Links

User menu

Not signed in.

Misc Menu