[Python-checkins] CVS: python/dist/src/Objects fileobject.c,2.96,2.97
Guido van Rossum
python-dev@python.org
Fri, 05 Jan 2001 06:43:07 -0800
Update of /cvsroot/python/python/dist/src/Objects
In directory usw-pr-cvs1:/tmp/cvs-serv3183
Modified Files:
fileobject.c
Log Message:
Restructured get_line() for clarity and speed.
- The raw_input() functionality is moved to a separate function.
- Drop GNU getline() in favor of getc_unlocked(), which exists on more
platforms (and is even a tad faster on my system).
Index: fileobject.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Objects/fileobject.c,v
retrieving revision 2.96
retrieving revision 2.97
diff -C2 -r2.96 -r2.97
*** fileobject.c 2000/12/20 00:55:07 2.96
--- fileobject.c 2001/01/05 14:43:05 2.97
***************
*** 640,686 ****
> 0: max length;
= 0: read arbitrary line;
! < 0: strip trailing '\n', raise EOFError if EOF reached immediately
*/
static PyObject *
get_line(PyFileObject *f, int n)
{
! register FILE *fp = f->f_fp;
! register int c;
char *buf, *end;
size_t n1, n2;
PyObject *v;
- #if defined(HAVE_GETLINE) && defined(_GNU_SOURCE)
- /* Use GNU libc extension getline() for arbitrary-sized lines */
- if (n == 0) {
- size_t size = 0;
- buf = NULL;
- Py_BEGIN_ALLOW_THREADS
- n1 = getline(&buf, &size, fp);
- Py_END_ALLOW_THREADS
- if (n1 == -1) {
- if (buf){
- free(buf);
- }
- clearerr(fp);
- if (PyErr_CheckSignals()) {
- return NULL;
- }
- if (n < 0 && feof(fp)) {
- PyErr_SetString(PyExc_EOFError,
- "EOF when reading a line");
- return NULL;
- }
- return PyString_FromStringAndSize(NULL, 0);
- }
- /* No error */
-
- v = PyString_FromStringAndSize(buf, n1);
- free(buf);
- return v;
- }
- #endif
-
n2 = n > 0 ? n : 100;
v = PyString_FromStringAndSize((char *)NULL, n2);
--- 640,665 ----
> 0: max length;
= 0: read arbitrary line;
! < 0: illegal (use get_line_raw() instead)
*/
+ #ifdef HAVE_GETC_UNLOCKED
+ #define GETC(f) getc_unlocked(f)
+ #define FLOCKFILE(f) flockfile(f)
+ #define FUNLOCKFILE(f) funlockfile(f)
+ #else
+ #define GETC(f) getc(f)
+ #define FLOCKFILE(f)
+ #define FUNLOCKFILE(f)
+ #endif
+
static PyObject *
get_line(PyFileObject *f, int n)
{
! FILE *fp = f->f_fp;
! int c;
char *buf, *end;
size_t n1, n2;
PyObject *v;
n2 = n > 0 ? n : 100;
v = PyString_FromStringAndSize((char *)NULL, n2);
***************
*** 690,735 ****
end = buf + n2;
- Py_BEGIN_ALLOW_THREADS
for (;;) {
! if ((c = getc(fp)) == EOF) {
clearerr(fp);
- Py_BLOCK_THREADS
if (PyErr_CheckSignals()) {
Py_DECREF(v);
return NULL;
}
- if (n < 0 && buf == BUF(v)) {
- Py_DECREF(v);
- PyErr_SetString(PyExc_EOFError,
- "EOF when reading a line");
- return NULL;
- }
- Py_UNBLOCK_THREADS
break;
}
! if ((*buf++ = c) == '\n') {
! if (n < 0)
! buf--;
break;
! }
! if (buf == end) {
! if (n > 0)
! break;
! n1 = n2;
! n2 += 1000;
! if (n2 > INT_MAX) {
! PyErr_SetString(PyExc_OverflowError,
! "line is longer than a Python string can hold");
! return NULL;
! }
! Py_BLOCK_THREADS
! if (_PyString_Resize(&v, n2) < 0)
! return NULL;
! Py_UNBLOCK_THREADS
! buf = BUF(v) + n1;
! end = BUF(v) + n2;
}
}
- Py_END_ALLOW_THREADS
n1 = buf - BUF(v);
--- 669,706 ----
end = buf + n2;
for (;;) {
! Py_BEGIN_ALLOW_THREADS
! FLOCKFILE(fp);
! while ((c = GETC(fp)) != EOF &&
! (*buf++ = c) != '\n' &&
! buf != end)
! ;
! FUNLOCKFILE(fp);
! Py_END_ALLOW_THREADS
! if (c == '\n')
! break;
! if (c == EOF) {
clearerr(fp);
if (PyErr_CheckSignals()) {
Py_DECREF(v);
return NULL;
}
break;
}
! /* Must be because buf == end */
! if (n > 0)
break;
! n1 = n2;
! n2 += 1000;
! if (n2 > INT_MAX) {
! PyErr_SetString(PyExc_OverflowError,
! "line is longer than a Python string can hold");
! return NULL;
}
+ if (_PyString_Resize(&v, n2) < 0)
+ return NULL;
+ buf = BUF(v) + n1;
+ end = BUF(v) + n2;
}
n1 = buf - BUF(v);
***************
*** 739,742 ****
--- 710,732 ----
}
+ /* Internal routine to get a line for raw_input():
+ strip trailing '\n', raise EOFError if EOF reached immediately
+ */
+
+ static PyObject *
+ get_line_raw(PyFileObject *f)
+ {
+ PyObject *line;
+
+ line = get_line(f, 0);
+ if (line == NULL || PyString_GET_SIZE(line) > 0)
+ return line;
+ else {
+ Py_DECREF(line);
+ PyErr_SetString(PyExc_EOFError, "EOF when reading a line");
+ return NULL;
+ }
+ }
+
/* External C interface */
***************
*** 797,801 ****
if (((PyFileObject*)f)->f_fp == NULL)
return err_closed();
! return get_line((PyFileObject *)f, n);
}
--- 787,794 ----
if (((PyFileObject*)f)->f_fp == NULL)
return err_closed();
! if (n < 0)
! return get_line_raw((PyFileObject *)f);
! else
! return get_line((PyFileObject *)f, n);
}