aboutsummaryrefslogtreecommitdiff
path: root/libstdc++-v3
diff options
context:
space:
mode:
authorPaolo Carlini <pcarlini@suse.de>2004-08-25 23:38:29 +0000
committerPaolo Carlini <paolo@gcc.gnu.org>2004-08-25 23:38:29 +0000
commitcb7930898721b14def216a5cf3b8bd619b1dbc52 (patch)
treecd9586c361c21f24a5b329f3c983a4a4701cc9b9 /libstdc++-v3
parent6d1c50cce40910b7015fefa7ce6c632c750bda22 (diff)
downloadgcc-cb7930898721b14def216a5cf3b8bd619b1dbc52.zip
gcc-cb7930898721b14def216a5cf3b8bd619b1dbc52.tar.gz
gcc-cb7930898721b14def216a5cf3b8bd619b1dbc52.tar.bz2
PR libstdc++/17038 (partial)
2004-08-25 Paolo Carlini <pcarlini@suse.de> PR libstdc++/17038 (partial) * include/bits/locale_facets.tcc (time_put<>::do_put): Increase __maxlen to 128. * include/bits/locale_facets.h (class __timepunct): Add FIXME comment about _M_put. * config/locale/generic/time_members.cc (_M_put): Always null terminate __s. * config/locale/gnu/time_members.cc (_M_put): Likewise. * testsuite/22_locale/time_put/put/char/17038.cc: New. * testsuite/22_locale/time_put/put/wchar_t/17038.cc: New. From-SVN: r86586
Diffstat (limited to 'libstdc++-v3')
-rw-r--r--libstdc++-v3/ChangeLog13
-rw-r--r--libstdc++-v3/config/locale/generic/time_members.cc10
-rw-r--r--libstdc++-v3/config/locale/gnu/time_members.cc16
-rw-r--r--libstdc++-v3/include/bits/locale_facets.h2
-rw-r--r--libstdc++-v3/include/bits/locale_facets.tcc2
-rw-r--r--libstdc++-v3/testsuite/22_locale/time_put/put/char/17038.cc63
-rw-r--r--libstdc++-v3/testsuite/22_locale/time_put/put/wchar_t/17038.cc63
7 files changed, 162 insertions, 7 deletions
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog
index 94abb59..9a21c1f 100644
--- a/libstdc++-v3/ChangeLog
+++ b/libstdc++-v3/ChangeLog
@@ -1,3 +1,16 @@
+2004-08-25 Paolo Carlini <pcarlini@suse.de>
+
+ PR libstdc++/17038 (partial)
+ * include/bits/locale_facets.tcc (time_put<>::do_put): Increase
+ __maxlen to 128.
+ * include/bits/locale_facets.h (class __timepunct): Add FIXME
+ comment about _M_put.
+ * config/locale/generic/time_members.cc (_M_put): Always null
+ terminate __s.
+ * config/locale/gnu/time_members.cc (_M_put): Likewise.
+ * testsuite/22_locale/time_put/put/char/17038.cc: New.
+ * testsuite/22_locale/time_put/put/wchar_t/17038.cc: New.
+
2004-08-24 Paolo Carlini <pcarlini@suse.de>
* testsuite/27_io/basic_istringstream/rdbuf/wchar_t/2832.cc: New.
diff --git a/libstdc++-v3/config/locale/generic/time_members.cc b/libstdc++-v3/config/locale/generic/time_members.cc
index 6e2f755..f27b2a0 100644
--- a/libstdc++-v3/config/locale/generic/time_members.cc
+++ b/libstdc++-v3/config/locale/generic/time_members.cc
@@ -46,9 +46,12 @@ namespace std
{
char* __old = strdup(setlocale(LC_ALL, NULL));
setlocale(LC_ALL, _M_name_timepunct);
- strftime(__s, __maxlen, __format, __tm);
+ const size_t __len = strftime(__s, __maxlen, __format, __tm);
setlocale(LC_ALL, __old);
free(__old);
+ // Make sure __s is null terminated.
+ if (__len == 0)
+ __s[0] = '\0';
}
template<>
@@ -125,9 +128,12 @@ namespace std
{
char* __old = strdup(setlocale(LC_ALL, NULL));
setlocale(LC_ALL, _M_name_timepunct);
- wcsftime(__s, __maxlen, __format, __tm);
+ const size_t __len = wcsftime(__s, __maxlen, __format, __tm);
setlocale(LC_ALL, __old);
free(__old);
+ // Make sure __s is null terminated.
+ if (__len == 0)
+ __s[0] = L'\0';
}
template<>
diff --git a/libstdc++-v3/config/locale/gnu/time_members.cc b/libstdc++-v3/config/locale/gnu/time_members.cc
index 440f0b7a..1d12e80 100644
--- a/libstdc++-v3/config/locale/gnu/time_members.cc
+++ b/libstdc++-v3/config/locale/gnu/time_members.cc
@@ -46,14 +46,18 @@ namespace std
const tm* __tm) const
{
#if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 2)
- __strftime_l(__s, __maxlen, __format, __tm, _M_c_locale_timepunct);
+ const size_t __len = __strftime_l(__s, __maxlen, __format, __tm,
+ _M_c_locale_timepunct);
#else
char* __old = strdup(setlocale(LC_ALL, NULL));
setlocale(LC_ALL, _M_name_timepunct);
- strftime(__s, __maxlen, __format, __tm);
+ const size_t __len = strftime(__s, __maxlen, __format, __tm);
setlocale(LC_ALL, __old);
free(__old);
#endif
+ // Make sure __s is null terminated.
+ if (__len == 0)
+ __s[0] = '\0';
}
template<>
@@ -195,14 +199,18 @@ namespace std
const tm* __tm) const
{
#if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 2)
- __wcsftime_l(__s, __maxlen, __format, __tm, _M_c_locale_timepunct);
+ const size_t __len = __wcsftime_l(__s, __maxlen, __format, __tm,
+ _M_c_locale_timepunct);
#else
char* __old = strdup(setlocale(LC_ALL, NULL));
setlocale(LC_ALL, _M_name_timepunct);
- wcsftime(__s, __maxlen, __format, __tm);
+ const size_t __len = wcsftime(__s, __maxlen, __format, __tm);
setlocale(LC_ALL, __old);
free(__old);
#endif
+ // Make sure __s is null terminated.
+ if (__len == 0)
+ __s[0] = L'\0';
}
template<>
diff --git a/libstdc++-v3/include/bits/locale_facets.h b/libstdc++-v3/include/bits/locale_facets.h
index 60db8a4..193733f 100644
--- a/libstdc++-v3/include/bits/locale_facets.h
+++ b/libstdc++-v3/include/bits/locale_facets.h
@@ -2834,6 +2834,8 @@ namespace std
explicit
__timepunct(__c_locale __cloc, const char* __s, size_t __refs = 0);
+ // FIXME: for error checking purposes _M_put should return the return
+ // value of strftime/wcsftime.
void
_M_put(_CharT* __s, size_t __maxlen, const _CharT* __format,
const tm* __tm) const;
diff --git a/libstdc++-v3/include/bits/locale_facets.tcc b/libstdc++-v3/include/bits/locale_facets.tcc
index 1aea83a..f7a9564 100644
--- a/libstdc++-v3/include/bits/locale_facets.tcc
+++ b/libstdc++-v3/include/bits/locale_facets.tcc
@@ -2246,7 +2246,7 @@ namespace std
// NB: This size is arbitrary. Should this be a data member,
// initialized at construction?
- const size_t __maxlen = 64;
+ const size_t __maxlen = 128;
char_type* __res =
static_cast<char_type*>(__builtin_alloca(sizeof(char_type) * __maxlen));
diff --git a/libstdc++-v3/testsuite/22_locale/time_put/put/char/17038.cc b/libstdc++-v3/testsuite/22_locale/time_put/put/char/17038.cc
new file mode 100644
index 0000000..39071e6
--- /dev/null
+++ b/libstdc++-v3/testsuite/22_locale/time_put/put/char/17038.cc
@@ -0,0 +1,63 @@
+// 2004-08-25 Paolo Carlini <pcarlini@suse.de>
+
+// Copyright (C) 2004 Free Software Foundation
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+
+// 22.2.5.3.1 time_put members
+
+#include <locale>
+#include <sstream>
+#include <testsuite_hooks.h>
+
+// libstdc++/17038
+void test01()
+{
+ using namespace std;
+ typedef ostreambuf_iterator<char> iterator_type;
+
+ bool test __attribute__((unused)) = true;
+
+ // create "C" time objects
+ tm time1 = { 0, 0, 12, 4, 3, 71, 0, 93, 0 };
+
+ // basic construction
+ locale loc_c = locale::classic();
+ locale loc_in = __gnu_test::try_named_locale("ta_IN");
+ assert( loc_in != loc_c );
+
+ // create an ostream-derived object, cache the time_put facet
+ ostringstream oss;
+ oss.imbue(loc_in);
+ const time_put<char>& tim_put =
+ use_facet<time_put<char> >(oss.getloc());
+
+ iterator_type os_it01 = tim_put.put(oss.rdbuf(), oss, '*', &time1, 'c');
+ string result1 = oss.str();
+
+ char time_buffer[128];
+ setlocale(LC_ALL, "ta_IN");
+ VERIFY( strftime(time_buffer, 128, "%c", &time1) );
+
+ VERIFY( result1 == time_buffer );
+}
+
+int main()
+{
+ test01();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/22_locale/time_put/put/wchar_t/17038.cc b/libstdc++-v3/testsuite/22_locale/time_put/put/wchar_t/17038.cc
new file mode 100644
index 0000000..f903aab
--- /dev/null
+++ b/libstdc++-v3/testsuite/22_locale/time_put/put/wchar_t/17038.cc
@@ -0,0 +1,63 @@
+// 2004-08-25 Paolo Carlini <pcarlini@suse.de>
+
+// Copyright (C) 2004 Free Software Foundation
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+
+// 22.2.5.3.1 time_put members
+
+#include <locale>
+#include <sstream>
+#include <testsuite_hooks.h>
+
+// libstdc++/17038
+void test01()
+{
+ using namespace std;
+ typedef ostreambuf_iterator<wchar_t> iterator_type;
+
+ bool test __attribute__((unused)) = true;
+
+ // create "C" time objects
+ tm time1 = { 0, 0, 12, 4, 3, 71, 0, 93, 0 };
+
+ // basic construction
+ locale loc_c = locale::classic();
+ locale loc_in = __gnu_test::try_named_locale("ta_IN");
+ assert( loc_in != loc_c );
+
+ // create an ostream-derived object, cache the time_put facet
+ wostringstream oss;
+ oss.imbue(loc_in);
+ const time_put<wchar_t>& tim_put =
+ use_facet<time_put<wchar_t> >(oss.getloc());
+
+ iterator_type os_it01 = tim_put.put(oss.rdbuf(), oss, L'*', &time1, 'c');
+ wstring result1 = oss.str();
+
+ wchar_t time_buffer[128];
+ setlocale(LC_ALL, "ta_IN");
+ VERIFY( wcsftime(time_buffer, 128, L"%c", &time1) );
+
+ VERIFY( result1 == time_buffer );
+}
+
+int main()
+{
+ test01();
+ return 0;
+}