aboutsummaryrefslogtreecommitdiff
path: root/src/glob.c
diff options
context:
space:
mode:
authorB. Watson <urchlay@slackware.uk>2025-11-14 04:22:39 -0500
committerB. Watson <urchlay@slackware.uk>2025-11-14 04:22:39 -0500
commite286ed23ae3cabfb75327d8512dc937b2ecf9be1 (patch)
treea39a2494cdcca3145f283a515bfa42eb5f33e0df /src/glob.c
parente2da2bffe58a76c091d3496bd3ca2d2f18ea2eb6 (diff)
downloadunalf-e286ed23ae3cabfb75327d8512dc937b2ecf9be1.tar.gz
Add command-line options.
Diffstat (limited to 'src/glob.c')
-rw-r--r--src/glob.c120
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