mirror of
				https://github.com/ciphervance/supercell-wx.git
				synced 2025-10-31 16:50:06 +00:00 
			
		
		
		
	Merge pull request #104 from dpaulat/feature/re2
Use RE2 in favor of std::regex
This commit is contained in:
		
						commit
						269cbdebd1
					
				
					 10 changed files with 56 additions and 58 deletions
				
			
		|  | @ -35,6 +35,7 @@ Supercell Wx uses code from the following dependencies: | |||
| | [nunicode](https://bitbucket.org/alekseyt/nunicode/src/master/) | [MIT License](https://spdx.org/licenses/MIT.html) | Modified for MapLibre Native | | ||||
| | [OpenSSL](https://www.openssl.org/) | [OpenSSL License](https://spdx.org/licenses/OpenSSL.html) | | ||||
| | [Qt](https://www.qt.io/) | [GNU Lesser General Public License v3.0 only](https://spdx.org/licenses/LGPL-3.0-only.html) | Qt Core, Qt GUI, Qt Multimedia, Qt Network, Qt OpenGL, Qt Positioning, Qt SQL, Qt SVG, Qt Widgets<br/>Additional Licenses: https://doc.qt.io/qt-6/licenses-used-in-qt.html | | ||||
| | [re2](https://github.com/google/re2) | [BSD 3-Clause "New" or "Revised" License](https://spdx.org/licenses/BSD-3-Clause.html) | | ||||
| | [spdlog](https://github.com/gabime/spdlog) | [MIT License](https://spdx.org/licenses/MIT.html) | | ||||
| | [SQLite](https://www.sqlite.org/) | Public Domain | | ||||
| | [stb](https://github.com/nothings/stb) | Public Domain | | ||||
|  |  | |||
|  | @ -13,6 +13,7 @@ class SupercellWxConan(ConanFile): | |||
|                   "libcurl/8.4.0", | ||||
|                   "libxml2/2.12.2", | ||||
|                   "openssl/3.2.0", | ||||
|                   "re2/20231101", | ||||
|                   "spdlog/1.12.0", | ||||
|                   "sqlite3/3.44.2", | ||||
|                   "vulkan-loader/1.3.243.0", | ||||
|  |  | |||
|  | @ -2,10 +2,10 @@ | |||
| #include <scwx/util/logger.hpp> | ||||
| 
 | ||||
| #include <mutex> | ||||
| #include <regex> | ||||
| 
 | ||||
| #include <boost/json.hpp> | ||||
| #include <cpr/cpr.h> | ||||
| #include <re2/re2.h> | ||||
| 
 | ||||
| namespace scwx | ||||
| { | ||||
|  | @ -61,16 +61,10 @@ std::string UpdateManager::latest_version() const | |||
| std::string | ||||
| UpdateManager::Impl::GetVersionString(const std::string& releaseName) | ||||
| { | ||||
|    static const std::regex re {"\\d+\\.\\d+\\.\\d+"}; | ||||
|    static constexpr LazyRE2 re = {"(\\d+\\.\\d+\\.\\d+)"}; | ||||
|    std::string              versionString {}; | ||||
|    std::smatch             m; | ||||
| 
 | ||||
|    std::regex_search(releaseName, m, re); | ||||
| 
 | ||||
|    if (!m.empty()) | ||||
|    { | ||||
|       versionString = m[0].str(); | ||||
|    } | ||||
|    RE2::PartialMatch(releaseName, *re, &versionString); | ||||
| 
 | ||||
|    return versionString; | ||||
| } | ||||
|  |  | |||
|  | @ -23,7 +23,6 @@ | |||
| #include <scwx/util/logger.hpp> | ||||
| #include <scwx/util/time.hpp> | ||||
| 
 | ||||
| #include <regex> | ||||
| #include <set> | ||||
| 
 | ||||
| #include <backends/imgui_impl_opengl3.h> | ||||
|  | @ -33,6 +32,7 @@ | |||
| #include <boost/uuid/random_generator.hpp> | ||||
| #include <fmt/format.h> | ||||
| #include <imgui.h> | ||||
| #include <re2/re2.h> | ||||
| #include <QApplication> | ||||
| #include <QColor> | ||||
| #include <QDebug> | ||||
|  | @ -769,13 +769,13 @@ std::string MapWidgetImpl::FindMapSymbologyLayer() | |||
|       const std::string layer = qlayer.toStdString(); | ||||
| 
 | ||||
|       // Draw below layers defined in map style
 | ||||
|       auto it = std::find_if( | ||||
|          currentStyle_->drawBelow_.cbegin(), | ||||
|       auto it = std::find_if(currentStyle_->drawBelow_.cbegin(), | ||||
|                              currentStyle_->drawBelow_.cend(), | ||||
|                              [&layer](const std::string& styleLayer) -> bool | ||||
|                              { | ||||
|             std::regex re {styleLayer, std::regex_constants::icase}; | ||||
|             return std::regex_match(layer, re); | ||||
|                                 // Perform case-insensitive matching
 | ||||
|                                 RE2 re {"(?i)" + styleLayer}; | ||||
|                                 return RE2::FullMatch(layer, re); | ||||
|                              }); | ||||
| 
 | ||||
|       if (it != currentStyle_->drawBelow_.cend()) | ||||
|  |  | |||
|  | @ -2,10 +2,9 @@ | |||
| #include <scwx/qt/settings/settings_variable.hpp> | ||||
| #include <scwx/qt/util/color.hpp> | ||||
| 
 | ||||
| #include <regex> | ||||
| 
 | ||||
| #include <boost/gil.hpp> | ||||
| #include <fmt/format.h> | ||||
| #include <re2/re2.h> | ||||
| 
 | ||||
| namespace scwx | ||||
| { | ||||
|  | @ -134,8 +133,8 @@ public: | |||
| 
 | ||||
| bool PaletteSettings::Impl::ValidateColor(const std::string& value) | ||||
| { | ||||
|    static const std::regex re {"#[0-9A-Za-z]{8}"}; | ||||
|    return std::regex_match(value, re); | ||||
|    static constexpr LazyRE2 re = {"#[0-9A-Fa-f]{8}"}; | ||||
|    return RE2::FullMatch(value, *re); | ||||
| } | ||||
| 
 | ||||
| PaletteSettings::PaletteSettings() : | ||||
|  |  | |||
|  | @ -2,13 +2,12 @@ | |||
| #include <scwx/util/environment.hpp> | ||||
| #include <scwx/util/logger.hpp> | ||||
| 
 | ||||
| #include <regex> | ||||
| 
 | ||||
| #include <QCoreApplication> | ||||
| #include <QMapLibreGL/QMapLibreGL> | ||||
| #include <QTimer> | ||||
| 
 | ||||
| #include <gtest/gtest.h> | ||||
| #include <re2/re2.h> | ||||
| 
 | ||||
| namespace scwx | ||||
| { | ||||
|  | @ -108,13 +107,14 @@ TEST_P(ByMapProviderTest, MapProviderLayers) | |||
|             const std::string layer = qlayer.toStdString(); | ||||
| 
 | ||||
|             // Draw below layers defined in map style
 | ||||
|             auto it = std::find_if( | ||||
|                mapStyle.drawBelow_.cbegin(), | ||||
|             auto it = | ||||
|                std::find_if(mapStyle.drawBelow_.cbegin(), | ||||
|                             mapStyle.drawBelow_.cend(), | ||||
|                             [&layer](const std::string& styleLayer) -> bool | ||||
|                             { | ||||
|                   std::regex re {styleLayer, std::regex_constants::icase}; | ||||
|                   return std::regex_match(layer, re); | ||||
|                                // Perform case insensitive matching
 | ||||
|                                RE2 re {"(?i)" + styleLayer}; | ||||
|                                return RE2::FullMatch(layer, re); | ||||
|                             }); | ||||
| 
 | ||||
|             if (it != mapStyle.drawBelow_.cend()) | ||||
|  |  | |||
|  | @ -4,11 +4,11 @@ | |||
| #include <scwx/util/streams.hpp> | ||||
| 
 | ||||
| #include <istream> | ||||
| #include <regex> | ||||
| #include <string> | ||||
| 
 | ||||
| #include <boost/algorithm/string/replace.hpp> | ||||
| #include <boost/algorithm/string/trim.hpp> | ||||
| #include <re2/re2.h> | ||||
| 
 | ||||
| namespace scwx | ||||
| { | ||||
|  | @ -24,7 +24,7 @@ static const auto        logger_    = scwx::util::Logger::Create(logPrefix_); | |||
| // Segment Header only:
 | ||||
| // * <hhmm>_xM_<tz1>_day_mon_<dd>_year_/<hhmm>_xM_<tz2>_day_mon_<dd>_year/
 | ||||
| // Look for hhmm (xM|UTC) to key the date/time string
 | ||||
| static const std::regex reDateTimeString {"^[0-9]{3,4} ([AP]M|UTC)"}; | ||||
| static constexpr LazyRE2 reDateTimeString = {"^[0-9]{3,4} ([AP]M|UTC)"}; | ||||
| 
 | ||||
| static void ParseCodedInformation(std::shared_ptr<Segment> segment, | ||||
|                                   const std::string&       wfo); | ||||
|  | @ -333,7 +333,7 @@ void ParseCodedInformation(std::shared_ptr<Segment> segment, | |||
|       else if (codedMotionBegin != productContent.cend() && | ||||
|                codedMotionEnd == productContent.cend() && | ||||
|                !it->starts_with(" ") && | ||||
|                !std::regex_search(*it, std::regex {"^[0-9]"}) | ||||
|                !(it->length() > 0 && std::isdigit(it->at(0))) | ||||
|                /* Continuation lines */) | ||||
|       { | ||||
|          codedMotionEnd = it; | ||||
|  | @ -448,7 +448,7 @@ std::vector<std::string> TryParseMndHeader(std::istream& is) | |||
|    } | ||||
| 
 | ||||
|    if (!mndHeader.empty() && | ||||
|        !std::regex_search(mndHeader.back(), reDateTimeString)) | ||||
|        !RE2::PartialMatch(mndHeader.back(), *reDateTimeString)) | ||||
|    { | ||||
|       // MND Header should end with an Issuance Date/Time Line
 | ||||
|       mndHeader.clear(); | ||||
|  | @ -489,8 +489,8 @@ std::optional<SegmentHeader> TryParseSegmentHeader(std::istream& is) | |||
|    // UGC takes the form SSFNNN-NNN>NNN-SSFNNN-DDHHMM- (NWSI 10-1702)
 | ||||
|    // Look for SSF(NNN)?[->] to key the UGC string
 | ||||
|    // Look for DDHHMM- to end the UGC string
 | ||||
|    static const std::regex reUgcString {"^[A-Z]{2}[CZ]([0-9]{3})?[->]"}; | ||||
|    static const std::regex reUgcExpiration {"[0-9]{6}-$"}; | ||||
|    static constexpr LazyRE2 reUgcString     = {"^[A-Z]{2}[CZ]([0-9]{3})?[->]"}; | ||||
|    static constexpr LazyRE2 reUgcExpiration = {"[0-9]{6}-$"}; | ||||
| 
 | ||||
|    std::optional<SegmentHeader> header = std::nullopt; | ||||
|    std::string                  line; | ||||
|  | @ -498,14 +498,14 @@ std::optional<SegmentHeader> TryParseSegmentHeader(std::istream& is) | |||
| 
 | ||||
|    util::getline(is, line); | ||||
| 
 | ||||
|    if (std::regex_search(line, reUgcString)) | ||||
|    if (RE2::PartialMatch(line, *reUgcString)) | ||||
|    { | ||||
|       header = SegmentHeader(); | ||||
|       header->ugcString_.push_back(line); | ||||
| 
 | ||||
|       // If UGC is multi-line, continue parsing
 | ||||
|       while (!is.eof() && is.peek() != '\r' && | ||||
|              !std::regex_search(line, reUgcExpiration)) | ||||
|              !RE2::PartialMatch(line, *reUgcExpiration)) | ||||
|       { | ||||
|          util::getline(is, line); | ||||
|          header->ugcString_.push_back(line); | ||||
|  | @ -526,7 +526,7 @@ std::optional<SegmentHeader> TryParseSegmentHeader(std::istream& is) | |||
|       while (!is.eof() && is.peek() != '\r') | ||||
|       { | ||||
|          util::getline(is, line); | ||||
|          if (!std::regex_search(line, reDateTimeString)) | ||||
|          if (!RE2::PartialMatch(line, *reDateTimeString)) | ||||
|          { | ||||
|             header->ugcNames_.push_back(line); | ||||
|          } | ||||
|  | @ -553,12 +553,12 @@ std::optional<Vtec> TryParseVtecString(std::istream& is) | |||
|    // P-VTEC takes the form /k.aaa.cccc.pp.s.####.yymmddThhnnZB-yymmddThhnnZE/
 | ||||
|    // (NWSI 10-1703)
 | ||||
|    // Look for /k. to key the P-VTEC string
 | ||||
|    static const std::regex rePVtecString {"^/[OTEX]\\."}; | ||||
|    static constexpr LazyRE2 rePVtecString = {"^/[OTEX]\\."}; | ||||
| 
 | ||||
|    // H-VTEC takes the form
 | ||||
|    // /nwsli.s.ic.yymmddThhnnZB.yymmddThhnnZC.yymmddThhnnZE.fr/ (NWSI 10-1703)
 | ||||
|    // Look for /nwsli. to key the H-VTEC string
 | ||||
|    static const std::regex reHVtecString {"^/[A-Z0-9]{5}\\."}; | ||||
|    static constexpr LazyRE2 reHVtecString = {"^/[A-Z0-9]{5}\\."}; | ||||
| 
 | ||||
|    std::optional<Vtec> vtec = std::nullopt; | ||||
|    std::string         line; | ||||
|  | @ -566,7 +566,7 @@ std::optional<Vtec> TryParseVtecString(std::istream& is) | |||
| 
 | ||||
|    util::getline(is, line); | ||||
| 
 | ||||
|    if (std::regex_search(line, rePVtecString)) | ||||
|    if (RE2::PartialMatch(line, *rePVtecString)) | ||||
|    { | ||||
|       bool vtecValid; | ||||
| 
 | ||||
|  | @ -577,7 +577,7 @@ std::optional<Vtec> TryParseVtecString(std::istream& is) | |||
| 
 | ||||
|       util::getline(is, line); | ||||
| 
 | ||||
|       if (std::regex_search(line, reHVtecString)) | ||||
|       if (RE2::PartialMatch(line, *reHVtecString)) | ||||
|       { | ||||
|          vtec->hVtec_.swap(line); | ||||
|       } | ||||
|  |  | |||
|  | @ -2,12 +2,12 @@ | |||
| #include <scwx/util/logger.hpp> | ||||
| 
 | ||||
| #include <map> | ||||
| #include <regex> | ||||
| 
 | ||||
| #include <boost/assign.hpp> | ||||
| #include <boost/bimap.hpp> | ||||
| #include <boost/bimap/unordered_set_of.hpp> | ||||
| #include <boost/tokenizer.hpp> | ||||
| #include <re2/re2.h> | ||||
| 
 | ||||
| namespace scwx | ||||
| { | ||||
|  | @ -104,10 +104,10 @@ bool Ugc::Parse(const std::vector<std::string>& ugcString) | |||
|    bool dataValid = false; | ||||
| 
 | ||||
|    // UGC takes the form SSFNNN-NNN>NNN-SSFNNN-DDHHMM- (NWSI 10-1702)
 | ||||
|    static const std::regex reStart {"[A-Z]{2}[CZ]([0-9]{3}|ALL)"}; | ||||
|    static const std::regex reAnyFipsId {"([0-9]{3}|ALL)"}; | ||||
|    static const std::regex reSpecificFipsId {"(?!0{3})[0-9]{3}"}; | ||||
|    static const std::regex reProductExpiration {"[0-9]{6}"}; | ||||
|    static constexpr LazyRE2 reStart          = {"[A-Z]{2}[CZ]([0-9]{3}|ALL)"}; | ||||
|    static constexpr LazyRE2 reAnyFipsId      = {"([0-9]{3}|ALL)"}; | ||||
|    static constexpr LazyRE2 reSpecificFipsId = {"[0-9]{3}"}; | ||||
|    static constexpr LazyRE2 reProductExpiration = {"[0-9]{6}"}; | ||||
| 
 | ||||
|    std::stringstream ugcStream; | ||||
|    for (auto& line : ugcString) | ||||
|  | @ -131,7 +131,7 @@ bool Ugc::Parse(const std::vector<std::string>& ugcString) | |||
|    for (auto& token : tokens) | ||||
|    { | ||||
|       // Product Expiration is the final token
 | ||||
|       if (std::regex_match(token, reProductExpiration)) | ||||
|       if (RE2::FullMatch(token, *reProductExpiration)) | ||||
|       { | ||||
|          p->productExpiration_ = token; | ||||
|          dataValid             = true; | ||||
|  | @ -153,7 +153,7 @@ bool Ugc::Parse(const std::vector<std::string>& ugcString) | |||
| 
 | ||||
|       // Look for the start of the UGC string (may be multiple per UGC string
 | ||||
|       // for multiple states, territories, or marine area)
 | ||||
|       if (std::regex_match(firstToken, reStart)) | ||||
|       if (RE2::FullMatch(firstToken, *reStart)) | ||||
|       { | ||||
|          currentState  = firstToken.substr(0, 2); | ||||
|          currentFormat = ugcFormatMap_.right.at(firstToken.at(2)); | ||||
|  | @ -167,7 +167,7 @@ bool Ugc::Parse(const std::vector<std::string>& ugcString) | |||
|       } | ||||
|       // Look for additional FIPS IDs in the UGC string
 | ||||
|       else if (!currentState.empty() && | ||||
|                std::regex_match(firstToken, reAnyFipsId)) | ||||
|                RE2::FullMatch(firstToken, *reAnyFipsId)) | ||||
|       { | ||||
|          firstFipsId = firstToken; | ||||
|       } | ||||
|  | @ -188,7 +188,8 @@ bool Ugc::Parse(const std::vector<std::string>& ugcString) | |||
|       { | ||||
|          std::string secondToken {(++tokenIt).current_token()}; | ||||
| 
 | ||||
|          if (std::regex_match(secondToken, reSpecificFipsId)) | ||||
|          if (RE2::FullMatch(secondToken, *reSpecificFipsId) && | ||||
|              secondToken != "000") | ||||
|          { | ||||
|             secondFipsId = secondToken; | ||||
|          } | ||||
|  |  | |||
|  | @ -3,7 +3,6 @@ | |||
| #include <scwx/util/logger.hpp> | ||||
| 
 | ||||
| #include <ranges> | ||||
| #include <regex> | ||||
| #include <shared_mutex> | ||||
| 
 | ||||
| #if defined(_MSC_VER) | ||||
|  | @ -13,6 +12,7 @@ | |||
| #define LIBXML_HTML_ENABLED | ||||
| #include <cpr/cpr.h> | ||||
| #include <libxml/HTMLparser.h> | ||||
| #include <re2/re2.h> | ||||
| 
 | ||||
| #if !defined(_MSC_VER) | ||||
| #   include <date/date.h> | ||||
|  | @ -77,7 +77,7 @@ WarningsProvider::ListFiles(std::chrono::system_clock::time_point newerThan) | |||
|    using namespace date; | ||||
| #endif | ||||
| 
 | ||||
|    static const std::regex reWarningsFilename { | ||||
|    static constexpr LazyRE2 reWarningsFilename = { | ||||
|       "warnings_[0-9]{8}_[0-9]{2}.txt"}; | ||||
|    static const std::string dateTimeFormat {"warnings_%Y%m%d_%H.txt"}; | ||||
| 
 | ||||
|  | @ -101,7 +101,7 @@ WarningsProvider::ListFiles(std::chrono::system_clock::time_point newerThan) | |||
|          [](auto& record) | ||||
|          { | ||||
|             return record.type_ == std::filesystem::file_type::regular && | ||||
|                    std::regex_match(record.filename_, reWarningsFilename); | ||||
|                    RE2::FullMatch(record.filename_, *reWarningsFilename); | ||||
|          }); | ||||
| 
 | ||||
|    std::unique_lock lock(p->filesMutex_); | ||||
|  |  | |||
|  | @ -5,6 +5,7 @@ project(scwx-data) | |||
| find_package(Boost) | ||||
| find_package(cpr) | ||||
| find_package(LibXml2) | ||||
| find_package(re2) | ||||
| find_package(spdlog) | ||||
| 
 | ||||
| if (NOT MSVC) | ||||
|  | @ -268,6 +269,7 @@ target_link_libraries(wxdata PUBLIC aws-cpp-sdk-core | |||
|                                     aws-cpp-sdk-s3 | ||||
|                                     cpr::cpr | ||||
|                                     LibXml2::LibXml2 | ||||
|                                     re2::re2 | ||||
|                                     spdlog::spdlog | ||||
|                                     units::units) | ||||
| target_link_libraries(wxdata INTERFACE Boost::iostreams | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Dan Paulat
						Dan Paulat