AxlSubcommand — Multi-command CLI dispatch
Warning
Deprecated. Use AxlArgs — Argument Parsing (axl_args_run from
<axl/axl-args.h>) instead — it handles flags, positionals, and
arbitrarily nested subcommands in one declarative AxlArgsNode
tree. The axl_subcommand_* functions are marked
__attribute__((deprecated)) and remain only for existing
consumers; new tools should not use them.
Helper for UEFI applications that expose multiple distinct operations
under a common executable (e.g. tool bios, tool sysid,
tool crb …). Pairs with AxlConfig — Configuration — each subcommand uses
its own AxlConfig descriptor table for flag parsing.
See AxlSys — System Utilities for an overview of all utility modules.
Header: <axl/axl-subcommand.h>
Single-purpose tools (e.g. mkrd) skip this layer and use
axl_config_* directly. Multi-command tool wrappers declare an
AxlSubcommand table and call axl_subcommand_dispatch from
main.
API Reference
Typedefs
-
typedef int (*AxlSubcommandFn)(int argc, char **argv)
axl-subcommand.h:
- Deprecated:
Use axl_args_run from
<axl/axl-args.h>instead. AxlArgs’s multi-verb mode (AxlArgsApp.verbs[]) strictly subsumes this dispatcher and adds typed positional args, bounds checking, and auto-generated--help. AxlSubcommand is retained as a thin wrapper for source compatibility while out-of-tree consumers migrate. New tools should not use this header.
Subcommand-style CLI dispatch for multi-command UEFI apps. Pairs with axl-config —
mkrdwas the canonical “single-purpose tool” shape; the multi-command shape has been migrated to AxlArgs in tree.Migrating to AxlArgs in one diff:
Subcommand implementation function signature.// before: static int tool_bios(int argc, char **argv) { ... } static const AxlSubcommand commands[] = { { "bios", tool_bios, "[test|pci|irq|slot|emb]", "tool bios test — ..." }, }; int main(int argc, char **argv) { return axl_subcommand_dispatch(commands, ARRAY_LEN(commands), argc, argv, "tool"); } // after: static const AxlArgDesc bios_args[] = { { .name = "args", .type = AXL_ARG_MULTI, .help = "subcommand arguments" }, {0} }; static int tool_bios(AxlArgs *a) { int n = axl_args_get_pos_count(a); const char *sub = (n > 0) ? axl_args_get_pos(a, 0) : NULL; ... } static const AxlArgsNode verbs[] = { { .name = "bios", .handler = tool_bios, .positionals = bios_args, .help = "BIOS / SMBIOS info (test|pci|irq|slot|emb)" }, {0} }; int main(int argc, char **argv) { return axl_args_run(argc, argv, &(AxlArgsNode){ .name = "tool", .verbs = verbs, }); }Receives (argc, argv) where argv[0] is the subcommand name (the dispatcher rewrites it from the parent’s argv so subcommand implementations don’t need to know about the parent’s name). Use AxlConfig or hand-written parsing on the remaining args.
Functions
-
int axl_subcommand_dispatch(const AxlSubcommand *table, size_t count, int argc, char **argv, const char *prog_name)
Dispatch argv[1] to the matching subcommand, or print help.
Behavior:
argc < 2, or argv[1] is “help” / “-h” / “–help” with no further args → prints the formatted help table and returns 0.
argv[1] is “help <cmd>” → prints cmd’s
usagefield (orsummaryifusageis NULL) and returns 0.argv[1] matches a table entry → invokes its
fnwith (argc - 1, argv + 1) so the subcommand sees its own name as argv[0]. Returns the function’s return value.argv[1] doesn’t match anything → prints “<prog>: unknown command
’foo’” plus a “did you mean ‘bar’?” suggestion if a close match exists, and returns -1.
The table is 100% caller-owned. No allocation; no internal state.
- Parameters:
table – array of AxlSubcommand
count – number of entries in table
argc – forwarded from main()
argv – forwarded from main()
prog_name – used in help / error output. NULL → use the basename of argv[0].
- Returns:
whatever the subcommand returned, 0 for help/empty, or -1 if the command wasn’t found.
-
void axl_subcommand_print_help(const AxlSubcommand *table, size_t count, const char *prog_name)
Print only the formatted help table.
Useful when the caller wants to show help in response to an invalid argument outside the dispatch path. Output format:
Usage:
<prog> <command> [args...]Commands: bios [test|pci|irq|slot|emb] sysid [hexValue]
Run
<prog> help <command>for detailed usage.
-
void axl_subcommand_print_command_help(const AxlSubcommand *entry, const char *prog_name)
Print a single subcommand’s detailed usage.
Used by
<prog> help <cmd>. Prints entry->usage, falling back to entry->summary if entry->usage is NULL. Pass NULL entry to print the global help (same as axl_subcommand_print_help).
-
struct AxlSubcommand
- #include <axl-subcommand.h>
One entry in a subcommand table. Define a static array of these (or allocate dynamically — the dispatcher doesn’t care) and pass it to axl_subcommand_dispatch.
Public Members
-
const char *name
e.g. “bios”, “sysid”, “crb”
-
AxlSubcommandFn fn
Implementation function.
-
const char *summary
One-line, shown in
<prog> help
-
const char *usage
Multiline, shown in
<prog> help <cmd>(NULL = usesummary)
-
const char *name