[core] Regex refactoring

Signed-off-by: x7z4w <x7z4w@noreply.codeberg.org>
This commit is contained in:
x7z4w
2025-11-03 21:16:16 +00:00
parent a62f6c0ef6
commit 0a3a4ebd9a
17 changed files with 134 additions and 83 deletions

View File

@@ -16,7 +16,7 @@ Below are our specific (but not all!) exceptions to the Google's coding standard
- Includes are sorted and grouped by directory, there should be newlines between different directories. - Includes are sorted and grouped by directory, there should be newlines between different directories.
- Order of directories in includes: "current_dir/current_file.hpp", includes from other dirs sorted by dependencies (e.g. indexer, then coding, then base), "defines.hpp", C++ standard library headers, boost headers, 3party. - Order of directories in includes: "current_dir/current_file.hpp", includes from other dirs sorted by dependencies (e.g. indexer, then coding, then base), "defines.hpp", C++ standard library headers, boost headers, 3party.
- We ARE using C++ exceptions. - We ARE using C++ exceptions.
- We are using all features of C++17 and C++23 except std::filesystem, std::to_chars & std::from_chars which are not fully supported on all platforms. - We are using all features of C++17 and C++23 except `std::filesystem`, `std::to_chars`, `std::from_chars` and `std::format` which are not fully supported on all platforms.
- We try to limit the usage of boost libraries which require linking (and prefer C++23 types over their boost counterparts). - We try to limit the usage of boost libraries which require linking (and prefer C++23 types over their boost counterparts).
Naming and formatting Naming and formatting

View File

