AxlSubcommand — Multi-command CLI dispatch
Helper for UEFI applications that expose multiple distinct operations under a common executable (do bios, do sysid, do 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 tools (e.g. do.efi)
declare an AxlSubcommand table and call
axl_subcommand_dispatch from main.
API Reference
Typedefs
-
typedef int (*AxlSubcommandFn)(int argc, char **argv)
axl-subcommand.h:
Subcommand-style CLI dispatch for multi-command UEFI apps. Pairs with axl-config (each subcommand can use its own AxlConfig descriptor table for flag parsing) —
mkrdis the canonical “single-purpose tool” shape,do.efiand friends are the canonical “multi-command tool” shape.Usage:
static int do_bios(int argc, char **argv) { // argv[0] is “bios”; flags via axl_config_* return 0; } static int do_sysid(int argc, char **argv) { // argv[0] is “sysid” return 0; }
static const AxlSubcommand kCommands[] = { { “bios”, do_bios, “[test|pci|irq|slot|emb]”, “do bios test — run BIOS POST self-test\n” “do bios pci — dump PCI bus info\n” }, { “sysid”, do_sysid, “[hexValue]”, “do sysid — print system ID\n” “do sysid <hex> — set system ID\n” }, };
int main(int argc, char **argv) { return axl_subcommand_dispatch(kCommands, sizeof(kCommands) / sizeof(kCommands[0]), argc, argv, “do”); } Subcommand implementation function signature.
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