1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90
|
#pragma once
namespace nall {
//todo: these functions are not binary-safe
auto string::match(rstring 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(rstring 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(lstring& 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;
}
}
|