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; }