[evolution-data-server] libedata-book: Avoid setlocale()



commit 8ed8d658dd727533e6ce92797f4171b393c4f2ee
Author: Mathias Hasselmann <mathias openismus com>
Date:   Thu Feb 28 23:46:39 2013 +0100

    libedata-book: Avoid setlocale()
    
    It is not thread-safe at it changes the entire program's locale
    settings. As a side effect also permit locale strings for functions
    like e_phone_number_get_country_code_for_region().

 .../libebook-contacts/e-phone-number-private.cpp   |   56 +++++----
 addressbook/libebook-contacts/e-phone-number.c     |    5 +-
 addressbook/libedata-book/e-book-backend-sexp.c    |  131 ++++++++++++--------
 .../libedata-book/e-book-backend-sqlitedb.c        |   85 ++++++++------
 4 files changed, 162 insertions(+), 115 deletions(-)
---
diff --git a/addressbook/libebook-contacts/e-phone-number-private.cpp 
b/addressbook/libebook-contacts/e-phone-number-private.cpp
index 9c7abbb..f0acc2b 100644
--- a/addressbook/libebook-contacts/e-phone-number-private.cpp
+++ b/addressbook/libebook-contacts/e-phone-number-private.cpp
@@ -89,33 +89,41 @@ e_phone_number_error_code (PhoneNumberUtil::ErrorType error)
 }
 
 static std::string
-e_phone_number_make_region_code (const gchar *region_code)
+_e_phone_number_cxx_region_code_from_locale (const gchar *locale)
 {
+       std::string current_region = locale;
+       const std::string::size_type uscore = current_region.find ('_');
+
+       if (uscore != std::string::npos) {
+               const std::string::size_type n = std::min (uscore + 3, current_region.length ());
+
+               if (n == current_region.length() || not ::isalpha(current_region.at(n)))
+                       current_region = current_region.substr (uscore + 1, 2);
+       }
+
+       if (current_region.length() != 2)
+               return "US";
+
+       return current_region;
+}
+
+static std::string
+_e_phone_number_cxx_make_region_code (const gchar *region_code)
+{
+       if (region_code && strlen (region_code) > 2)
+               return _e_phone_number_cxx_region_code_from_locale (region_code);
+
        /* Get two-letter country code from current locale's address facet if supported */
 #if HAVE__NL_ADDRESS_COUNTRY_AB2
        if (region_code == NULL || region_code[0] == '\0')
                region_code = nl_langinfo (_NL_ADDRESS_COUNTRY_AB2);
 #endif /* HAVE__NL_ADDRESS_COUNTRY_AB2 */
 
-       /* Extract two-letter country code from current locale id if needed */
-       if (region_code == NULL || region_code[0] == '\0') {
-               /* From outside this is a C library, so we better consult the
-                * C infrastructure instead of std::locale, which might divert. */
-               std::string current_region = setlocale (LC_ADDRESS, NULL);
-               const std::string::size_type uscore = current_region.find ('_');
-
-               if (uscore != std::string::npos) {
-                       const std::string::size_type n = std::min (uscore + 3, current_region.length ());
-
-                       if (n == current_region.length() || not ::isalpha(current_region.at(n)))
-                               current_region = current_region.substr (uscore + 1, 2);
-               }
-
-               if (current_region.length() != 2)
-                       return "US";
-
-               return current_region;
-       }
+       /* Extract two-letter country code from current locale id if needed.
+        * From outside this is a C library, so we better consult the
+         * C infrastructure instead of std::locale, which might divert. */
+       if (region_code == NULL || region_code[0] == '\0')
+               return _e_phone_number_cxx_region_code_from_locale (setlocale (LC_ADDRESS, NULL));
 
        return region_code;
 }
@@ -124,13 +132,13 @@ gint
 _e_phone_number_cxx_get_country_code_for_region (const gchar *region_code)
 {
        return e_phone_number_util_get_instance ()->GetCountryCodeForRegion (
-               e_phone_number_make_region_code (region_code));
+               _e_phone_number_cxx_make_region_code (region_code));
 }
 
 gchar *
 _e_phone_number_cxx_get_default_region ()
 {
-       return g_strdup (e_phone_number_make_region_code (NULL).c_str ());
+       return g_strdup (_e_phone_number_cxx_make_region_code (NULL).c_str ());
 }
 
 static bool
