aboutsummaryrefslogtreecommitdiff
path: root/bin
diff options
context:
space:
mode:
authorEuAndreh <eu@euandre.org>2023-04-22 16:05:09 -0300
committerEuAndreh <eu@euandre.org>2023-04-22 16:06:05 -0300
commit59396c99089ab67a748465f67c62280e50e791b4 (patch)
tree54f2acd6c9e12100aaa645fb95a82808cf204935 /bin
parentetc/sh/rc: Also exclude vendor/ from tree(1) by default (diff)
downloaddotfiles-59396c99089ab67a748465f67c62280e50e791b4.tar.gz
dotfiles-59396c99089ab67a748465f67c62280e50e791b4.tar.xz
bin/uninclude: Add new utility, with simple tests
Diffstat (limited to 'bin')
-rwxr-xr-xbin/uninclude107
1 files changed, 107 insertions, 0 deletions
diff --git a/bin/uninclude b/bin/uninclude
new file mode 100755
index 0000000..ac2d98c
--- /dev/null
+++ b/bin/uninclude
@@ -0,0 +1,107 @@
+#!/bin/sh
+set -eu
+
+usage() {
+ cat <<-'EOF'
+ Usage:
+ uninclude -E REGEXP -- COMMAND...
+ uninclude -h
+ EOF
+}
+
+help() {
+ cat <<-'EOF'
+
+
+ Options:
+ -E REGEXP the test expression for lines to be deleted
+ -h, --help show this message
+
+ COMMAND the build/test command used to validate the uninclusion
+
+
+ Read list of files from STDIN, and for each try to delete all lines
+ that match REGEXP and see if COMMAND passes. Do this for every match
+ untill all lines that could be removed are removed.
+
+
+ Examples:
+
+ Remove all non-required "#include" lines from lib.c and main.c:
+
+ $ find lib.c main.c | uninclude -E '^#include ' -- cc $CFLAGS
+ lib.c: 3 lines unincluded
+ main.c: nothing to uninclude
+ EOF
+}
+
+
+for flag in "$@"; do
+ case "$flag" in
+ --)
+ break
+ ;;
+ --help)
+ usage
+ help
+ exit
+ ;;
+ *)
+ ;;
+ esac
+done
+
+while getopts 'E:h' flag; do
+ case "$flag" in
+ E)
+ REGEXP="$OPTARG"
+ ;;
+ h)
+ usage
+ help
+ exit
+ ;;
+ *)
+ usage >&2
+ exit 2
+ ;;
+ esac
+done
+shift $((OPTIND - 1))
+
+eval "$(assert-arg -- "${REGEXP:-}" '-E REGEXP')"
+
+
+
+ORIG="$(mkstemp)"
+VALID="$(mkstemp)"
+MATCHES="$(mkstemp)"
+LINES="$(mkstemp)"
+trap 'rm -f "$ORIG" "$VALID" "$MATCHES" "$LINES"' EXIT
+while read -r file; do
+ cp "$file" "$ORIG"
+ cp "$file" "$VALID"
+
+ NTH=1
+ while true; do
+ if ! grep -nE "$REGEXP" "$file" > "$MATCHES" ||
+ [ "$NTH" -ge "$(wc -l < "$MATCHES")" ]; then
+ FROM="$(wc -l < "$ORIG")"
+ TO="$( wc -l < "$file")"
+ if [ "$FROM" -eq "$TO" ]; then
+ printf '%s: nothing to uninclude\n' "$file" >&2
+ else
+ printf '%s: %s lines unincluded\n' "$file" $((FROM - TO)) >&2
+ fi
+ break
+ fi
+ line="$(cut -d: -f1 "$MATCHES" | lines "$NTH")"
+ sed "${line}d" "$file" | sponge "$file"
+ if ! "$@" "$file"; then
+ cp "$VALID" "$file"
+ NTH=$((NTH + 1))
+ else
+ cp "$file" "$VALID"
+ fi
+ done
+done