guile-commits
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Guile-commits] GNU Guile branch, master, updated. release_1-9-3-7-g5b87


From: Michael Gran
Subject: [Guile-commits] GNU Guile branch, master, updated. release_1-9-3-7-g5b87844
Date: Thu, 17 Sep 2009 15:23:15 +0000

This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "GNU Guile".

http://git.savannah.gnu.org/cgit/guile.git/commit/?id=5b87844575ff7e8071d0fd9f10c9212a4f6afd16

The branch, master has been updated
       via  5b87844575ff7e8071d0fd9f10c9212a4f6afd16 (commit)
      from  f564f4784f856d0b38008327bc877905e36fc56a (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit 5b87844575ff7e8071d0fd9f10c9212a4f6afd16
Author: Michael Gran <address@hidden>
Date:   Thu Sep 17 08:14:08 2009 -0700

    Adapt i18n string and char comparison funcs for Unicode
    
    * libguile/i18n.c (RUN_IN_LOCALE_SECTION) [USE_GNU_LOCALE_API]: new
      macro for this define.  Should work the same as the !USE_GNU_LOCAL_API
      version
      (SCM_STRING_TO_U32_BUF, SCM_U32_BUF_FREE): helper macros
      (compare_u32_strings, compare_u32_strings_ci): new functions that
      compare scheme strings in the presence of the locale
      (u32_locale_casecoll): new helper function for compare_u32_strings_ci
      (compare_strings, compare_strings_ci): removed and replaced by
      compare_u32_strings and compare_u32_strings_ci
      (scm_string_locale_lt, scm_string_locale_gt, scm_string_locale_ci_lt)
      (scm_string_locale_ci_gt, scm_string_locale_ci_eq): modified to
      use new compare_u32_strings and compare_u32_strings_ci comparison
      functions
      (scm_char_locale_lt, scm_char_locale_gt, scm_char_locale_ci_lt)
      (scm_char_locale_ci_gt, scm_char_locale_ci_eq): modified to use
      new compare_u32_strings and compare_u32_strings_ci comparison
      functions

-----------------------------------------------------------------------

Summary of changes:
 libguile/i18n.c |  287 +++++++++++++++++++++++++++----------------------------
 1 files changed, 142 insertions(+), 145 deletions(-)

diff --git a/libguile/i18n.c b/libguile/i18n.c
index 4b7eb04..28dfe4d 100644
--- a/libguile/i18n.c
+++ b/libguile/i18n.c
@@ -37,6 +37,8 @@
 #include <string.h> /* `strcoll ()' */
 #include <ctype.h>  /* `toupper ()' et al. */
 #include <errno.h>
+#include <unicase.h>
+#include <unistr.h>
 
 #if (defined HAVE_NEWLOCALE) && (defined HAVE_STRCOLL_L)
 /* The GNU thread-aware locale API is documented in ``Thread-Aware Locale
@@ -504,8 +506,26 @@ get_current_locale (SCM *result)
   return err;
 }
 
+#else /* USE_GNU_LOCALE_API */
 
-#endif /* !USE_GNU_LOCALE_API */
+/* Convenient macro to run STATEMENT in the locale context of C_LOCALE.  */
+#define RUN_IN_LOCALE_SECTION(_c_locale, _statement)                    \
+  do                                                                    \
+    {                                                                   \
+      scm_t_locale old_loc = uselocale (NULL);                          \
+      if (old_loc != _c_locale)                                         \
+        {                                                               \
+          uselocale (_c_locale);                                        \
+          _statement ;                                                  \
+          uselocale (old_loc);                                          \
+        }                                                               \
+      else                                                              \
+        _statement;                                                     \
+    }                                                                   \
+  while (0)
+
+
+#endif /* USE_GNU_LOCALE_API */
 
 
 
@@ -710,39 +730,115 @@ SCM_DEFINE (scm_locale_p, "locale?", 1, 0, 0,
    A similar API can be found in MzScheme starting from version 200:
    http://download.plt-scheme.org/chronology/mzmr200alpha14.html .  */
 
-
-/* Compare null-terminated strings C_S1 and C_S2 according to LOCALE.  Return
-   an integer whose sign is the same as the difference between C_S1 and
-   C_S2.  */
+#define SCM_STRING_TO_U32_BUF(s1, c_s1)                                 \
+  do {                                                                  \
+    if (scm_i_is_narrow_string (s1))                                    \
+      {                                                                 \
+        size_t i, len;                                                  \
+        const char *buf = scm_i_string_chars (s1);                      \
+        len = scm_i_string_length (s1);                                 \
+        c_s1 = (scm_t_wchar *) scm_malloc (sizeof (scm_t_wchar) * (len + 1)); \
+        for (i = 0; i < len; i ++)                                      \
+          c_s1[i] = (unsigned char ) buf[i];                            \
+        c_s1[len] = 0;                                                  \
+      }                                                                 \
+    else                                                                \
+      c_s1 = (scm_t_wchar *) scm_i_string_wide_chars (s1);              \
+  } while (0)
+
+#define SCM_U32_BUF_FREE(s1, c_s1)              \
+  do {                                          \
+    if (scm_i_is_narrow_string (s1))            \
+      free (c_s1);                              \
+  } while (0)
+
+
+/* Compare u32 strings according to the LOCALE.  Returns a negative
+     value if S1 compares smaller than S2, a positive value if S1
+     compares larger than S2, or 0 if they compare equal.  */
 static inline int
-compare_strings (const char *c_s1, const char *c_s2, SCM locale,
-                const char *func_name)
+compare_u32_strings (SCM s1, SCM s2, SCM locale, const char *func_name) 
 #define FUNC_NAME func_name
 {
   int result;
   scm_t_locale c_locale;
+  scm_t_wchar *c_s1, *c_s2;
+  SCM_VALIDATE_OPTIONAL_LOCALE_COPY (3, locale, c_locale);
+
+  SCM_STRING_TO_U32_BUF (s1, c_s1);
+  SCM_STRING_TO_U32_BUF (s2, c_s2);
+
+  if (c_locale)
+    RUN_IN_LOCALE_SECTION (c_locale, 
+                           result = u32_strcoll ((const scm_t_uint32 *) c_s1, 
+                                                 (const scm_t_uint32 *) c_s2));
+  else
+    result = u32_strcmp ((const scm_t_uint32 *) c_s1, 
+                         (const scm_t_uint32 *) c_s2);
+
+  SCM_U32_BUF_FREE (s1, c_s1);
+  SCM_U32_BUF_FREE (s2, c_s2);
 
+  scm_remember_upto_here_2 (s1, s2);
+  scm_remember_upto_here (locale);
+  return result;
+}
+#undef FUNC_NAME
+
+static inline int
+u32_locale_casecoll (const char *func_name, const scm_t_uint32 *c_s1, 
+                     const scm_t_uint32 *c_s2)
+{
+  int result, ret;
+  const char *loc = uc_locale_language ();
+
+
+  ret = u32_casecoll (c_s1, u32_strlen (c_s1), 
+                      c_s2, u32_strlen (c_s2),
+                      loc, UNINORM_NFC, &result);
+  if (ret != 0)
+    scm_syserror (func_name);
+
+  return result;
+}
+
+static inline int
+compare_u32_strings_ci (SCM s1, SCM s2, SCM locale, const char *func_name) 
+#define FUNC_NAME func_name
+{
+  int ret, result;
+  scm_t_locale c_locale;
+  scm_t_wchar *c_s1, *c_s2;
   SCM_VALIDATE_OPTIONAL_LOCALE_COPY (3, locale, c_locale);
 
+  SCM_STRING_TO_U32_BUF (s1, c_s1);
+  SCM_STRING_TO_U32_BUF (s2, c_s2);
+
   if (c_locale)
+    RUN_IN_LOCALE_SECTION 
+      (c_locale, 
+       result = u32_locale_casecoll (func_name, 
+                                     (const scm_t_uint32 *) c_s1, 
+                                     (const scm_t_uint32 *) c_s2)
+       );
+  else
     {
-#ifdef USE_GNU_LOCALE_API
-      result = strcoll_l (c_s1, c_s2, c_locale);
-#else
-#ifdef HAVE_STRCOLL
-      RUN_IN_LOCALE_SECTION (c_locale, result = strcoll (c_s1, c_s2));
-#else
-      result = strcmp (c_s1, c_s2);
-#endif
-#endif /* !USE_GNU_LOCALE_API */
+      /* Passing NULL to u32_casecmp to do the default,
+         language-independent case folding. */
+      ret = u32_casecmp ((const scm_t_uint32 *) c_s1, 
+                         u32_strlen ((const scm_t_uint32 *) c_s1),
+                         (const scm_t_uint32 *) c_s2,
+                         u32_strlen ((const scm_t_uint32 *) c_s2),
+                         NULL, UNINORM_NFC, &result);
+      if (ret != 0)
+        scm_syserror (func_name);
     }
-  else
+  
+  SCM_U32_BUF_FREE (s1, c_s1);
+  SCM_U32_BUF_FREE (s2, c_s2);
 
-#ifdef HAVE_STRCOLL
-    result = strcoll (c_s1, c_s2);
-#else
-    result = strcmp (c_s1, c_s2);
-#endif
+  scm_remember_upto_here_2 (s1, s2);
+  scm_remember_upto_here (locale);
 
   return result;
 }
@@ -786,71 +882,6 @@ str_downcase_l (register char *dst, register const char 
*src,
 #endif
 
 
-/* Compare null-terminated strings C_S1 and C_S2 in a case-independent way
-   according to LOCALE.  Return an integer whose sign is the same as the
-   difference between C_S1 and C_S2.  */
-static inline int
-compare_strings_ci (const char *c_s1, const char *c_s2, SCM locale,
-                   const char *func_name)
-#define FUNC_NAME func_name
-{
-  int result;
-  scm_t_locale c_locale;
-  char *c_us1, *c_us2;
-
-  SCM_VALIDATE_OPTIONAL_LOCALE_COPY (3, locale, c_locale);
-
-  c_us1 = (char *) alloca (strlen (c_s1) + 1);
-  c_us2 = (char *) alloca (strlen (c_s2) + 1);
-
-  if (c_locale)
-    {
-#ifdef USE_GNU_LOCALE_API
-      str_upcase_l (c_us1, c_s1, c_locale);
-      str_upcase_l (c_us2, c_s2, c_locale);
-
-      result = strcoll_l (c_us1, c_us2, c_locale);
-#else
-      int err;
-      scm_t_locale_settings prev_locale;
-
-      err = enter_locale_section (c_locale, &prev_locale);
-      if (err)
-       {
-         scm_locale_error (func_name, err);
-         return 0;
-       }
-
-      str_upcase (c_us1, c_s1);
-      str_upcase (c_us2, c_s2);
-
-#ifdef HAVE_STRCOLL
-      result = strcoll (c_us1, c_us2);
-#else
-      result = strcmp (c_us1, c_us2);
-#endif /* !HAVE_STRCOLL */
-
-      leave_locale_section (&prev_locale);
-      free_locale_settings (&prev_locale);
-#endif /* !USE_GNU_LOCALE_API */
-    }
-  else
-    {
-      str_upcase (c_us1, c_s1);
-      str_upcase (c_us2, c_s2);
-
-#ifdef HAVE_STRCOLL
-      result = strcoll (c_us1, c_us2);
-#else
-      result = strcmp (c_us1, c_us2);
-#endif
-    }
-
-  return result;
-}
-#undef FUNC_NAME
-
-
 SCM_DEFINE (scm_string_locale_lt, "string-locale<?", 2, 1, 0,
            (SCM s1, SCM s2, SCM locale),
            "Compare strings @var{s1} and @var{s2} in a locale-dependent way."
@@ -860,17 +891,11 @@ SCM_DEFINE (scm_string_locale_lt, "string-locale<?", 2, 
1, 0,
 #define FUNC_NAME s_scm_string_locale_lt
 {
   int result;
-  const char *c_s1, *c_s2;
 
   SCM_VALIDATE_STRING (1, s1);
   SCM_VALIDATE_STRING (2, s2);
 
-  c_s1 = scm_i_string_chars (s1);
-  c_s2 = scm_i_string_chars (s2);
-
-  result = compare_strings (c_s1, c_s2, locale, FUNC_NAME);
-
-  scm_remember_upto_here_2 (s1, s2);
+  result = compare_u32_strings (s1, s2, locale, FUNC_NAME);
 
   return scm_from_bool (result < 0);
 }
@@ -885,17 +910,11 @@ SCM_DEFINE (scm_string_locale_gt, "string-locale>?", 2, 
1, 0,
 #define FUNC_NAME s_scm_string_locale_gt
 {
   int result;
-  const char *c_s1, *c_s2;
 
   SCM_VALIDATE_STRING (1, s1);
   SCM_VALIDATE_STRING (2, s2);
 
-  c_s1 = scm_i_string_chars (s1);
-  c_s2 = scm_i_string_chars (s2);
-
-  result = compare_strings (c_s1, c_s2, locale, FUNC_NAME);
-
-  scm_remember_upto_here_2 (s1, s2);
+  result = compare_u32_strings (s1, s2, locale, FUNC_NAME);
 
   return scm_from_bool (result > 0);
 }
@@ -911,17 +930,11 @@ SCM_DEFINE (scm_string_locale_ci_lt, 
"string-locale-ci<?", 2, 1, 0,
 #define FUNC_NAME s_scm_string_locale_ci_lt
 {
   int result;
-  const char *c_s1, *c_s2;
 
   SCM_VALIDATE_STRING (1, s1);
   SCM_VALIDATE_STRING (2, s2);
 
-  c_s1 = scm_i_string_chars (s1);
-  c_s2 = scm_i_string_chars (s2);
-
-  result = compare_strings_ci (c_s1, c_s2, locale, FUNC_NAME);
-
-  scm_remember_upto_here_2 (s1, s2);
+  result = compare_u32_strings_ci (s1, s2, locale, FUNC_NAME);
 
   return scm_from_bool (result < 0);
 }
@@ -937,17 +950,11 @@ SCM_DEFINE (scm_string_locale_ci_gt, 
"string-locale-ci>?", 2, 1, 0,
 #define FUNC_NAME s_scm_string_locale_ci_gt
 {
   int result;
-  const char *c_s1, *c_s2;
 
   SCM_VALIDATE_STRING (1, s1);
   SCM_VALIDATE_STRING (2, s2);
 
-  c_s1 = scm_i_string_chars (s1);
-  c_s2 = scm_i_string_chars (s2);
-
-  result = compare_strings_ci (c_s1, c_s2, locale, FUNC_NAME);
-
-  scm_remember_upto_here_2 (s1, s2);
+  result = compare_u32_strings_ci (s1, s2, locale, FUNC_NAME);
 
   return scm_from_bool (result > 0);
 }
@@ -963,17 +970,11 @@ SCM_DEFINE (scm_string_locale_ci_eq, 
"string-locale-ci=?", 2, 1, 0,
 #define FUNC_NAME s_scm_string_locale_ci_eq
 {
   int result;
-  const char *c_s1, *c_s2;
 
   SCM_VALIDATE_STRING (1, s1);
   SCM_VALIDATE_STRING (2, s2);
 
-  c_s1 = scm_i_string_chars (s1);
-  c_s2 = scm_i_string_chars (s2);
-
-  result = compare_strings_ci (c_s1, c_s2, locale, FUNC_NAME);
-
-  scm_remember_upto_here_2 (s1, s2);
+  result = compare_u32_strings_ci (s1, s2, locale, FUNC_NAME);
 
   return scm_from_bool (result == 0);
 }
@@ -986,15 +987,16 @@ SCM_DEFINE (scm_char_locale_lt, "char-locale<?", 2, 1, 0,
            "according to @var{locale} or to the current locale.")
 #define FUNC_NAME s_scm_char_locale_lt
 {
-  char c_c1[2], c_c2[2];
+  int result;
 
   SCM_VALIDATE_CHAR (1, c1);
   SCM_VALIDATE_CHAR (2, c2);
 
-  c_c1[0] = (char)SCM_CHAR (c1); c_c1[1] = '\0';
-  c_c2[0] = (char)SCM_CHAR (c2); c_c2[1] = '\0';
+  result = compare_u32_strings (scm_string (scm_list_1 (c1)), 
+                                scm_string (scm_list_1 (c2)), 
+                                locale, FUNC_NAME);
 
-  return scm_from_bool (compare_strings (c_c1, c_c2, locale, FUNC_NAME) < 0);
+  return scm_from_bool (result < 0);
 }
 #undef FUNC_NAME
 
@@ -1004,15 +1006,16 @@ SCM_DEFINE (scm_char_locale_gt, "char-locale>?", 2, 1, 
0,
            "according to @var{locale} or to the current locale.")
 #define FUNC_NAME s_scm_char_locale_gt
 {
-  char c_c1[2], c_c2[2];
+  int result;
 
   SCM_VALIDATE_CHAR (1, c1);
   SCM_VALIDATE_CHAR (2, c2);
 
-  c_c1[0] = (char)SCM_CHAR (c1); c_c1[1] = '\0';
-  c_c2[0] = (char)SCM_CHAR (c2); c_c2[1] = '\0';
+  result = compare_u32_strings (scm_string (scm_list_1 (c1)), 
+                                scm_string (scm_list_1 (c2)), 
+                                locale, FUNC_NAME);
 
-  return scm_from_bool (compare_strings (c_c1, c_c2, locale, FUNC_NAME) > 0);
+  return scm_from_bool (result > 0);
 }
 #undef FUNC_NAME
 
@@ -1024,15 +1027,13 @@ SCM_DEFINE (scm_char_locale_ci_lt, "char-locale-ci<?", 
2, 1, 0,
 #define FUNC_NAME s_scm_char_locale_ci_lt
 {
   int result;
-  char c_c1[2], c_c2[2];
 
   SCM_VALIDATE_CHAR (1, c1);
   SCM_VALIDATE_CHAR (2, c2);
 
-  c_c1[0] = (char)SCM_CHAR (c1); c_c1[1] = '\0';
-  c_c2[0] = (char)SCM_CHAR (c2); c_c2[1] = '\0';
-
-  result = compare_strings_ci (c_c1, c_c2, locale, FUNC_NAME);
+  result = compare_u32_strings_ci (scm_string (scm_list_1 (c1)), 
+                                   scm_string (scm_list_1 (c2)), 
+                                   locale, FUNC_NAME);
 
   return scm_from_bool (result < 0);
 }
@@ -1046,15 +1047,13 @@ SCM_DEFINE (scm_char_locale_ci_gt, "char-locale-ci>?", 
2, 1, 0,
 #define FUNC_NAME s_scm_char_locale_ci_gt
 {
   int result;
-  char c_c1[2], c_c2[2];
 
   SCM_VALIDATE_CHAR (1, c1);
   SCM_VALIDATE_CHAR (2, c2);
 
-  c_c1[0] = (char)SCM_CHAR (c1); c_c1[1] = '\0';
-  c_c2[0] = (char)SCM_CHAR (c2); c_c2[1] = '\0';
-
-  result = compare_strings_ci (c_c1, c_c2, locale, FUNC_NAME);
+  result = compare_u32_strings_ci (scm_string (scm_list_1 (c1)), 
+                                   scm_string (scm_list_1 (c2)), 
+                                   locale, FUNC_NAME);
 
   return scm_from_bool (result > 0);
 }
@@ -1068,15 +1067,13 @@ SCM_DEFINE (scm_char_locale_ci_eq, "char-locale-ci=?", 
2, 1, 0,
 #define FUNC_NAME s_scm_char_locale_ci_eq
 {
   int result;
-  char c_c1[2], c_c2[2];
 
   SCM_VALIDATE_CHAR (1, c1);
   SCM_VALIDATE_CHAR (2, c2);
 
-  c_c1[0] = (char)SCM_CHAR (c1); c_c1[1] = '\0';
-  c_c2[0] = (char)SCM_CHAR (c2); c_c2[1] = '\0';
-
-  result = compare_strings_ci (c_c1, c_c2, locale, FUNC_NAME);
+  result = compare_u32_strings_ci (scm_string (scm_list_1 (c1)), 
+                                   scm_string (scm_list_1 (c2)), 
+                                   locale, FUNC_NAME);
 
   return scm_from_bool (result == 0);
 }


hooks/post-receive
-- 
GNU Guile




reply via email to

[Prev in Thread] Current Thread [Next in Thread]