[Python-checkins] CVS: python/dist/src/Objects fileobject.c,2.104,2.105

Tim Peters python-dev@python.org
Sun, 14 Jan 2001 22:33:21 -0800


Update of /cvsroot/python/python/dist/src/Objects
In directory usw-pr-cvs1:/tmp/cvs-serv30235/python/dist/src/Objects

Modified Files:
	fileobject.c 
Log Message:
Use the "MS" getline hack (fgets()) by default on non-get_unlocked
platforms.  See NEWS for details.


Index: fileobject.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Objects/fileobject.c,v
retrieving revision 2.104
retrieving revision 2.105
diff -C2 -r2.104 -r2.105
*** fileobject.c	2001/01/09 21:50:24	2.104
--- fileobject.c	2001/01/15 06:33:19	2.105
***************
*** 636,640 ****
  
  /**************************************************************************
! Win32 MS routine to get next line.
  
  Under MSVC 6:
--- 636,640 ----
  
  /**************************************************************************
! Routine to get next line using platform fgets().
  
  Under MSVC 6:
***************
*** 652,672 ****
  MS realloc is also slow.
  
! In the usual case, we have one pleasantly small line already sitting in a
! stdio buffer, and we optimize heavily for that case.
! 
! CAUTION:  This routine cheats, relying on that MSVC 6 fgets doesn't overwrite
! any buffer positions to the right of the terminating null byte.  Seems
! unlikely that will change in the future, but ... std test test_bufio should
! catch it if that changes.
  **************************************************************************/
  
! /* if Win32 and MS's compiler */
! #if defined(MS_WIN32) && defined(_MSC_VER)
! #define USE_MS_GETLINE_HACK
  #endif
  
! #ifdef USE_MS_GETLINE_HACK
  static PyObject*
