[evolution-data-server] libebook: Better region guessing for phone numbers



commit 287d18208323c20480ad9806f430e2b8257d8007
Author: Mathias Hasselmann <mathias openismus com>
Date:   Fri Jan 25 07:59:05 2013 +0100

    libebook: Better region guessing for phone numbers
    
    Extract country code from current locale id if needed, that is because
    _NL_ADDRESS_COUNTRY_AB2 is missing or gives bad information.
    
    See: https://bugzilla.gnome.org/show_bug.cgi?id=689622

 addressbook/libebook/e-phone-number-private.cpp |   30 ++++++++++++----
 addressbook/libebook/e-phone-number-private.h   |    2 +-
 addressbook/libebook/e-phone-number.c           |   10 +++---
 addressbook/libebook/e-phone-number.h           |    2 +-
 tests/libebook/test-ebook-phone-number.c        |   44 ++++++++++++++++++++++-
 5 files changed, 73 insertions(+), 15 deletions(-)
---
diff --git a/addressbook/libebook/e-phone-number-private.cpp b/addressbook/libebook/e-phone-number-private.cpp
index 5679f52..4dd5720 100644
--- a/addressbook/libebook/e-phone-number-private.cpp
+++ b/addressbook/libebook/e-phone-number-private.cpp
@@ -34,6 +34,7 @@
 
 /* system headers */
 #include <langinfo.h>
+#include <locale.h>
 
 /* libphonenumber */
 #include <phonenumbers/logger.h>
