This is the mail archive of the
libstdc++@gcc.gnu.org
mailing list for the libstdc++ project.
Patch: for libstdc++/2071 test case
- To: libstdc++ at gcc dot gnu dot org
- Subject: Patch: for libstdc++/2071 test case
- From: Loren James Rittle <rittle at latour dot rsch dot comm dot mot dot com>
- Date: Thu, 10 May 2001 04:18:49 -0500 (CDT)
- Reply-to: rittle at rsch dot comm dot mot dot com
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