version 5.0.0_beta
integrate PIRegularExpression into PIString and PIDir add piliterals_regularexpression.h for ""_regex and ""_glob literals
This commit is contained in:
@@ -4,10 +4,10 @@ if (POLICY CMP0177)
|
||||
cmake_policy(SET CMP0177 OLD)
|
||||
endif()
|
||||
project(PIP)
|
||||
set(PIP_MAJOR 4)
|
||||
set(PIP_MINOR 8)
|
||||
set(PIP_MAJOR 5)
|
||||
set(PIP_MINOR 0)
|
||||
set(PIP_REVISION 0)
|
||||
set(PIP_SUFFIX )
|
||||
set(PIP_SUFFIX _beta)
|
||||
set(PIP_COMPANY SHS)
|
||||
set(PIP_DOMAIN org.SHS)
|
||||
|
||||
@@ -371,6 +371,9 @@ set(PCRE2_BUILD_PCRE2_32 OFF)
|
||||
set(PCRE2_BUILD_PCRE2GREP OFF)
|
||||
set(PCRE2_BUILD_TESTS OFF)
|
||||
set(PCRE2_SHOW_REPORT OFF)
|
||||
if (WIN32)
|
||||
set (ZLIB_ROOT "${MINGW_INCLUDE}")
|
||||
endif()
|
||||
add_subdirectory("3rd/pcre2" EXCLUDE_FROM_ALL)
|
||||
list(APPEND LIBS_MAIN pcre2-16-static)
|
||||
|
||||
|
||||
@@ -298,9 +298,9 @@ bool sort_compare(const PIFile::FileInfo & v0, const PIFile::FileInfo & v1) {
|
||||
//! также "." и "..". Возвращаются абсолютные пути.
|
||||
//! \attention Этот метод не читает содержимое директорий
|
||||
//! рекурсивно!
|
||||
PIVector<PIFile::FileInfo> PIDir::entries() {
|
||||
PIVector<PIFile::FileInfo> l;
|
||||
if (!isExists()) return l;
|
||||
PIVector<PIFile::FileInfo> PIDir::entries(const PIRegularExpression & regexp) {
|
||||
if (!isExists()) return {};
|
||||
PIVector<PIFile::FileInfo> ret;
|
||||
PIString dp = absolutePath();
|
||||
PIString p(dp);
|
||||
if (dp == ".")
|
||||
@@ -309,9 +309,9 @@ PIVector<PIFile::FileInfo> PIDir::entries() {
|
||||
dp += separator;
|
||||
// piCout << "start entries from" << p;
|
||||
#ifdef WINDOWS
|
||||
PIFile::FileInfo fi;
|
||||
if (dp == separator) {
|
||||
char letters[1024];
|
||||
PIFile::FileInfo fi;
|
||||
DWORD ll = GetLogicalDriveStringsA(1023, letters);
|
||||
PIString clet;
|
||||
for (DWORD i = 0; i < ll; ++i) {
|
||||
@@ -319,7 +319,12 @@ PIVector<PIFile::FileInfo> PIDir::entries() {
|
||||
clet.resize(2);
|
||||
fi.path = clet;
|
||||
fi.flags = PIFile::FileInfo::Dir;
|
||||
l << fi;
|
||||
if (regexp.isValid()) {
|
||||
if (regexp.match(fi.name())) {
|
||||
ret << fi;
|
||||
}
|
||||
} else
|
||||
ret << fi;
|
||||
clet.clear();
|
||||
} else
|
||||
clet += PIChar(letters[i]);
|
||||
@@ -329,21 +334,27 @@ PIVector<PIFile::FileInfo> PIDir::entries() {
|
||||
piZeroMemory(fd);
|
||||
p += "\\*";
|
||||
void * hf = FindFirstFileA((LPCSTR)(p.data()), &fd);
|
||||
if (!hf) return l;
|
||||
if (!hf) return ret;
|
||||
bool hdd = false;
|
||||
do {
|
||||
PIString fn(fd.cFileName);
|
||||
if (fn == "..") hdd = true;
|
||||
l << PIFile::fileInfo(dp + fn);
|
||||
fi = PIFile::fileInfo(dp + fn);
|
||||
if (regexp.isValid()) {
|
||||
if (regexp.match(fi.name())) {
|
||||
ret << fi;
|
||||
}
|
||||
} else
|
||||
ret << fi;
|
||||
piZeroMemory(fd);
|
||||
} while (FindNextFileA(hf, &fd) != 0);
|
||||
FindClose(hf);
|
||||
l.sort(sort_compare);
|
||||
ret.sort(sort_compare);
|
||||
if (!hdd) {
|
||||
PIFile::FileInfo fi;
|
||||
fi.path = "..";
|
||||
fi.flags = PIFile::FileInfo::Dir | PIFile::FileInfo::DotDot;
|
||||
l.push_front(fi);
|
||||
ret.push_front(fi);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -356,7 +367,7 @@ PIVector<PIFile::FileInfo> PIDir::entries() {
|
||||
for (;;) {
|
||||
de = readdir(dir);
|
||||
if (!de) break;
|
||||
l << PIFile::fileInfo(dp + PIString(de->d_name));
|
||||
ret << PIFile::fileInfo(dp + PIString(de->d_name));
|
||||
}
|
||||
closedir(dir);
|
||||
}
|
||||
@@ -371,14 +382,14 @@ PIVector<PIFile::FileInfo> PIDir::entries() {
|
||||
versionsort);
|
||||
# endif
|
||||
for (int i = 0; i < cnt; ++i) {
|
||||
l << PIFile::fileInfo(dp + PIString(list[i]->d_name));
|
||||
ret << PIFile::fileInfo(dp + PIString(list[i]->d_name));
|
||||
free(list[i]);
|
||||
}
|
||||
free(list);
|
||||
# endif
|
||||
#endif
|
||||
// piCout << "end entries from" << p;
|
||||
return l;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
@@ -394,7 +405,7 @@ PIVector<PIFile::FileInfo> PIDir::entries() {
|
||||
//! одним списком, сортированным по алфавиту. Список не содержит
|
||||
//! "." и "..". Возвращаются абсолютные пути, причём файлы
|
||||
//! располагаются после директорий.
|
||||
PIVector<PIFile::FileInfo> PIDir::allEntries() {
|
||||
PIVector<PIFile::FileInfo> PIDir::allEntries(const PIRegularExpression & regexp) {
|
||||
PIVector<PIFile::FileInfo> ret;
|
||||
PIVector<PIFile::FileInfo> dirs;
|
||||
PIStringList cdirs, ndirs;
|
||||
@@ -409,10 +420,16 @@ PIVector<PIFile::FileInfo> PIDir::allEntries() {
|
||||
if (de.isDir()) {
|
||||
dirs << de;
|
||||
ndirs << de.path;
|
||||
} else
|
||||
} else {
|
||||
if (regexp.isValid()) {
|
||||
if (!regexp.match(de.name())) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
ret << de;
|
||||
}
|
||||
}
|
||||
}
|
||||
cdirs = ndirs;
|
||||
ndirs.clear();
|
||||
}
|
||||
@@ -516,8 +533,8 @@ PIDir PIDir::temporary() {
|
||||
}
|
||||
|
||||
|
||||
PIVector<PIFile::FileInfo> PIDir::allEntries(const PIString & path) {
|
||||
return PIDir(path).allEntries();
|
||||
PIVector<PIFile::FileInfo> PIDir::allEntries(const PIString & path, const PIRegularExpression & regexp) {
|
||||
return PIDir(path).allEntries(regexp);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
#define PIDIR_H
|
||||
|
||||
#include "pifile.h"
|
||||
#include "piregularexpression.h"
|
||||
|
||||
|
||||
//! \ingroup IO
|
||||
@@ -104,11 +105,11 @@ public:
|
||||
|
||||
//! \~english Returns this directory content
|
||||
//! \~russian Возвращает содержимое этой директории
|
||||
PIVector<PIFile::FileInfo> entries();
|
||||
PIVector<PIFile::FileInfo> entries(const PIRegularExpression & regexp = {});
|
||||
|
||||
//! \~english Returns this directory content recursively
|
||||
//! \~russian Возвращает содержимое этой директории рекурсивно
|
||||
PIVector<PIFile::FileInfo> allEntries();
|
||||
PIVector<PIFile::FileInfo> allEntries(const PIRegularExpression & regexp = {});
|
||||
|
||||
//! \~english Make this directory, recursively if "withParents"
|
||||
//! \~russian Создаёт эту директорию, рекурсивно если "withParents"
|
||||
@@ -155,7 +156,7 @@ public:
|
||||
|
||||
//! \~english Returns directory "path" content recursively
|
||||
//! \~russian Возвращает содержимое директории "path" рекурсивно
|
||||
static PIVector<PIFile::FileInfo> allEntries(const PIString & path);
|
||||
static PIVector<PIFile::FileInfo> allEntries(const PIString & path, const PIRegularExpression & regexp = {});
|
||||
|
||||
//! \~english Returns if directory "path" exists
|
||||
//! \~russian Возвращает существует ли эта директория
|
||||
|
||||
@@ -34,6 +34,7 @@
|
||||
|
||||
#include "piliterals_bytearray.h"
|
||||
#include "piliterals_bytes.h"
|
||||
#include "piliterals_regularexpression.h"
|
||||
#include "piliterals_string.h"
|
||||
#include "piliterals_time.h"
|
||||
|
||||
|
||||
46
libs/main/literals/piliterals_regularexpression.h
Normal file
46
libs/main/literals/piliterals_regularexpression.h
Normal file
@@ -0,0 +1,46 @@
|
||||
/*! \file piliterals_regularexpression.h
|
||||
* \ingroup Core
|
||||
* \~\brief
|
||||
* \~english PIRegularExpression C++11 literals
|
||||
* \~russian C++11 суффиксы PIString
|
||||
*/
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
PIRegularExpression C++11 literals
|
||||
Ivan Pelipenko peri4ko@yandex.ru
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef PILITERALS_REGULAREXPRESSION_H
|
||||
#define PILITERALS_REGULAREXPRESSION_H
|
||||
|
||||
#include "piregularexpression.h"
|
||||
|
||||
//! \~\brief
|
||||
//! \~english PIRegularExpression from string pattern in PCRE2 format
|
||||
//! \~russian PIRegularExpression из строки в формате PCRE2
|
||||
inline PIRegularExpression operator""_regex(const char * v, size_t sz) {
|
||||
return PIRegularExpression(PIString::fromUTF8(v, sz));
|
||||
}
|
||||
|
||||
//! \~\brief
|
||||
//! \~english PIRegularExpression from string pattern in Glob format
|
||||
//! \~russian PIRegularExpression из строки в формате Glob
|
||||
inline PIRegularExpression operator""_glob(const char * v, size_t sz) {
|
||||
return PIRegularExpression::fromGlob(PIString::fromUTF8(v, sz));
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
@@ -192,25 +192,8 @@ int PIRegularExpression::captureGroupIndex(const PIString & gname) const {
|
||||
}
|
||||
|
||||
|
||||
PIRegularExpression::Matcher PIRegularExpression::matchIterator(PIString & subject, size_t offset) {
|
||||
PIRegularExpression::Matcher ret(this);
|
||||
ret.start_offset = offset;
|
||||
ret.subject = &subject;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
PIRegularExpression::Matcher PIRegularExpression::matchIterator(PIString && subject, size_t offset) {
|
||||
PIRegularExpression::Matcher ret(this);
|
||||
ret.start_offset = offset;
|
||||
ret.subject_own = std::move(subject);
|
||||
ret.subject = &ret.subject_own;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
PIRegularExpression::Matcher PIRegularExpression::matchIterator(const PIString & subject, size_t offset) {
|
||||
PIRegularExpression::Matcher ret(this);
|
||||
PIRegularExpression::Matcher PIRegularExpression::matchIterator(const PIString & subject, size_t offset) const {
|
||||
PIRegularExpression::Matcher ret(const_cast<PIRegularExpression *>(this));
|
||||
ret.start_offset = offset;
|
||||
ret.subject_own = subject;
|
||||
ret.subject = &ret.subject_own;
|
||||
@@ -218,27 +201,44 @@ PIRegularExpression::Matcher PIRegularExpression::matchIterator(const PIString &
|
||||
}
|
||||
|
||||
|
||||
PIRegularExpression::Matcher PIRegularExpression::match(PIString & subject, size_t offset) {
|
||||
PIRegularExpression::Matcher PIRegularExpression::matchIterator(PIString & subject, size_t offset) const {
|
||||
PIRegularExpression::Matcher ret(const_cast<PIRegularExpression *>(this));
|
||||
ret.start_offset = offset;
|
||||
ret.subject = &subject;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
PIRegularExpression::Matcher PIRegularExpression::matchIterator(PIString && subject, size_t offset) const {
|
||||
PIRegularExpression::Matcher ret(const_cast<PIRegularExpression *>(this));
|
||||
ret.start_offset = offset;
|
||||
ret.subject_own = std::move(subject);
|
||||
ret.subject = &ret.subject_own;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
PIRegularExpression::Matcher PIRegularExpression::match(const PIString & subject, size_t offset) const {
|
||||
PIRegularExpression::Matcher ret = matchIterator(subject, offset);
|
||||
PRIVATE->match(ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
PIRegularExpression::Matcher PIRegularExpression::match(PIString && subject, size_t offset) {
|
||||
PIRegularExpression::Matcher PIRegularExpression::match(PIString & subject, size_t offset) const {
|
||||
PIRegularExpression::Matcher ret = matchIterator(subject, offset);
|
||||
PRIVATE->match(ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
PIRegularExpression::Matcher PIRegularExpression::match(PIString && subject, size_t offset) const {
|
||||
PIRegularExpression::Matcher ret = matchIterator(std::move(subject), offset);
|
||||
PRIVATE->match(ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
PIRegularExpression::Matcher PIRegularExpression::match(const PIString & subject, size_t offset) {
|
||||
PIRegularExpression::Matcher ret = matchIterator(subject, offset);
|
||||
PRIVATE->match(ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
PIRegularExpression::Matcher::Matcher(PIRegularExpression * p): parent(p) {}
|
||||
|
||||
|
||||
|
||||
@@ -103,13 +103,13 @@ public:
|
||||
PIString captureGroupName(int index) const;
|
||||
int captureGroupIndex(const PIString & gname) const;
|
||||
|
||||
Matcher match(const PIString & subject, size_t offset = 0);
|
||||
Matcher match(PIString & subject, size_t offset = 0);
|
||||
Matcher match(PIString && subject, size_t offset = 0);
|
||||
Matcher match(const PIString & subject, size_t offset = 0) const;
|
||||
Matcher match(PIString & subject, size_t offset = 0) const;
|
||||
Matcher match(PIString && subject, size_t offset = 0) const;
|
||||
|
||||
Matcher matchIterator(const PIString & subject, size_t offset = 0);
|
||||
Matcher matchIterator(PIString & subject, size_t offset = 0);
|
||||
Matcher matchIterator(PIString && subject, size_t offset = 0);
|
||||
Matcher matchIterator(const PIString & subject, size_t offset = 0) const;
|
||||
Matcher matchIterator(PIString & subject, size_t offset = 0) const;
|
||||
Matcher matchIterator(PIString && subject, size_t offset = 0) const;
|
||||
|
||||
static PIRegularExpression fromGlob(const PIString & pattern, Options opt = None);
|
||||
static PIRegularExpression fromPOSIX(const PIString & pattern, Options opt = None);
|
||||
|
||||
@@ -998,6 +998,11 @@ PIStringList PIString::split(const PIString & delim) const {
|
||||
}
|
||||
|
||||
|
||||
bool PIString::contains(const PIRegularExpression & regexp) const {
|
||||
return regexp.match(const_cast<PIString &>(*this)).hasMatch();
|
||||
}
|
||||
|
||||
|
||||
//! \~\details
|
||||
//! \~\code
|
||||
//! PIString s("012345012345");
|
||||
@@ -1033,6 +1038,11 @@ int PIString::find(const PIString & str, const int start) const {
|
||||
}
|
||||
|
||||
|
||||
int PIString::find(const PIRegularExpression & regexp, const int start) const {
|
||||
return regexp.match(const_cast<PIString &>(*this), start).matchedStart();
|
||||
}
|
||||
|
||||
|
||||
//! \~\details
|
||||
//! \~\code
|
||||
//! piCout << PIString("1.str").findAny(".,:"); // 1
|
||||
@@ -1090,6 +1100,16 @@ int PIString::findLast(const PIString & str, const int start) const {
|
||||
}
|
||||
|
||||
|
||||
int PIString::findLast(const PIRegularExpression & regexp, const int start) const {
|
||||
auto m = regexp.match(const_cast<PIString &>(*this), start);
|
||||
int ret = m.matchedStart();
|
||||
while (m.next()) {
|
||||
ret = m.matchedStart();
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
//! \~\details
|
||||
//! \~\code
|
||||
//! piCout << PIString(".str.0").findAnyLast(".,:"); // 4
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
|
||||
|
||||
class PIStringList;
|
||||
class PIRegularExpression;
|
||||
|
||||
//! \ingroup Text
|
||||
//! \~\brief
|
||||
@@ -1174,6 +1175,10 @@ public:
|
||||
//! \~russian Возвращает содержит ли строка подстроку "str".
|
||||
bool contains(const PIString & str) const { return find(str) >= 0; }
|
||||
|
||||
//! \~english Returns if string match "regexp".
|
||||
//! \~russian Возвращает совпадает ли строка "regexp".
|
||||
bool contains(const PIRegularExpression & regexp) const;
|
||||
|
||||
|
||||
//! \~english Search character "c" from character at index "start" and return first occur position.
|
||||
//! \~russian Ищет символ "c" от символа "start" и возвращает первое вхождение.
|
||||
@@ -1200,6 +1205,10 @@ public:
|
||||
//! \~\sa \a findAny(), \a findLast(), \a findAnyLast(), \a findWord(), \a findCWord(), \a findRange()
|
||||
int find(const char * str, const int start = 0) const { return find(PIString(str), start); }
|
||||
|
||||
//! \~english Search match of "regexp" from character at index "start" and return first occur position.
|
||||
//! \~russian Ищет совпадение с "regexp" от символа "start" и возвращает первое вхождение.
|
||||
int find(const PIRegularExpression & regexp, const int start = 0) const;
|
||||
|
||||
//! \~english Search any character of "str" from character at index "start" and return first occur position.
|
||||
//! \~russian Ищет любой символ строки "str" от симола "start" и возвращает первое вхождение.
|
||||
int findAny(const PIString & str, const int start = 0) const;
|
||||
@@ -1240,6 +1249,10 @@ public:
|
||||
//! \~\sa \a find(), \a findAny(), \a findAnyLast(), \a findWord(), \a findCWord(), \a findRange()
|
||||
int findLast(const char * str, const int start = 0) const { return findLast(PIString(str), start); }
|
||||
|
||||
//! \~english Search match of "regexp" from character at index "start" and return last occur position.
|
||||
//! \~russian Ищет совпадение с "regexp" от символа "start" и возвращает последнее вхождение.
|
||||
int findLast(const PIRegularExpression & regexp, const int start = 0) const;
|
||||
|
||||
//! \~english Search any character of "str" from character at index "start" and return last occur position.
|
||||
//! \~russian Ищет любой символ строки "str" от символа "start" и возвращает последнее вхождение.
|
||||
int findAnyLast(const PIString & str, const int start = 0) const;
|
||||
|
||||
Reference in New Issue
Block a user