@@ -88,23 +89,38 @@ e_phone_number_error_code (PhoneNumberUtil::ErrorType error)
 
 EPhoneNumber *
 _e_phone_number_cxx_from_string (const gchar *phone_number,
-                                 const gchar *country_code,
+                                 const gchar *region_code,
                                  GError **error)
 {
 	g_return_val_if_fail (NULL != phone_number, NULL);
 
-	if (country_code == NULL) {
+	std::string valid_region;
+
+	/* Get country code from current locale's address facet if supported */
 #if HAVE__NL_ADDRESS_COUNTRY_AB2
-		country_code = nl_langinfo (_NL_ADDRESS_COUNTRY_AB2);
-#else /* HAVE__NL_ADDRESS_COUNTRY_AB2 */
-#error Cannot resolve default 2-letter country code. Find a replacement for _NL_ADDRESS_COUNTRY_AB2 or implement code to parse the locale name.
+	if (region_code == NULL || region_code[0] == '\0')
+		region_code = nl_langinfo (_NL_ADDRESS_COUNTRY_AB2);
 #endif /* HAVE__NL_ADDRESS_COUNTRY_AB2 */
+
+	/* Extract 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. */
+		valid_region = setlocale (LC_ADDRESS, NULL);
+
+		const std::string::size_type underscore = valid_region.find ('_');
+
+		if (underscore != std::string::npos)
+			valid_region.resize (underscore);
+	} else {
+		valid_region = region_code;
 	}
 
+	/* Now finally parse the phone number */
 	std::auto_ptr<EPhoneNumber> parsed_number(new EPhoneNumber);
 
 	const PhoneNumberUtil::ErrorType err =
-		e_phone_number_util_get_instance ()->Parse (phone_number, country_code,
+		e_phone_number_util_get_instance ()->Parse (phone_number, valid_region,
 		                                            &parsed_number->phone_number);
 
 	if (err != PhoneNumberUtil::NO_PARSING_ERROR) {
@@ -112,7 +128,7 @@ _e_phone_number_cxx_from_string (const gchar *phone_number,
 		return NULL;
 	}
 
-	return parsed_number.release();
+	return parsed_number.release ();
 }
 
 gchar *
diff --git a/addressbook/libebook/e-phone-number-private.h b/addressbook/libebook/e-phone-number-private.h
index 091f18e..c5a4d0e 100644
--- a/addressbook/libebook/e-phone-number-private.h
+++ b/addressbook/libebook/e-phone-number-private.h
@@ -58,7 +58,7 @@ E_PHONE_NUMBER_LOCAL void		_e_phone_number_set_error		(GError **error,
 /* defined in e-phone-number-private.cpp, and used by by e-phone-number.c */
 
 E_PHONE_NUMBER_LOCAL EPhoneNumber *	_e_phone_number_cxx_from_string		(const gchar *phone_number,
-										 const gchar *country_code,
+										 const gchar *region,
 										 GError **error);
 E_PHONE_NUMBER_LOCAL gchar *		_e_phone_number_cxx_to_string		(const EPhoneNumber *phone_number,
 										 EPhoneNumberFormat format);
diff --git a/addressbook/libebook/e-phone-number.c b/addressbook/libebook/e-phone-number.c
index dee3bac..b9795af 100644
--- a/addressbook/libebook/e-phone-number.c
+++ b/addressbook/libebook/e-phone-number.c
@@ -93,16 +93,16 @@ e_phone_number_is_supported (void)
 /**
  * e_phone_number_from_string:
  * @phone_number: the phone number to parse
- * @country_code: (allow-none): a 2-letter country code, or %NULL
+ * @region_code: (allow-none): a 2-letter country code, or %NULL
  * @error: (out): a #GError to set an error, if any
  *
  * Parses the string passed in @phone_number. Note that no validation is
  * performed whether the recognized phone number is valid for a particular
  * region.
  *
- * The 2-letter country code passed in @country_code only is used if the
+ * The 2-letter country code passed in @region_code only is used if the
  * @phone_number is not written in international format. The applications's
- * currently locale is consulted if %NULL gets passed for @country_code.
+ * currently locale is consulted if %NULL gets passed for @region_code.
  * If the number is guaranteed to start with a '+' followed by the country
  * calling code, then "ZZ" can be passed here.
  *
@@ -113,12 +113,12 @@ e_phone_number_is_supported (void)
  **/
 EPhoneNumber *
 e_phone_number_from_string (const gchar *phone_number,
-                            const gchar *country_code,
+                            const gchar *region_code,
                             GError **error)
 {
 #ifdef ENABLE_PHONENUMBER
 
-	return _e_phone_number_cxx_from_string (phone_number, country_code, error);
+	return _e_phone_number_cxx_from_string (phone_number, region_code, error);
 
 #else /* ENABLE_PHONENUMBER */
 
diff --git a/addressbook/libebook/e-phone-number.h b/addressbook/libebook/e-phone-number.h
index 2e33835..7187482 100644
--- a/addressbook/libebook/e-phone-number.h
+++ b/addressbook/libebook/e-phone-number.h
@@ -169,7 +169,7 @@ GQuark			e_phone_number_error_quark	(void);
 gboolean		e_phone_number_is_supported	(void) G_GNUC_CONST;
 
 EPhoneNumber *		e_phone_number_from_string	(const gchar *phone_number,
-							 const gchar *country_code,
+							 const gchar *region_code,
 							 GError **error);
 gchar *			e_phone_number_to_string	(const EPhoneNumber *phone_number,
 							 EPhoneNumberFormat format);
diff --git a/tests/libebook/test-ebook-phone-number.c b/tests/libebook/test-ebook-phone-number.c
index 9d9e740..219873f 100644
--- a/tests/libebook/test-ebook-phone-number.c
+++ b/tests/libebook/test-ebook-phone-number.c
@@ -24,6 +24,7 @@
 #endif
 
 #include <libebook/libebook.h>
+#include <locale.h>
 
 static const char *match_candidates[] = {
 	"not-a-number",
@@ -185,6 +186,41 @@ test_parse_bad_number (void)
 }
 
 static void
+test_parse_auto_region (void)
+{
+	GError *error = NULL;
+	EPhoneNumber *parsed;
+
+	parsed = e_phone_number_from_string ("212-5423789", NULL, &error);
+
+#ifdef ENABLE_PHONENUMBER
+
+	{
+		gchar *formatted;
+
+		g_assert (parsed != NULL);
+		g_assert (error == NULL);
+
+		formatted = e_phone_number_to_string (parsed, E_PHONE_NUMBER_FORMAT_E164);
+		g_assert_cmpstr (formatted, ==, "+12125423789");
+		g_free (formatted);
+
+		e_phone_number_free (parsed);
+	}
+
+#else /* ENABLE_PHONENUMBER */
+
+	g_assert (parsed == NULL);
+	g_assert (error != NULL);
+	g_assert (error->domain == E_PHONE_NUMBER_ERROR);
+	g_assert (error->code == E_PHONE_NUMBER_ERROR_NOT_IMPLEMENTED);
+	g_assert (error->message != NULL);
+	g_clear_error (&error);
+
+#endif /* ENABLE_PHONENUMBER */
+}
+
+static void
 test_compare_numbers (gconstpointer data)
 {
 	const size_t n = GPOINTER_TO_UINT (data);
@@ -242,6 +278,8 @@ main (gint argc,
 {
 	size_t i, j;
 
+	setlocale (LC_ALL, "en_US.UTF-8");
+
 	g_type_init ();
 
 	g_test_init (&argc, &argv, NULL);
@@ -268,9 +306,13 @@ main (gint argc,
 		 test_parse_and_format);
 
 	g_test_add_func
-		("/ebook-phone-number/parse-and-format/BadNumber",
+		("/ebook-phone-number/parse-and-format/bad-number",
 		 test_parse_bad_number);
 
+	g_test_add_func
+		("/ebook-phone-number/parse-and-format/auto-region",
+		 test_parse_auto_region);
+
 	g_assert_cmpint (G_N_ELEMENTS (match_candidates) * G_N_ELEMENTS (match_candidates),
 			 ==, G_N_ELEMENTS (expected_matches));
 



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