summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bos-args.sh54
-rw-r--r--t/args.t35
-rw-r--r--t/testlib.sh1
3 files changed, 90 insertions, 0 deletions
diff --git a/bos-args.sh b/bos-args.sh
new file mode 100644
index 0000000..e0f0729
--- /dev/null
+++ b/bos-args.sh
@@ -0,0 +1,54 @@
+#!bash
+
+function bos-args/build-parser-code-into() {
+ local -n parser_result_var="$1"; shift
+
+ local -A argvar argtype assignment
+ while [[ "${#@}" -gt 0 ]]; do
+ case "$1" in
+ -scalar|-array|-assoc)
+ argtype["$2"]="${1#-}";
+ argvar["$2"]="$3";
+ shift 3
+ ;;
+ -assignment-*)
+ assignment["${1#-assignment-}"]="$2";
+ shift 2
+ ;;
+ *)
+ >&2 echo "bad argument <$1>";
+ return 1
+ ;;
+ esac
+ done
+
+ parser_result_var="while [[ \"\${#@}\" -gt 0 ]]; do
+case \"\$1\" in
+"
+
+ local argassign
+ for argname in "${!argvar[@]}"; do
+ argassign="${assignment["${argtype["$argname"]}"]}"
+ argassign="${argassign//\$\{name\}/${argvar["$argname"]}}"
+
+ if [[ "${argtype["$argname"]}" == scalar || "${argtype["$argname"]}" == array ]]; then
+ argassign="${argassign//\$\{value/\$\{2}"
+
+ parser_result_var+="-${argname}) $argassign; shift 2 ;;
+"
+ elif [[ "${argtype["$argname"]}" == assoc ]]; then
+ argassign="${argassign//\$\{key/\$\{2}"
+ argassign="${argassign//\$\{value/\$\{3}"
+
+ parser_result_var+="-${argname}) $argassign; shift 3 ;;
+"
+ fi
+ done
+
+ parser_result_var+="*) shift ;;
+esac
+done
+"
+
+ return 0
+}
diff --git a/t/args.t b/t/args.t
new file mode 100644
index 0000000..686adc6
--- /dev/null
+++ b/t/args.t
@@ -0,0 +1,35 @@
+#!/bin/bash
+
+. t/testlib.sh
+
+declare first_parser
+
+set +x
+
+bos-args/build-parser-code-into first_parser \
+ -scalar one scalar_var \
+ -array two array_var \
+ -assoc three assoc_var \
+ -assignment-scalar '${name}="${value}"' \
+ -assignment-array '${name}+=( "${value}" )' \
+ -assignment-assoc '${name}+=( ["${key}"]="${value}" )'
+
+should-succeed "should build parser"
+
+diag "$first_parser"
+
+declare -a array_var
+declare -A assoc_var
+
+eval "function first-parser() { $first_parser }"
+first-parser -two a -three x y -two b -one foo -three w z -unused
+
+is "$scalar_var" 'foo' 'scalar should be set'
+
+is "${array_var[0]}" 'a' 'array should get first value'
+is "${array_var[1]}" 'b' 'array should get second value'
+
+is "${assoc_var[x]}" 'y' 'assoc should get first value'
+is "${assoc_var[w]}" 'z' 'assoc should get second value'
+
+done-testing
diff --git a/t/testlib.sh b/t/testlib.sh
index edbd973..d506257 100644
--- a/t/testlib.sh
+++ b/t/testlib.sh
@@ -2,6 +2,7 @@
PS4='[${#FUNCNAME[*]}] ${BASH_SOURCE[0]}:${LINENO} (${FUNCNAME[0]}) +'
+. bos-args.sh
. bos-dispatch.sh
. bos-namespaces.sh
. bos-object-id.sh