From 01f6c8daad80b26ab55b6826ad95f0c606c46e03 Mon Sep 17 00:00:00 2001 From: Paul Beckingham Date: Sun, 20 Dec 2015 09:58:54 -0500 Subject: [PATCH] Common: Added RX --- src/common/CMakeLists.txt | 10 +-- src/common/RX.cpp | 165 ++++++++++++++++++++++++++++++++++++++ src/common/RX.h | 58 ++++++++++++++ 3 files changed, 228 insertions(+), 5 deletions(-) create mode 100644 src/common/RX.cpp create mode 100644 src/common/RX.h diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt index b2ca6485..0cc1165f 100644 --- a/src/common/CMakeLists.txt +++ b/src/common/CMakeLists.txt @@ -1,13 +1,13 @@ cmake_minimum_required (VERSION 2.8) include_directories (${CMAKE_SOURCE_DIR} - ${CMAKE_SOURCE_DIR}/src ${CMAKE_SOURCE_DIR}/src/common ${TIMEW_INCLUDE_DIRS}) -set (common_SRCS Color.cpp Color.h - text.cpp text.h - utf8.cpp utf8.h - wcwidth6.cpp) +set (common_SRCS Color.cpp Color.h + RX.cpp RX.h + text.cpp text.h + utf8.cpp utf8.h + wcwidth6.cpp) add_library (common STATIC ${common_SRCS}) diff --git a/src/common/RX.cpp b/src/common/RX.cpp new file mode 100644 index 00000000..a5da5b33 --- /dev/null +++ b/src/common/RX.cpp @@ -0,0 +1,165 @@ +//////////////////////////////////////////////////////////////////////////////// +// +// Copyright 2006 - 2015, Paul Beckingham, Federico Hernandez. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. +// +// http://www.opensource.org/licenses/mit-license.php +// +//////////////////////////////////////////////////////////////////////////////// + +#include +#include +#include +#include + +//////////////////////////////////////////////////////////////////////////////// +RX::RX () +: _compiled (false) +, _pattern ("") +, _case_sensitive (false) +{ +} + +//////////////////////////////////////////////////////////////////////////////// +RX::RX ( + const std::string& pattern, + bool case_sensitive /* = true */) +: _compiled (false) +, _pattern (pattern) +, _case_sensitive (case_sensitive) +{ + compile (); +} + +//////////////////////////////////////////////////////////////////////////////// +RX::RX (const RX& other) +{ + _compiled = false; + _pattern = other._pattern; + _case_sensitive = other._case_sensitive; +} + +//////////////////////////////////////////////////////////////////////////////// +RX::~RX () +{ + if (_compiled) + regfree (&_regex); +} + +//////////////////////////////////////////////////////////////////////////////// +RX& RX::operator= (const RX& other) +{ + if (this != &other) + { + _compiled = false; + _pattern = other._pattern; + _case_sensitive = other._case_sensitive; + } + + return *this; +} + +//////////////////////////////////////////////////////////////////////////////// +void RX::compile () +{ + if (! _compiled) + { + memset (&_regex, 0, sizeof (regex_t)); + + int result; + if ((result = regcomp (&_regex, _pattern.c_str (), +#ifdef DARWIN + REG_ENHANCED | REG_EXTENDED | REG_NEWLINE | +#else + REG_EXTENDED | REG_NEWLINE | +#endif + (_case_sensitive ? 0 : REG_ICASE))) != 0) + { + char message[256]; + regerror (result, &_regex, message, 256); + throw std::string (message); + } + + _compiled = true; + } +} + +//////////////////////////////////////////////////////////////////////////////// +bool RX::match (const std::string& in) +{ + if (! _compiled) + compile (); + + return regexec (&_regex, in.c_str (), 0, NULL, 0) == 0 ? true : false; +} + +//////////////////////////////////////////////////////////////////////////////// +bool RX::match ( + std::vector& matches, + const std::string& in) +{ + if (! _compiled) + compile (); + + regmatch_t rm[2]; + int offset = 0; + int length = in.length (); + while (regexec (&_regex, in.c_str () + offset, 2, &rm[0], 0) == 0 && + offset < length) + { + matches.push_back (in.substr (rm[0].rm_so + offset, rm[0].rm_eo - rm[0].rm_so)); + offset += rm[0].rm_eo; + + // Protection against zero-width patterns causing infinite loops. + if (rm[0].rm_so == rm[0].rm_eo) + ++offset; + } + + return matches.size () ? true : false; +} + +//////////////////////////////////////////////////////////////////////////////// +bool RX::match ( + std::vector & start, + std::vector & end, + const std::string& in) +{ + if (! _compiled) + compile (); + + regmatch_t rm[2]; + int offset = 0; + int length = in.length (); + while (regexec (&_regex, in.c_str () + offset, 2, &rm[0], 0) == 0 && + offset < length) + { + start.push_back (rm[0].rm_so + offset); + end.push_back (rm[0].rm_eo + offset); + offset += rm[0].rm_eo; + + // Protection against zero-width patterns causing infinite loops. + if (rm[0].rm_so == rm[0].rm_eo) + ++offset; + } + + return start.size () ? true : false; +} + +//////////////////////////////////////////////////////////////////////////////// diff --git a/src/common/RX.h b/src/common/RX.h new file mode 100644 index 00000000..5a41ad22 --- /dev/null +++ b/src/common/RX.h @@ -0,0 +1,58 @@ +//////////////////////////////////////////////////////////////////////////////// +// +// Copyright 2006 - 2015, Paul Beckingham, Federico Hernandez. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. +// +// http://www.opensource.org/licenses/mit-license.php +// +//////////////////////////////////////////////////////////////////////////////// + +#ifndef INCLUDED_RX +#define INCLUDED_RX + +#include +#include +#include + +class RX +{ +public: + RX (); + RX (const std::string&, bool caseSensitive = true); + RX (const RX&); + ~RX (); + RX& operator= (const RX&); + + bool match (const std::string&); + bool match (std::vector&, const std::string&); + bool match (std::vector &, std::vector &, const std::string&); + +private: + void compile (); + +private: + bool _compiled; + std::string _pattern; + bool _case_sensitive; + regex_t _regex; +}; + +#endif +