Switch to compiler-tester
[mono.git] / mono / metadata / locales.c
index fed8e602b0a5a6ebc0cb2de71e8d53fc933296fc..2c8fdff303e31184b9ca4b29091eec39ffd00824 100644 (file)
@@ -409,7 +409,7 @@ ves_icall_System_Globalization_CultureInfo_construct_internal_locale_from_name (
                        sizeof (CultureInfoNameEntry), culture_name_locator);
 
        if (ne == NULL) {
-                g_print ("ne (%s) is null\n", n);
+                /*g_print ("ne (%s) is null\n", n);*/
                g_free (n);
                return FALSE;
         }
@@ -460,12 +460,21 @@ ves_icall_System_Globalization_CultureInfo_internal_get_cultures (MonoBoolean ne
 
        class = mono_class_from_name (mono_get_corlib (),
                        "System.Globalization", "CultureInfo");
+
+       /* The InvariantCulture is not in culture_entries */
+       /* We reserve the first slot in the array for it */
+       if (neutral)
+               len++;
+
        ret = mono_array_new (domain, class, len);
 
        if (len == 0)
                return ret;
 
        len = 0;
+       if (neutral)
+               mono_array_set (ret, MonoCultureInfo *, len++, NULL);
+
        for (i = 0; i < NUM_CULTURE_ENTRIES; i++) {
                ci = &culture_entries [i];
                is_neutral = ((ci->lcid & 0xff00) == 0 || ci->specific_lcid == 0);
@@ -1521,190 +1530,7 @@ MonoString *ves_icall_System_String_InternalReplace_Str_Comp (MonoString *this,
        return(ret);
 }
 
-MonoString *ves_icall_System_String_InternalToLower_Comp (MonoString *this, MonoCultureInfo *cult)
-{
-       MonoString *ret;
-       UChar *udest;
-       UErrorCode ec;
-       char *icu_loc;
-       int32_t len;
-
-       MONO_ARCH_SAVE_REGS;
-
-#ifdef DEBUG
-       g_message (G_GNUC_PRETTY_FUNCTION ": [%s]",
-                  mono_string_to_utf8 (this));
-#endif
-
-#ifdef DEBUG
-       g_message (G_GNUC_PRETTY_FUNCTION ": LCID is %d", cult->lcid);
-#endif
-
-       icu_loc=mono_string_to_icu_locale (cult->icu_name);
-       if(icu_loc==NULL) {
-               mono_raise_exception ((MonoException *)mono_exception_from_name (mono_get_corlib (), "System", "SystemException"));
-               return(NULL);
-       }
-       
-       udest=(UChar *)g_malloc0 (sizeof(UChar)*(mono_string_length (this)+1));
-       
-       /* According to the docs, this might result in a longer or
-        * shorter string than we started with...
-        */
-
-       ec=U_ZERO_ERROR;
-       len=u_strToLower (udest, mono_string_length (this)+1,
-                         mono_string_chars (this), mono_string_length (this),
-                         icu_loc, &ec);
-       if(ec==U_BUFFER_OVERFLOW_ERROR ||
-          ec==U_STRING_NOT_TERMINATED_WARNING) {
-               g_free (udest);
-               udest=(UChar *)g_malloc0 (sizeof(UChar)*(len+1));
-               len=u_strToLower (udest, len+1, mono_string_chars (this),
-                                 mono_string_length (this), icu_loc, &ec);
-       }
-
-       if(U_SUCCESS (ec)) {
-               ret=mono_string_from_utf16 ((gunichar2 *)udest);
-       } else {
-               g_message (G_GNUC_PRETTY_FUNCTION ": u_strToLower error: %s",
-                          u_errorName (ec));
-               /* return something */
-               ret=this;
-       }
-       
-       g_free (icu_loc);
-       g_free (udest);
-       
-#ifdef DEBUG
-       g_message (G_GNUC_PRETTY_FUNCTION ": returning [%s]",
-                  mono_string_to_utf8 (ret));
-#endif
-
-       return(ret);
-}
-
-MonoString *ves_icall_System_String_InternalToUpper_Comp (MonoString *this, MonoCultureInfo *cult)
-{
-       MonoString *ret;
-       UChar *udest;
-       UErrorCode ec;
-       char *icu_loc;
-       int32_t len;
-
-       MONO_ARCH_SAVE_REGS;
-
-#ifdef DEBUG
-       g_message (G_GNUC_PRETTY_FUNCTION ": [%s]",
-                  mono_string_to_utf8 (this));
-#endif
-
-#ifdef DEBUG
-       g_message (G_GNUC_PRETTY_FUNCTION ": LCID is %d", cult->lcid);
-#endif
-
-       icu_loc=mono_string_to_icu_locale (cult->icu_name);
-       if(icu_loc==NULL) {
-               mono_raise_exception ((MonoException *)mono_exception_from_name (mono_get_corlib (), "System", "SystemException"));
-               return(NULL);
-       }
-       
-       udest=(UChar *)g_malloc0 (sizeof(UChar)*(mono_string_length (this)+1));
-       
-       /* According to the docs, this might result in a longer or
-        * shorter string than we started with...
-        */
-
-       ec=U_ZERO_ERROR;
-       len=u_strToUpper (udest, mono_string_length (this)+1,
-                         mono_string_chars (this), mono_string_length (this),
-                         icu_loc, &ec);
-       if(ec==U_BUFFER_OVERFLOW_ERROR ||
-          ec==U_STRING_NOT_TERMINATED_WARNING) {
-               g_free (udest);
-               udest=(UChar *)g_malloc0 (sizeof(UChar)*(len+1));
-               len=u_strToUpper (udest, len+1, mono_string_chars (this),
-                                 mono_string_length (this), icu_loc, &ec);
-       }
-
-       if(U_SUCCESS (ec)) {
-               ret=mono_string_from_utf16 ((gunichar2 *)udest);
-       } else {
-               g_message (G_GNUC_PRETTY_FUNCTION ": u_strToUpper error: %s",
-                          u_errorName (ec));
-               /* return something */
-               ret=this;
-       }
-       
-       g_free (icu_loc);
-       g_free (udest);
-       
-#ifdef DEBUG
-       g_message (G_GNUC_PRETTY_FUNCTION ": returning [%s]",
-                  mono_string_to_utf8 (ret));
-#endif
-       
-       return(ret);
-}
-
-gunichar2 ves_icall_System_Char_InternalToUpper_Comp (gunichar2 c, MonoCultureInfo *cult)
-{
-       UChar udest;
-       UErrorCode ec;
-       char *icu_loc;
-       int32_t len;
-       
-       MONO_ARCH_SAVE_REGS;
-
-       icu_loc=mono_string_to_icu_locale (cult->icu_name);
-       if(icu_loc==NULL) {
-               mono_raise_exception ((MonoException *)mono_exception_from_name (mono_get_corlib (), "System", "SystemException"));
-               return(0);
-       }
-       
-       ec=U_ZERO_ERROR;
-       len=u_strToUpper (&udest, 1, &c, 1, icu_loc, &ec);
-       g_free (icu_loc);
-
-       if(U_SUCCESS (ec) && len==1) {
-               return udest;
-       } else {
-               /* return something */
-               return c;
-       }
-}
-
-
-gunichar2 ves_icall_System_Char_InternalToLower_Comp (gunichar2 c, MonoCultureInfo *cult)
-{
-       UChar udest;
-       UErrorCode ec;
-       char *icu_loc;
-       int32_t len;
-       
-       MONO_ARCH_SAVE_REGS;
-
-       icu_loc=mono_string_to_icu_locale (cult->icu_name);
-       if(icu_loc==NULL) {
-               mono_raise_exception ((MonoException *)mono_exception_from_name (mono_get_corlib (), "System", "SystemException"));
-               return(0);
-       }
-       
-       ec=U_ZERO_ERROR;
-       len=u_strToLower (&udest, 1, &c, 1, icu_loc, &ec);
-       g_free (icu_loc);
-
-       if(U_SUCCESS (ec) && len==1) {
-               return udest;
-       } else {
-               /* return something */
-               return c;
-       }
-}
-
 #else /* HAVE_ICU */
-static MonoString *string_invariant_tolower (MonoString *this);
-static MonoString *string_invariant_toupper (MonoString *this);
 
 void ves_icall_System_Globalization_CultureInfo_construct_internal_locale (MonoCultureInfo *this, MonoString *locale)
 {
@@ -1788,75 +1614,6 @@ MonoString *ves_icall_System_String_InternalReplace_Str_Comp (MonoString *this,
        return(string_invariant_replace (this, old, new));
 }
 
-MonoString *ves_icall_System_String_InternalToLower_Comp (MonoString *this, MonoCultureInfo *cult)
-{
-       MONO_ARCH_SAVE_REGS;
-       
-       return(string_invariant_tolower (this));
-}
-
-MonoString *ves_icall_System_String_InternalToUpper_Comp (MonoString *this, MonoCultureInfo *cult)
-{
-       MONO_ARCH_SAVE_REGS;
-       
-       return(string_invariant_toupper (this));
-}
-
-gunichar2 ves_icall_System_Char_InternalToUpper_Comp (gunichar2 c, MonoCultureInfo *cult)
-{
-       MONO_ARCH_SAVE_REGS;
-
-       return g_unichar_toupper (c);
-}
-
-
-gunichar2 ves_icall_System_Char_InternalToLower_Comp (gunichar2 c, MonoCultureInfo *cult)
-{
-       MONO_ARCH_SAVE_REGS;
-
-       return g_unichar_tolower (c);
-}
-
-static MonoString *string_invariant_tolower (MonoString *this)
-{
-       MonoString *ret;
-       gunichar2 *src; 
-       gunichar2 *dest;
-       gint32 i;
-
-       ret = mono_string_new_size(mono_domain_get (),
-                                  mono_string_length(this));
-
-       src = mono_string_chars (this);
-       dest = mono_string_chars (ret);
-
-       for (i = 0; i < mono_string_length (this); ++i) {
-               dest[i] = g_unichar_tolower(src[i]);
-       }
-
-       return(ret);
-}
-
-static MonoString *string_invariant_toupper (MonoString *this)
-{
-       MonoString *ret;
-       gunichar2 *src; 
-       gunichar2 *dest;
-       guint32 i;
-
-       ret = mono_string_new_size(mono_domain_get (),
-                                  mono_string_length(this));
-
-       src = mono_string_chars (this);
-       dest = mono_string_chars (ret);
-
-       for (i = 0; i < mono_string_length (this); ++i) {
-               dest[i] = g_unichar_toupper(src[i]);
-       }
-
-       return(ret);
-}
-
 #endif /* HAVE_ICU */
 
 static gint32 string_invariant_compare_char (gunichar2 c1, gunichar2 c2,
@@ -1865,19 +1622,28 @@ static gint32 string_invariant_compare_char (gunichar2 c1, gunichar2 c2,
        gint32 result;
        GUnicodeType c1type, c2type;
 
+       /* Ordinal can not be mixed with other options, and must return the difference, not only -1, 0, 1 */
+       if (options & CompareOptions_Ordinal) 
+               return (gint32) c1 - c2;
+       
        c1type = g_unichar_type (c1);
        c2type = g_unichar_type (c2);
-
+       
        if (options & CompareOptions_IgnoreCase) {
-               result = (gint32) (c1type != G_UNICODE_LOWERCASE_LETTER ? g_unichar_tolower(c1) : c1) - (c2type != G_UNICODE_LOWERCASE_LETTER ? g_unichar_tolower(c2) : c2);
-       } else if (options & CompareOptions_Ordinal) {
-               /*  Rotor/ms return the full value just not -1 and 1 */
-               return (gint32) c1 - c2;
+               result = (gint32) (c1type != G_UNICODE_LOWERCASE_LETTER ? g_unichar_tolower(c1) : c1) -
+                       (c2type != G_UNICODE_LOWERCASE_LETTER ? g_unichar_tolower(c2) : c2);
        } else {
-               /* No options. Kana, symbol and spacing options don't
+               /*
+                * No options. Kana, symbol and spacing options don't
                 * apply to the invariant culture.
                 */
-               
+
+               /*
+                * FIXME: here we must use the information from c1type and c2type
+                * to find out the proper collation, even on the InvariantCulture, the
+                * sorting is not done by computing the unicode values, but their
+                * actual sort order.
+                */
                result = (gint32) c1 - c2;
        }