@@ -163,7 +171,7 @@ _e_phone_number_cxx_from_string (const gchar *phone_number,
 {
        g_return_val_if_fail (NULL != phone_number, NULL);
 
-       const std::string valid_region = e_phone_number_make_region_code (region_code);
+       const std::string valid_region = _e_phone_number_cxx_make_region_code (region_code);
        std::auto_ptr<EPhoneNumber> parsed_number(new EPhoneNumber);
 
        if (!_e_phone_number_cxx_parse (
@@ -320,7 +328,7 @@ _e_phone_number_cxx_compare_strings (const gchar *first_number,
        g_return_val_if_fail (NULL != first_number, E_PHONE_NUMBER_MATCH_NONE);
        g_return_val_if_fail (NULL != second_number, E_PHONE_NUMBER_MATCH_NONE);
 
-       const std::string region = e_phone_number_make_region_code (region_code);
+       const std::string region = _e_phone_number_cxx_make_region_code (region_code);
        PhoneNumber pn1, pn2;
 
        if (!_e_phone_number_cxx_parse (first_number, region, &pn1, error))
diff --git a/addressbook/libebook-contacts/e-phone-number.c b/addressbook/libebook-contacts/e-phone-number.c
index 6194f69..b8f7c2b 100644
--- a/addressbook/libebook-contacts/e-phone-number.c
+++ b/addressbook/libebook-contacts/e-phone-number.c
@@ -94,10 +94,11 @@ e_phone_number_is_supported (void)
 
 /**
  * e_phone_number_get_country_code_for_region:
- * @region_code: (allow-none): a two-letter country code, or %NULL
+ * @region_code: (allow-none): a two-letter country code, a locale name, or
+ * %NULL
  *
  * Retrieves the preferred country calling code for @region_code,
- * e.g. 358 for "fi".
+ * e.g. 358 for "fi" or 1 for "en_US UTF-8".
  *
  * If %NULL is passed for @region_code the default region as returned by
  * e_phone_number_get_default_region() is used.
diff --git a/addressbook/libedata-book/e-book-backend-sexp.c b/addressbook/libedata-book/e-book-backend-sexp.c
index 9ca37a0..3cd220f 100644
--- a/addressbook/libedata-book/e-book-backend-sexp.c
+++ b/addressbook/libedata-book/e-book-backend-sexp.c
@@ -30,7 +30,7 @@
 G_DEFINE_TYPE (EBookBackendSExp, e_book_backend_sexp, G_TYPE_OBJECT)
 
 typedef struct _SearchContext SearchContext;
-typedef gboolean (*CompareFunc) (const gchar *, const gchar *);
+typedef gboolean (*CompareFunc) (const gchar *, const gchar *, const gchar *);
 
 struct _EBookBackendSExpPrivate {
        ESExp *search_sexp;
@@ -45,6 +45,7 @@ struct _SearchContext {
 static gboolean
 compare_im (EContact *contact,
             const gchar *str,
+            const gchar *region,
             CompareFunc compare,
             EContactField im_field)
 {
@@ -56,7 +57,7 @@ compare_im (EContact *contact,
        for (l = aims; l != NULL; l = l->next) {
                gchar *im = (gchar *) l->data;
 
-               if (im && compare (im, str)) {
+               if (im && compare (im, str, region)) {
                        found_it = TRUE;
                        break;
                }
@@ -70,78 +71,88 @@ compare_im (EContact *contact,
 static gboolean
 compare_im_aim (EContact *contact,
                 const gchar *str,
+                const gchar *region,
                 CompareFunc compare)
 {
-       return compare_im (contact, str, compare, E_CONTACT_IM_AIM);
+       return compare_im (contact, str, region, compare, E_CONTACT_IM_AIM);
 }
 
 static gboolean
 compare_im_msn (EContact *contact,
                 const gchar *str,
+                const gchar *region,
                 CompareFunc compare)
 {
-       return compare_im (contact, str, compare, E_CONTACT_IM_MSN);
+       return compare_im (contact, str, region, compare, E_CONTACT_IM_MSN);
 }
 
 static gboolean
 compare_im_skype (EContact *contact,
                   const gchar *str,
+                  const gchar *region,
                   CompareFunc compare)
 {
-       return compare_im (contact, str, compare, E_CONTACT_IM_SKYPE);
+       return compare_im (contact, str, region, compare, E_CONTACT_IM_SKYPE);
 }
 
 static gboolean
 compare_im_google_talk (EContact *contact,
                         const gchar *str,
+                        const gchar *region,
                         CompareFunc compare)
 {
-       return compare_im (contact, str, compare, E_CONTACT_IM_GOOGLE_TALK);
+       return compare_im (contact, str, region, compare, E_CONTACT_IM_GOOGLE_TALK);
 }
 
 static gboolean
 compare_im_icq (EContact *contact,
                 const gchar *str,
+                const gchar *region,
                 CompareFunc compare)
 {
-       return compare_im (contact, str, compare, E_CONTACT_IM_ICQ);
+       return compare_im (contact, str, region, compare, E_CONTACT_IM_ICQ);
 }
 
 static gboolean
 compare_im_yahoo (EContact *contact,
                   const gchar *str,
+                  const gchar *region,
                   CompareFunc compare)
 {
-       return compare_im (contact, str, compare, E_CONTACT_IM_YAHOO);
+       return compare_im (contact, str, region, compare, E_CONTACT_IM_YAHOO);
 }
 
 static gboolean
 compare_im_gadugadu (EContact *contact,
                      const gchar *str,
+                     const gchar *region,
                      CompareFunc compare)
 {
-       return compare_im (contact, str, compare, E_CONTACT_IM_GADUGADU);
+       return compare_im (contact, str, region, compare, E_CONTACT_IM_GADUGADU);
 }
 
 static gboolean
 compare_im_jabber (EContact *contact,
                    const gchar *str,
+                   const gchar *region,
                    CompareFunc compare)
 {
-       return compare_im (contact, str, compare, E_CONTACT_IM_JABBER);
+       return compare_im (contact, str, region, compare, E_CONTACT_IM_JABBER);
 }
 
 static gboolean
 compare_im_groupwise (EContact *contact,
                       const gchar *str,
+                      const gchar *region,
                       CompareFunc compare)
 {
-       return compare_im (contact, str, compare, E_CONTACT_IM_GROUPWISE);
+       return compare_im (contact, str, region, compare, E_CONTACT_IM_GROUPWISE);
 }
 
 static gboolean
 compare_email (EContact *contact,
                const gchar *str,
+               const gchar *region,
                CompareFunc compare)
 {
        gboolean rv = FALSE;
@@ -152,7 +163,7 @@ compare_email (EContact *contact,
        for (l = list; l; l = l->next) {
                const gchar *email = l->data;
 
-               rv = email && compare (email, str);
+               rv = email && compare (email, str, region);
 
                if (rv)
                        break;
@@ -166,6 +177,7 @@ compare_email (EContact *contact,
 static gboolean
 compare_phone (EContact *contact,
                const gchar *str,
+               const gchar *region,
                CompareFunc compare)
 {
        GList *list, *l;
@@ -176,7 +188,7 @@ compare_phone (EContact *contact,
        for (l = list; l; l = l->next) {
                const gchar *phone = l->data;
 
-               rv = phone && compare (phone, str);
+               rv = phone && compare (phone, str, region);
 
                if (rv)
                        break;
@@ -190,24 +202,25 @@ compare_phone (EContact *contact,
 static gboolean
 compare_name (EContact *contact,
               const gchar *str,
+              const gchar *region,
               CompareFunc compare)
 {
        const gchar *name;
 
        name = e_contact_get_const (contact, E_CONTACT_FULL_NAME);
-       if (name && compare (name, str))
+       if (name && compare (name, str, region))
                return TRUE;
 
        name = e_contact_get_const (contact, E_CONTACT_FAMILY_NAME);
-       if (name && compare (name, str))
+       if (name && compare (name, str, region))
                return TRUE;
 
        name = e_contact_get_const (contact, E_CONTACT_GIVEN_NAME);
-       if (name && compare (name, str))
+       if (name && compare (name, str, region))
                return TRUE;
 
        name = e_contact_get_const (contact, E_CONTACT_NICKNAME);
-       if (name && compare (name, str))
+       if (name && compare (name, str, region))
                return TRUE;
 
        return FALSE;
@@ -216,6 +229,7 @@ compare_name (EContact *contact,
 static gboolean
 compare_photo_uri (EContact *contact,
                    const gchar *str,
+                   const gchar *region,
                    CompareFunc compare)
 {
        EContactPhoto *photo;
@@ -226,7 +240,7 @@ compare_photo_uri (EContact *contact,
        if (photo) {
                /* Compare the photo uri with the string */
                if ((photo->type == E_CONTACT_PHOTO_TYPE_URI)
-                    && compare (photo->data.uri, str)) {
+                    && compare (photo->data.uri, str, region)) {
                        ret_val = TRUE;
                }
                e_contact_photo_free (photo);
@@ -237,6 +251,7 @@ compare_photo_uri (EContact *contact,
 static gboolean
 compare_address (EContact *contact,
                  const gchar *str,
+                 const gchar *region,
                  CompareFunc compare)
 {
 
@@ -246,13 +261,13 @@ compare_address (EContact *contact,
        for (i = E_CONTACT_FIRST_ADDRESS_ID; i <= E_CONTACT_LAST_ADDRESS_ID; i++) {
                EContactAddress *address = e_contact_get (contact, i);
                if (address) {
-                       rv =  (address->po && compare (address->po, str)) ||
-                               (address->street && compare (address->street, str)) ||
-                               (address->ext && compare (address->ext, str)) ||
-                               (address->locality && compare (address->locality, str)) ||
-                               (address->region && compare (address->region, str)) ||
-                               (address->code && compare (address->code, str)) ||
-                               (address->country && compare (address->country, str));
+                       rv =  (address->po && compare (address->po, str, region)) ||
+                               (address->street && compare (address->street, str, region)) ||
+                               (address->ext && compare (address->ext, str, region)) ||
+                               (address->locality && compare (address->locality, str, region)) ||
+                               (address->region && compare (address->region, str, region)) ||
+                               (address->code && compare (address->code, str, region)) ||
+                               (address->country && compare (address->country, str, region));
 
                        e_contact_address_free (address);
 
@@ -268,6 +283,7 @@ compare_address (EContact *contact,
 static gboolean
 compare_category (EContact *contact,
                   const gchar *str,
+                  const gchar *region,
                   CompareFunc compare)
 {
        GList *categories;
@@ -279,7 +295,7 @@ compare_category (EContact *contact,
        for (iterator = categories; iterator; iterator = iterator->next) {
                const gchar *category = iterator->data;
 
-               if (compare (category, str)) {
+               if (compare (category, str, region)) {
                        ret_val = TRUE;
                        break;
                }
@@ -294,13 +310,14 @@ compare_category (EContact *contact,
 static gboolean
 compare_date (EContactDate *date,
               const gchar *str,
+              const gchar *region,
               CompareFunc compare)
 {
        gchar *date_str = e_contact_date_to_string (date);
        gboolean ret_val = FALSE;
 
        if (date_str) {
-               if (compare (date_str, str)) {
+               if (compare (date_str, str, region)) {
                        ret_val = TRUE;
                }
                g_free (date_str);
@@ -320,6 +337,7 @@ static struct prop_info {
        enum prop_type prop_type;
        gboolean (*list_compare) (EContact *contact,
                                  const gchar *str,
+                                 const gchar *region,
                                  CompareFunc compare);
 
 } prop_info_table[] = {
@@ -378,7 +396,6 @@ entry_compare (SearchContext *ctx,
 {
        ESExpResult *r;
        gint truth = FALSE;
-       const gchar *saved_locale = NULL;
 
        if ((argc == 2
                && argv[0]->type == ESEXP_RES_STRING
@@ -389,12 +406,13 @@ entry_compare (SearchContext *ctx,
                && argv[2]->type == ESEXP_RES_STRING)) {
                gchar *propname;
                struct prop_info *info = NULL;
+               const gchar *region = NULL;
                gint i;
                gboolean any_field;
                gboolean saw_any = FALSE;
 
                if (argc > 2)
-                       saved_locale = setlocale (LC_ADDRESS, argv[2]->value.string);
+                       region = argv[2]->value.string;
 
                propname = argv[0]->value.string;
 
@@ -418,16 +436,16 @@ entry_compare (SearchContext *ctx,
 
                                        prop = e_contact_get_const (ctx->contact, info->field_id);
 
-                                       if (prop && compare (prop, argv[1]->value.string)) {
+                                       if (prop && compare (prop, argv[1]->value.string, region)) {
                                                truth = TRUE;
                                        }
-                                       if ((!prop) && compare ("", argv[1]->value.string)) {
+                                       if ((!prop) && compare ("", argv[1]->value.string, region)) {
                                                truth = TRUE;
                                        }
                                }
                                else if (info->prop_type == PROP_TYPE_LIST) {
                                        /* the special searches that match any of the list elements */
-                                       truth = info->list_compare (ctx->contact, argv[1]->value.string, 
compare);
+                                       truth = info->list_compare (ctx->contact, argv[1]->value.string, 
region, compare);
                                }
                                else if (info->prop_type == PROP_TYPE_DATE) {
                                        /* the special searches that match dates */
@@ -436,7 +454,7 @@ entry_compare (SearchContext *ctx,
                                        date = e_contact_get (ctx->contact, info->field_id);
 
                                        if (date) {
-                                               truth = compare_date (date, argv[1]->value.string, compare);
+                                               truth = compare_date (date, argv[1]->value.string, region, 
compare);
                                                e_contact_date_free (date);
                                        }
                                } else {
@@ -464,11 +482,11 @@ entry_compare (SearchContext *ctx,
                        if (fid >= E_CONTACT_FIELD_FIRST && fid < E_CONTACT_FIELD_LAST) {
                                const gchar *prop = e_contact_get_const (ctx->contact, fid);
 
-                               if (prop && compare (prop, argv[1]->value.string)) {
+                               if (prop && compare (prop, argv[1]->value.string, region)) {
                                        truth = TRUE;
                                }
 
-                               if ((!prop) && compare ("", argv[1]->value.string)) {
+                               if ((!prop) && compare ("", argv[1]->value.string, region)) {
                                        truth = TRUE;
                                }
                        } else {
@@ -483,9 +501,9 @@ entry_compare (SearchContext *ctx,
                                                for (l = values; l && !truth; l = l->next) {
                                                        const gchar *value = l->data;
 
-                                                       if (value && compare (value, argv[1]->value.string)) {
+                                                       if (value && compare (value, argv[1]->value.string, 
region)) {
                                                                truth = TRUE;
-                                                       } else if ((!value) && compare ("", 
argv[1]->value.string)) {
+                                                       } else if ((!value) && compare ("", 
argv[1]->value.string, region)) {
                                                                truth = TRUE;
                                                        }
                                                }
@@ -495,9 +513,6 @@ entry_compare (SearchContext *ctx,
                }
        }
 
-       if (saved_locale)
-               saved_locale = setlocale (LC_ADDRESS, saved_locale);
-
        r = e_sexp_result_new (f, ESEXP_RES_BOOL);
        r->value.boolean = truth;
 
@@ -566,7 +581,8 @@ try_contains_word (const gchar *s1,
 */
 static gboolean
 contains_helper (const gchar *s1,
-                 const gchar *s2)
+                 const gchar *s2,
+                 const gchar *region)
 {
        gchar *s1uni;
        gchar *s2uni;
@@ -669,7 +685,8 @@ func_contains (struct _ESExp *f,
 
 static gboolean
 is_helper (const gchar *ps1,
-           const gchar *ps2)
+           const gchar *ps2,
+           const gchar *region)
 {
        gchar *s1, *s2;
        gboolean res = FALSE;
@@ -699,7 +716,8 @@ func_is (struct _ESExp *f,
 
 static gboolean
 endswith_helper (const gchar *ps1,
-                 const gchar *ps2)
+                 const gchar *ps2,
+                 const gchar *region)
 {
        gchar *s1 = e_util_utf8_remove_accents (ps1);
        gchar *s2 = e_util_utf8_remove_accents (ps2);
@@ -731,7 +749,8 @@ func_endswith (struct _ESExp *f,
 
 static gboolean
 beginswith_helper (const gchar *ps1,
-                   const gchar *ps2)
+                   const gchar *ps2,
+                   const gchar *region)
 {
        gchar *p;
        gboolean res = FALSE;
@@ -762,10 +781,12 @@ func_beginswith (struct _ESExp *f,
 static gboolean
 eqphone_helper (const gchar *ps1,
                 const gchar *ps2,
+                const gchar *region,
                 EPhoneNumberMatch required_match)
 {
        const EPhoneNumberMatch actual_match =
-               e_phone_number_compare_strings (ps1, ps2, NULL);
+               e_phone_number_compare_strings_with_region (
+                       ps1, ps2, region, NULL);
 
        return actual_match >= E_PHONE_NUMBER_MATCH_EXACT
                && actual_match <= required_match;
@@ -773,23 +794,26 @@ eqphone_helper (const gchar *ps1,
 
 static gboolean
 eqphone_exact_helper (const gchar *ps1,
-                      const gchar *ps2)
+                      const gchar *ps2,
+                      const gchar *region)
 {
-       return eqphone_helper (ps1, ps2, E_PHONE_NUMBER_MATCH_EXACT);
+       return eqphone_helper (ps1, ps2, region, E_PHONE_NUMBER_MATCH_EXACT);
 }
 
 static gboolean
 eqphone_national_helper (const gchar *ps1,
-                         const gchar *ps2)
+                         const gchar *ps2,
+                         const gchar *region)
 {
-       return eqphone_helper (ps1, ps2, E_PHONE_NUMBER_MATCH_NATIONAL);
+       return eqphone_helper (ps1, ps2, region, E_PHONE_NUMBER_MATCH_NATIONAL);
 }
 
 static gboolean
 eqphone_short_helper (const gchar *ps1,
-                      const gchar *ps2)
+                      const gchar *ps2,
+                      const gchar *region)
 {
-       return eqphone_helper (ps1, ps2, E_PHONE_NUMBER_MATCH_SHORT);
+       return eqphone_helper (ps1, ps2, region, E_PHONE_NUMBER_MATCH_SHORT);
 }
 
 static ESExpResult *
@@ -827,7 +851,8 @@ func_eqphone_short (struct _ESExp *f,
 
 static gboolean
 exists_helper (const gchar *ps1,
-               const gchar *ps2)
+               const gchar *ps2,
+               const gchar *region)
 {
        gboolean res = FALSE;
        gchar *s1 = e_util_utf8_remove_accents (ps1);
@@ -878,7 +903,7 @@ func_exists (struct _ESExp *f,
                                }
                                else if (info->prop_type == PROP_TYPE_LIST) {
                                        /* the special searches that match any of the list elements */
-                                       truth = info->list_compare (ctx->contact, "", exists_helper);
+                                       truth = info->list_compare (ctx->contact, "", NULL, exists_helper);
                                }
                                else if (info->prop_type == PROP_TYPE_DATE) {
                                        EContactDate *date;
diff --git a/addressbook/libedata-book/e-book-backend-sqlitedb.c 
b/addressbook/libedata-book/e-book-backend-sqlitedb.c
index c93891a..f729442 100644
--- a/addressbook/libedata-book/e-book-backend-sqlitedb.c
+++ b/addressbook/libedata-book/e-book-backend-sqlitedb.c
@@ -1800,7 +1800,8 @@ insert_stmt_from_contact (EBookBackendSqliteDB *ebsdb,
 }
 
 static void
-update_e164_attribute_params (EVCard *vcard)
+update_e164_attribute_params (EVCard *vcard,
+                             const gchar *default_region)
 {
        GList *attr_list;
 
@@ -1816,7 +1817,10 @@ update_e164_attribute_params (EVCard *vcard)
 
                /* Compute E164 number. */
                values = e_vcard_attribute_get_values (attr);
-               e164 = values && values->data ? convert_phone (values->data, NULL) : NULL;
+
+               e164 = values && values->data
+                       ? convert_phone (values->data, default_region)
+                       : NULL;
 
                if (e164 == NULL) {
                        e_vcard_attribute_remove_param (attr, EVC_X_E164);
@@ -1880,7 +1884,7 @@ insert_contact (EBookBackendSqliteDB *ebsdb,
 
        /* Update E.164 parameters in vcard if needed */
        if (priv->store_vcard)
-               update_e164_attribute_params (E_VCARD (contact));
+               update_e164_attribute_params (E_VCARD (contact), default_region);
 
        /* Update main summary table */
        stmt = insert_stmt_from_contact (ebsdb, contact, folderid, priv->store_vcard, replace_existing, 
default_region);
@@ -2988,9 +2992,10 @@ extract_digits (const gchar *normal)
 
 static gchar *
 convert_string_value (EBookBackendSqliteDB *ebsdb,
-                      const gchar *value,
-                      ConvertFlags flags,
-                      MatchType match)
+                     const gchar          *value,
+                     const gchar          *region,
+                     ConvertFlags          flags,
+                     MatchType             match)
 {
        GString *str;
        size_t len;
@@ -3034,7 +3039,7 @@ convert_string_value (EBookBackendSqliteDB *ebsdb,
                computed = g_utf8_strreverse (normal, -1);
                ptr = computed;
        } else if (flags & CONVERT_PHONE) {
-               computed = convert_phone (normal, NULL);
+               computed = convert_phone (normal, region);
                ptr = computed;
        } else {
                ptr = normal;
@@ -3078,13 +3083,14 @@ convert_string_value (EBookBackendSqliteDB *ebsdb,
 
 static gchar *
 field_name_and_query_term (EBookBackendSqliteDB *ebsdb,
-                           const gchar *folderid,
-                           const gchar *field_name_input,
-                           const gchar *query_term_input,
-                           MatchType match,
-                           gboolean *is_list_attr,
-                           gchar **query_term,
-                           gchar **extra_term)
+                          const gchar          *folderid,
+                          const gchar          *field_name_input,
+                          const gchar          *query_term_input,
+                          const gchar          *region,
+                          MatchType             match,
+                          gboolean             *is_list_attr,
+                          gchar               **query_term,
+                          gchar               **extra_term)
 {
        gint summary_index;
        gchar *field_name = NULL;
@@ -3097,7 +3103,9 @@ field_name_and_query_term (EBookBackendSqliteDB *ebsdb,
        if (summary_index < 0) {
                g_critical ("Only summary field matches should be converted to sql queries");
                field_name = g_strconcat (folderid, ".", field_name_input, NULL);
-               value = convert_string_value (ebsdb, query_term_input, CONVERT_NORMALIZE, match);
+               value = convert_string_value (
+                       ebsdb, query_term_input, region,
+                       CONVERT_NORMALIZE, match);
        } else {
                gboolean suffix_search = FALSE;
                gboolean phone_search = FALSE;
@@ -3139,18 +3147,19 @@ field_name_and_query_term (EBookBackendSqliteDB *ebsdb,
                        if (ebsdb->priv->summary_fields[summary_index].field == E_CONTACT_UID ||
                            ebsdb->priv->summary_fields[summary_index].field == E_CONTACT_REV)
                                value = convert_string_value (
-                                       ebsdb, query_term_input, CONVERT_REVERSE,
+                                       ebsdb, query_term_input, region, CONVERT_REVERSE,
                                        (match == MATCH_ENDS_WITH) ? MATCH_BEGINS_WITH : MATCH_IS);
                        else
                                value = convert_string_value (
-                                       ebsdb, query_term_input, CONVERT_REVERSE | CONVERT_NORMALIZE,
+                                       ebsdb, query_term_input, region,
+                                       CONVERT_REVERSE | CONVERT_NORMALIZE,
                                        (match == MATCH_ENDS_WITH) ? MATCH_BEGINS_WITH : MATCH_IS);
                } else if (phone_search) {
                        /* Special case for E.164 matching:
                         *  o Normalize the string
                         *  o Check the E.164 column instead
                         */
-                       const gint country_code = e_phone_number_get_country_code_for_region (NULL);
+                       const gint country_code = e_phone_number_get_country_code_for_region (region);
 
                        if (ebsdb->priv->summary_fields[summary_index].type == E_TYPE_CONTACT_ATTR_LIST) {
                                field_name = g_strdup ("multi.value_phone");
@@ -3165,16 +3174,20 @@ field_name_and_query_term (EBookBackendSqliteDB *ebsdb,
                                extra = g_strdup_printf (" COLLATE ixphone_%d", country_code);
 
                                value = convert_string_value (
-                                       ebsdb, query_term_input,
+                                       ebsdb, query_term_input, region,
                                        CONVERT_NORMALIZE | CONVERT_PHONE, match);
                        } else {
                                extra = g_strdup (" COLLATE ixphone_nn");
 
                                if (match == MATCH_NATIONAL_PHONE_NUMBER) {
-                                       value = convert_string_value (ebsdb, query_term_input, CONVERT_PHONE, 
MATCH_NATIONAL_PHONE_NUMBER);
+                                       value = convert_string_value (
+                                               ebsdb, query_term_input, region,
+                                               CONVERT_PHONE, MATCH_NATIONAL_PHONE_NUMBER);
                                } else {
                                        gchar *const digits = extract_digits (query_term_input);
-                                       value = convert_string_value (ebsdb, digits, CONVERT_NOTHING, 
MATCH_ENDS_WITH);
+                                       value = convert_string_value (
+                                               ebsdb, digits, region,
+                                               CONVERT_NOTHING, MATCH_ENDS_WITH);
                                        g_free (digits);
                                }
 
@@ -3189,10 +3202,15 @@ field_name_and_query_term (EBookBackendSqliteDB *ebsdb,
                                        ebsdb->priv->summary_fields[summary_index].dbname, NULL);
 
                        if (ebsdb->priv->summary_fields[summary_index].field == E_CONTACT_UID ||
-                           ebsdb->priv->summary_fields[summary_index].field == E_CONTACT_REV)
-                               value = convert_string_value (ebsdb, query_term_input, CONVERT_NOTHING, 
match);
-                       else
-                               value = convert_string_value (ebsdb, query_term_input, CONVERT_NORMALIZE, 
match);
+                           ebsdb->priv->summary_fields[summary_index].field == E_CONTACT_REV) {
+                               value = convert_string_value (
+                                       ebsdb, query_term_input, region,
+                                       CONVERT_NOTHING, match);
+                       } else {
+                               value = convert_string_value (
+                                       ebsdb, query_term_input, region,
+                                       CONVERT_NORMALIZE, match);
+                       }
                }
        }
 
@@ -3259,7 +3277,7 @@ convert_match_exp (struct _ESExp *f,
 
                                field_name = field_name_and_query_term (
                                        ebsdb, qdata->folderid, "full_name",
-                                       argv[1]->value.string,
+                                       argv[1]->value.string, NULL,
                                        match, NULL, &query_term, NULL);
                                g_string_append_printf (
                                        names, "(%s IS NOT NULL AND %s %s %s)",
@@ -3270,7 +3288,7 @@ convert_match_exp (struct _ESExp *f,
                                if (summary_dbname_from_field (ebsdb, E_CONTACT_FAMILY_NAME)) {
                                        field_name = field_name_and_query_term (
                                                ebsdb, qdata->folderid, "family_name",
-                                               argv[1]->value.string,
+                                               argv[1]->value.string, NULL,
                                                match, NULL, &query_term, NULL);
                                        g_string_append_printf (
                                                names, " OR (%s IS NOT NULL AND %s %s %s)",
@@ -3282,7 +3300,7 @@ convert_match_exp (struct _ESExp *f,
                                if (summary_dbname_from_field (ebsdb, E_CONTACT_GIVEN_NAME)) {
                                        field_name = field_name_and_query_term (
                                                ebsdb, qdata->folderid, "given_name",
-                                               argv[1]->value.string,
+                                               argv[1]->value.string, NULL,
                                                match, NULL, &query_term, NULL);
                                        g_string_append_printf (
                                                names, " OR (%s IS NOT NULL AND %s %s %s)",
@@ -3294,7 +3312,7 @@ convert_match_exp (struct _ESExp *f,
                                if (summary_dbname_from_field (ebsdb, E_CONTACT_NICKNAME)) {
                                        field_name = field_name_and_query_term (
                                                ebsdb, qdata->folderid, "nickname",
-                                               argv[1]->value.string,
+                                               argv[1]->value.string, NULL,
                                                match, NULL, &query_term, NULL);
                                        g_string_append_printf (
                                                names, " OR (%s IS NOT NULL AND %s %s %s)",
@@ -3307,18 +3325,16 @@ convert_match_exp (struct _ESExp *f,
                                g_string_free (names, FALSE);
 
                        } else {
-                               const gchar *const query_locale =
+                               const gchar *const region =
                                        argc > 2 && argv[2]->type == ESEXP_RES_STRING ?
                                        argv[2]->value.string : NULL;
-                               const gchar *const saved_locale = query_locale ?
-                                       setlocale (LC_ADDRESS, query_locale) : NULL;
 
                                gboolean is_list = FALSE;
 
                                /* This should ideally be the only valid case from all the above special 
casing, but oh well... */
                                field_name = field_name_and_query_term (
                                        ebsdb, qdata->folderid, field,
-                                       argv[1]->value.string,
+                                       argv[1]->value.string, region,
                                        match, &is_list, &query_term, &extra_term);
 
                                /* User functions like eqphone_national() cannot utilize indexes. Therefore we
@@ -3342,9 +3358,6 @@ convert_match_exp (struct _ESExp *f,
 
                                g_free (field_name);
                                g_free (query_term);
-
-                               if (saved_locale)
-                                       setlocale (LC_ADDRESS, saved_locale);
                        }
                }
        }


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