tur/args
CLI argument parser with a builder-pattern API.
Structured argument parsing for Turmeric CLI scripts.
Since: Phase B1
ArgSpec
(defopaque ArgSpec : int)
ArgResult
(defopaque ArgResult : int)
args/spec-new
(args/spec-new : ArgSpec)
create a new empty argument specification.
A fresh ArgSpec handle. Free with args/spec-free when done.
(let [spec (args/spec-new)] ...)
Since: Phase A1
args/spec-prog
(args/spec-prog [spec : ArgSpec name : cstr] : ArgSpec)
set the program name displayed in help text.
| spec | ArgSpec handle from args/spec-new | |
| name | program name cstr |
The same ArgSpec (mutated in place).
(args/spec-prog spec "mytool")
Since: Phase A1
args/spec-flag
(args/spec-flag [spec : ArgSpec name : cstr] : ArgSpec)
register a boolean flag in the arg spec.
| spec | ArgSpec handle | |
| name | flag name including dashes (e.g., "--verbose") |
The same ArgSpec (mutated in place).
(args/spec-flag spec "--verbose")
Since: Phase A1
args/-no-default
(args/-no-default : cstr)
the NULL cstr the option cell stores for "required".
args/-spec-option-raw
(args/-spec-option-raw [spec : ArgSpec name : cstr type : cstr dflt : cstr] : ArgSpec)
register an option whose default is a cstr or NULL.
args/spec-option
(args/spec-option [spec : ArgSpec name : cstr type : cstr dflt : (Option cstr)] : ArgSpec)
register a named option in the arg spec.
| spec | ArgSpec handle | |
| name | option name with dashes (e.g., "--input") | |
| type | one of "string", "int", "float", "bool" | |
| dflt | (some "value") for a default, (none) if the option is required |
The same ArgSpec (mutated in place).
(args/spec-option spec "--input" "string" (none))
(args/spec-option spec "--count" "int" (some "1"))
Since: Phase A1
args/-set-implicit
(args/-set-implicit [spec : ArgSpec implicit : cstr] : ArgSpec)
give the most recently registered option an implicit value.
args/spec-option-implicit
(args/spec-option-implicit [spec : ArgSpec name : cstr type : cstr dflt : (Option cstr) implicit : cstr] : ArgSpec)
register an option whose value may be left out.
Like args/spec-option, but the option may also be given bare: --name with no =value stands for implicit. A value must then be attached with = (--name=value); the next word is never taken as the value, so --isolate dist is --isolate followed by the positional dist. Left out entirely, the option takes dflt as usual.
| spec | ArgSpec handle | |
| name | option name with dashes (e.g., "--isolate") | |
| type | one of "string", "int", "float", "bool" (shown in help) | |
| dflt | (some "value") for the value when the option is absent, | |
| (none) if the option is required | ||
| implicit | the value a bare --name stands for |
The same ArgSpec (mutated in place).
(args/spec-option-implicit spec "--color" "string" (some "never") "always")
;; (no flag) => "never", --color => "always", --color=auto => "auto"
Since: tur serve --isolate
args/spec-subcommand
(args/spec-subcommand [spec : ArgSpec name : cstr sub-spec : ArgSpec] : ArgSpec)
register a nested subcommand.
| spec | parent ArgSpec handle | |
| name | subcommand name (e.g., "build") | |
| sub-spec | ArgSpec for the subcommand (from args/spec-new) |
The same parent ArgSpec (mutated in place).
(let [sub (args/spec-new)]
(args/spec-flag sub "--release")
(args/spec-subcommand spec "build" sub))
Since: Phase A1
args/spec-short
(args/spec-short [spec : ArgSpec short-name : cstr long-name : cstr] : ArgSpec)
register a short spelling for a flag or an option.
A token equal to short-name is read as long-name before anything else looks at it, so -p 8080 is --port 8080 and -q is --quiet. Only the whole token is matched: -p8080 and bundled -qv are not split. long-name may also be "--help", which is always accepted.
| spec | ArgSpec handle | |
| short-name | the short spelling, e.g. "-p" | |
| long-name | the registered flag or option it stands for, e.g. "--port" |
The same ArgSpec (mutated in place).
(args/spec-short spec "-p" "--port")
Since: project-less-tools-plan PT1
args/parse
(args/parse [spec : ArgSpec argv : int] : ArgResult)
parse a Turmeric *args* cons list against an arg spec.
Accepts both --key=value (preferred) and --key value forms for options; an option registered with args/spec-option-implicit takes only --key=value, and a bare --key stands for its implicit value. Flags are set to "1" when present. --help is always accepted. The first non-flag token matching a registered subcommand name triggers recursive dispatch: remaining tokens are parsed against the sub-spec. Defaults are injected after parsing; required options that are missing produce an error in the result.
| spec | ArgSpec handle from args/spec-new | |
| argv | Turmeric *args* cons list (the elaborator declares *args* itself | |
| as :int, so this slot matches that global's own type) |
An ArgResult handle. Free with args/result-free when done.
(let [res (args/parse spec *args*)] ...)
Since: Phase A1
args/has?
(args/has? [result : ArgResult key : cstr] : bool)
check whether a key is present in the result.
| result | ArgResult handle from args/parse | |
| key | option or flag name without dashes (e.g., "verbose") |
true if the key was parsed or injected via a default.
(args/has? res "verbose") ; => true if --verbose was passed
Since: Phase A1
args/get-str
(args/get-str [result : ArgResult key : cstr] : cstr)
look up a string value in the result.
| result | ArgResult handle from args/parse | |
| key | option name without dashes (e.g., "input") |
The string value, or 0 (NULL) if the key is not present.
(args/get-str res "input") ; => "file.txt"
Since: Phase A1
args/get-int
(args/get-int [result : ArgResult key : cstr] : int)
look up an integer value in the result.
| result | ArgResult handle from args/parse | |
| key | option name without dashes |
The parsed integer value, or 0 if the key is not present.
(args/get-int res "count") ; => 5
Since: Phase A1
args/get-bool
(args/get-bool [result : ArgResult key : cstr] : bool)
look up a boolean flag value in the result.
| result | ArgResult handle from args/parse | |
| key | flag name without dashes (e.g., "verbose") |
true if the flag was set (value is "1", "true", "yes", or "on").
(args/get-bool res "verbose") ; => true if --verbose was passed
Since: Phase A1
args/subcommand
(args/subcommand [result : ArgResult] : cstr)
return the matched subcommand name, or 0 if none.
| result | ArgResult handle from args/parse |
The subcommand name cstr, or 0 if no subcommand was matched.
(args/subcommand res) ; => "build"
Since: Phase A1
args/-sub-result-raw
(args/-sub-result-raw [result : ArgResult] : int)
the raw sub-result slot (0 when no subcommand ran).
args/sub-result
(args/sub-result [result : ArgResult] : (Option ArgResult))
the result from subcommand parsing, if one matched.
| result | ArgResult handle from args/parse |
(some sub-result) if a subcommand was matched, (none) otherwise.
(let [sub (args/sub-result res)]
(match sub
(Some s) (args/get-bool s "release")
(None) false))
Since: Phase A1
args/positional
(args/positional [result : ArgResult] : int)
return the positional arg cons list from the result.
The list is in reverse order (last positional arg is the head).
| result | ArgResult handle from args/parse |
A Turmeric cons list (int64_t) of remaining positional cstr args.
(args/positional res) ; => cons list
Since: Phase A1
args/error?
(args/error? [result : ArgResult] : bool)
check whether parsing produced an error.
| result | ArgResult handle from args/parse |
true if the result contains a parse error.
(args/error? res) ; => true if an unknown flag was passed
Since: Phase A1
args/error-msg
(args/error-msg [result : ArgResult] : cstr)
return the parse error message, or 0 if no error.
| result | ArgResult handle from args/parse |
The error message cstr, or 0 if there was no error.
(args/error-msg res) ; => "required option --input not provided"
Since: Phase A1
args/print-help
(args/print-help [spec : ArgSpec] : void)
print usage information to stdout.
| spec | ArgSpec handle from args/spec-new |
(args/print-help spec)
Since: Phase A1
args/spec-free
(args/spec-free [spec : ArgSpec] : void)
free a spec created by args/spec-new.
Does not free sub-specs registered via args/spec-subcommand; the caller must free those separately.
| spec | ArgSpec handle to free |
(args/spec-free spec)
Since: Phase A1
args/result-free
(args/result-free [result : ArgResult] : void)
free a result created by args/parse (including sub-results).
| result | ArgResult handle to free |
(args/result-free result)
Since: Phase A1