This is the mail archive of the libstdc++@gcc.gnu.org mailing list for the libstdc++ project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Patch: for libstdc++/2071 test case


Here is a tentative patch for libstdc++/2071 which conforms to the
design for portability I sent earlier.  I expect that some tweaking
will be required based on comments (but please read the design
requirements before complaining about this patch).  libstdc++ was
rebuilt twice on i386-unknown-freebsd4.2 from scratch in an otherwise
fully-bootstrapped tree (gcc version 3.1 20010508).

libstdc++ was rebuilt without _GLIBCPP_AVOID_FSEEK defined.  Of
course, the failure when cin is an interactive stream was still seen
on this platform since the fseek paths in underflow() were still
active.  Other than an implementation class API addition, no port
should see any difference with this patch installed.

Then, the sample port configuration patch [2] was applied to the
FreeBSD version of os_defines.h.  libstdc++ was rebuilt with
_GLIBCPP_AVOID_FSEEK defined.  The code from libstdc++/2071 was seen
to work when cin is an interactive stream.  No additional libstdc++
test suite failures were detected.  Current results:

FAIL: 21_strings/ctor_copy_dtor.cc (execution test), static  
XPASS: 26_numerics/c99_classification_macros_c.cc [...], static  
XPASS: 26_numerics/c99_classification_macros_c.cc [...], shared  

Final comments (restatement of some found in the design overview):
Logically, based upon the analysis of the failure mode and wide
testing of the derived plain C example and its portability-enhanced
version, I think this is the right minimal patch for Solaris as well
as FreeBSD but it relies on a current quirk in implementation.  All
buffers for cin, etc. are set to 1 (is that also true for _CharT ==
wide char?  I wonder if that even works.).  For FreeBSD, it is
probably right to always replace this particular use of fseek() with a
loop over ungetc() or getc() until the count grows somewhat large (you
can do a lot in user space in the time it takes to do 2 OS calls).
For Solaris, we probably shouldn't ever use a loop for pushback counts
over 4 since the manual page is fairly clear that no guarantees are
made beyond 4 on the platform.

This patch has NOT been applied anywhere and should not be until
everyone with a stake has had a chance to comment.

Regards,
Loren

2001-05-10  Loren J. Rittle  <ljrittle@acm.org>

	* config/basic_file_stdio.h (sys_getc): New method.
	(sys_ungetc): New method.
	* include/bits/basic_file.h: (sys_getc): New method signature.
	(sys_ungetc): New method signature.
	* include/bits/fstream.tcc (underflow): Add code paths to
	avoid using short seeks on streams which might be interactive
	or pipes.
	* config/os/bsd/freebsd/bits/os_defines.h (_GLIBCPP_AVOID_FSEEK):
	Define it.

Index: config/basic_file_stdio.h
===================================================================
RCS file: /cvs/gcc/egcs/libstdc++-v3/config/basic_file_stdio.h,v
retrieving revision 1.2
diff -c -r1.2 basic_file_stdio.h
*** basic_file_stdio.h	2001/03/27 03:48:16	1.2
--- basic_file_stdio.h	2001/05/10 08:19:37
***************
*** 93,98 ****
--- 93,112 ----
  
        return __ret;
      }
+ 
+   template<typename _CharT>
+     _CharT
+     __basic_file<_CharT>::sys_getc()
+     {
+       return getc (_M_cfile);
+     }
+ 
+   template<typename _CharT>
+     _CharT
+     __basic_file<_CharT>::sys_ungetc(_CharT __s)
+     {
+       return ungetc (__s, _M_cfile);
+     }
    
    template<typename _CharT>
      __basic_file<_CharT>* 
Index: include/bits/basic_file.h
===================================================================
RCS file: /cvs/gcc/egcs/libstdc++-v3/include/bits/basic_file.h,v
retrieving revision 1.8
diff -c -r1.8 basic_file.h
*** basic_file.h	2001/03/27 03:48:16	1.8
--- basic_file.h	2001/05/10 08:19:37
***************
*** 147,152 ****
--- 147,158 ----
        __basic_file*
        sys_open(__c_file_type* __file, ios_base::openmode __mode);
  
+       _CharT
+       sys_getc();
+ 
+       _CharT
+       sys_ungetc(_CharT);
+ 
        __basic_file* 
        close(); 
  
Index: include/bits/fstream.tcc
===================================================================
RCS file: /cvs/gcc/egcs/libstdc++-v3/include/bits/fstream.tcc,v
retrieving revision 1.13
diff -c -r1.13 fstream.tcc
*** fstream.tcc	2001/05/08 03:07:56	1.13
--- fstream.tcc	2001/05/10 08:19:37
***************
*** 232,237 ****
--- 232,241 ----
  	    {
  	      if (__testout)
  		_M_really_overflow();
+ #if _GLIBCPP_AVOID_FSEEK
+ 	      else if ((_M_in_cur - _M_in_beg) == 1)
+ 		_M_file->sys_getc();
+ #endif
  	      else 
  		_M_file->seekoff(_M_in_cur - _M_in_beg, 
  				 ios_base::cur, ios_base::in);
***************
*** 247,258 ****
--- 251,271 ----
  		  if (__testout)
  		    _M_out_cur = _M_in_cur;
  		  __ret = traits_type::to_int_type(*_M_in_cur);
+ #if _GLIBCPP_AVOID_FSEEK
+ 		  if (__size == 1)
+ 		    _M_file->sys_ungetc(*_M_in_cur);
+ 		  else
+ 		    {
+ #endif
  		  streamoff __p = _M_file->seekoff(0 - __size, ios_base::cur, 
  						   ios_base::in);
  		  if (__p == -1)
  		    {
  		      // XXX Something is wrong, do error checking.
  		    }
+ #if _GLIBCPP_AVOID_FSEEK
+ 		    }
+ #endif
  		}	   
  	    }
  	}

[2] Here is the sample patch to enable the alternate sync style for
ports that absolutely need it:

Index: config/os/bsd/freebsd/bits/os_defines.h
===================================================================
RCS file: /cvs/gcc/egcs/libstdc++-v3/config/os/bsd/freebsd/bits/os_defines.h,v
retrieving revision 1.1
diff -c -r1.1 os_defines.h
*** os_defines.h	2000/12/05 23:25:08	1.1
--- os_defines.h	2001/05/10 08:19:37
***************
*** 35,40 ****
--- 35,41 ----
  /* System-specific #define, typedefs, corrections, etc, go here.  This
     file will come before all others. */
  
+ #define _GLIBCPP_AVOID_FSEEK 1
  
  #endif
  


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]