mirror of
https://foundry.openuru.org/gitblit/r/CWE-ou-minkata.git
synced 2025-07-18 11:19:10 +00:00
Add basic regex functionality to plString
This commit is contained in:
@ -44,6 +44,7 @@ find_package(Ogg REQUIRED) #TODO: Not required if we aren't building the clie
|
|||||||
find_package(Vorbis REQUIRED) #TODO: Not required if we aren't building the client
|
find_package(Vorbis REQUIRED) #TODO: Not required if we aren't building the client
|
||||||
find_package(Speex REQUIRED) #TODO: Not required if we aren't building the client
|
find_package(Speex REQUIRED) #TODO: Not required if we aren't building the client
|
||||||
find_package(CURL REQUIRED)
|
find_package(CURL REQUIRED)
|
||||||
|
find_package(PCRE REQUIRED)
|
||||||
|
|
||||||
if(WIN32)
|
if(WIN32)
|
||||||
find_package(PhysX REQUIRED) #TODO: Not required if we aren't building the client
|
find_package(PhysX REQUIRED) #TODO: Not required if we aren't building the client
|
||||||
|
@ -31,6 +31,7 @@ Plasma currently utilizes the following third-party libraries:
|
|||||||
- libPNG - http://www.libpng.org/
|
- libPNG - http://www.libpng.org/
|
||||||
- speex - http://www.speex.org/downloads/
|
- speex - http://www.speex.org/downloads/
|
||||||
- zlib - http://zlib.net/
|
- zlib - http://zlib.net/
|
||||||
|
- PCRE - http://www.pcre.org/
|
||||||
|
|
||||||
- PyGTK - http://www.pygtk.org/downloads.html
|
- PyGTK - http://www.pygtk.org/downloads.html
|
||||||
- PIL - http://www.pythonware.com/products/pil/
|
- PIL - http://www.pythonware.com/products/pil/
|
||||||
|
@ -172,10 +172,6 @@ target_link_libraries(plClient ${Vorbis_LIBRARIES})
|
|||||||
target_link_libraries(plClient ${DirectX_LIBRARIES})
|
target_link_libraries(plClient ${DirectX_LIBRARIES})
|
||||||
target_link_libraries(plClient ${CURL_LIBRARY})
|
target_link_libraries(plClient ${CURL_LIBRARY})
|
||||||
|
|
||||||
if(Bink_SDK_AVAILABLE)
|
|
||||||
target_link_libraries(plClient ${Bink_LIBRARIES})
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(USE_VLD)
|
if(USE_VLD)
|
||||||
target_link_libraries(plClient ${VLD_LIBRARY})
|
target_link_libraries(plClient ${VLD_LIBRARY})
|
||||||
endif()
|
endif()
|
||||||
|
@ -97,6 +97,8 @@ set(CoreLib_HEADERS
|
|||||||
)
|
)
|
||||||
|
|
||||||
add_library(CoreLib STATIC ${CoreLib_SOURCES} ${CoreLib_HEADERS})
|
add_library(CoreLib STATIC ${CoreLib_SOURCES} ${CoreLib_HEADERS})
|
||||||
|
target_link_libraries(CoreLib ${PCRE_LIBRARY})
|
||||||
|
|
||||||
if(UNIX)
|
if(UNIX)
|
||||||
target_link_libraries(CoreLib pthread)
|
target_link_libraries(CoreLib pthread)
|
||||||
endif(UNIX)
|
endif(UNIX)
|
||||||
|
@ -46,6 +46,8 @@ You can contact Cyan Worlds, Inc. by email legal@cyan.com
|
|||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include <wchar.h>
|
#include <wchar.h>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <functional>
|
||||||
|
#include <pcre.h>
|
||||||
|
|
||||||
const plString plString::Null;
|
const plString plString::Null;
|
||||||
|
|
||||||
@ -600,6 +602,70 @@ int plString::Find(const char *str, CaseSensitivity sense) const
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool plString::REMatch(const char *pattern, CaseSensitivity sense) const
|
||||||
|
{
|
||||||
|
int opts = PCRE_UTF8;
|
||||||
|
if (sense == kCaseInsensitive)
|
||||||
|
opts |= PCRE_CASELESS;
|
||||||
|
|
||||||
|
plString pat_full = plString::Format("(?:%s)\\z", pattern);
|
||||||
|
const char *errptr;
|
||||||
|
int erroffs;
|
||||||
|
std::unique_ptr<pcre, std::function<void (pcre *)>>
|
||||||
|
re(pcre_compile(pat_full.c_str(), opts, &errptr, &erroffs, nullptr), pcre_free);
|
||||||
|
if (!re.get()) {
|
||||||
|
hsAssert(0, plString::Format("Invalid Regex pattern: %s (at %d)", errptr, erroffs).c_str());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
int result = pcre_exec(re.get(), nullptr, c_str(), GetSize(), 0,
|
||||||
|
PCRE_ANCHORED, nullptr, 0);
|
||||||
|
if (result >= 0)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
hsAssert(result == PCRE_ERROR_NOMATCH, plString::Format("Regex match error: %d", result).c_str());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<plString> plString::RESearch(const char *pattern,
|
||||||
|
CaseSensitivity sense) const
|
||||||
|
{
|
||||||
|
int opts = PCRE_UTF8;
|
||||||
|
if (sense == kCaseInsensitive)
|
||||||
|
opts |= PCRE_CASELESS;
|
||||||
|
|
||||||
|
const char *errptr;
|
||||||
|
int erroffs;
|
||||||
|
std::unique_ptr<pcre, std::function<void (pcre *)>>
|
||||||
|
re(pcre_compile(pattern, opts, &errptr, &erroffs, nullptr), pcre_free);
|
||||||
|
if (!re.get()) {
|
||||||
|
hsAssert(0, plString::Format("Invalid Regex pattern: %s (at %d)", errptr, erroffs).c_str());
|
||||||
|
return std::vector<plString>();
|
||||||
|
}
|
||||||
|
|
||||||
|
int ncaps = 0;
|
||||||
|
pcre_fullinfo(re.get(), nullptr, PCRE_INFO_CAPTURECOUNT, &ncaps);
|
||||||
|
|
||||||
|
ncaps += 1; // For the whole-pattern capture
|
||||||
|
std::unique_ptr<int> outvec(new int[ncaps * 3]);
|
||||||
|
memset(outvec.get(), -1, sizeof(int) * ncaps * 3);
|
||||||
|
int result = pcre_exec(re.get(), nullptr, c_str(), GetSize(), 0, 0,
|
||||||
|
outvec.get(), ncaps * 3);
|
||||||
|
if (result >= 0) {
|
||||||
|
std::vector<plString> caps;
|
||||||
|
caps.resize(ncaps);
|
||||||
|
for (int i = 0; i < ncaps; ++i) {
|
||||||
|
int start = outvec.get()[i*2], end = outvec.get()[i*2+1];
|
||||||
|
if (start >= 0)
|
||||||
|
caps[i] = Substr(start, end - start);
|
||||||
|
}
|
||||||
|
return caps;
|
||||||
|
}
|
||||||
|
|
||||||
|
hsAssert(result == PCRE_ERROR_NOMATCH, plString::Format("Regex search error: %d", result).c_str());
|
||||||
|
return std::vector<plString>();
|
||||||
|
}
|
||||||
|
|
||||||
static bool in_set(char key, const char *charset)
|
static bool in_set(char key, const char *charset)
|
||||||
{
|
{
|
||||||
for (const char *cs = charset; *cs; ++cs) {
|
for (const char *cs = charset; *cs; ++cs) {
|
||||||
|
@ -479,6 +479,20 @@ public:
|
|||||||
int Find(const plString &str, CaseSensitivity sense = kCaseSensitive) const
|
int Find(const plString &str, CaseSensitivity sense = kCaseSensitive) const
|
||||||
{ return Find(str.c_str(), sense); }
|
{ return Find(str.c_str(), sense); }
|
||||||
|
|
||||||
|
/** Check that this string matches the specified regular expression.
|
||||||
|
* This with only return true if the whole string can be matched
|
||||||
|
* by \a pattern.
|
||||||
|
*/
|
||||||
|
bool REMatch(const char *pattern, CaseSensitivity sense = kCaseSensitive) const;
|
||||||
|
|
||||||
|
/** Search for substrings which match the specified regular expression.
|
||||||
|
* If capture groups are specified in the pattern, they will be
|
||||||
|
* returned as additional strings in the returned vector, starting at
|
||||||
|
* index 1 (index 0 contains the whole match). If the pattern was not
|
||||||
|
* found, this returns an empty vector.
|
||||||
|
*/
|
||||||
|
std::vector<plString> RESearch(const char *pattern, CaseSensitivity sense = kCaseSensitive) const;
|
||||||
|
|
||||||
/** Trim any characters in the supplied \a charset from the left of
|
/** Trim any characters in the supplied \a charset from the left of
|
||||||
* this string.
|
* this string.
|
||||||
*/
|
*/
|
||||||
|
21
cmake/FindPCRE.cmake
Normal file
21
cmake/FindPCRE.cmake
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
if(PCRE_INCLUDE_DIR AND PCRE_LIBRARY)
|
||||||
|
set(PCRE_FIND_QUIETLY TRUE)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
find_path(PCRE_INCLUDE_DIR pcre.h)
|
||||||
|
find_library(PCRE_LIBRARY NAMES pcre)
|
||||||
|
set(PCRE_LIBRARIES ${PCRE_LIBRARY})
|
||||||
|
|
||||||
|
if(PCRE_INCLUDE_DIR AND PCRE_LIBRARY)
|
||||||
|
set(PCRE_FOUND TRUE)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(PCRE_FOUND)
|
||||||
|
if(NOT PCRE_FIND_QUIETLY)
|
||||||
|
message(STATUS "Found Perl Compatible Regular Expressions library: ${PCRE_INCLUDE_DIR}")
|
||||||
|
endif()
|
||||||
|
else()
|
||||||
|
if(PCRE_FIND_REQUIRED)
|
||||||
|
message(FATAL_ERROR "Could not find Perl Compatible Regular Expressions library")
|
||||||
|
endif()
|
||||||
|
endif()
|
Reference in New Issue
Block a user