vis

a vi-like editor based on Plan 9's structural regular expressions

git clone https://9o.is/git/vis.git

commit 6ccdede8e44d33c76e99829de71120bf2b6dfce4
parent 968d9efd9445e7d3d3bd00f73e622a3200f04d66
Author: Marc André Tanner <mat@brain-dump.org>
Date:   Fri, 31 Mar 2017 08:28:10 +0200

Use a minimal POSIX shar implementation for self extracting executable

This only requires POSIX shell utilies for extraction. The resulting
archive is bigger (it is not gzip compressed) and startup will be slower
due to many spawned processes.

Diffstat:
MGNUmakefile | 3+--
Ashar.sh | 120+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Dvis-single.sh | 14--------------
3 files changed, 121 insertions(+), 16 deletions(-)

diff --git a/GNUmakefile b/GNUmakefile @@ -256,10 +256,9 @@ standalone: clean PATH=$(DEPS_BIN):$$PATH $(MAKE) single: standalone - cp vis-single.sh vis-single for e in $(ELF); do \ ${STRIP} "$$e"; \ done - tar c $(EXECUTABLES) lua/ | gzip -9 >> vis-single + ./shar.sh vis-single $(EXECUTABLES) $$(find lua -name '*.lua') .PHONY: standalone local dependencies-common dependencies-local dependencies-clean diff --git a/shar.sh b/shar.sh @@ -0,0 +1,120 @@ +#!/bin/sh +# Modified version of https://shiz.me/junk/code/fun/shar.sh +# The generated shell archive is automatically extracted to a +# temporary directory and the first archive member is executed. +set -e + +if test $# -lt 2 ; then + echo "usage: $0 <output> <files>" + exit 1 +fi + +save() { + for i ; do + printf "%s\n" "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" + done + echo " " +} + +octal_mode() { + local mode + + mode="$(ls -ld "$1" | awk '{ print $1 }' | tr '[A-Z]' '-' | cut -c2-)" + for i in 1 2 3 ; do + i=0 + case "$mode" in r??*) i=$((i + 4)) ;; esac + case "$mode" in ?w?*) i=$((i + 2)) ;; esac + case "$mode" in ??-*) ;; ???*) i=$((i + 1)) ;; esac + printf "%d" "$i" + mode=$(echo "$mode" | cut -c4-) + done +} + +out=$1 +tmpout=$1.tmp +exe=$2 +shift + +rm -f "$tmpout" +for f ; do + if test -f "$f" ; then + cat "$f" >> "$tmpout" + fi +done +trap 'rm "$tmpout"' EXIT + +clear= + +for f ; do + if test -z "$clear" ; then + set -- + clear=1 + fi + + mode=$(octal_mode "$f") + if test -f "$f" ; then + size=$(wc -c "$f" | awk '{ print $1 }') + echo "adding: $f (mode $mode, $size bytes)" + set -- "$@" "f+$mode+$size:$f" + elif test -d "$f" ; then + echo "adding directory: $f (mode $mode)" + set -- "$@" "d+$mode:$f" + else + echo "can't add unknown file type $f" >&2 + fi +done + +cat >"$out"<<HEADER +#!/bin/sh +set -e + +outdir="\$(mktemp -d -p "\${TMPDIR:-/tmp}" .unshar-XXXXXX)" +if test \$? -ne 0 -o ! -d "\$outdir" ; then + echo "failed to create temporary directory" + exit 1 +fi +trap 'rm -rf "\$outdir"' EXIT INT QUIT TERM HUP +argc=\$# + +self="\$0" +set -- $(save "$@") "\$@" + +exec 3<"\$self" +while read -r l ; do + test "\$l" = "exit 0;" && break +done <&3 + +while test \$# -gt \$argc ; do + file="\$1" + shift + meta="\${file%%:*}" + fn="\${file#*:}" + type="\${meta%%+*}" + meta="\${meta#*+}" + mode="\${meta%%+*}" + size="\${meta#*+}" + base="\${fn%/*}" + + case "\$type" in + f) + echo "unpacking: \$fn (mode \$mode, \$size bytes)" + test "\$base" != "\$fn" && mkdir -p "\$outdir/\$base" + dd of="\$outdir/\$fn" bs="\$size" count=1 >/dev/null <&3 + ;; + d) + echo "creating: \$fn (mode \$mode)" + mkdir -p "\$outdir/\$fn" + ;; + esac + chmod "\$mode" "\$outdir/\$fn" || : +done >/dev/null 2>&1 + +PATH="\$outdir:\$PATH" "\$outdir/$exe" "\$@" +exit \$? + +exit 0; +HEADER + +cat "$tmpout" >> "$out" +chmod +x "$out" + diff --git a/vis-single.sh b/vis-single.sh @@ -1,14 +0,0 @@ -#!/bin/sh - -set -e - -VISTMP="$(mktemp -d -p "${TMPDIR:-/tmp}" .vis-XXXXXX)" -trap 'rm -rf "$VISTMP"' EXIT INT QUIT TERM HUP - -sed '1,/^__TAR_GZ_ARCHIVE_BELOW__$/d' "$0" | gzip -d | tar xC "$VISTMP" - -PATH="$VISTMP:$PATH" "$VISTMP/vis" "$@" - -exit $? - -__TAR_GZ_ARCHIVE_BELOW__