90 lines
1.8 KiB
C++
90 lines
1.8 KiB
C++
#pragma once
|
|
|
|
namespace nall {
|
|
|
|
//todo: these functions are not binary-safe
|
|
|
|
auto string::match(string_view source) const -> bool {
|
|
const char* s = data();
|
|
const char* p = source.data();
|
|
|
|
const char* cp = nullptr;
|
|
const char* mp = nullptr;
|
|
while(*s && *p != '*') {
|
|
if(*p != '?' && *s != *p) return false;
|
|
p++, s++;
|
|
}
|
|
while(*s) {
|
|
if(*p == '*') {
|
|
if(!*++p) return true;
|
|
mp = p, cp = s + 1;
|
|
} else if(*p == '?' || *p == *s) {
|
|
p++, s++;
|
|
} else {
|
|
p = mp, s = cp++;
|
|
}
|
|
}
|
|
while(*p == '*') p++;
|
|
return !*p;
|
|
}
|
|
|
|
auto string::imatch(string_view source) const -> bool {
|
|
static auto chrlower = [](char c) -> char {
|
|
return (c >= 'A' && c <= 'Z') ? c + ('a' - 'A') : c;
|
|
};
|
|
|
|
const char* s = data();
|
|
const char* p = source.data();
|
|
|
|
const char* cp = nullptr;
|
|
const char* mp = nullptr;
|
|
while(*s && *p != '*') {
|
|
if(*p != '?' && chrlower(*s) != chrlower(*p)) return false;
|
|
p++, s++;
|
|
}
|
|
while(*s) {
|
|
if(*p == '*') {
|
|
if(!*++p) return true;
|
|
mp = p, cp = s + 1;
|
|
} else if(*p == '?' || chrlower(*p) == chrlower(*s)) {
|
|
p++, s++;
|
|
} else {
|
|
p = mp, s = cp++;
|
|
}
|
|
}
|
|
while(*p == '*') p++;
|
|
return !*p;
|
|
}
|
|
|
|
auto tokenize(const char* s, const char* p) -> bool {
|
|
while(*s) {
|
|
if(*p == '*') {
|
|
while(*s) if(tokenize(s++, p + 1)) return true;
|
|
return !*++p;
|
|
}
|
|
if(*s++ != *p++) return false;
|
|
}
|
|
while(*p == '*') p++;
|
|
return !*p;
|
|
}
|
|
|
|
auto tokenize(string_vector& list, const char* s, const char* p) -> bool {
|
|
while(*s) {
|
|
if(*p == '*') {
|
|
const char* b = s;
|
|
while(*s) {
|
|
if(tokenize(list, s++, p + 1)) {
|
|
list.prepend(slice(b, 0, --s - b));
|
|
return true;
|
|
}
|
|
}
|
|
list.prepend(b);
|
|
return !*++p;
|
|
}
|
|
if(*s++ != *p++) return false;
|
|
}
|
|
while(*p == '*') { list.prepend(s); p++; }
|
|
return !*p;
|
|
}
|
|
|
|
}
|