Test: Add wildcard matching

This commit is contained in:
Vicki Pfau 2020-07-26 21:56:09 -07:00
parent 0c01546102
commit 89de06a610
3 changed files with 116 additions and 0 deletions

View File

@ -45,6 +45,7 @@ const char* hex4(const char* line, uint8_t* out);
void rtrim(char* string);
ssize_t parseQuotedString(const char* unparsed, ssize_t unparsedLen, char* parsed, ssize_t parsedLen);
bool wildcard(const char* search, const char* string);
CXX_GUARD_END

View File

@ -403,6 +403,84 @@ static void testToPath(const char* testName, char* path) {
path[i] = '\0';
}
static bool globTests(struct CInemaTestList* tests, const char* glob, const char* ancestors) {
bool success = true;
const char* next = strpbrk(glob, "*.");
char path[PATH_MAX];
if (!next) {
testToPath(glob, path);
return collectTests(tests, path);
} else if (next[0] == '.') {
char subtest[MAX_TEST];
if (!ancestors) {
strncpy(subtest, glob, next - glob);
} else {
size_t len = strlen(ancestors) + (next - glob) + 2;
if (len > sizeof(subtest)) {
len = sizeof(subtest);
}
snprintf(subtest, len, "%s.%s", ancestors, glob);
}
return globTests(tests, next + 1, subtest);
} else if (next[0] == '*') {
char globBuffer[MAX_TEST];
const char* subglob;
next = strchr(next, '.');
if (!next) {
subglob = glob;
} else {
size_t len = next - glob + 1;
if (len > sizeof(globBuffer)) {
len = sizeof(globBuffer);
}
strncpy(globBuffer, glob, len - 1);
subglob = globBuffer;
}
bool hasMoreGlobs = next && strchr(next, '*');
struct VDir* dir;
if (ancestors) {
testToPath(ancestors, path);
dir = VDirOpen(path);
} else {
dir = VDirOpen(base);
}
if (!dir) {
return false;
}
struct VDirEntry* dirent = dir->listNext(dir);
while (dirent) {
const char* name = dirent->name(dirent);
if (dirent->type(dirent) != VFS_DIRECTORY || strncmp(name, ".", 2) == 0 || strncmp(name, "..", 3) == 0) {
dirent = dir->listNext(dir);
continue;
}
if (wildcard(subglob, name)) {
char newgen[MAX_TEST];
if (ancestors) {
snprintf(newgen, sizeof(newgen), "%s.%s", ancestors, name);
} else {
strlcpy(newgen, name, sizeof(newgen));
}
if (next && hasMoreGlobs) {
globTests(tests, next + 1, newgen);
} else {
testToPath(newgen, path);
collectTests(tests, path);
}
}
dirent = dir->listNext(dir);
}
return true;
} else {
abort();
}
}
static void _loadConfigTree(struct Table* configTree, const char* testName) {
char key[MAX_TEST];
strlcpy(key, testName, sizeof(key));
@ -1285,6 +1363,13 @@ int main(int argc, char** argv) {
if (argc > 0) {
size_t i;
for (i = 0; i < (size_t) argc; ++i) {
if (strchr(argv[i], '*')) {
if (!globTests(&tests, argv[i], NULL)) {
status = 1;
break;
}
continue;
}
char path[PATH_MAX + 1] = {0};
testToPath(argv[i], path);

View File

@ -519,3 +519,33 @@ ssize_t parseQuotedString(const char* unparsed, ssize_t unparsedLen, char* parse
}
return -1;
}
bool wildcard(const char* search, const char* string) {
while (true) {
if (search[0] == '*') {
while (search[0] == '*') {
++search;
}
if (!search[0]) {
return true;
}
while (string[0]) {
if (string[0] == search[0] && wildcard(search, string)) {
return true;
}
++string;
}
return false;
} else if (!search[0]) {
return !string[0];
} else if (!string[0]) {
return false;
} else if (string[0] != search[0]) {
return false;
} else {
++search;
++string;
}
}
return false;
}