! ms_getline_hack(FILE *fp)
  {
  /* INITBUFSIZE is the maximum line length that lets us get away with the fast
--- 652,690 ----
  MS realloc is also slow.
  
! Reports from other platforms on this method vs getc_unlocked (which MS doesn't
! have):
! 	Linux		a wash
! 	Solaris		a wash
! 	Tru64 Unix	getline_via_fgets significantly faster
! 
! CAUTION:  The C std isn't clear about this:  in those cases where fgets
! writes something into the buffer, can it write into any position beyond the
! required trailing null byte?  MSVC 6 fgets does not, and no platform is (yet)
! known on which it does; and it would be a strange way to code fgets. Still,
! getline_via_fgets may not work correctly if it does.  The std test
! test_bufio.py should fail if platform fgets() routinely writes beyond the
! trailing null byte.  #define DONT_USE_FGETS_IN_GETLINE to disable this code.
  **************************************************************************/
+ 
+ /* Use this routine if told to, or by default on non-get_unlocked()
+  * platforms unless told not to.  Yikes!  Let's spell that out:
+  * On a platform with getc_unlocked():
+  *     By default, use getc_unlocked().
+  *     If you want to use fgets() instead, #define USE_FGETS_IN_GETLINE.
+  * On a platform without getc_unlocked():
+  *     By default, use fgets().
+  *     If you don't want to use fgets(), #define DONT_USE_FGETS_IN_GETLINE.
+  */
+ #if !defined(USE_FGETS_IN_GETLINE) && !defined(HAVE_GETC_UNLOCKED)
+ #define USE_FGETS_IN_GETLINE
+ #endif
  
! #if defined(DONT_USE_FGETS_IN_GETLINE) && defined(USE_FGETS_IN_GETLINE)
! #undef USE_FGETS_IN_GETLINE
  #endif
  
! #ifdef USE_FGETS_IN_GETLINE
  static PyObject*
! getline_via_fgets(FILE *fp)
  {
  /* INITBUFSIZE is the maximum line length that lets us get away with the fast
***************
*** 687,698 ****
  	char* pvend;    /* address one beyond last free slot */
  	char* p;	/* temp */
! 	char msbuf[INITBUFSIZE];
  
  	/* Optimize for normal case:  avoid _PyString_Resize if at all
! 	 * possible via first reading into auto msbuf.
  	 */
  	Py_BEGIN_ALLOW_THREADS
! 	memset(msbuf, '\n', INITBUFSIZE);
! 	p = fgets(msbuf, INITBUFSIZE, fp);
  	Py_END_ALLOW_THREADS
  
--- 705,716 ----
  	char* pvend;    /* address one beyond last free slot */
  	char* p;	/* temp */
! 	char buf[INITBUFSIZE];
  
  	/* Optimize for normal case:  avoid _PyString_Resize if at all
! 	 * possible via first reading into auto buf.
  	 */
  	Py_BEGIN_ALLOW_THREADS
! 	memset(buf, '\n', INITBUFSIZE);
! 	p = fgets(buf, INITBUFSIZE, fp);
  	Py_END_ALLOW_THREADS
  
***************
*** 705,709 ****
  	}
  	/* fgets read *something* */
! 	p = memchr(msbuf, '\n', INITBUFSIZE);
  	if (p != NULL) {
  		/* Did the \n come from fgets or from us?
--- 723,727 ----
  	}
  	/* fgets read *something* */
! 	p = memchr(buf, '\n', INITBUFSIZE);
  	if (p != NULL) {
  		/* Did the \n come from fgets or from us?
***************
*** 713,717 ****
  		 * buffer with have only more \n's to the right.
  		 */
! 		pvend = msbuf + INITBUFSIZE;
  		if (p+1 < pvend && *(p+1) == '\0') {
  			/* It's from fgets:  we win!  In particular, we
--- 731,735 ----
  		 * buffer with have only more \n's to the right.
  		 */
! 		pvend = buf + INITBUFSIZE;
  		if (p+1 < pvend && *(p+1) == '\0') {
  			/* It's from fgets:  we win!  In particular, we
***************
*** 719,723 ****
  			 * final result on the first try.
  			 */
! 			v = PyString_FromStringAndSize(msbuf, p - msbuf + 1);
  			return v;
  		}
--- 737,741 ----
  			 * final result on the first try.
  			 */
! 			v = PyString_FromStringAndSize(buf, p - buf + 1);
  			return v;
  		}
***************
*** 726,731 ****
  		 * line of the file.
  		 */
! 		assert(p > msbuf && *(p-1) == '\0');
! 		v = PyString_FromStringAndSize(msbuf, p - msbuf - 1);
  		return v;
  	}
--- 744,749 ----
  		 * line of the file.
  		 */
! 		assert(p > buf && *(p-1) == '\0');
! 		v = PyString_FromStringAndSize(buf, p - buf - 1);
  		return v;
  	}
***************
*** 734,738 ****
  	 * EOF; in either case, we're tired <wink>.
  	 */
! 	assert(msbuf[INITBUFSIZE-1] == '\0');
  	total_v_size = INITBUFSIZE + INCBUFSIZE;
  	v = PyString_FromStringAndSize((char*)NULL, (int)total_v_size);
--- 752,756 ----
  	 * EOF; in either case, we're tired <wink>.
  	 */
! 	assert(buf[INITBUFSIZE-1] == '\0');
  	total_v_size = INITBUFSIZE + INCBUFSIZE;
  	v = PyString_FromStringAndSize((char*)NULL, (int)total_v_size);
***************
*** 740,744 ****
  		return v;
  	/* copy over everything except the last null byte */
! 	memcpy(BUF(v), msbuf, INITBUFSIZE-1);
  	pvfree = BUF(v) + INITBUFSIZE - 1;
  
--- 758,762 ----
  		return v;
  	/* copy over everything except the last null byte */
! 	memcpy(BUF(v), buf, INITBUFSIZE-1);
  	pvfree = BUF(v) + INITBUFSIZE - 1;
  
***************
*** 799,803 ****
  #undef INCBUFSIZE
  }
! #endif	/* ifdef USE_MS_GETLINE_HACK */
  
  /* Internal routine to get a line.
--- 817,821 ----
  #undef INCBUFSIZE
  }
! #endif	/* ifdef USE_FGETS_IN_GETLINE */
  
  /* Internal routine to get a line.
***************
*** 826,833 ****
  	PyObject *v;
  
! #ifdef USE_MS_GETLINE_HACK
! 	
  	if (n <= 0)
! 		return ms_getline_hack(fp);
  #endif
  	n2 = n > 0 ? n : 100;
--- 844,850 ----
  	PyObject *v;
  
! #ifdef USE_FGETS_IN_GETLINE
  	if (n <= 0)
! 		return getline_via_fgets(fp);
  #endif
  	n2 = n > 0 ? n : 100;
***************
*** 968,975 ****
  {
  	static PyObject* xreadlines_function = NULL;
! 	
  	if (!PyArg_ParseTuple(args, ":xreadlines"))
  		return NULL;
! 	
  	if (!xreadlines_function) {
  		PyObject *xreadlines_module =
--- 985,992 ----
  {
  	static PyObject* xreadlines_function = NULL;
! 
  	if (!PyArg_ParseTuple(args, ":xreadlines"))
  		return NULL;
! 
  	if (!xreadlines_function) {
  		PyObject *xreadlines_module =