[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