[gfortran] patch for pr15472 and sequential unformatted I/O
Paul Brook
paul@codesourcery.com
Sun Jul 4 15:43:00 GMT 2004
On Sunday 04 July 2004 16:20, Bud Davis wrote:
> On Sun, 2004-07-04 at 08:53, Paul Brook wrote:
> > This looks wrong. We already know (where >= s->buffer_offset).
> > Also s->ndirty = s->ndirty; suggests there's something missing.
> > I guess this is intended to catch overlapping buffers. A comment would be
> > helpful :)
> >
> > > + else if (where>s->dirty_offset && where <
> > > s->ndirty+s->dirty_offset) + ; /* right in the middle, do
> > > nothing */
> >
> > I'm not convinced that this is correct either. What about when
> > (where + *len > s->dirty_offset + s->ndirty)
> >
> > Paul
>
> how about this ?
>
> else
> {
> /* add to the end */
> if (s->dirty_offset + s->ndirty == where)
> s->ndirty += *len;
> /* add to the beginning */
> else if (where + *len == s->dirty_offset)
> {
> s->dirty_offset = where;
> s->ndirty = *len;
s->ndirty = *len + s->ndirty
> }
> /* middle */
> else if (where > s->dirty_offset && where + *len < s->ndirty +
> s->dirty_offset) ; /* do nothing, overwriting data written before */
These could be >= and <=
> else
> fd_flush (s); /* Can't combine two dirty blocks */
Looking again, I think this was already wrong.
You need to set s->dirty_offset and s->ndirty after calling fd_flush.
This may be what was causing the problem.
Better would be to allow arbitary overlapping blocks:
if (s->ndirty == 0
|| where > s->dirty_offset + s->ndirty
|| s->dirty_offset > where + *len)
{
/* Discontiguous blocks, start with a clean buffer. */
/* Flush the buffer. */
if (s->ndirty != 0)
fd_flush (s)
s->dirty_offset = where;
s->ndirty = *len;
}
else
{
gfc_offset start;
/* Merge with the existing data. */
if (where < s->dirty_offset)
start = where;
else
start = s->dirty_offset;
if (where + *len > s->dirty_offset + s->ndirty)
s->ndirty = where + *len - start;
else
s->ndirty = s->dirty_offset + s->ndirty - start;
s->dirty_offset = start;
}
Paul
More information about the Fortran
mailing list