Mail Archives: djgpp/1996/02/18/08:19:56
On 15 Feb 1996, Robert Hoehne wrote:
> Patch 2.1 from DJGPP V2.0 doesn't work
[snipp]
> Hmm... Looks like a new-style context diff to me...
> Exiting due to signal SIGABRT
> Assertion failed at pch.c line 409: p_base <= file_pos
>
>
> I think, this is only an error in compiling patch.
No, it's a bug in the library function `ftell' (unless I didn't understand
its code). It incorrectly assumes that, for files open for reading, the
position returned by `lseek (file, 0L, SEEK_CUR)' corresponds to the
*beginning* of the buffered portion of the file. The truth is, that it
corresponds to the *end* of that buffered portion. Below please find a
patch to fix this problem. When linked with the fixed version of `ftell',
`patch' works under v2.0 (at least for the simple test submitted by
Robert). The test program `fseek' from djtst200.zip also succeeds with
the fixed version of `ftell', except with Unix-style text files (without a
CR before each NL) in TEXT mode. The original code also failed in that
case, and IMHO there is no way to make it work unless some low-level
library function (like `filbuf') detects that this is a Unix-style file
and sets a flag which could be tested by `ftell'. DJ, can we make such a
change? I can submit it, if we decide to do it (but then I already
submitted it once and it wasn't installed ;-).
*** ansi/stdio/ftell.c~0 Mon Feb 5 00:13:42 1996
--- ansi/stdio/ftell.c Sun Feb 18 14:35:22 1996
***************
*** 17,44 ****
f->_cnt = 0;
if (f->_flag&_IOREAD)
{
if (__file_handle_modes[f->_file] & O_TEXT) /* if a text file */
{
! if (f->_cnt && f->_ptr != f->_base)
{
char *cp;
! adjust = - f->_bufsiz + (f->_ptr-f->_base);
! for (cp=f->_base; cp < f->_ptr; cp++) /* for every char in buf */
! if (*cp == '\n') /* if it's LF */
! adjust++; /* there was a CR also */
}
}
- else
- adjust = - f->_cnt;
}
else if (f->_flag&(_IOWRT|_IORW))
{
! adjust = 0;
if (f->_flag&_IOWRT && f->_base && (f->_flag&_IONBF)==0)
{
! adjust = f->_ptr - f->_base;
if (__file_handle_modes[f->_file] & O_TEXT)
! for (idx=0; idx<adjust; idx++)
if (f->_base[idx] == '\n')
adjust++;
}
--- 17,55 ----
f->_cnt = 0;
if (f->_flag&_IOREAD)
{
+ /* When reading files, the file position known by `lseek' is
+ at the end of the buffered portion of the file. So `adjust'
+ is negative (current buf position is BEFORE the one returned
+ by `lseek') and, for TEXT files, it gets decremented (larger
+ in absolute value) for every NL from current pos to the end
+ of the buffer, to account for stripped CR characters. */
+ adjust = - f->_cnt;
+
if (__file_handle_modes[f->_file] & O_TEXT) /* if a text file */
{
! if (f->_cnt)
{
char *cp;
!
! /* For every char in buf AFTER current pos... */
! for (cp=f->_ptr + f->_cnt - 1; cp >= f->_ptr; cp--)
! if (*cp == '\n') /* ...if it's LF... */
! adjust--; /* ...there was a CR also */
}
}
}
else if (f->_flag&(_IOWRT|_IORW))
{
! /* When writing a file, the current file position known by `lseek'
! is at the beginning of the buffered portion of the file. We
! have to adjust it by our offset from the beginning of the buffer,
! and account for the CR characters which will be added by `write'. */
if (f->_flag&_IOWRT && f->_base && (f->_flag&_IONBF)==0)
{
! int lastidx = adjust = f->_ptr - f->_base;
!
if (__file_handle_modes[f->_file] & O_TEXT)
! for (idx=0; idx < lastidx; idx++)
if (f->_base[idx] == '\n')
adjust++;
}
- Raw text -