diff options
author | EuAndreh <eu@euandre.org> | 2024-05-08 08:20:58 -0300 |
---|---|---|
committer | EuAndreh <eu@euandre.org> | 2024-05-08 09:10:47 -0300 |
commit | 5e8e65015a77ed7606c6cfbd2d1cedc79e42a6a5 (patch) | |
tree | 7e39359779ca29e512171e14828a5c5fd2f20e7b | |
parent | Initial empty commit (diff) | |
download | q-5e8e65015a77ed7606c6cfbd2d1cedc79e42a6a5.tar.gz q-5e8e65015a77ed7606c6cfbd2d1cedc79e42a6a5.tar.xz |
Initial version
-rw-r--r-- | Makefile | 86 | ||||
-rw-r--r-- | deps.mk | 3 | ||||
-rwxr-xr-x | mkdeps.sh | 13 | ||||
-rwxr-xr-x | src/q | 116 |
4 files changed, 218 insertions, 0 deletions
diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..f911417 --- /dev/null +++ b/Makefile @@ -0,0 +1,86 @@ +.POSIX: +DATE = 1970-01-01 +VERSION = 0.1.0 +NAME = q +NAME_UC = $(NAME) +LANGUAGES = en +## Installation prefix. Defaults to "/usr". +PREFIX = /usr +BINDIR = $(PREFIX)/bin +LIBDIR = $(PREFIX)/lib +INCLUDEDIR = $(PREFIX)/include +SRCDIR = $(PREFIX)/src/$(NAME) +SHAREDIR = $(PREFIX)/share +LOCALEDIR = $(SHAREDIR)/locale +MANDIR = $(SHAREDIR)/man +EXEC = ./ +## Where to store the installation. Empty by default. +DESTDIR = +LDLIBS = + + + +.SUFFIXES: + + + +all: +include deps.mk + +sources = \ + $(sources.sh) \ + + +derived-assets = \ + +side-assets = \ + + + +## Default target. Builds all artifacts required for testing +## and installation. +all: $(derived-assets) + + + +check-unit: + + +check-integration: + + +## Run all tests. Each test suite is isolated, so that a parallel +## build can run tests at the same time. The required artifacts +## are created if missing. +check: check-unit check-integration + + + +## Remove *all* derived artifacts produced during the build. +## A dedicated test asserts that this is always true. +clean: + rm -rf $(derived-assets) $(side-assets) + + +## Installs into $(DESTDIR)$(PREFIX). Its dependency target +## ensures that all installable artifacts are crafted beforehand. +install: all + mkdir -p \ + '$(DESTDIR)$(BINDIR)' \ + '$(DESTDIR)$(SRCDIR)' + cp $(sources.sh) '$(DESTDIR)$(BINDIR)' + cp $(sources.sh) '$(DESTDIR)$(SRCDIR)' + + +## Uninstalls from $(DESTDIR)$(PREFIX). This is a perfect mirror +## of the "install" target, and removes *all* that was installed. +## A dedicated test asserts that this is always true. +uninstall: + rm -rf \ + '$(DESTDIR)$(SRCDIR)' + for f in $(sources.sh); do \ + rm -f '$(DESTDIR)$(BINDIR)'/"$${f#src/}"; \ + done + + +ALWAYS: @@ -0,0 +1,3 @@ +sources.sh = \ + src/q \ + diff --git a/mkdeps.sh b/mkdeps.sh new file mode 100755 index 0000000..8204798 --- /dev/null +++ b/mkdeps.sh @@ -0,0 +1,13 @@ +#!/bin/sh +set -eu + +export LANG=POSIX.UTF-8 + +varlist() { + printf '%s = \\\n' "$1" + sort | sed 's|^\(.*\)$|\t\1 \\|' + printf '\n' +} + + +find src/* -type f -perm -111 | varlist 'sources.sh' @@ -0,0 +1,116 @@ +#!/bin/sh +set -eu + + +usage() { + echo 'Usage: q TOPIC ACTION [OPTION]' +} + +CONSUMER='default-consumer' +while getopts 'C:' flag; do + case "$flag" in + C) + CONSUMER="$OPTARG" + ;; + *) + usage >&2 + exit 2 + ;; + esac +done +shift $((OPTIND - 1)) + +TOPIC="${1:-}" +ACTION="${2:-}" + +eval "$(assert-arg -- "$TOPIC" 'TOPIC')" +eval "$(assert-arg -- "$ACTION" 'ACTION')" + + +Q_DIR="${Q_DIR:-$XDG_DATA_HOME/q}/topics/$TOPIC" +mkdir -p "$Q_DIR" +cd "$Q_DIR" + +mkdir -p tmp cur dead/"$CONSUMER" offset/"$CONSUMER" + +for f in n offset/"$CONSUMER"/n; do + if [ ! -e "$f" ]; then + echo 0 > "$f" + fi +done + + +case "$ACTION" in + in) + N="$(cat n)" + ID="$(uuid)" + cat > tmp/"$ID" + mv tmp/"$ID" cur/"$N" + echo $((N + 1)) > n + ;; + out) + N="$(cat offset/"$CONSUMER"/n)" + if [ ! -e cur/"$N" ]; then + exit 3 + fi + cat cur/"$N" + ;; + commit) + N="$(cat offset/"$CONSUMER"/n)" + if [ ! -e cur/"$N" ]; then + exit 3 + fi + echo $((N + 1)) > offset/"$CONSUMER"/n + ;; + dead) + N="$(cat offset/"$CONSUMER"/n)" + if [ ! -e cur/"$N" ]; then + exit 3 + fi + touch "dead/$CONSUMER/$N" + echo $((N + 1)) > offset/"$CONSUMER"/n + ;; + ls-dead) + ( + cd dead/"$CONSUMER"/ + find * 2>/dev/null | sort -n + ) + ;; + cat) + eval "$(assert-arg -- "${3:-}" 'N')" + OLD_N="$3" + if [ ! -e cur/"$OLD_N" ]; then + exit 3 + fi + cat cur/"$OLD_N" + ;; + revive) + eval "$(assert-arg -- "${3:-}" 'N')" + OLD_N="$3" + if [ ! -e dead/"$CONSUMER"/"$OLD_N" ]; then + exit 3 + fi + N="$(cat n)" + ln -s "$OLD_N" cur/"$N" + echo $((N + 1)) > n + rm -f dead/"$CONSUMER"/"$OLD_N" + ;; + size) + cat n + ;; + offset) + cat offset/"$CONSUMER"/n + ;; + has-data) + ! cmp -s n offset/"$CONSUMER"/n + ;; + reset) + eval "$(assert-arg -- "${3:-}" 'N')" + N="$3" + echo "$N" > offset/"$CONSUMER"/n + ;; + *) + echo "Bad ACTION: $ACTION" >&2 + exit 2 + ;; +esac |