Skip to content

0.0.4: actions return a status; run dispatches at any depth; usage errors go to standard error - #11

Merged
Sunrisepeak merged 1 commit into
mainfrom
feat/0.0.4-action-status
Nov 13, 2026
Merged

Sunrisepeak merged 1 commit into
mainfrom
feat/0.0.4-action-status

Conversation

@Sunrisepeak

Copy link
Copy Markdown
Member

Summary

Three programs built on cmdline work around the same three gaps, each in its own way:

  • an action cannot return an exit status, so a status is carried out through a captured variable;
  • run dispatches one level only, so nested command groups are dispatched by hand;
  • run(argc, argv) prints a parse error to standard output and returns 1, so programs whose standard output carries data parse and report errors themselves.

This change closes the three gaps in the library. It is source-compatible with 0.0.3.

Changes

  • action accepts int(const ParsedArgs&), whose result is the status run returns, or void(const ParsedArgs&), whose status is 0. The callable is checked by a constraint: it returns void or a type convertible to int.
  • int run(const ParsedArgs&) replaces void run(const ParsedArgs&). It descends to the deepest matched subcommand at any depth and runs that command's action. A command without an action leaves the run to its nearest ancestor that has one; the ancestor receives its own parse and dispatches on subcommand_name(), which is what one-level dispatchers already do. When no command on the path has an action and the named command has subcommands, the run writes the subcommands to standard error and returns 2. Otherwise it returns 0.
  • run(argc, argv) and the new run(std::span<const std::string>) print help and the version to standard output and return 0. A parse error is written to standard error as <name>: <message>, followed by <name>: see '<name> --help', and the run returns 2, the usual status of a usage error.
  • parse and parse_from share one token entry.
  • The version is 0.0.4. docs/api.md states the dispatch rules and the statuses; the README lists them.

Compatibility

  • Existing void actions compile and behave as before.
  • Callers that ignored run(parsed) still compile; its result is now the status.
  • Two behaviours change, both on paths that previously did nothing useful:
    • a parse error in run(argc, argv) goes to standard error and returns 2 (previously standard output and 1);
    • a matched subcommand without an action now falls back to an ancestor's action, or reports a missing subcommand (previously nothing ran and the status was 0).

Tests

mcpp test runs 51 tests, all passing. The new tests cover:

  • int and void action statuses, and function-pointer actions;
  • three-level dispatch, and an ancestor action dispatching on the child name;
  • a command group named alone (status 2, message on standard error);
  • run(Argv) statuses, a parse error on standard error with empty standard output, help and version returning 0, and run(argc, argv).

…rors go to standard error

An action is int(const ParsedArgs&), whose result is the status run returns, or
void(const ParsedArgs&), whose status is 0; existing void actions are unchanged.
run(parsed) descends to the deepest matched subcommand at any depth and runs its
action, else the nearest ancestor's (which dispatches on subcommand_name()); a
command group named without a subcommand writes its subcommands to standard
error and returns 2. run(argc, argv) and the new run(Argv) write a parse error to
standard error, as '<name>: <message>' and a pointer to --help, and return 2, the
status of a usage error; standard output carries only help, the version and the
actions' own output. parse and parse_from share one token entry.
@Sunrisepeak
Sunrisepeak merged commit 16cc7b8 into main Nov 13, 2026
1 check passed
@Sunrisepeak
Sunrisepeak deleted the feat/0.0.4-action-status branch November 13, 2026 07:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant