Author: vitek
Date: Mon Mar 31 16:56:14 2008
New Revision: 643214
URL: http://svn.apache.org/viewvc?rev=643214&view=rev
Log:
2008-03-31 Travis Vitek <[EMAIL PROTECTED]>
STDCXX-716
* tests/src/locale.cpp: Add functions _rw_isspace(), _rw_toupper() and
_rw_tolower() to avoid problems when sign extending character to int.
(_rw_all_locales): Avoid using uninitialized struct member in calls to
rw_note(). Use _rw_isspace(), _rw_toupper() and _rw_tolower(). Remove
duplicate locales using canonical locale name matching.
(rw_locale_query): Use larger buffer for cached locale name to avoid
buffer overflow. Remember to close file on error condition. Use
_rw_isspace(), _rw_toupper() and _rw_tolower().
* tests/localization/22.locale.ctype.tolower.cpp: Use rw_locale_query()
to select a subset of installed locales.
(run_test): Call test_libc() before test_libstd() to avoid problem with
our locale utility on windows that causes only C locale to be returned.
* tests/localization/22.locale.ctype.toupper.cpp: Ditto.
* tests/localization/22.locale.ctype.scan.cpp: Ditto.
* tests/localization/22.locale.ctype.cpp: Ditto.
* tests/localization/22.locale.ctype.narrow.cpp: Ditto.
* tests/localization/22.locale.ctype.is.cpp: Ditto.
* tests/localization/22.locale.time.get.cpp: Ditto.
Modified:
stdcxx/trunk/tests/localization/22.locale.ctype.cpp
stdcxx/trunk/tests/localization/22.locale.ctype.is.cpp
stdcxx/trunk/tests/localization/22.locale.ctype.narrow.cpp
stdcxx/trunk/tests/localization/22.locale.ctype.scan.cpp
stdcxx/trunk/tests/localization/22.locale.ctype.tolower.cpp
stdcxx/trunk/tests/localization/22.locale.ctype.toupper.cpp
stdcxx/trunk/tests/localization/22.locale.time.get.cpp
stdcxx/trunk/tests/src/locale.cpp
Modified: stdcxx/trunk/tests/localization/22.locale.ctype.cpp
URL:
http://svn.apache.org/viewvc/stdcxx/trunk/tests/localization/22.locale.ctype.cpp?rev=643214&r1=643213&r2=643214&view=diff
==============================================================================
--- stdcxx/trunk/tests/localization/22.locale.ctype.cpp (original)
+++ stdcxx/trunk/tests/localization/22.locale.ctype.cpp Mon Mar 31 16:56:14 2008
@@ -67,7 +67,7 @@
#include <driver.h>
#include <file.h> // for SLASH
-#include <rw_locale.h> // for rw_locales()
+#include <rw_locale.h> // for rw_locale_query()
/**************************************************************************/
@@ -78,8 +78,13 @@
#define NLOOPS 25
#define MAX_STR_SIZE 16
+#define LOCALES "{{en-US,de-DE,fr-FR,es-ES}-*-{ISO-8859-*,UTF-8,CP125?}," \
+ "{ja-JP-*-{EUC-JP,SHIFT_JIS,UTF-8,CP125?}}," \
+ "{zh-CN-*-{GB*,UTF-8,CP125?}}," \
+ "{ru-RU-*-{KOI*,UTF-8,CP125?}}}"
+
#define BEGIN_LOCALE_LOOP(num, locname, loop_cntrl) \
- for (const char* locname = rw_locales (LC_CTYPE, 0); \
+ for (const char* locname = rw_locale_query (LC_CTYPE, LOCALES); \
locname && *locname; locname += std::strlen (locname) + 1) { \
_TRY { \
const std::locale loc (locname); \
Modified: stdcxx/trunk/tests/localization/22.locale.ctype.is.cpp
URL:
http://svn.apache.org/viewvc/stdcxx/trunk/tests/localization/22.locale.ctype.is.cpp?rev=643214&r1=643213&r2=643214&view=diff
==============================================================================
--- stdcxx/trunk/tests/localization/22.locale.ctype.is.cpp (original)
+++ stdcxx/trunk/tests/localization/22.locale.ctype.is.cpp Mon Mar 31 16:56:14
2008
@@ -67,7 +67,7 @@
#include <driver.h>
#include <file.h> // for SLASH
-#include <rw_locale.h> // for rw_locales()
+#include <rw_locale.h> // for rw_locale_query()
/**************************************************************************/
@@ -78,8 +78,13 @@
#define NLOOPS 25
#define MAX_STR_SIZE 16
+#define LOCALES "{{en-US,de-DE,fr-FR,es-ES}-*-{ISO-8859-*,UTF-8,CP125?}," \
+ "{ja-JP-*-{EUC-JP,SHIFT_JIS,UTF-8,CP125?}}," \
+ "{zh-CN-*-{GB*,UTF-8,CP125?}}," \
+ "{ru-RU-*-{KOI*,UTF-8,CP125?}}}"
+
#define BEGIN_LOCALE_LOOP(num, locname, loop_cntrl) \
- for (const char* locname = rw_locales (LC_CTYPE, 0); \
+ for (const char* locname = rw_locale_query (LC_CTYPE, LOCALES); \
locname && *locname; locname += std::strlen (locname) + 1) { \
_TRY { \
const std::locale loc (locname); \
Modified: stdcxx/trunk/tests/localization/22.locale.ctype.narrow.cpp
URL:
http://svn.apache.org/viewvc/stdcxx/trunk/tests/localization/22.locale.ctype.narrow.cpp?rev=643214&r1=643213&r2=643214&view=diff
==============================================================================
--- stdcxx/trunk/tests/localization/22.locale.ctype.narrow.cpp (original)
+++ stdcxx/trunk/tests/localization/22.locale.ctype.narrow.cpp Mon Mar 31
16:56:14 2008
@@ -67,7 +67,7 @@
#include <driver.h>
#include <file.h> // for SLASH
-#include <rw_locale.h> // for rw_locales()
+#include <rw_locale.h> // for rw_locale_query()
/**************************************************************************/
@@ -78,8 +78,13 @@
#define NLOOPS 25
#define MAX_STR_SIZE 16
+#define LOCALES "{{en-US,de-DE,fr-FR,es-ES}-*-{ISO-8859-*,UTF-8,CP125?}," \
+ "{ja-JP-*-{EUC-JP,SHIFT_JIS,UTF-8,CP125?}}," \
+ "{zh-CN-*-{GB*,UTF-8,CP125?}}," \
+ "{ru-RU-*-{KOI*,UTF-8,CP125?}}}"
+
#define BEGIN_LOCALE_LOOP(num, locname, loop_cntrl) \
- for (const char* locname = rw_locales (LC_CTYPE, 0); \
+ for (const char* locname = rw_locale_query (LC_CTYPE, LOCALES); \
locname && *locname; locname += std::strlen (locname) + 1) { \
_TRY { \
const std::locale loc (locname); \
Modified: stdcxx/trunk/tests/localization/22.locale.ctype.scan.cpp
URL:
http://svn.apache.org/viewvc/stdcxx/trunk/tests/localization/22.locale.ctype.scan.cpp?rev=643214&r1=643213&r2=643214&view=diff
==============================================================================
--- stdcxx/trunk/tests/localization/22.locale.ctype.scan.cpp (original)
+++ stdcxx/trunk/tests/localization/22.locale.ctype.scan.cpp Mon Mar 31
16:56:14 2008
@@ -67,7 +67,7 @@
#include <driver.h>
#include <file.h> // for SLASH
-#include <rw_locale.h> // for rw_locales()
+#include <rw_locale.h> // for rw_locale_query()
/**************************************************************************/
@@ -78,8 +78,13 @@
#define NLOOPS 25
#define MAX_STR_SIZE 16
+#define LOCALES "{{en-US,de-DE,fr-FR,es-ES}-*-{ISO-8859-*,UTF-8,CP125?}," \
+ "{ja-JP-*-{EUC-JP,SHIFT_JIS,UTF-8,CP125?}}," \
+ "{zh-CN-*-{GB*,UTF-8,CP125?}}," \
+ "{ru-RU-*-{KOI*,UTF-8,CP125?}}}"
+
#define BEGIN_LOCALE_LOOP(num, locname, loop_cntrl) \
- for (const char* locname = rw_locales (LC_CTYPE, 0); \
+ for (const char* locname = rw_locale_query (LC_CTYPE, LOCALES); \
locname && *locname; locname += std::strlen (locname) + 1) { \
_TRY { \
const std::locale loc (locname); \
@@ -827,8 +832,8 @@
_STD_USE_FACET (std::ctype_byname<charT>, std::locale ());
}
- test_libstd (charT (), cname);
test_libc (charT (), cname);
+ test_libstd (charT (), cname);
}
/**************************************************************************/
Modified: stdcxx/trunk/tests/localization/22.locale.ctype.tolower.cpp
URL:
http://svn.apache.org/viewvc/stdcxx/trunk/tests/localization/22.locale.ctype.tolower.cpp?rev=643214&r1=643213&r2=643214&view=diff
==============================================================================
--- stdcxx/trunk/tests/localization/22.locale.ctype.tolower.cpp (original)
+++ stdcxx/trunk/tests/localization/22.locale.ctype.tolower.cpp Mon Mar 31
16:56:14 2008
@@ -67,7 +67,7 @@
#include <driver.h>
#include <file.h> // for SLASH
-#include <rw_locale.h> // for rw_locales()
+#include <rw_locale.h> // for rw_locale_query()
/**************************************************************************/
@@ -78,8 +78,13 @@
#define NLOOPS 25
#define MAX_STR_SIZE 16
+#define LOCALES "{{en-US,de-DE,fr-FR,es-ES}-*-{ISO-8859-*,UTF-8,CP125?}," \
+ "{ja-JP-*-{EUC-JP,SHIFT_JIS,UTF-8,CP125?}}," \
+ "{zh-CN-*-{GB*,UTF-8,CP125?}}," \
+ "{ru-RU-*-{KOI*,UTF-8,CP125?}}}"
+
#define BEGIN_LOCALE_LOOP(num, locname, loop_cntrl) \
- for (const char* locname = rw_locales (LC_CTYPE, 0); \
+ for (const char* locname = rw_locale_query (LC_CTYPE, LOCALES); \
locname && *locname; locname += std::strlen (locname) + 1) { \
_TRY { \
const std::locale loc (locname); \
@@ -460,8 +465,8 @@
_STD_USE_FACET (std::ctype_byname<charT>, std::locale ());
}
- test_libstd (charT (), cname);
test_libc (charT (), cname);
+ test_libstd (charT (), cname);
}
/**************************************************************************/
Modified: stdcxx/trunk/tests/localization/22.locale.ctype.toupper.cpp
URL:
http://svn.apache.org/viewvc/stdcxx/trunk/tests/localization/22.locale.ctype.toupper.cpp?rev=643214&r1=643213&r2=643214&view=diff
==============================================================================
--- stdcxx/trunk/tests/localization/22.locale.ctype.toupper.cpp (original)
+++ stdcxx/trunk/tests/localization/22.locale.ctype.toupper.cpp Mon Mar 31
16:56:14 2008
@@ -67,7 +67,7 @@
#include <driver.h>
#include <file.h> // for SLASH
-#include <rw_locale.h> // for rw_locales()
+#include <rw_locale.h> // for rw_locale_query()
/**************************************************************************/
@@ -78,8 +78,13 @@
#define NLOOPS 25
#define MAX_STR_SIZE 16
+#define LOCALES "{{en-US,de-DE,fr-FR,es-ES}-*-{ISO-8859-*,UTF-8,CP125?}," \
+ "{ja-JP-*-{EUC-JP,SHIFT_JIS,UTF-8,CP125?}}," \
+ "{zh-CN-*-{GB*,UTF-8,CP125?}}," \
+ "{ru-RU-*-{KOI*,UTF-8,CP125?}}}"
+
#define BEGIN_LOCALE_LOOP(num, locname, loop_cntrl) \
- for (const char* locname = rw_locales (LC_CTYPE, 0); \
+ for (const char* locname = rw_locale_query (LC_CTYPE, LOCALES); \
locname && *locname; locname += std::strlen (locname) + 1) { \
_TRY { \
const std::locale loc (locname); \
@@ -461,8 +466,8 @@
_STD_USE_FACET (std::ctype_byname<charT>, std::locale ());
}
- test_libstd (charT (), cname);
test_libc (charT (), cname);
+ test_libstd (charT (), cname);
}
/**************************************************************************/
Modified: stdcxx/trunk/tests/localization/22.locale.time.get.cpp
URL:
http://svn.apache.org/viewvc/stdcxx/trunk/tests/localization/22.locale.time.get.cpp?rev=643214&r1=643213&r2=643214&view=diff
==============================================================================
--- stdcxx/trunk/tests/localization/22.locale.time.get.cpp (original)
+++ stdcxx/trunk/tests/localization/22.locale.time.get.cpp Mon Mar 31 16:56:14
2008
@@ -38,7 +38,7 @@
#include <driver.h> // for rw_test()
#include <file.h> // for rw_nextfd()
-#include <rw_locale.h> // for rw_locales()
+#include <rw_locale.h> // for rw_locale_query()
#include <rw_printf.h> // for rw_snprintf()
/**************************************************************************/
@@ -1584,33 +1584,6 @@
/**************************************************************************/
-
-// try to find a named locale (use a grep expression if available)
-static const char*
-find_locale (const char *name)
-{
-#if !defined (_WIN32) && !defined (_WIN64)
-
- rw_locales (_UNUSED_CAT, name);
- return rw_locales (LC_ALL, name);
-
-#else // _WIN{32,64}
-
- // FIXME: handle non-UNIX systems
- for (const char *loc = rw_locales (); loc && *loc;
- loc += std::strlen (loc) + 1) {
-
- if (!std::strcmp (loc, name))
- return loc;
- }
-
- return 0;
-
-#endif // _WIN{32,64}
-}
-
-/**************************************************************************/
-
static int
run_test (int, char**)
{
@@ -1627,36 +1600,26 @@
const char *locname;
-#if !defined (_WIN32) && !defined (_WIN64)
-
- const char en_US[] = "en_US";
- const char de[] = "^de[^a-z1-9]*";
- const char da[] = "^da[^a-z1-9]*";
-
-#else // dumbass Windows
-
- const char en_US[] = "ENU";
- const char de[] = "DEU";
- const char da[] = "DAN";
-
-#endif
+ const char en[] = "en-*-*-*";
+ const char de[] = "de-*-*-*";
+ const char da[] = "da-*-*-*";
int nnamed = 0;
// try to find and exercise the english locale
- if ((locname = find_locale (en_US)) && *locname) {
+ if ((locname = rw_locale_query (LC_ALL, en, 1)) && *locname) {
test_english (char (), "char", locname);
++nnamed;
}
// try to find and exercise the german locale
- if ((locname = find_locale (de)) && *locname) {
+ if ((locname = rw_locale_query (LC_ALL, de, 1)) && *locname) {
test_german (char (), "char", locname);
++nnamed;
}
// try to find and exercise the danish locale
- if ((locname = find_locale (da)) && *locname) {
+ if ((locname = rw_locale_query (LC_ALL, da, 1)) && *locname) {
test_danish (char (), "char", locname);
++nnamed;
}
Modified: stdcxx/trunk/tests/src/locale.cpp
URL:
http://svn.apache.org/viewvc/stdcxx/trunk/tests/src/locale.cpp?rev=643214&r1=643213&r2=643214&view=diff
==============================================================================
--- stdcxx/trunk/tests/src/locale.cpp (original)
+++ stdcxx/trunk/tests/src/locale.cpp Mon Mar 31 16:56:14 2008
@@ -943,6 +943,23 @@
return ret;
}
+inline bool
+_rw_isspace (char ch)
+{
+ return 0 != isspace ((unsigned char)ch);
+}
+
+inline char
+_rw_toupper (char ch)
+{
+ return toupper ((unsigned char)ch);
+}
+
+inline char
+_rw_tolower (char ch)
+{
+ return tolower ((unsigned char)ch);
+}
// our locale database is a big array of these
struct _rw_locale_entry {
@@ -1125,25 +1142,30 @@
const size_t len = strlen (locale);
locale [len ? len - 1 : 0] = '\0';
- // we need MB_CUR_MAX and CODESET
+ // make sure that the named locale is one that we can use
if (!setlocale (LC_CTYPE, locale)) {
rw_note (0, __FILE__, __LINE__,
- "setlocale() failed for '%s'",
- entry->locale_name);
+ "setlocale() failed for '%s'", locale);
continue;
- } else if (sizeof (entry->locale_name) < len) {
+ }
+
+ // is not an alias for the C or POSIX locale
+ else if (!strcmp (locale, "C") || !strcmp (locale, "POSIX")) {
+ continue; // we don't do C/POSIX locale
+ }
+
+ // has a name that is short enough for our buffer
+ else if (sizeof (entry->locale_name) < len) {
rw_note (0, __FILE__, __LINE__,
- "locale name '%s' was to long for fixed buffer",
- entry->locale_name);
+ "locale name '%s' was to long for fixed buffer",
+ locale);
continue; // locale name didn't fit, so we skip it
}
- else if (!strcmp (locale, "C") || !strcmp (locale, "POSIX"))
- continue; // we don't do C/POSIX locale
#ifndef _RWSTD_NO_LANGINFO
char codeset [40];
@@ -1152,7 +1174,7 @@
for (const char* charset = nl_langinfo (CODESET);
*charset;
++charset) {
- codeset [i++] = toupper (*charset);
+ codeset [i++] = _rw_toupper (*charset);
}
codeset [i] = '\0';
@@ -1172,7 +1194,7 @@
*encoding++ = '\0';
for (int n = 0; encoding [n]; ++n)
- encoding [n] = toupper (encoding [n]);
+ encoding [n] = _rw_toupper (encoding [n]);
}
char* country = strrchr (locale, '_');
@@ -1180,13 +1202,13 @@
*country++ = '\0';
for (int n = 0; country [n]; ++n)
- country [n] = toupper (country [n]);
+ country [n] = _rw_toupper (country [n]);
}
char* language = locale;
for (int n = 0; language [n]; ++n)
- language [n] = tolower (language [n]);
+ language [n] = _rw_tolower (language [n]);
// use mapping databases to find the canonical
// names for each part of the locale name
@@ -1218,25 +1240,25 @@
// require all three mappings are valid
if (!planguage || !*planguage) {
- rw_note (0, __FILE__, __LINE__,
- "failed to get language for locale %s",
- entry->locale_name);
+ //rw_note (0, __FILE__, __LINE__,
+ // "failed to get language for locale '%s'",
+ // entry->locale_name);
continue;
}
else if (!pcountry || !*pcountry) {
- rw_note (0, __FILE__, __LINE__,
- "failed to get country for locale %s",
- entry->locale_name);
+ //rw_note (0, __FILE__, __LINE__,
+ // "failed to get country for locale '%s'",
+ // entry->locale_name);
continue;
}
else if (!pencoding || !*pencoding) {
- rw_note (0, __FILE__, __LINE__,
- "failed to get codeset for locale %s",
- entry->locale_name);
+ //rw_note (0, __FILE__, __LINE__,
+ // "failed to get codeset for locale '%s'",
+ // entry->locale_name);
continue;
}
@@ -1245,7 +1267,33 @@
sprintf (entry->canonical_name, "%s-%s-%d-%s",
planguage, pcountry, int (MB_CUR_MAX), pencoding);
- size += 1;
+ //
+ // eliminate locales that are duplicates according to
+ // canonical name. we do this because the setlocale()
+ // doesn't seem to tell us about aliases.
+ //
+
+ bool duplicate = false;
+
+ // search backward as matches are more likely to be near
+ // the back
+ for (size_t e = size; 0 != e; --e) {
+
+ if (!strcmp (entries [e-1].canonical_name,
+ entry->canonical_name)) {
+
+ //rw_note (0, __FILE__, __LINE__,
+ // "ignoring duplicate locale '%s'",
+ // entry->locale_name);
+
+ duplicate = true;
+
+ break;
+ }
+ }
+
+ if (!duplicate)
+ size += 1;
}
fclose (file);
@@ -1282,14 +1330,14 @@
// get a brace expanded representation of query, each expansion
// is a null terminated string. the entire buffer is also null
// terminated
- char* res = rw_brace_expand (query, 0, buf, sizeof (buf), '\0');
+ char* res = rw_shell_expand (query, 0, buf, sizeof (buf), '\0');
if (!res)
return 0;
// cache the locale name so we can restore later, this must happen
// before _rw_all_locales() because that function just changes the
// locale without restoring it
- char save_locale [128];
+ char save_locale [PATH_MAX];
strcpy (save_locale, setlocale (LC_ALL, 0));
const _rw_locale_array all = _rw_all_locales ();
@@ -1445,9 +1493,11 @@
const size_t table_data_size = ftell (file);
fseek (file, 0, SEEK_SET);
- char* table_data = (char*)malloc (table_data_size + 1);
+ char* table_data =
+ (char*)malloc (table_data_size + 1);
if (!table_data) {
+ fclose (file);
return false;
}
@@ -1456,6 +1506,7 @@
fread (table_data, 1, table_data_size, file);
if (bytes_read != table_data_size) {
free (table_data);
+ fclose (file);
return false;
}
@@ -1488,27 +1539,27 @@
// make upper or lower case as requested
if (upper_or_lower < 0) {
for (char* s = key; *s; ++s)
- *s = tolower (*s);
+ *s = _rw_tolower (*s);
}
else if (0 < upper_or_lower) {
for (char* s = key; *s; ++s)
- *s = toupper (*s);
+ *s = _rw_toupper (*s);
}
// if first character of new line is not whitespace, then we have
a new
// canonical name token
- if (!isspace (*key)) {
+ if (!_rw_isspace (*key)) {
canonical_name = key;
// increment key past cannonical name
for (/**/; *key; ++key)
- if (isspace (*key))
+ if (_rw_isspace (*key))
break;
}
// kill whitespace
- while (isspace (*key))
+ while (_rw_isspace (*key))
*key++ = '\0';
// key points to first non-whitespace after canonical name
@@ -1529,11 +1580,11 @@
*key++ = '\0';
// kill any whitespace before comma
- for (char* bey = key - 1; isspace (*bey); --bey)
+ for (char* bey = key - 1; _rw_isspace (*bey); --bey)
*bey = '\0';
// kill whitespace after comma
- while (isspace (*key))
+ while (_rw_isspace (*key))
*key++ = '\0';
// ensure we have enough entries
@@ -1548,6 +1599,8 @@
free (entries);
free (table_data);
+
+ fclose (file);
return false;
}