Nikola Petrov 6d9404b9b5 Format
2023-08-15 16:54:08 +02:00

94 lines
1.8 KiB
C++

#include "glob.h"
Glob_Result glob(const char* pattern, const char* text)
{
while (*pattern != '\0' && *text != '\0') {
switch (*pattern) {
case '?': {
pattern += 1;
text += 1;
}
break;
case '*': {
Glob_Result result = glob(pattern + 1, text);
if (result != Glob_Result::UNMATCHED) return result;
text += 1;
}
break;
case '[': {
bool matched = false;
bool negate = false;
pattern += 1; // skipping [
if (*pattern == '\0') return Glob_Result::SYNTAX_ERROR; // unclosed [
if (*pattern == '!') {
negate = true;
pattern += 1;
if (*pattern == '\0') return Glob_Result::SYNTAX_ERROR; // unclosed [
}
char prev = *pattern;
matched |= prev == *text;
pattern += 1;
while (*pattern != ']' && *pattern != '\0') {
switch (*pattern) {
case '-': {
pattern += 1;
switch (*pattern) {
case ']':
matched |= '-' == *text;
break;
case '\0':
return Glob_Result::SYNTAX_ERROR; // unclosed [
default: {
matched |= prev <= *text && *text <= *pattern;
prev = *pattern;
pattern += 1;
}
}
}
break;
default: {
prev = *pattern;
matched |= prev == *text;
pattern += 1;
}
}
}
if (*pattern != ']') return Glob_Result::SYNTAX_ERROR; // unclosed [
if (negate) matched = !matched;
if (!matched) return Glob_Result::UNMATCHED;
pattern += 1;
text += 1;
}
break;
case '\\':
pattern += 1;
if (*pattern == '\0') return Glob_Result::SYNTAX_ERROR; // unfinished escape
// fallthrough
default: {
if (*pattern == *text) {
pattern += 1;
text += 1;
}
else {
return Glob_Result::UNMATCHED;
}
}
}
}
if (*text == '\0') {
while (*pattern == '*') pattern += 1;
if (*pattern == '\0') return Glob_Result::MATCHED;
}
return Glob_Result::UNMATCHED;
}