Mailing List Archive

python/dist/src/Objects fileobject.c,2.158,2.159
Update of /cvsroot/python/python/dist/src/Objects
In directory usw-pr-cvs1:/tmp/cvs-serv23161/Objects

Modified Files:
fileobject.c
Log Message:
Py_UniversalNewlineFread(): Many changes.

+ Continued looping until n bytes in the buffer have been filled, not
just when n bytes have been read from the file. This repairs the
bug that f.readlines() only sucked up the first 8192 bytes of the file
on Windows when universal newlines was enabled and f was opened in
U mode (see Python-Dev -- this was the ultimate cause of the
test_inspect.py failure).

+ Changed prototye to take a char* buffer (void* doesn't make much sense).

+ Squashed size_t vs int mismatches (in particular, besides the unsigned
vs signed distinction, size_t may be larger than int).

+ Gets out under all error conditions now (it's possible for fread() to
suffer an error even if it returns a number larger than 0 -- any
"short read" is an error or EOF condition).

+ Rearranged and simplified declarations.


Index: fileobject.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Objects/fileobject.c,v
retrieving revision 2.158
retrieving revision 2.159
diff -C2 -d -r2.158 -r2.159
*** fileobject.c 14 Apr 2002 20:12:40 -0000 2.158
--- fileobject.c 21 Apr 2002 07:29:14 -0000 2.159
***************
*** 1229,1233 ****
Py_BEGIN_ALLOW_THREADS
errno = 0;
! nread = Py_UniversalNewlineFread(buffer+nfilled,
buffersize-nfilled, f->f_fp, (PyObject *)f);
Py_END_ALLOW_THREADS
--- 1229,1233 ----
Py_BEGIN_ALLOW_THREADS
errno = 0;
! nread = Py_UniversalNewlineFread(buffer+nfilled,
buffersize-nfilled, f->f_fp, (PyObject *)f);
Py_END_ALLOW_THREADS
***************
*** 1944,1948 ****
int skipnextlf = 0;
int univ_newline = 1;
!
if (fobj) {
if (!PyFile_Check(fobj)) {
--- 1944,1948 ----
int skipnextlf = 0;
int univ_newline = 1;
!
if (fobj) {
if (!PyFile_Check(fobj)) {
***************
*** 2025,2072 ****
*/
size_t
! Py_UniversalNewlineFread(void *buf, size_t n,
FILE *stream, PyObject *fobj)
{
! char *src = buf, *dst = buf, c;
! int nread, ntodo=n;
! int newlinetypes, skipnextlf, univ_newline;
!
if (!fobj || !PyFile_Check(fobj)) {
errno = ENXIO; /* What can you do... */
return -1;
}
! univ_newline = ((PyFileObject *)fobj)->f_univ_newline;
! if ( !univ_newline )
return fread(buf, 1, n, stream);
! newlinetypes = ((PyFileObject *)fobj)->f_newlinetypes;
! skipnextlf = ((PyFileObject *)fobj)->f_skipnextlf;
! while (ntodo > 0) {
! if (ferror(stream))
! break;
! nread = fread(dst, 1, ntodo, stream);
! src = dst;
! if (nread <= 0) {
! if (skipnextlf)
! newlinetypes |= NEWLINE_CR;
! break;
! }
! ntodo -= nread;
! while ( nread-- ) {
! c = *src++;
if (c == '\r') {
! /* Save CR as LF and set flag to skip next newline
! */
*dst++ = '\n';
skipnextlf = 1;
! } else if (skipnextlf && c == '\n') {
! /* Skip an LF, and remember that we saw CR LF
! */
skipnextlf = 0;
newlinetypes |= NEWLINE_CRLF;
! } else {
! /* Normal char to be stored in buffer. Also update
! ** the newlinetypes flag if either this is an LF
! ** or the previous char was a CR.
! */
if (c == '\n')
newlinetypes |= NEWLINE_LF;
--- 2025,2075 ----
*/
size_t
! Py_UniversalNewlineFread(char *buf, size_t n,
FILE *stream, PyObject *fobj)
{
! char *dst = buf;
! PyFileObject *f = (PyFileObject *)fobj;
! int newlinetypes, skipnextlf;
!
! assert(buf != NULL);
! assert(stream != NULL);
!
if (!fobj || !PyFile_Check(fobj)) {
errno = ENXIO; /* What can you do... */
return -1;
}
! if (!f->f_univ_newline)
return fread(buf, 1, n, stream);
! newlinetypes = f->f_newlinetypes;
! skipnextlf = f->f_skipnextlf;
! /* Invariant: n is the number of bytes remaining to be filled
! * in the buffer.
! */
! while (n) {
! size_t nread;
! int shortread;
! char *src = dst;
!
! nread = fread(dst, 1, n, stream);
! assert(nread <= n);
! shortread = nread != n; /* true iff EOF or error */
! while (nread--) {
! char c = *src++;
if (c == '\r') {
! /* Save as LF and set flag to skip next LF. */
*dst++ = '\n';
+ --n;
skipnextlf = 1;
! }
! else if (skipnextlf && c == '\n') {
! /* Skip LF, and remember we saw CR LF. */
skipnextlf = 0;
newlinetypes |= NEWLINE_CRLF;
! }
! else {
! /* Normal char to be stored in buffer. Also
! * update the newlinetypes flag if either this
! * is an LF or the previous char was a CR.
! */
if (c == '\n')
newlinetypes |= NEWLINE_LF;
***************
*** 2074,2084 ****
newlinetypes |= NEWLINE_CR;
*dst++ = c;
skipnextlf = 0;
}
}
}
! ((PyFileObject *)fobj)->f_newlinetypes = newlinetypes;
! ((PyFileObject *)fobj)->f_skipnextlf = skipnextlf;
! return dst - (char *)buf;
}
#endif
--- 2077,2094 ----
newlinetypes |= NEWLINE_CR;
*dst++ = c;
+ --n;
skipnextlf = 0;
}
}
+ if (shortread) {
+ /* If this is EOF, update type flags. */
+ if (skipnextlf && feof(stream))
+ newlinetypes |= NEWLINE_CR;
+ break;
+ }
}
! f->f_newlinetypes = newlinetypes;
! f->f_skipnextlf = skipnextlf;
! return dst - buf;
}
#endif