diff --git a/src/lib.sh b/src/lib.sh index d60e7c5..5682898 100644 --- a/src/lib.sh +++ b/src/lib.sh @@ -1,4 +1,4 @@ -std::mod::init clap 0.1.1 +std::mod::init clap 0.2.0 ## # must be called after declaring a `clap__flags` as associative arrays, where: @@ -8,12 +8,27 @@ std::mod::init clap 0.1.1 # If the flag expects a value it must have assigned "value", if its a flat flag # "bool", otherwise UB. # -# Returns the data in -A clap__options (with values or `1` for boolean flags) -# and -a clap_arguments +# Returns the data in -A clap__options (with values or `1` for boolean flags), +# -a clap_arguments and -a clap__subcommand_arguments +# +# # Subcommands +# +# Subcommands whould be done by nested parsing, there's no "one pass" parsing. +# An implementation should be obvious by the following. +# +# If CLAP__PARSE_IS_SUBCOMMAND=1, `clap_arguments` will only have the first +# subcommand it finds and `clap__subcommand_arguments` will contain the rest of +# the arguments and flags, for nested parsing. Subcommand might be empty in the +# case no arguments were provided or a `--` was given. +# +# If unset or equal to 0, `clap_arguments` will have proper parsed arguments +# (not flags) and `clap__subcommand_arguments` will be empty. ## clap::parse() { declare -gA clap__options=() declare -ga clap__arguments=() + declare -ga clap__subcommand_arguments=() + local is_subcommand=${CLAP__PARSE_IS_SUBCOMMAND:-0} local flag_i local short_flag @@ -24,6 +39,11 @@ clap::parse() { shift if [[ "$flag_i" == "--" ]]; then + if [ "$is_subcommand" -eq 1 ]; then + clap__subcommand_arguments=("$@") + return + fi + while [ "$#" -gt 0 ]; do clap__arguments+=("$1") shift @@ -73,11 +93,17 @@ clap::parse() { [ -n "$flag_i" ] do true; done else + if [ "$is_subcommand" -eq 1 ]; then + clap__arguments=("$flag_i") + clap__subcommand_arguments=("$@") + return + fi + clap__arguments+=("$flag_i") fi done - export clap__options clap__arguments + export clap__options clap__arguments clap__subcommand_arguments } clap::flag::is-short() { diff --git a/test.sh b/test.sh index 9761a7a..98b0534 100755 --- a/test.sh +++ b/test.sh @@ -38,7 +38,7 @@ std::assert-eq "should have parsed 1 arg" 1 "${#clap__arguments[@]}" clap::parse -- -- std::assert-eq "should have parsed 0 flags" 0 "${#clap__options[@]}" std::assert-eq "should have parsed 1 arg" 1 "${#clap__arguments[@]}" -std::assert "1st arg should be '--'" "${clap__arguments[0]}" "==" "--" +std::assert "1st arg should be '--'" "${clap__arguments[0]}" == "--" # shellcheck disable=2251 ! clap::parse --long-flagarg &>/dev/null @@ -47,12 +47,23 @@ std::assert "1st arg should be '--'" "${clap__arguments[0]}" "==" "--" clap::parse --long-flag arg std::assert-eq "should have parsed 0 args" 0 "${#clap__arguments[@]}" -std::assert "'--long-flag' should be set" "${clap__options[$__long_flag]}" "==" arg +std::assert "'--long-flag' should be set" "${clap__options[$__long_flag]}" == arg clap::parse --long-bool-flag arg std::assert-eq "should have parsed 1 args" 1 "${#clap__arguments[@]}" std::assert-eq "'--long-bool-flag' should be set" 1 "${clap__options[$__long_bool_flag]}" +# --- Subcommands + +CLAP__PARSE_IS_SUBCOMMAND=1 clap::parse --long-flag arg subcommand --subc-arg +std::assert-eq "should have parsed 1 subcommand" 1 "${#clap__arguments[@]}" +std::assert "subcommand should be 'subcommand'" subcommand == "${clap__arguments[0]}" +std::assert "'--long-flag' should be 'arg'" arg == "${clap__options[$__long_flag]}" +std::assert-eq "should have 1 subcommand argument" 1 "${#clap__subcommand_arguments[@]}" +std::assert "subcommand argument should be '--subc-arg'" "--subc-arg" == "${clap__subcommand_arguments[0]}" + +# --- Help Menus + declare -a clap__help_commands=() declare -a clap__help_options=()