summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Include/fileobject.h10
-rw-r--r--Objects/fileobject.c84
2 files changed, 52 insertions, 42 deletions
diff --git a/Include/fileobject.h b/Include/fileobject.h
index d696475..6c34223 100644
--- a/Include/fileobject.h
+++ b/Include/fileobject.h
@@ -41,7 +41,7 @@ extern DL_IMPORT(int) PyFile_WriteString(const char *, PyObject *);
extern DL_IMPORT(int) PyObject_AsFileDescriptor(PyObject *);
/* The default encoding used by the platform file system APIs
- If non-NULL, this is different than the default encoding for strings
+ If non-NULL, this is different than the default encoding for strings
*/
extern DL_IMPORT(const char *) Py_FileSystemDefaultEncoding;
@@ -51,12 +51,12 @@ extern DL_IMPORT(const char *) Py_FileSystemDefaultEncoding;
*/
#define PY_STDIOTEXTMODE "b"
char *Py_UniversalNewlineFgets(char *, int, FILE*, PyObject *);
-size_t Py_UniversalNewlineFread(void *, size_t, FILE *, PyObject *);
+size_t Py_UniversalNewlineFread(char *, size_t, FILE *, PyObject *);
#else
#define PY_STDIOTEXTMODE ""
-#define Py_UniversalNewlineFgets(buf, len, fp, obj) (fgets((buf), (len), (fp)))
-#define Py_UniversalNewlineFread(buf, len, fp, obj) \
- (fread((buf), 1, (len), (fp)))
+#define Py_UniversalNewlineFgets(buf, len, fp, obj) fgets((buf), (len), (fp))
+#define Py_UniversalNewlineFread(buf, len, fp, obj)
+ fread((buf), 1, (len), (fp))
#endif /* WITH_UNIVERSAL_NEWLINES */
#ifdef __cplusplus
}
diff --git a/Objects/fileobject.c b/Objects/fileobject.c
index 152ba1a..044dfd8 100644
--- a/Objects/fileobject.c
+++ b/Objects/fileobject.c
@@ -1228,7 +1228,7 @@ file_readlines(PyFileObject *f, PyObject *args)
else {
Py_BEGIN_ALLOW_THREADS
errno = 0;
- nread = Py_UniversalNewlineFread(buffer+nfilled,
+ nread = Py_UniversalNewlineFread(buffer+nfilled,
buffersize-nfilled, f->f_fp, (PyObject *)f);
Py_END_ALLOW_THREADS
shortread = (nread < buffersize-nfilled);
@@ -1943,7 +1943,7 @@ Py_UniversalNewlineFgets(char *buf, int n, FILE *stream, PyObject *fobj)
int newlinetypes = 0;
int skipnextlf = 0;
int univ_newline = 1;
-
+
if (fobj) {
if (!PyFile_Check(fobj)) {
errno = ENXIO; /* What can you do... */
@@ -2024,61 +2024,71 @@ Py_UniversalNewlineFgets(char *buf, int n, FILE *stream, PyObject *fobj)
** the different types of newlines seen.
*/
size_t
-Py_UniversalNewlineFread(void *buf, size_t n,
+Py_UniversalNewlineFread(char *buf, size_t n,
FILE *stream, PyObject *fobj)
{
- char *src = buf, *dst = buf, c;
- int nread, ntodo=n;
- int newlinetypes, skipnextlf, univ_newline;
-
+ 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;
}
- univ_newline = ((PyFileObject *)fobj)->f_univ_newline;
- if ( !univ_newline )
+ if (!f->f_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++;
+ 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 CR as LF and set flag to skip next newline
- */
+ /* Save as LF and set flag to skip next LF. */
*dst++ = '\n';
+ --n;
skipnextlf = 1;
- } else if (skipnextlf && c == '\n') {
- /* Skip an LF, and remember that we saw CR LF
- */
+ }
+ 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.
- */
+ }
+ 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;
else if (skipnextlf)
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;
+ }
}
- ((PyFileObject *)fobj)->f_newlinetypes = newlinetypes;
- ((PyFileObject *)fobj)->f_skipnextlf = skipnextlf;
- return dst - (char *)buf;
+ f->f_newlinetypes = newlinetypes;
+ f->f_skipnextlf = skipnextlf;
+ return dst - buf;
}
#endif