diff --git a/cpp/CMakeLists.txt b/cpp/CMakeLists.txt index 44db6834b..72b7913a6 100644 --- a/cpp/CMakeLists.txt +++ b/cpp/CMakeLists.txt @@ -14,7 +14,12 @@ # Author: Philippe Liard -cmake_minimum_required (VERSION 2.8.5) +cmake_minimum_required (VERSION 3.11) + +# Pick the C++ standard to compile with. +# Abseil currently supports C++11, C++14, and C++17. +set(CMAKE_CXX_STANDARD 11) +set(CMAKE_CXX_STANDARD_REQUIRED ON) project (libphonenumber) set (libphonenumber_VERSION_MAJOR 8) @@ -469,6 +474,12 @@ if (${USE_POSIX_THREAD} STREQUAL "ON" OR ((APPLE OR UNIX) AND ${USE_BOOST} STREQ endif() endif () +# Safeguarding against any potential link errors as mentioned in +# https://github.com/abseil/abseil-cpp/issues/225 +set(CMAKE_POSITION_INDEPENDENT_CODE TRUE) +list (APPEND LIBRARY_DEPS absl::strings) +list (APPEND COMMON_DEPS absl::synchronization) + if (APPLE) list (APPEND COMMON_DEPS ${COREFOUNDATION_LIB} ${FOUNDATION_LIB}) endif () diff --git a/cpp/src/phonenumbers/asyoutypeformatter.cc b/cpp/src/phonenumbers/asyoutypeformatter.cc index 396b53787..fe8519559 100644 --- a/cpp/src/phonenumbers/asyoutypeformatter.cc +++ b/cpp/src/phonenumbers/asyoutypeformatter.cc @@ -29,6 +29,9 @@ #include "phonenumbers/stringutil.h" #include "phonenumbers/unicodestring.h" +#include "absl/strings/str_cat.h" +#include "absl/strings/str_replace.h" + namespace i18n { namespace phonenumbers { @@ -273,7 +276,7 @@ void AsYouTypeFormatter::GetFormattingTemplate( regexp_cache_.GetRegExp(number_pattern).GlobalReplace( &a_phone_number, number_format); // Replaces each digit with character kDigitPlaceholder. - GlobalReplaceSubstring("9", kDigitPlaceholder, &a_phone_number); + absl::StrReplaceAll({{"9", kDigitPlaceholder}}, &a_phone_number); formatting_template->setTo(a_phone_number.c_str(), a_phone_number.size()); } diff --git a/cpp/src/phonenumbers/geocoding/phonenumber_offline_geocoder.cc b/cpp/src/phonenumbers/geocoding/phonenumber_offline_geocoder.cc index 55e7ab192..f8b013ce0 100644 --- a/cpp/src/phonenumbers/geocoding/phonenumber_offline_geocoder.cc +++ b/cpp/src/phonenumbers/geocoding/phonenumber_offline_geocoder.cc @@ -27,6 +27,8 @@ #include "phonenumbers/phonenumberutil.h" #include "phonenumbers/stl_util.h" +#include "absl/synchronization/mutex.h" + namespace i18n { namespace phonenumbers { @@ -75,6 +77,7 @@ void PhoneNumberOfflineGeocoder::Init( } PhoneNumberOfflineGeocoder::~PhoneNumberOfflineGeocoder() { + absl::MutexLock l(&mu_); gtl::STLDeleteContainerPairSecondPointers( available_maps_.begin(), available_maps_.end()); } @@ -195,6 +198,7 @@ const char* PhoneNumberOfflineGeocoder::GetAreaDescription( const int country_calling_code = number.country_code(); // NANPA area is not split in C++ code. const int phone_prefix = country_calling_code; + absl::MutexLock l(&mu_); const AreaCodeMap* const descriptions = GetPhonePrefixDescriptions( phone_prefix, lang, script, region); const char* description = descriptions ? descriptions->Lookup(number) : NULL; diff --git a/cpp/src/phonenumbers/geocoding/phonenumber_offline_geocoder.h b/cpp/src/phonenumbers/geocoding/phonenumber_offline_geocoder.h index f1e6c1288..9c0951057 100644 --- a/cpp/src/phonenumbers/geocoding/phonenumber_offline_geocoder.h +++ b/cpp/src/phonenumbers/geocoding/phonenumber_offline_geocoder.h @@ -21,6 +21,7 @@ #include #include // NOLINT(build/include_order) +#include "absl/synchronization/mutex.h" #include "phonenumbers/base/basictypes.h" #include "phonenumbers/base/memory/scoped_ptr.h" @@ -115,11 +116,12 @@ class PhoneNumberOfflineGeocoder { int prefix_language_code_pairs_size, prefix_descriptions_getter get_prefix_descriptions); - const AreaCodeMap* GetPhonePrefixDescriptions(int prefix, - const string& language, const string& script, const string& region) const; - AreaCodeMaps::const_iterator LoadAreaCodeMapFromFile( - const string& filename) const; + const string& filename) const ABSL_EXCLUSIVE_LOCKS_REQUIRED(mu_); + + const AreaCodeMap* GetPhonePrefixDescriptions( + int prefix, const string& language, const string& script, + const string& region) const ABSL_EXCLUSIVE_LOCKS_REQUIRED(mu_); // Returns the customary display name in the given language for the given // region. @@ -143,7 +145,7 @@ class PhoneNumberOfflineGeocoder { // 3166-1. const char* GetAreaDescription(const PhoneNumber& number, const string& lang, const string& script, - const string& region) const; + const string& region) const ABSL_LOCKS_EXCLUDED(mu_); bool MayFallBackToEnglish(const string& lang) const; @@ -160,8 +162,8 @@ class PhoneNumberOfflineGeocoder { // A mapping from country calling codes languages pairs to the corresponding // phone prefix map that has been loaded. - mutable AreaCodeMaps available_maps_; - + mutable absl::Mutex mu_; + mutable AreaCodeMaps available_maps_ ABSL_GUARDED_BY(mu_); DISALLOW_COPY_AND_ASSIGN(PhoneNumberOfflineGeocoder); }; diff --git a/cpp/src/phonenumbers/phonenumberutil.cc b/cpp/src/phonenumbers/phonenumberutil.cc index 0f4365d57..48366e082 100644 --- a/cpp/src/phonenumbers/phonenumberutil.cc +++ b/cpp/src/phonenumbers/phonenumberutil.cc @@ -47,6 +47,8 @@ #include "phonenumbers/utf/unicodetext.h" #include "phonenumbers/utf/utf.h" +#include "absl/strings/str_replace.h" + namespace i18n { namespace phonenumbers { @@ -1163,10 +1165,9 @@ void PhoneNumberUtil::FormatByPattern( const string& national_prefix = metadata->national_prefix(); if (!national_prefix.empty()) { // Replace $NP with national prefix and $FG with the first group ($1). - GlobalReplaceSubstring("$NP", national_prefix, - &national_prefix_formatting_rule); - GlobalReplaceSubstring("$FG", "$1", - &national_prefix_formatting_rule); + absl::StrReplaceAll({{"$NP", national_prefix}}, + &national_prefix_formatting_rule); + absl::StrReplaceAll({{"$FG", "$1"}}, &national_prefix_formatting_rule); num_format_copy.set_national_prefix_formatting_rule( national_prefix_formatting_rule); } else { diff --git a/cpp/src/phonenumbers/regexp_adapter_re2.cc b/cpp/src/phonenumbers/regexp_adapter_re2.cc index 773416910..ccfd28fd6 100644 --- a/cpp/src/phonenumbers/regexp_adapter_re2.cc +++ b/cpp/src/phonenumbers/regexp_adapter_re2.cc @@ -27,6 +27,8 @@ #include "phonenumbers/base/logging.h" #include "phonenumbers/stringutil.h" +#include "absl/strings/str_replace.h" +#include "absl/strings/string_view.h" namespace i18n { namespace phonenumbers { @@ -76,14 +78,14 @@ bool DispatchRE2Call(Function regex_function, // when they escape dollar-signs. string TransformRegularExpressionToRE2Syntax(const string& regex) { string re2_regex(regex); - if (GlobalReplaceSubstring("$", "\\", &re2_regex) == 0) { + if (absl::StrReplaceAll({{"$", "\\"}}, &re2_regex) == 0) { return regex; } // If we replaced a dollar sign with a backslash and there are now two // backslashes in the string, we assume that the dollar-sign was previously // escaped and that we need to retain it. To do this, we replace pairs of // backslashes with a dollar sign. - GlobalReplaceSubstring("\\\\", "$", &re2_regex); + absl::StrReplaceAll({{"\\\\", "$"}}, &re2_regex); return re2_regex; } diff --git a/cpp/test/phonenumbers/geocoding/geocoding_data_test.cc b/cpp/test/phonenumbers/geocoding/geocoding_data_test.cc index a21eac6cb..70a120775 100644 --- a/cpp/test/phonenumbers/geocoding/geocoding_data_test.cc +++ b/cpp/test/phonenumbers/geocoding/geocoding_data_test.cc @@ -24,6 +24,8 @@ #include "phonenumbers/geocoding/geocoding_data.h" #include "phonenumbers/geocoding/geocoding_test_data.h" +#include "absl/container/btree_set.h" + namespace i18n { namespace phonenumbers { @@ -63,7 +65,7 @@ void TestCountryCallingCodeLanguages( void TestPrefixDescriptions(const PrefixDescriptions* descriptions) { EXPECT_GT(descriptions->prefixes_size, 0); - set possible_lengths; + absl::btree_set possible_lengths; for (int i = 0; i < descriptions->prefixes_size; ++i) { int prefix = descriptions->prefixes[i]; EXPECT_GT(prefix, 0); diff --git a/tools/cpp/CMakeLists.txt b/tools/cpp/CMakeLists.txt index fafa84694..ab2d54b3f 100644 --- a/tools/cpp/CMakeLists.txt +++ b/tools/cpp/CMakeLists.txt @@ -14,17 +14,43 @@ # Author: Patrick Mezard -cmake_minimum_required (VERSION 2.8) +cmake_minimum_required (VERSION 3.11) + +# Pick the C++ standard to compile with. +# Abseil currently supports C++11, C++14, and C++17. +set(CMAKE_CXX_STANDARD 11) +set(CMAKE_CXX_STANDARD_REQUIRED ON) project (generate_geocoding_data) # Helper functions dealing with finding libraries and programs this library # depends on. - include (gtest.cmake) +include (FetchContent) -find_or_build_gtest () +# Downloading the abseil sources. +FetchContent_Declare( + abseil-cpp + GIT_REPOSITORY https://github.com/abseil/abseil-cpp.git + GIT_TAG origin/master +) + +# Building the abseil binaries +FetchContent_GetProperties(abseil-cpp) +if (NOT abseil-cpp_POPULATED) + FetchContent_Populate(abseil-cpp) +endif () + +if (NOT abseil-cpp_POPULATED) + message (FATAL_ERROR "Could not build abseil-cpp binaries.") +endif () +# Safeguarding against any potential link errors as mentioned in +# https://github.com/abseil/abseil-cpp/issues/225 +set(CMAKE_POSITION_INDEPENDENT_CODE TRUE) +add_subdirectory(${abseil-cpp_SOURCE_DIR} ${abseil-cpp_BINARY_DIR}) + +find_or_build_gtest () set ( SOURCES "src/cpp-build/generate_geocoding_data.cc" @@ -38,6 +64,7 @@ endif () include_directories ("src") add_executable (generate_geocoding_data ${SOURCES}) +target_link_libraries (generate_geocoding_data absl::strings absl::btree) set (TEST_SOURCES "src/cpp-build/generate_geocoding_data.cc" @@ -54,4 +81,4 @@ endif () # Build the testing binary. include_directories ("test") add_executable (generate_geocoding_data_test ${TEST_SOURCES}) -target_link_libraries (generate_geocoding_data_test ${TEST_LIBS}) +target_link_libraries (generate_geocoding_data_test absl::btree ${TEST_LIBS}) diff --git a/tools/cpp/src/cpp-build/generate_geocoding_data.cc b/tools/cpp/src/cpp-build/generate_geocoding_data.cc index 021cf5c81..205947e83 100644 --- a/tools/cpp/src/cpp-build/generate_geocoding_data.cc +++ b/tools/cpp/src/cpp-build/generate_geocoding_data.cc @@ -36,6 +36,9 @@ #include "base/basictypes.h" +#include "absl/container/btree_map.h" +#include "absl/container/btree_set.h" + namespace i18n { namespace phonenumbers { @@ -161,7 +164,8 @@ bool IntToStr(int32 n, string* s) { // Parses the prefix descriptions file at path, clears and fills the output // prefixes phone number prefix to description mapping. // Returns true on success. -bool ParsePrefixes(const string& path, map* prefixes) { +bool ParsePrefixes(const string& path, + absl::btree_map* prefixes) { prefixes->clear(); FILE* input = fopen(path.c_str(), "r"); if (!input) { @@ -338,12 +342,13 @@ void WritePrefixDescriptionsDefinition( // ... // }; // -void WritePrefixDescriptions(const string& var_name, const map& - prefixes, FILE* output) { - set possible_lengths; +void WritePrefixDescriptions(const string& var_name, + const absl::btree_map& prefixes, + FILE* output) { + absl::btree_set possible_lengths; const string prefixes_name = var_name + "_prefixes"; fprintf(output, "const int32 %s[] = {\n", prefixes_name.c_str()); - for (map::const_iterator it = prefixes.begin(); + for (absl::btree_map::const_iterator it = prefixes.begin(); it != prefixes.end(); ++it) { fprintf(output, " %d,\n", it->first); possible_lengths.insert(static_cast(log10(it->first) + 1)); @@ -354,7 +359,7 @@ void WritePrefixDescriptions(const string& var_name, const map& const string desc_name = var_name + "_descriptions"; fprintf(output, "const char* %s[] = {\n", desc_name.c_str()); - for (map::const_iterator it = prefixes.begin(); + for (absl::btree_map::const_iterator it = prefixes.begin(); it != prefixes.end(); ++it) { fprintf(output, " "); WriteStringLiteral(it->second, output); @@ -366,7 +371,7 @@ void WritePrefixDescriptions(const string& var_name, const map& const string possible_lengths_name = var_name + "_possible_lengths"; fprintf(output, "const int32 %s[] = {\n ", possible_lengths_name.c_str()); - for (set::const_iterator it = possible_lengths.begin(); + for (absl::btree_set::const_iterator it = possible_lengths.begin(); it != possible_lengths.end(); ++it) { fprintf(output, " %d,", *it); } @@ -394,10 +399,10 @@ void WritePrefixDescriptions(const string& var_name, const map& // &prefix_1_en, // }; // -void WritePrefixesDescriptions(const map& prefix_var_names, - FILE* output) { +void WritePrefixesDescriptions( + const absl::btree_map& prefix_var_names, FILE* output) { fprintf(output, "const char* prefix_language_code_pairs[] = {\n"); - for (map::const_iterator it = prefix_var_names.begin(); + for (absl::btree_map::const_iterator it = prefix_var_names.begin(); it != prefix_var_names.end(); ++it) { fprintf(output, " \"%s\",\n", it->first.c_str()); } @@ -405,7 +410,7 @@ void WritePrefixesDescriptions(const map& prefix_var_names, "};\n" "\n" "const PrefixDescriptions* prefixes_descriptions[] = {\n"); - for (map::const_iterator it = prefix_var_names.begin(); + for (absl::btree_map::const_iterator it = prefix_var_names.begin(); it != prefix_var_names.end(); ++it) { fprintf(output, " &%s,\n", it->second.c_str()); } @@ -563,7 +568,7 @@ bool WriteSource(const string& data_path, const string& base_name, "\n"); // Enumerate language/script directories. - map prefix_vars; + absl::btree_map prefix_vars; map > country_languages; vector entries; if (!ListDirectory(data_path, &entries)) { @@ -595,7 +600,7 @@ bool WriteSource(const string& data_path, const string& base_name, } const string path = dir_path + "/" + fname; - map prefixes; + absl::btree_map prefixes; if (!ParsePrefixes(path, &prefixes)) { return false; }