Skip to content

Commit

Permalink
fsdevice: fix file name pattern matching.
Browse files Browse the repository at this point in the history
The 1581 allows matches with text following a * wildcard and that case
was not handled correctly. The code allows one * with following text.
If we want to go completely generic, allowing multiple * wildcards, I
would propose we take the algorithm from
https://dogankurt.com/wildcard.html#Iterative_Algorithms .


git-svn-id: https://svn.code.sf.net/p/vice-emu/code/trunk@45227 379a1393-f5fb-40a0-bcee-ef074d9b53f7
  • Loading branch information
Rhialto committed Jul 14, 2024
1 parent a7ba382 commit 2aa6f01
Showing 1 changed file with 25 additions and 4 deletions.
29 changes: 25 additions & 4 deletions vice/src/fsdevice/fsdevice-read.c
Original file line number Diff line number Diff line change
Expand Up @@ -432,29 +432,50 @@ static void command_directory_get(vdrive_t *vdrive, bufinfo_t *bufinfo,

l = (int)strlen(bufinfo->dirmask);

/* fix 2 bugs:
* - pattern A*Z would not match AZZ because it jumped to the first Z
* only.
* - pattern FOO* didn't match filename FOO
*/

for (p = finfo->name, i = 0;
*p && bufinfo->dirmask[i] && i < l; i++) {
if (bufinfo->dirmask[i] == '?') {
p++;
} else if (bufinfo->dirmask[i] == '*') {
if (!(bufinfo->dirmask[i + 1])) {
if (bufinfo->dirmask[i + 1] == '\0') {
f = 0;
break;
} /* end mask */
while (*p && (*p != bufinfo->dirmask[i + 1])) {
p++;
/* Handle ONE * followed by text but no more (like 1581):
* When at the * in A*XYZ, skip to 3 positions before
* the end of the file name to try to match XYZ. */
int rest_of_filename = strlen((const char *)p);
int rest_of_pattern = strlen(&bufinfo->dirmask[i + 1]);

if (rest_of_filename < rest_of_pattern) {
break; /* no match: file name too short */
}
p = p + rest_of_filename - rest_of_pattern;
} else {
if (*p != bufinfo->dirmask[i]) {
break;
}
p++;
}
if ((!*p) && (!(bufinfo->dirmask[i + 1]))) {
if (*p == '\0' && bufinfo->dirmask[i + 1] == '\0') {
f = 0;
break;
}
}
/* Check for an edge case missed by the loop:
* pattern "FOO*" should match filename "FOO". */
if (f > 0 &&
*p == '\0' &&
bufinfo->dirmask[i ] == '*' &&
bufinfo->dirmask[i + 1] == '\0') {
f = 0;
}
if (f > 0) {
fileio_close(finfo);
}
Expand Down

0 comments on commit 2aa6f01

Please sign in to comment.