summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakob Kaivo <jkk@ung.org>2022-05-09 16:31:34 -0400
committerJakob Kaivo <jkk@ung.org>2022-05-09 16:31:34 -0400
commite2f11f4a24bcfa76e0d2fc7178cb15703b24df9a (patch)
tree1ba2b52e78cd18f7675248eff522a250193f27e3
initial commitHEADnot
-rw-r--r--.gitignore2
-rw-r--r--Makefile34
-rw-r--r--README.md18
-rw-r--r--not.c48
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
diff --git a/not.c b/not.c
new file mode 100644
index 0000000..5d1170f
--- /dev/null
+++ b/not.c
@@ -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;
+}