diff options
author | Jakob Kaivo <jkk@ung.org> | 2022-05-09 16:31:34 -0400 |
---|---|---|
committer | Jakob Kaivo <jkk@ung.org> | 2022-05-09 16:31:34 -0400 |
commit | e2f11f4a24bcfa76e0d2fc7178cb15703b24df9a (patch) | |
tree | 1ba2b52e78cd18f7675248eff522a250193f27e3 |
-rw-r--r-- | .gitignore | 2 | ||||
-rw-r--r-- | Makefile | 34 | ||||
-rw-r--r-- | README.md | 18 | ||||
-rw-r--r-- | not.c | 48 |
4 files changed, 102 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..d5c101f --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +not +*.o diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..31d0468 --- /dev/null +++ b/Makefile @@ -0,0 +1,34 @@ +.POSIX: + +# This Makefile was generated by maje +# See https://src.kaivo.net/dev/maje/ for more information +# Do not edit this Makefile by hand + +CC=c99 +LD=$(CC) +CFLAGS=-Wall -Wextra -Wpedantic -Werror -g +LDFLAGS= +LDLIBS= +SRCDIR=. +OBJDIR=. +BINDIR=$(OBJDIR) +LIBDIR=$(OBJDIR) +DESTDIR=/usr/local + +all: $(BINDIR)/not + +clean: + rm -f $(BINDIR)/not $(OBJDIR)/*.o + +install: $(BINDIR)/not + mkdir -p $(DESTDIR)/bin + cp $(BINDIR)/not $(DESTDIR)/bin + +$(BINDIR)/not: $(OBJDIR)/not.o +$(OBJDIR)/not.o: $(SRCDIR)/not.c + @mkdir -p $(@D) + $(CC) $(CFLAGS) -o $@ -c $(SRCDIR)/not.c + +$(BINDIR)/not: + @mkdir -p $(@D) + $(LD) $(LDFLAGS) -o $@ $(OBJDIR)/*.o $(LDLIBS) diff --git a/README.md b/README.md new file mode 100644 index 0000000..4258ca5 --- /dev/null +++ b/README.md @@ -0,0 +1,18 @@ +This program inverts wildcards for use in shell commands. For example, if you +want a list of all files in the current directory that do *not* end in `.o`, +run: + + ls $(not '*.o') + +Note two things: You'll need to wrap `not` in the `$(...)` syntax to get +command substitution; and, you should wrap your glob(s) in single quotes to +prevent them from being expanded by the shell. You can specify more than one +glob; not will ignore files matching any of the provided globs. + +To build, just run: + + make + +To install, with privileges run: + + make install @@ -0,0 +1,48 @@ +#define _POSIX_C_SOURCE 2 +#include <dirent.h> +#include <fnmatch.h> +#include <locale.h> +#include <stdio.h> +#include <unistd.h> + +static int matches(char *fn, int argc, char *argv[]) +{ + for (int i = 0; i < argc; i++) { + if (fnmatch(argv[i], fn, 0) == 0) { + return 1; + } + } + return 0; +} + +int main(int argc, char *argv[]) +{ + setlocale(LC_ALL, ""); + int c; + while ((c = getopt(argc, argv, "")) != -1) { + switch (c) { + default: + return 1; + } + } + + if (argc <= optind) { + fprintf(stderr, "not: missing operands\n"); + return 1; + } + + DIR *d = opendir("."); + if (d == NULL) { + perror("not"); + return 1; + } + + struct dirent *de; + while ((de = readdir(d)) != NULL) { + if (!matches(de->d_name, argc - optind, argv + optind)) { + printf("%s\n", de->d_name); + } + } + + return 0; +} |