diff options
| author | B. Watson <urchlay@slackware.uk> | 2025-11-14 04:22:39 -0500 |
|---|---|---|
| committer | B. Watson <urchlay@slackware.uk> | 2025-11-14 04:22:39 -0500 |
| commit | e286ed23ae3cabfb75327d8512dc937b2ecf9be1 (patch) | |
| tree | a39a2494cdcca3145f283a515bfa42eb5f33e0df /src/glob.c | |
| parent | e2da2bffe58a76c091d3496bd3ca2d2f18ea2eb6 (diff) | |
| download | unalf-e286ed23ae3cabfb75327d8512dc937b2ecf9be1.tar.gz | |
Add command-line options.
Diffstat (limited to 'src/glob.c')
| -rw-r--r-- | src/glob.c | 120 |
1 files changed, 120 insertions, 0 deletions
diff --git a/src/glob.c b/src/glob.c new file mode 100644 index 0000000..cb91b79 --- /dev/null +++ b/src/glob.c @@ -0,0 +1,120 @@ +#include <stdio.h> +#include <unistd.h> +#include <stdlib.h> +#include <string.h> +#include <ctype.h> +#include "unalf.h" + +/* this is an Atari DOS or MS-DOS style match: "*.*" matches everything, + even files with no extension (no dot). "*" by itself matches only + files with no extension, as does "*." + matching is case-insensitive. */ + +static void split_filename(const char *fname, char *name, const char **ext) { + int i; + + for(i = 0; i < 8; i++) { + if(fname[i] == '.' || fname[i] == '\0') + break; + name[i] = fname[i]; + } + name[i] = '\0'; + + *ext = strchr(fname, '.'); + if(*ext) { + (*ext)++; + if(!**ext) *ext = 0; + } + + // fprintf(stderr, "split %s into: '%s' and '%s'\n", + // fname, name, (*ext ? *ext : "<none>")); +} + +static int match_part(const char *pat, const char *arg) { + char p; + + if(arg && arg[0] == '\0') arg = 0; + + if(!pat) { + if(arg) + return 0; + else + return 1; + } + + while((p = toupper(*pat++))) { + // fprintf(stderr, "p == %c\n", p); + switch(p) { + case '*': return 1; + case '?': + if(!arg || *arg == '\0') + return 0; + arg++; + break; + default: + if(!arg || toupper(*arg) != p) + return 0; + arg++; + break; + } + } + + return *arg ? 0 : 1; +} + +int globmatch(const char *pat, const char *arg) { + char npat[9], name[9]; + const char *epat = 0, *ext = 0; + + split_filename(pat, npat, &epat); + split_filename(arg, name, &ext); + + return match_part(npat, name) && match_part(epat, ext); +} + +int file_wanted(const char *filename) { + int i; + char **ig; + + /* if excluded, always return false */ + for(i = 0; i < exclude_count; i++) { + if(globmatch(exclude_globs[i], filename)) + return 0; + } + + /* if no include globs, always match (as though *.* were given) */ + if(!*include_globs) + return 1; + + ig = (char **)include_globs; + while(*ig) { + if(globmatch(*ig, filename)) + return 1; + ig++; + } + + return 0; +} + +/* for testing: */ +#if 0 +int main(int argc, char **argv) { + int matched; + const char *pattern; + + if(argc < 3) { + fprintf(stderr, "usage: %s <glob-pattern> <filename> ...\n", argv[0]); + return 1; + } + + pattern = argv[1]; + argv++; + + while(*++argv) { + matched = globmatch(pattern, *argv); + printf("%s %s %s\n", *argv, matched ? "matches" : "DOES NOT match", pattern); + } + + return 0; +} +#endif |
