summaryrefslogtreecommitdiff
path: root/src/util/shmk.sh
diff options
context:
space:
mode:
authordavidovski <david@davidovski.xyz>2022-06-27 01:14:42 +0100
committerdavidovski <david@davidovski.xyz>2022-06-27 01:14:42 +0100
commit7bba6cd7612293796e905885f9ed3072877798ab (patch)
treedd01942dbdd474a4df62ecf74479f5e78d83f1c8 /src/util/shmk.sh
parent79fb6f41104cd0d88891598ddfc3c30d1bb0352d (diff)
added shmk, building all with shmk
Diffstat (limited to 'src/util/shmk.sh')
-rwxr-xr-xsrc/util/shmk.sh200
1 files changed, 200 insertions, 0 deletions
diff --git a/src/util/shmk.sh b/src/util/shmk.sh
new file mode 100755
index 0000000..0174857
--- /dev/null
+++ b/src/util/shmk.sh
@@ -0,0 +1,200 @@
+#!/bin/sh
+#
+# A tool to build a single executable from a collection of shell scripts
+
+#include colors
+
+usage () {
+ cat << EOF
+${BLUE}Available Options:
+
+EOF
+}
+
+find_file () {
+ for p in $search_path; do
+ for f in $p/$1.sh $p/$1; do
+ $verbose \
+ && printf "${LIGHT_BLACK}checking: $f\n" 1>&2
+
+ [ -f "$f" ] && {
+ echo "$f"
+ return 0
+ }
+ done
+ done
+ return 1
+}
+
+parse_lines () {
+ while IFS= read -r line; do
+ case "$line" in
+ "#include "*)
+ cat $(find_file ${line#\#include}) | parse_lines
+ ;;
+ "#>"*)
+ eval ${line#'#>'}
+ ;;
+ "#!"*)
+ printf "%s\n" "$line"
+ ;;
+ "#"*);;
+ *)
+ printf "%s\n" "$line"
+ ;;
+ esac
+ done
+}
+
+build_shmk () {
+ [ -f "$1" ] || return 1
+ [ ! -z "$2" ] && output="$2"
+ [ -z "$output" ] && output=$(basename $1)
+ output=${output%.*}
+
+ $clean && {
+ rm -f $output
+ exit
+ }
+
+ $verbose && echo "building $1 to $output"
+
+ [ ! -d "${output%/*}" ] && mkdir -p "${output%/*}"
+
+ cat $1 \
+ | parse_lines > ${output} &&
+ [ ! -z ${entry_function} ] && echo "$entry_function" >> ${output}
+ chmod +x ${output}
+}
+
+interpret_shmk () {
+ . $1
+ local cmdlist=""
+
+ DIST="./dist"
+ PROGS="$PROGS $(sed -rn "s/^prog_(.*)\s*\(\)\s*\{/\1/p" $1)"
+ LIBS="$LIBS $(sed -rn "s/^lib_(.*)\s*\(\)\s*\{/\1/p" $1)"
+ CHECKS="$CHECKS $(sed -rn "s/^check_(.*)\s*\(\)\s*\{/\1/p" $1)"
+
+ shift
+ [ -z "$1" ] && set -- clean build check install
+ while [ ! -z "$1" ]; do
+ case "$1" in
+ install)
+ for prog in $PROGS; do
+ prog=$(basename $prog)
+ prog="${prog%.*}"
+ cmdlist="$cmdlist
+ install -Dm755 $DIST/$prog ${DESTDIR}/${PREFIX}/bin/$prog #Install program $prog"
+ done
+ for lib in $LIBS; do
+ lib=$(basename $lib)
+ lib="${lib%.*}"
+ cmdlist="$cmdlist
+ install -Dm755 $DIST/$lib ${DESTDIR}/${PREFIX}/lib/$lib #Install library $lib"
+ done
+ ;;
+ clean)
+ [ -d "$DIST" ] && cmdlist="$cmdlist
+ rm -r $DIST #Clean"
+ ;;
+ check)
+ for check in $CHECKS; do
+ command -v check_$check > /dev/null 2>&1 && cmdlist="$cmdlist
+ check_$check #Check $check"
+ done
+ ;;
+ *) # build all programs
+ search_path="$DIST $search_path"
+
+ for lib in $LIBS; do
+ name=$(basename $lib)
+ build_cmd=lib_$lib
+ command -v $build_cmd > /dev/null 2>&1 || {
+ build_cmd="build_shmk $lib $DIST/$name"
+ }
+ cmdlist="$cmdlist
+ $build_cmd #Build library $name"
+ done
+
+ for prog in $PROGS; do
+ name=$(basename $prog)
+ build_cmd=prog_$prog
+ command -v $build_cmd > /dev/null 2>&1 || {
+ build_cmd="build_shmk $prog $DIST/$name"
+ }
+ cmdlist="$cmdlist
+ $build_cmd #Build program $name"
+ done
+
+ # build all libs
+ ;;
+ esac
+ shift
+ done
+
+ local out len i
+ $verbose && out=/dev/stdout || out=/dev/null
+ len=$(($(echo "$cmdlist" | wc -l)-1))
+ i=-1
+ echo "$cmdlist" | while read -r cmd; do
+ i=$((i+1))
+ printf "${LIGHT_BLACK}[${LIGHT_BLUE}%s${LIGHT_BLACK}/${LIGHT_BLUE}%s${LIGHT_BLACK}] ${LIGHT_WHITE}%s${RESET}\n" "$i" "$len" "${cmd#*#}"
+ ${cmd%#*} 2>&1 > $out || {
+ printf "${RED}Error $?\n"
+ exit 1
+ }
+ done
+}
+
+search_path=".
+/usr/lib
+/usr/local/lib
+/usr/share/shmk
+"
+
+verbose=false
+clean=false
+
+while getopts ":e:I:o:chv" opt; do
+ case "${opt}" in
+ e)
+ entry_function="$OPTARG"
+ ;;
+ o)
+ output="$OPTARG"
+ ;;
+ c)
+ clean=true
+ ;;
+ I)
+ search_path="$search_path
+ $OPTARG"
+ ;;
+ v)
+ verbose=true
+ ;;
+ h)
+ usage && exit 0
+ ;;
+ esac
+done
+
+shift $((OPTIND-1))
+
+[ -z $1 ] && {
+ exit 1
+}
+
+echo "$0 $*"
+[ -f "$1" ] && shebang="$(head -1 $1)"
+case "$shebang" in
+ "#!"*"shmk"*)
+ interpret_shmk $@
+ ;;
+ *)
+ build_shmk $@
+ ;;
+esac
+
+