@@ -41,6 +41,8 @@
#include <exception> #include <exception>
#include <iostream> #include <iostream>
#include <boost/regex.hpp>
#include "defines.hpp" #include "defines.hpp"
#include <gflags/gflags.h> #include <gflags/gflags.h>
@@ -112,7 +114,8 @@ MAIN_WITH_ERROR_HANDLING([](int argc, char ** argv)
// Find directory with *.mwm. Directory FLAGS_maps_build_path must contain directory with *.mwm, // Find directory with *.mwm. Directory FLAGS_maps_build_path must contain directory with *.mwm,
// whose name must consist of six digits. // whose name must consist of six digits.
Platform::FilesList files; Platform::FilesList files;
pl.GetFilesByRegExp(FLAGS_maps_build_path, "[0-9]{6}", files); static boost::regex const regexp("[0-9]{6}");
pl.GetFilesByRegExp(FLAGS_maps_build_path, regexp, files);
CHECK_EQUAL(files.size(), 1, ()); CHECK_EQUAL(files.size(), 1, ());
auto const mwmPath = base::JoinPath(FLAGS_maps_build_path, files[0]); auto const mwmPath = base::JoinPath(FLAGS_maps_build_path, files[0]);
finalProcessor->UseCentersEnricher(mwmPath, osm2FtPath); finalProcessor->UseCentersEnricher(mwmPath, osm2FtPath);

View File

@@ -2,12 +2,12 @@
#include "base/stl_helpers.hpp" #include "base/stl_helpers.hpp"
#include <regex> #include <boost/regex.hpp>
namespace regexp_test namespace regexp_test
{ {
template <typename Fn> template <typename Fn>
void ForEachMatched(std::string const & s, std::regex const & regex, Fn && fn) void ForEachMatched(std::string const & s, boost::regex const & regex, Fn && fn)
{ {
for (std::sregex_token_iterator cur(s.begin(), s.end(), regex), end; cur != end; ++cur) for (std::sregex_token_iterator cur(s.begin(), s.end(), regex), end; cur != end; ++cur)
fn(*cur); fn(*cur);
@@ -15,24 +15,24 @@ void ForEachMatched(std::string const & s, std::regex const & regex, Fn && fn)
UNIT_TEST(RegExp_Or) UNIT_TEST(RegExp_Or)
{ {
std::regex exp("\\.mwm\\.(downloading2?$|resume2?$)"); boost::regex exp("\\.mwm\\.(downloading2?$|resume2?$)");
TEST(std::regex_search("Aruba.mwm.downloading", exp), ()); TEST(boost::regex_search("Aruba.mwm.downloading", exp), ());
TEST(!regex_search("Aruba.mwm.downloading1", exp), ()); TEST(!regex_search("Aruba.mwm.downloading1", exp), ());
TEST(std::regex_search("Aruba.mwm.downloading2", exp), ()); TEST(boost::regex_search("Aruba.mwm.downloading2", exp), ());
TEST(!regex_search("Aruba.mwm.downloading3", exp), ()); TEST(!regex_search("Aruba.mwm.downloading3", exp), ());
TEST(!regex_search("Aruba.mwm.downloading.tmp", exp), ()); TEST(!regex_search("Aruba.mwm.downloading.tmp", exp), ());
TEST(std::regex_search("Aruba.mwm.resume", exp), ()); TEST(boost::regex_search("Aruba.mwm.resume", exp), ());
TEST(!regex_search("Aruba.mwm.resume1", exp), ()); TEST(!regex_search("Aruba.mwm.resume1", exp), ());
TEST(std::regex_search("Aruba.mwm.resume2", exp), ()); TEST(boost::regex_search("Aruba.mwm.resume2", exp), ());
TEST(!regex_search("Aruba.mwm.resume3", exp), ()); TEST(!regex_search("Aruba.mwm.resume3", exp), ());
TEST(!regex_search("Aruba.mwm.resume.tmp", exp), ()); TEST(!regex_search("Aruba.mwm.resume.tmp", exp), ());
} }
UNIT_TEST(RegExp_ForEachMatched) UNIT_TEST(RegExp_ForEachMatched)
{ {
std::regex exp("-?\\d+\\.?\\d*, *-?\\d+\\.?\\d*"); boost::regex exp("-?\\d+\\.?\\d*, *-?\\d+\\.?\\d*");
{ {
std::string const s = "6.66, 9.99"; std::string const s = "6.66, 9.99";

View File

@@ -21,10 +21,10 @@ double constexpr kEps = 1e-10;
// maximal zoom levels. // maximal zoom levels.
double constexpr kMaxZoom = 20.0; double constexpr kMaxZoom = 20.0;
bool MatchLatLonZoom(string const & s, regex const & re, size_t lati, size_t loni, size_t zoomi, GeoURLInfo & info) bool MatchLatLonZoom(string const & s, boost::regex const & re, size_t lati, size_t loni, size_t zoomi, GeoURLInfo & info)
{ {
std::smatch m; boost::smatch m;
if (!std::regex_search(s, m, re) || m.size() != 4) if (!boost::regex_search(s, m, re) || m.size() != 4)
return false; return false;
double lat, lon, zoom; double lat, lon, zoom;
@@ -55,7 +55,7 @@ std::string const kFloatIntCoord = R"(([+-]?\d+\.?\d*))";
std::string const kFloatIntScale = R"((\d+\.?\d*))"; std::string const kFloatIntScale = R"((\d+\.?\d*))";
} // namespace } // namespace
LatLonParser::LatLonParser() : m_info(nullptr), m_regexp(kFloatCoord + ", *" + kFloatCoord) {} LatLonParser::LatLonParser() : m_info(nullptr), m_regexp(boost::regex(kFloatCoord + ", *" + kFloatCoord)) {}
void LatLonParser::Reset(url::Url const & url, GeoURLInfo & info) void LatLonParser::Reset(url::Url const & url, GeoURLInfo & info)
{ {
@@ -87,8 +87,8 @@ void LatLonParser::operator()(std::string name, std::string const & value)
if (priority != kXYPriority && priority != kLatLonPriority) if (priority != kXYPriority && priority != kLatLonPriority)
{ {
std::smatch m; boost::smatch m;
if (std::regex_search(value, m, m_regexp) && m.size() == 3) if (boost::regex_search(value, m, m_regexp) && m.size() == 3)
{ {
double lat, lon; double lat, lon;
VERIFY(strings::to_double(m[1].str(), lat), ()); VERIFY(strings::to_double(m[1].str(), lat), ());
@@ -146,9 +146,7 @@ int LatLonParser::GetCoordinatesPriority(string const & token)
return -1; return -1;
} }
std::string const kLatLon = R"(([+-]?\d+(?:\.\d+)?), *([+-]?\d+(?:\.\d+)?)(:?, *([+-]?\d+(?:\.\d+)?))?)"; GeoParser::GeoParser() : m_latlonRe(boost::regex(R"(([+-]?\d+(?:\.\d+)?), *([+-]?\d+(?:\.\d+)?)(:?, *([+-]?\d+(?:\.\d+)?))?)")), m_zoomRe(boost::regex(kFloatIntScale)) {}
GeoParser::GeoParser() : m_latlonRe(kLatLon), m_zoomRe(kFloatIntScale) {}
bool GeoParser::Parse(std::string const & raw, GeoURLInfo & info) const bool GeoParser::Parse(std::string const & raw, GeoURLInfo & info) const
{ {
@@ -202,12 +200,12 @@ bool GeoParser::Parse(std::string const & raw, GeoURLInfo & info) const
std::string coordinates = url.GetHost().substr(0, url.GetHost().find(';')); std::string coordinates = url.GetHost().substr(0, url.GetHost().find(';'));
if (!coordinates.empty()) if (!coordinates.empty())
{ {
std::smatch m; boost::smatch m;
if (!std::regex_match(coordinates, m, m_latlonRe) || m.size() < 3) if (!boost::regex_match(coordinates, m, m_latlonRe) || m.size() < 3)
{ {
// no match? try URL decoding before giving up // no match? try URL decoding before giving up
coordinates = url::UrlDecode(coordinates); coordinates = url::UrlDecode(coordinates);
if (!std::regex_match(coordinates, m, m_latlonRe) || m.size() < 3) if (!boost::regex_match(coordinates, m, m_latlonRe) || m.size() < 3)
{ {
LOG(LWARNING, ("Missing coordinates in", raw)); LOG(LWARNING, ("Missing coordinates in", raw));
return false; return false;
@@ -233,8 +231,8 @@ bool GeoParser::Parse(std::string const & raw, GeoURLInfo & info) const
if (q != nullptr && !q->empty()) if (q != nullptr && !q->empty())
{ {
// Try to extract lat,lon from q= // Try to extract lat,lon from q=
std::smatch m; boost::smatch m;
if (std::regex_match(*q, m, m_latlonRe) && m.size() != 3) if (boost::regex_match(*q, m, m_latlonRe) && m.size() != 3)
{ {
double lat, lon; double lat, lon;
VERIFY(strings::to_double(m[1].str(), lat), ()); VERIFY(strings::to_double(m[1].str(), lat), ());
@@ -271,8 +269,8 @@ bool GeoParser::Parse(std::string const & raw, GeoURLInfo & info) const
std::string const * z = url.GetParamValue("z"); std::string const * z = url.GetParamValue("z");
if (z != nullptr) if (z != nullptr)
{ {
std::smatch m; boost::smatch m;
if (std::regex_match(*z, m, m_zoomRe) && m.size() == 2) if (boost::regex_match(*z, m, m_zoomRe) && m.size() == 2)
{ {
double zoom; double zoom;
VERIFY(strings::to_double(m[0].str(), zoom), ()); VERIFY(strings::to_double(m[0].str(), zoom), ());
@@ -288,8 +286,8 @@ bool GeoParser::Parse(std::string const & raw, GeoURLInfo & info) const
} }
DoubleGISParser::DoubleGISParser() DoubleGISParser::DoubleGISParser()
: m_pathRe("/" + kFloatIntCoord + "," + kFloatIntCoord + "/zoom/" + kFloatIntScale) : m_pathRe(boost::regex("/" + kFloatIntCoord + "," + kFloatIntCoord + "/zoom/" + kFloatIntScale))
, m_paramRe(kFloatIntCoord + "," + kFloatIntCoord + "/" + kFloatIntScale) , m_paramRe(boost::regex(kFloatIntCoord + "," + kFloatIntCoord + "/" + kFloatIntScale))
{} {}
bool DoubleGISParser::Parse(url::Url const & url, GeoURLInfo & info) const bool DoubleGISParser::Parse(url::Url const & url, GeoURLInfo & info) const
@@ -305,7 +303,7 @@ bool DoubleGISParser::Parse(url::Url const & url, GeoURLInfo & info) const
return MatchLatLonZoom(url.GetHostAndPath(), m_pathRe, 2, 1, 3, info); return MatchLatLonZoom(url.GetHostAndPath(), m_pathRe, 2, 1, 3, info);
} }
OpenStreetMapParser::OpenStreetMapParser() : m_regex(kIntScale + "/" + kFloatCoord + "/" + kFloatCoord) {} OpenStreetMapParser::OpenStreetMapParser() : m_regex(boost::regex(kIntScale + "/" + kFloatCoord + "/" + kFloatCoord)) {}
bool OpenStreetMapParser::Parse(url::Url const & url, GeoURLInfo & info) const bool OpenStreetMapParser::Parse(url::Url const & url, GeoURLInfo & info) const
{ {

View File

@@ -2,9 +2,10 @@
#include "coding/url.hpp" #include "coding/url.hpp"
#include <regex>
#include <string> #include <string>
#include <boost/regex.hpp>
namespace geo namespace geo
{ {
@@ -34,8 +35,8 @@ public:
bool Parse(url::Url const & url, GeoURLInfo & info) const; bool Parse(url::Url const & url, GeoURLInfo & info) const;
private: private:
std::regex m_pathRe; boost::regex m_pathRe;
std::regex m_paramRe; boost::regex m_paramRe;
}; };
class OpenStreetMapParser class OpenStreetMapParser
@@ -45,7 +46,7 @@ public:
bool Parse(url::Url const & url, GeoURLInfo & info) const; bool Parse(url::Url const & url, GeoURLInfo & info) const;
private: private:
std::regex m_regex; boost::regex m_regex;
}; };
class LatLonParser class LatLonParser
@@ -73,7 +74,7 @@ private:
GeoURLInfo * m_info; GeoURLInfo * m_info;
bool m_swapLatLon; bool m_swapLatLon;
std::regex m_regexp; boost::regex m_regexp;
int m_latPriority; int m_latPriority;
int m_lonPriority; int m_lonPriority;
}; };
@@ -85,8 +86,8 @@ public:
bool Parse(std::string const & url, GeoURLInfo & info) const; bool Parse(std::string const & url, GeoURLInfo & info) const;
private: private:
std::regex m_latlonRe; boost::regex m_latlonRe;
std::regex m_zoomRe; boost::regex m_zoomRe;
}; };
class UnifiedParser class UnifiedParser

View File

@@ -17,10 +17,11 @@
#include <algorithm> #include <algorithm>
#include <cctype> #include <cctype>
#include <memory> #include <memory>
#include <regex>
#include <sstream> #include <sstream>
#include <unordered_set> #include <unordered_set>
#include <boost/regex.hpp>
#include "defines.hpp" #include "defines.hpp"
namespace platform namespace platform
@@ -42,8 +43,8 @@ bool IsSpecialName(string const & name) { return name == "." || name == ".."; }
*/ */
bool IsDownloaderFile(string const & name) bool IsDownloaderFile(string const & name)
{ {
static std::regex const filter(".*\\.(downloading|resume|ready)[0-9]?$"); static boost::regex const filter(".*\\.(downloading|resume|ready)[0-9]?$");
return std::regex_match(name.begin(), name.end(), filter); return boost::regex_match(name.begin(), name.end(), filter);
} }
bool IsDiffFile(string const & name) bool IsDiffFile(string const & name)

View File

@@ -10,6 +10,8 @@
#include <algorithm> #include <algorithm>
#include <thread> #include <thread>
#include <boost/regex.hpp>
#include "private.h" #include "private.h"
#include <cerrno> #include <cerrno>
@@ -30,7 +32,7 @@ std::string RandomString(size_t length)
return str; return str;
} }
bool IsSpecialDirName(std::string const & dirName) inline bool IsSpecialDirName(std::string const & dirName)
{ {
return dirName == "." || dirName == ".."; return dirName == "." || dirName == "..";
} }
@@ -73,7 +75,7 @@ bool Platform::RmDirRecursively(std::string const & dirName)
bool res = true; bool res = true;
FilesList allFiles; FilesList allFiles;
GetFilesByRegExp(dirName, ".*", allFiles); GetAllFiles(dirName, allFiles);
for (std::string const & file : allFiles) for (std::string const & file : allFiles)
{ {
std::string const path = base::JoinPath(dirName, file); std::string const path = base::JoinPath(dirName, file);
@@ -207,15 +209,14 @@ void Platform::GetFilesByExt(std::string const & directory, std::string_view ext
// Transform extension mask to regexp (.mwm -> \.mwm$) // Transform extension mask to regexp (.mwm -> \.mwm$)
ASSERT(!ext.empty(), ()); ASSERT(!ext.empty(), ());
ASSERT_EQUAL(ext[0], '.', ()); ASSERT_EQUAL(ext[0], '.', ());
std::string regexp = "\\"; GetFilesByRegExp(directory, boost::regex(std::string("\\").append(ext).append("$")), outFiles);
GetFilesByRegExp(directory, regexp.append(ext).append("$"), outFiles);
} }
// static // static
void Platform::GetFilesByType(std::string const & directory, unsigned typeMask, TFilesWithType & outFiles) void Platform::GetFilesByType(std::string const & directory, unsigned typeMask, TFilesWithType & outFiles)
{ {
FilesList allFiles; FilesList allFiles;
GetFilesByRegExp(directory, ".*", allFiles); GetAllFiles(directory, allFiles);
for (auto const & file : allFiles) for (auto const & file : allFiles)
{ {
EFileType type; EFileType type;

View File

@@ -18,6 +18,8 @@
#include <utility> #include <utility>
#include <vector> #include <vector>
#include <boost/regex.hpp>
#include "defines.hpp" #include "defines.hpp"
DECLARE_EXCEPTION(FileAbsentException, RootException); DECLARE_EXCEPTION(FileAbsentException, RootException);
@@ -209,7 +211,8 @@ public:
//@{ //@{
/// @param ext files extension to find, like ".mwm". /// @param ext files extension to find, like ".mwm".
static void GetFilesByExt(std::string const & directory, std::string_view ext, FilesList & outFiles); static void GetFilesByExt(std::string const & directory, std::string_view ext, FilesList & outFiles);
static void GetFilesByRegExp(std::string const & directory, std::string const & regexp, FilesList & outFiles); static void GetFilesByRegExp(std::string const & directory, boost::regex const & regexp, FilesList & outFiles);
static void GetAllFiles(std::string const & directory, FilesList & outFiles);
//@} //@}
static void GetFilesByType(std::string const & directory, unsigned typeMask, TFilesWithType & outFiles); static void GetFilesByType(std::string const & directory, unsigned typeMask, TFilesWithType & outFiles);

View File

@@ -9,12 +9,12 @@
#include "base/file_name_utils.hpp" #include "base/file_name_utils.hpp"
#include "base/logging.hpp" #include "base/logging.hpp"
#include "base/string_utils.hpp" #include "base/string_utils.hpp"
#include "base/thread.hpp"
#include <memory> #include <memory>
#include <regex>
#include <string> #include <string>
#include <boost/regex.hpp>
#include <sys/stat.h> #include <sys/stat.h>
#include <unistd.h> // for sysconf #include <unistd.h> // for sysconf
@@ -125,7 +125,7 @@ std::unique_ptr<ModelReader> Platform::GetReader(std::string const & file, std::
return nullptr; return nullptr;
} }
void Platform::GetFilesByRegExp(std::string const & directory, std::string const & regexp, FilesList & res) void Platform::GetFilesByRegExp(std::string const & directory, boost::regex const & regexp, FilesList & res)
{ {
if (ZipFileReader::IsZip(directory)) if (ZipFileReader::IsZip(directory))
{ {
@@ -134,12 +134,10 @@ void Platform::GetFilesByRegExp(std::string const & directory, std::string const
FilesT fList; FilesT fList;
ZipFileReader::FilesList(directory, fList); ZipFileReader::FilesList(directory, fList);
std::regex exp(regexp);
for (FilesT::iterator it = fList.begin(); it != fList.end(); ++it) for (FilesT::iterator it = fList.begin(); it != fList.end(); ++it)
{ {
std::string & name = it->first; std::string & name = it->first;
if (std::regex_search(name.begin(), name.end(), exp)) if (boost::regex_search(name.begin(), name.end(), regexp))
{ {
// Remove assets/ prefix - clean files are needed for fonts white/blacklisting logic // Remove assets/ prefix - clean files are needed for fonts white/blacklisting logic
size_t const ASSETS_LENGTH = 7; size_t const ASSETS_LENGTH = 7;
@@ -154,6 +152,30 @@ void Platform::GetFilesByRegExp(std::string const & directory, std::string const
pl::EnumerateFilesByRegExp(directory, regexp, res); pl::EnumerateFilesByRegExp(directory, regexp, res);
} }
void Platform::GetAllFiles(std::string const & directory, FilesList & res)
{
if (ZipFileReader::IsZip(directory))
{
// Get files list inside zip file
typedef ZipFileReader::FileList FilesT;
FilesT fList;
ZipFileReader::FilesList(directory, fList);
for (FilesT::iterator it = fList.begin(); it != fList.end(); ++it)
{
std::string & name = it->first;
// Remove assets/ prefix - clean files are needed for fonts white/blacklisting logic
size_t const ASSETS_LENGTH = 7;
if (name.find("assets/") == 0)
name.erase(0, ASSETS_LENGTH);
res.push_back(name);
}
}
else
pl::EnumerateFiles(directory, res);
}
int Platform::VideoMemoryLimit() const int Platform::VideoMemoryLimit() const
{ {
return 10 * 1024 * 1024; return 10 * 1024 * 1024;

View File

@@ -97,11 +97,16 @@ Platform::EError Platform::MkDir(std::string const & dirName)
return Platform::ERR_OK; return Platform::ERR_OK;
} }
void Platform::GetFilesByRegExp(std::string const & directory, std::string const & regexp, FilesList & res) void Platform::GetFilesByRegExp(std::string const & directory, boost::regex const & regexp, FilesList & res)
{ {
pl::EnumerateFilesByRegExp(directory, regexp, res); pl::EnumerateFilesByRegExp(directory, regexp, res);
} }
void Platform::GetAllFiles(std::string const & directory, FilesList & res)
{
pl::EnumerateFiles(directory, res);
}
bool Platform::GetFileSizeByName(std::string const & fileName, uint64_t & size) const bool Platform::GetFileSizeByName(std::string const & fileName, uint64_t & size) const
{ {
try try

View File

@@ -7,9 +7,9 @@
#include "base/logging.hpp" #include "base/logging.hpp"
#include <future>
#include <memory> #include <memory>
#include <regex>
#include <boost/regex.hpp>
#include <QtCore/QCoreApplication> #include <QtCore/QCoreApplication>
#include <QtCore/QDir> #include <QtCore/QDir>
@@ -33,21 +33,27 @@ bool Platform::GetFileSizeByName(std::string const & fileName, uint64_t & size)
} }
} }
void Platform::GetFilesByRegExp(std::string const & directory, std::string const & regexp, FilesList & outFiles) void Platform::GetFilesByRegExp(std::string const & directory, boost::regex const & regexp, FilesList & outFiles)
{ {
std::regex exp(regexp);
QDir dir(QString::fromUtf8(directory.c_str())); QDir dir(QString::fromUtf8(directory.c_str()));
int const count = dir.count(); int const count = dir.count();
for (int i = 0; i < count; ++i) for (int i = 0; i < count; ++i)
{ {
std::string name = dir[i].toStdString(); std::string name = dir[i].toStdString();
if (std::regex_search(name.begin(), name.end(), exp)) if (boost::regex_search(name.begin(), name.end(), regexp))
outFiles.push_back(std::move(name)); outFiles.push_back(std::move(name));
} }
} }
void Platform::GetAllFiles(std::string const & directory, FilesList & outFiles)
{
QDir dir(QString::fromUtf8(directory.c_str()));
for (int i = 0; i < dir.count(); ++i)
outFiles.push_back(dir[i].toStdString());
}
int Platform::PreCachingDepth() const int Platform::PreCachingDepth() const
{ {
return 3; return 3;

View File

@@ -18,6 +18,8 @@
#include <string> #include <string>
#include <utility> #include <utility>
#include <boost/regex.hpp>
#include "defines.hpp" #include "defines.hpp"
namespace namespace
@@ -100,7 +102,7 @@ UNIT_TEST(GetFilesInDir_Smoke)
TEST(base::IsExist(files1, "minsk-pass.mwm"), ()); TEST(base::IsExist(files1, "minsk-pass.mwm"), ());
pl.GetFilesByRegExp(dir, ".*\\" DATA_FILE_EXTENSION "$", files2); pl.GetFilesByRegExp(dir, boost::regex(".*\\" + DATA_FILE_EXTENSION + "$"), files2);
TEST_EQUAL(files1, files2, ()); TEST_EQUAL(files1, files2, ());
files1.clear(); files1.clear();

View File

@@ -8,7 +8,8 @@
#include <algorithm> #include <algorithm>
#include <cstring> #include <cstring>
#include <memory> #include <memory>
#include <regex>
#include <boost/regex.hpp>
#include <dirent.h> #include <dirent.h>
#include <sys/stat.h> #include <sys/stat.h>
@@ -143,15 +144,13 @@ void EnumerateFiles(std::string const & directory, std::function<void(char const
fn(entry->d_name); fn(entry->d_name);
} }
void EnumerateFilesByRegExp(std::string const & directory, std::string const & regexp, std::vector<std::string> & res) void EnumerateFilesByRegExp(std::string const & directory, boost::regex const & regexp, std::vector<std::string> & res)
{ {
std::regex exp(regexp);
EnumerateFiles(directory, [&](char const * entry) EnumerateFiles(directory, [&](char const * entry)
{ {
std::string const name(entry); std::string const name(entry);
if (std::regex_search(name.begin(), name.end(), exp)) if (boost::regex_search(name.begin(), name.end(), regexp))
res.push_back(name); res.push_back(name);
}); });
} }
} // namespace pl } // namespace pl

View File

@@ -4,9 +4,19 @@
#include <string> #include <string>
#include <vector> #include <vector>
#include <boost/regex.hpp>
namespace pl namespace pl
{ {
void EnumerateFiles(std::string const & directory, std::function<void(char const *)> const & fn); void EnumerateFiles(std::string const & directory, std::function<void(char const *)> const & fn);
void EnumerateFilesByRegExp(std::string const & directory, std::string const & regexp, std::vector<std::string> & res); void EnumerateFilesByRegExp(std::string const & directory, boost::regex const & regexp, std::vector<std::string> & res);
inline void EnumerateFiles(std::string const & directory, std::vector<std::string> & res)
{
EnumerateFiles(directory, [&](char const * entry)
{
res.push_back(std::string(entry));
});
}
} // namespace pl } // namespace pl

View File

@@ -7,9 +7,10 @@
#include "base/string_utils.hpp" #include "base/string_utils.hpp"
#include <regex>
#include <string> #include <string>
#include <boost/regex.hpp>
namespace routing::turns::sound namespace routing::turns::sound
{ {
@@ -200,9 +201,10 @@ std::string GetTtsText::GetTurnNotification(Notification const & notification) c
// if the first pronounceable character of the street is a vowel, use "az" instead of "a" // if the first pronounceable character of the street is a vowel, use "az" instead of "a"
// 1, 5, and 1000 start with vowels but not 10 or 100 (numbers are combined as in English: 5*, 5**, 1*, 1**, 1***, // 1, 5, and 1000 start with vowels but not 10 or 100 (numbers are combined as in English: 5*, 5**, 1*, 1**, 1***,
// etc) // etc)
static std::regex const rHun("^[5aeiouyáéíóúöüőű]|^1$|^1[^\\d]|^1\\d\\d\\d[^\\d]", std::regex_constants::icase); static boost::regex const rHun("^[5aeiouyáéíóúöüőű]|^1$|^1[^\\d]|^1\\d\\d\\d[^\\d]",
std::smatch ma; boost::regex_constants::icase);
if (std::regex_search(streetOut, ma, rHun) && ma.size() > 0) boost::smatch ma;
if (boost::regex_search(streetOut, ma, rHun) && ma.size() > 0)
{ {
if (ontoStr == "a") if (ontoStr == "a")
ontoStr.push_back('z'); ontoStr.push_back('z');
@@ -211,21 +213,18 @@ std::string GetTtsText::GetTurnNotification(Notification const & notification) c
} }
} }
char ttsOut[1024]; std::string ttsOut = distDirOntoStreetStr + distStr + // in 100 feet
std::snprintf(ttsOut, std::size(ttsOut), distDirOntoStreetStr.c_str(), dirStr + // turn right / take exit
distStr.c_str(), // in 100 feet ontoStr + // onto / null
dirStr.c_str(), // turn right / take exit streetOut + // Main Street / 543:: M4: Queens Parkway, London
ontoStr.c_str(), // onto / null dirVerb; // (optional "turn right" verb)
streetOut.c_str(), // Main Street / 543:: M4: Queens Parkway, London
dirVerb.c_str() // (optional "turn right" verb)
);
// remove floating punctuation // remove floating punctuation
static std::regex const rP(" [,\\.:;]+ "); static boost::regex const rP(" [,\\.:;]+ ");
std::string cleanOut = std::regex_replace(ttsOut, rP, " "); std::string cleanOut = boost::regex_replace(ttsOut, rP, " ");
// remove repetitious spaces or colons // remove repetitious spaces or colons
static std::regex const rS("[ :]{2,99}"); static boost::regex const rS("[ :]{2,99}");
cleanOut = std::regex_replace(cleanOut, rS, " "); cleanOut = boost::regex_replace(cleanOut, rS, " ");
// trim leading spaces // trim leading spaces
strings::Trim(cleanOut); strings::Trim(cleanOut);

View File

@@ -2,7 +2,6 @@
#include "base/string_utils.hpp" #include "base/string_utils.hpp"
#include "unicode/uchar.h" #include "unicode/uchar.h"
#include <regex>
#include <string> #include <string>
namespace routing::turns::sound namespace routing::turns::sound

View File

@@ -28,6 +28,8 @@
#include <unordered_map> #include <unordered_map>
#include <vector> #include <vector>
#include <boost/regex.hpp>
#include <gflags/gflags.h> #include <gflags/gflags.h>
#include <pugixml.hpp> #include <pugixml.hpp>
@@ -60,7 +62,7 @@ void LoadDataSources(std::string const & pathToMWMFolder, std::vector<FrozenData
CHECK(Platform::IsDirectory(pathToMWMFolder), (pathToMWMFolder, "must be a directory.")); CHECK(Platform::IsDirectory(pathToMWMFolder), (pathToMWMFolder, "must be a directory."));
Platform::FilesList files; Platform::FilesList files;
Platform::GetFilesByRegExp(pathToMWMFolder, std::string(".*\\") + DATA_FILE_EXTENSION, files); Platform::GetFilesByRegExp(pathToMWMFolder, boost::regex(".*\\") + DATA_FILE_EXTENSION, files);
CHECK(!files.empty(), (pathToMWMFolder, "Contains no .mwm files.")); CHECK(!files.empty(), (pathToMWMFolder, "Contains no .mwm files."));