Skip to content
Permalink
Browse files

Extract prelude and option parser

  • Loading branch information
sstephenson committed Aug 26, 2019
1 parent dda04b1 commit 73bb329640d6be03c1a9b90c8adf78195a755ebd
@@ -62,5 +62,7 @@ require() {
esac
}

require "prelude"
require "main"

main "$@"
@@ -1,5 +1,5 @@
examine() {
awk -f "$JWALK_LIB/commands/examine.awk" "$@" -v "examining=$examining" -v "filter=$filter"
awk -f "$JWALK_LIB/commands/examine.awk" -v "examining=$examining" -v "filter=$filter" "$@"
}

install() {
@@ -1,107 +1,73 @@
require "commands"
require "options"

main() {
parse_option_arguments "$@"
eval "set -- $args"

open "$json_file"
tokenize | parse | examine "$@"
}

parse_option_arguments() {
unset args examining filter json_file stored_scripts
index=1

while [ $index -le $# ]; do
eval 'this="$'$index'"'
eval 'next="$'$(( index + 1 ))'"'
incr=1

while
retry=0
case "$this" in
-e)
store $index "$next"
append args -f "$escaped_path"
examining=1
incr=2
;;
-f)
append args -f '"$'$(( index + 1 ))'"'
examining=1
incr=2
;;
-h|--help)
usage 0 2>&1
;;
--install)
install "$next"
;;
-l|--leaf-only|-le|-lf|-lp)
append args -v leafonly=1
if [ "${#this}" -eq 3 ]; then
this="-${this#-l}"
retry=1
fi
;;
-p|--pattern)
filter="${filter}|$(make_filter "$next")"
incr=2
;;
-v)
append args -v "$next"
incr=2
;;
-?*)
usage 1
;;
*)
[ -z "$json_file" ] || usage 1
json_file="$this"
;;
esac
[ $retry -ne 0 ]
do :; done

if [ $incr -gt 1 ] && [ $index -eq $# ]; then
warn "$(self): missing argument for option $this"
usage 1
else
index=$(( index + incr ))
fi
done

filter="${filter#?}"
unset filter json_file
parse_option_arguments_for walk "$@"
}

usage() {
warn "usage: $(self) [-l] [-e script ...] [-f script-file ...] [-p pattern ...] [file]"
warn "(see https://jwalk.sh for more information and examples)"
[ -z "$1" ] || exit "$1"
}

open() {
if [ "$1" != "-" ] && [ -n "$1" ]; then
exec < "$1"
fi
walk() {
filter="${filter#?}"
open "$json_file"
tokenize | parse | examine "$@"
}

store() {
store_path="${TMPDIR%/}/jwalk.$$.$1"
escaped_path="$(escape "$store_path")"
append stored_scripts "$escaped_path "
puts "$2" > "$store_path"
trap 'eval "rm -f $stored_scripts"' EXIT
}
parse_walk_option_argument() {
unset pattern script script_file variable
this="$1"
index=$2

append() {
eval "shift; $1=\"\$$1\$@ \""
case "$this" in
-e )
examining=1
read_option_value script
store_script "$index.awk" "$script"
append_option_arguments -f "$script_file"
;;
-f )
examining=1
read_option_value script_file
append_option_arguments -f "$script_file"
;;
-h | --help )
usage 2>&1
exit
;;
-l | --leaf-only )
append_option_arguments -v leafonly=1
;;
-p | --pattern )
read_option_value pattern
append filter "|$(make_filter "$pattern")"
;;
-v )
read_option_value variable
append_option_arguments -v "$variable"
;;
-?* )
invalid_option
;;
* )
[ -z "$json_file" ] || die "too many input files"
json_file="$this"
esac
}

escape() {
puts "$1" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/'/"
open() {
if [ "$1" != "-" ] && [ -n "$1" ]; then
exec < "$1"
fi
}

warn() {
puts "$@" >&2
store_script() {
script_dir="${TMPDIR%/}/jwalk.$$"
script_file="$script_dir/$1"
mkdir -p "$script_dir"
puts "$2" > "$script_file"
trap 'rm -fr "${TMPDIR%/}/jwalk.$$"' EXIT
}
@@ -0,0 +1,52 @@
parse_option_arguments_for() {
callback="$1"
iterator="parse_$1_option_argument"
option_arguments=""
shift

this_index=1
last_index=$#
while [ $this_index -le $last_index ]; do
next_index=$((this_index+1))
eval 'this_value="$'$this_index'"'
eval 'next_value="$'$next_index'"'

retry=1
while [ $retry != 0 ]; do
retry=0
option="$this_value"
case "$option" in
--?* )
;;
-??* )
retry="${this_value#??}"
option="${option%"$retry"}"
this_value="-${this_value#??}"
esac
"$iterator" "$option" $this_index || try usage 1
done
this_index=$next_index
done

eval "set -- $option_arguments"
"$callback" "$@"
}

append_option_arguments() {
for arg; do
append option_arguments " $(escape "$arg")"
done
}

read_option_value() {
if [ $this_index -lt $last_index ]; then
next_index=$((next_index+1))
eval "$1"'="$next_value"'
else
die "missing argument for option '$this_value'"
fi
}

invalid_option() {
die "invalid option '$this_value'"
}
@@ -0,0 +1,21 @@
append() {
eval "shift; $1=\"\$$1\$@\""
}

die() {
warn "$(self): $@"
try usage
exit 1
}

escape() {
puts "$1" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/'/"
}

try() {
! command -v "$1" >/dev/null || "$@"
}

warn() {
puts "$@" >&2
}
@@ -4,7 +4,7 @@ assert_output "fixtures/usage/help"

run jwalk --nonexistent
assert_status 1
assert_output "fixtures/usage/help"
assert_output "fixtures/usage/nonexistent"

run jwalk -e
assert_status 1
@@ -1,3 +1,3 @@
jwalk: missing argument for option -e
jwalk: missing argument for option '-e'
usage: jwalk [-l] [-e script ...] [-f script-file ...] [-p pattern ...] [file]
(see https://jwalk.sh for more information and examples)
@@ -1,3 +1,3 @@
jwalk: missing argument for option -f
jwalk: missing argument for option '-f'
usage: jwalk [-l] [-e script ...] [-f script-file ...] [-p pattern ...] [file]
(see https://jwalk.sh for more information and examples)
@@ -0,0 +1,3 @@
jwalk: invalid option '--nonexistent'
usage: jwalk [-l] [-e script ...] [-f script-file ...] [-p pattern ...] [file]
(see https://jwalk.sh for more information and examples)

0 comments on commit 73bb329

Please sign in to comment.
You can’t perform that action at this time.