<commit_before>/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
/*
 * Copyright (C) 2012,2013 Intel Corporation
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of version 2 of the GNU Lesser General Public
 * License as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this program; if not, write to the
 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 *
 * Author: <NAME> <<EMAIL>>
 */

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#ifndef ENABLE_PHONENUMBER
#error Phone number support must be enabled for this file
#endif /* ENABLE_PHONENUMBER */

#include "e-phone-number-private.h"

/* C++ standard library */
#include <string>

/* system headers */
#include <langinfo.h>
#include <locale.h>

/* libphonenumber */
#include <phonenumbers/logger.h>
#include <phonenumbers/phonenumberutil.h>

using i18n::phonenumbers::PhoneNumber;
using i18n::phonenumbers::PhoneNumberUtil;

struct _EPhoneNumber {
	PhoneNumber priv;
};

static PhoneNumberUtil *
e_phone_number_util_get_instance (void)
{
	static PhoneNumberUtil *instance = NULL;

	if (g_once_init_enter (&instance)) {
		/* FIXME: Ideally PhoneNumberUtil would not be a singleton,
		 * so that we could safely tweak it's attributes without
		 * influencing other users of the library. */
		PhoneNumberUtil *new_instance = PhoneNumberUtil::GetInstance ();

		/* Disable all logging: libphonenumber is pretty verbose. */
		new_instance->SetLogger (new i18n::phonenumbers::NullLogger);
		g_once_init_leave (&instance, new_instance);
	}

	return instance;
}

static EPhoneNumberError
e_phone_number_error_code (PhoneNumberUtil::ErrorType error)
{
	switch (error) {
	case PhoneNumberUtil::NO_PARSING_ERROR:
		g_return_val_if_reached (E_PHONE_NUMBER_ERROR_UNKNOWN);
	case PhoneNumberUtil::INVALID_COUNTRY_CODE_ERROR:
		return E_PHONE_NUMBER_ERROR_INVALID_COUNTRY_CODE;
	case PhoneNumberUtil::NOT_A_NUMBER:
		return E_PHONE_NUMBER_ERROR_NOT_A_NUMBER;
	case PhoneNumberUtil::TOO_SHORT_AFTER_IDD:
		return E_PHONE_NUMBER_ERROR_TOO_SHORT_AFTER_IDD;
	case PhoneNumberUtil::TOO_SHORT_NSN:
		return E_PHONE_NUMBER_ERROR_TOO_SHORT;
	case PhoneNumberUtil::TOO_LONG_NSN:
		return E_PHONE_NUMBER_ERROR_TOO_LONG;
	}

	/* Please file a bug that we can add a proper error code. */
	g_return_val_if_reached (E_PHONE_NUMBER_ERROR_UNKNOWN);
}

static std::string
e_phone_number_make_region_code (const gchar *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 underscore = current_region.find ('_');

		if (underscore != std::string::npos)
			current_region.resize (underscore);

		return current_region;
	}

	return region_code;
}

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

gchar *
_e_phone_number_cxx_get_default_region ()
{
	return g_strdup (e_phone_number_make_region_code (NULL).c_str ());<commit_msg>libebook: Really extract the 2-letter country code<commit_after>/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
/*
 * Copyright (C) 2012,2013 Intel Corporation
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of version 2 of the GNU Lesser General Public
 * License as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this program; if not, write to the
 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 *
 * Author: <NAME> <<EMAIL>>
 */

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#ifndef ENABLE_PHONENUMBER
#error Phone number support must be enabled for this file
#endif /* ENABLE_PHONENUMBER */

#include "e-phone-number-private.h"

/* C++ standard library */
#include <string>

/* system headers */
#include <langinfo.h>
#include <locale.h>

/* libphonenumber */
#include <phonenumbers/logger.h>
#include <phonenumbers/phonenumberutil.h>

using i18n::phonenumbers::PhoneNumber;
using i18n::phonenumbers::PhoneNumberUtil;

struct _EPhoneNumber {
	PhoneNumber priv;
};

static PhoneNumberUtil *
e_phone_number_util_get_instance (void)
{
	static PhoneNumberUtil *instance = NULL;

	if (g_once_init_enter (&instance)) {
		/* FIXME: Ideally PhoneNumberUtil would not be a singleton,
		 * so that we could safely tweak it's attributes without
		 * influencing other users of the library. */
		PhoneNumberUtil *new_instance = PhoneNumberUtil::GetInstance ();

		/* Disable all logging: libphonenumber is pretty verbose. */
		new_instance->SetLogger (new i18n::phonenumbers::NullLogger);
		g_once_init_leave (&instance, new_instance);
	}

	return instance;
}

static EPhoneNumberError
e_phone_number_error_code (PhoneNumberUtil::ErrorType error)
{
	switch (error) {
	case PhoneNumberUtil::NO_PARSING_ERROR:
		g_return_val_if_reached (E_PHONE_NUMBER_ERROR_UNKNOWN);
	case PhoneNumberUtil::INVALID_COUNTRY_CODE_ERROR:
		return E_PHONE_NUMBER_ERROR_INVALID_COUNTRY_CODE;
	case PhoneNumberUtil::NOT_A_NUMBER:
		return E_PHONE_NUMBER_ERROR_NOT_A_NUMBER;
	case PhoneNumberUtil::TOO_SHORT_AFTER_IDD:
		return E_PHONE_NUMBER_ERROR_TOO_SHORT_AFTER_IDD;
	case PhoneNumberUtil::TOO_SHORT_NSN:
		return E_PHONE_NUMBER_ERROR_TOO_SHORT;
	case PhoneNumberUtil::TOO_LONG_NSN:
		return E_PHONE_NUMBER_ERROR_TOO_LONG;
	}

	/* Please file a bug that we can add a proper error code. */
	g_return_val_if_reached (E_PHONE_NUMBER_ERROR_UNKNOWN);
}

static std::string
e_phone_number_make_region_code (const gchar *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;
	}

	return region_code;
}

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

gchar *
_e_phone_number_cxx_get_default_region ()
{
	return g_strdup (e_phone_number_make_region_code (NULL).c_str ());
{'fraction_non_alphanumeric': 0.09498164014687882, 'fraction_numerical': 0.009179926560587515, 'mean_word_length': 5.280553420445811, 'pattern_counts': {'":': 0, '<': 21, '<?xml version=': 0, '>': 25, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7383507', 'n_tokens_mistral': 2795, 'n_tokens_neox': 2641, 'n_words': 750}