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


Reply via email to