Sub-Command Management¶
The Argtable3 library provides a robust API for managing sub-commands in
command-line applications. This API allows developers to define, register, and
dispatch sub-commands, making it easier to implement multi-command interfaces
similar to tools like git
or docker
.
Sub-commands are individual commands within a larger command-line application, each with its own arguments and behavior. The functions in this API enable the creation, iteration, and management of these sub-commands, offering flexibility and control over their lifecycle.
Overview of Functions¶
Initialization and Cleanup: Functions like
arg_cmd_init
andarg_cmd_uninit
handle the setup and teardown of the sub-command system.Registration and Unregistration: Use
arg_cmd_register
andarg_cmd_unregister
to add or remove sub-commands dynamically.Dispatching Commands: The
arg_cmd_dispatch
function executes the appropriate sub-command based on user input.Command Information: Retrieve details about registered sub-commands using
arg_cmd_info
or count them witharg_cmd_count
.Iterators: Functions such as
arg_cmd_itr_create
,arg_cmd_itr_destroy
,arg_cmd_itr_advance
,arg_cmd_itr_key
,arg_cmd_itr_value
, andarg_cmd_itr_search
provide tools for iterating over and searching through sub-commands.
This API is designed to simplify the implementation of complex command-line interfaces, enabling developers to focus on the functionality of their commands rather than the underlying infrastructure. Below is a detailed reference for each function in the sub-command management API.
Data Types¶
-
typedef int arg_cmdfn(int argc, char *argv[], arg_dstr_t res, void *ctx)¶
Function pointer type for sub-command handler functions.
The
arg_cmdfn
type defines the signature for functions that implement the logic of a sub-command in a multi-command command-line application. When a sub-command is dispatched (for example, viaarg_cmd_dispatch
), the corresponding handler function is called with the command-line arguments, a dynamic string buffer for output or error messages, and an optional user-defined context pointer.This function pointer is primarily intended for developers who want to implement custom sub-commands and register them with Argtable3. The handler should return 0 on success, or a nonzero error code on failure.
- Param argc:
The number of command-line arguments for the sub-command.
- Param argv:
The array of command-line arguments for the sub-command.
- Param res:
Dynamic string buffer for output or error messages.
- Param ctx:
User-defined context pointer, as provided during registration.
- Return:
0 on success, or a nonzero error code on failure.
-
typedef struct arg_cmd_info arg_cmd_info_t¶
Structure for storing sub-command information.
The
arg_cmd_info
struct is used to represent metadata and handler information for a sub-command in a multi-command command-line application. Each sub-command can have its own name, description, handler function, and context pointer, allowing you to build flexible interfaces similar to tools likegit
ordocker
.The
name
field stores the sub-command name, while thedescription
provides a short summary for help and usage messages. Theproc
field is a pointer to the function that implements the sub-command’s behavior, andctx
is a user-defined context pointer that can be used to pass additional data to the handler.Example usage:
// Define a handler function for the "list" sub-command int list_cmd(int argc, char* argv[], arg_dstr_t res, void* ctx) { // Implementation for the "list" command return 0; } // Register the sub-command arg_cmd_register("list", list_cmd, "List all items", NULL); // Retrieve sub-command info arg_cmd_info_t* info = arg_cmd_info("list"); if (info) { printf("Sub-command: %s - %s\n", info->name, info->description); }
See also
arg_cmd_register, arg_cmd_info, arg_cmd_dispatch
API¶
-
void arg_cmd_init(void)¶
Initializes the sub-command mechanism.
The
arg_cmd_init
function sets up the internal data structures required for sub-command support in Argtable3. It must be called before registering, dispatching, or iterating over sub-commands in your application.This function is typically called once at program startup, before any sub-commands are registered. It ensures that the sub-command API is ready for use. After initialization, you can use functions such as
arg_cmd_register
,arg_cmd_dispatch
, andarg_cmd_itr_create
.When sub-command support is no longer needed (e.g., at program shutdown), call
arg_cmd_uninit
to release resources and prevent memory leaks.Example usage:
arg_cmd_init(); // Register and use sub-commands... arg_cmd_uninit();
See also
arg_cmd_uninit, arg_cmd_register, arg_cmd_unregister, arg_cmd_count
-
void arg_cmd_uninit(void)¶
Releases resources and cleans up the sub-command mechanism.
The
arg_cmd_uninit
function deinitializes the sub-command infrastructure, freeing any memory or resources allocated for sub-command registration, lookup, and iteration. After calling this function, all registered sub-commands are removed, and the sub-command API can no longer be used untilarg_cmd_init
is called again.This function should be called at program shutdown or when you no longer need sub-command support, to prevent memory leaks and ensure proper cleanup.
Example usage:
arg_cmd_init(); // Register and use sub-commands... arg_cmd_uninit();
See also
arg_cmd_init, arg_cmd_register, arg_cmd_unregister, arg_cmd_count
-
void arg_cmd_register(const char *name, arg_cmdfn *proc, const char *description, void *ctx)¶
Registers a new sub-command with the application.
The
arg_cmd_register
function adds a sub-command to the application’s sub-command table, associating it with a handler function, a description, and an optional context pointer. This enables applications to support multiple commands (such asgit
ordocker
-style interfaces), where each sub-command can have its own logic and help text.The handler function (
proc
) will be called when the sub-command is dispatched viaarg_cmd_dispatch
. The description is used in help and usage messages. The context pointer (ctx
) can be used to pass user-defined data to the handler.If a sub-command with the same name already exists, its registration will be replaced with the new handler, description, and context.
Example usage:
// Register a "list" sub-command arg_cmd_register("list", list_cmd, "List all items", NULL); // Register a "remove" sub-command with context arg_cmd_register("remove", remove_cmd, "Remove an item", my_context_ptr);
See also
arg_cmd_unregister, arg_cmd_dispatch, arg_cmd_info, arg_cmd_count
- Parameters:
name – The name of the sub-command (null-terminated string).
proc – Pointer to the handler function for the sub-command.
description – A short description of the sub-command for help output.
ctx – Optional user-defined context pointer (may be NULL).
-
void arg_cmd_unregister(const char *name)¶
Unregisters a sub-command by name.
The
arg_cmd_unregister
function removes a previously registered sub-command from the application’s sub-command table. After calling this function, the specified sub-command will no longer be available for dispatch, iteration, or help output.This function is useful for applications that support dynamic registration and removal of sub-commands at runtime, such as plugin-based tools or interactive shells.
If the sub-command with the given name does not exist, the function has no effect.
Example usage:
arg_cmd_register("remove", remove_cmd, "Remove an item", NULL); // ... later ... arg_cmd_unregister("remove");
See also
arg_cmd_register, arg_cmd_dispatch, arg_cmd_count, arg_cmd_info
- Parameters:
name – The name of the sub-command to unregister (null-terminated string).
-
int arg_cmd_dispatch(const char *name, int argc, char *argv[], arg_dstr_t res)¶
Dispatches a registered sub-command by name.
The
arg_cmd_dispatch
function locates the sub-command with the specified name and invokes its handler function, passing the provided command-line arguments and a dynamic string buffer for output or error messages.This function is typically used in applications that support multiple sub-commands (such as
git
ordocker
-style interfaces), allowing you to delegate command-line processing to the appropriate handler based on the user’s input.If the sub-command is found, its handler function is called with the given arguments and context. If the sub-command is not found, an error message may be written to the result buffer, and a nonzero error code is returned.
Example usage:
// Register sub-commands arg_cmd_register("list", list_cmd, "List items", NULL); arg_cmd_register("add", add_cmd, "Add an item", NULL); // Dispatch based on argv[1] arg_dstr_t res = arg_dstr_create(); int ret = arg_cmd_dispatch(argv[1], argc - 1, argv + 1, res); if (ret != 0) { fprintf(stderr, "%s\n", arg_dstr_cstr(res)); } arg_dstr_destroy(res);
See also
arg_cmd_register, arg_cmd_info, arg_cmd_count, arg_dstr_create, arg_dstr_cstr
- Parameters:
name – The name of the sub-command to dispatch (null-terminated string).
argc – The number of command-line arguments for the sub-command.
argv – The array of command-line arguments for the sub-command.
res – Pointer to a dynamic string buffer for output or error messages.
- Returns:
0 if the sub-command was found and executed successfully, nonzero if the sub-command was not found or an error occurred.
-
unsigned int arg_cmd_count(void)¶
Returns the number of registered sub-commands.
The
arg_cmd_count
function returns the total number of sub-commands currently registered in the application. This is useful for applications that support multiple commands (such asgit
ordocker
-style interfaces) and need to enumerate, display, or manage the available sub-commands.You can use this function to determine the size of the sub-command table, iterate over all registered sub-commands, or display a summary of available commands to the user.
Example usage:
unsigned int count = arg_cmd_count(); printf("There are %u sub-commands registered.\n", count);
See also
arg_cmd_register, arg_cmd_info, arg_cmd_itr_create
- Returns:
The number of sub-commands currently registered.
-
arg_cmd_info_t *arg_cmd_info(const char *name)¶
Retrieves information about a registered sub-command by name.
The
arg_cmd_info
function returns a pointer to thearg_cmd_info_t
structure for the sub-command with the specified name. This structure contains metadata such as the sub-command’s name, description, handler function, and context pointer.This function is useful for querying details about a specific sub-command, such as when generating help output, dispatching commands, or inspecting available sub-commands in applications that support multiple commands (e.g.,
git
ordocker
-style interfaces).If the sub-command is not found, the function returns
NULL
.Example usage:
arg_cmd_info_t* info = arg_cmd_info("list"); if (info) { printf("Sub-command: %s - %s\n", info->name, info->description); }
See also
arg_cmd_register, arg_cmd_count, arg_cmd_itr_create, arg_cmd_info_t
- Parameters:
name – The name of the sub-command to look up (null-terminated string).
- Returns:
Pointer to the
arg_cmd_info_t
structure for the sub-command, orNULL
if the sub-command is not found.
-
arg_cmd_itr_t arg_cmd_itr_create(void)¶
Creates a new sub-command iterator for traversing registered sub-commands.
The
arg_cmd_itr_create
function allocates and initializes a sub-command iterator, which can be used to traverse all registered sub-commands in the application. This iterator provides a convenient way to enumerate, search, or process sub-commands, especially in applications that support multiple commands (such asgit
ordocker
-style interfaces).After creating the iterator, you can use functions like
arg_cmd_itr_advance
to move through the sub-command table, andarg_cmd_itr_key
orarg_cmd_itr_value
to access the current sub-command’s name or metadata. When finished, callarg_cmd_itr_destroy
to release resources.Example usage:
arg_cmd_itr_t itr = arg_cmd_itr_create(); while (arg_cmd_itr_advance(itr)) { const char* key = arg_cmd_itr_key(itr); printf("Sub-command: %s\n", key); } arg_cmd_itr_destroy(itr);
See also
arg_cmd_itr_destroy, arg_cmd_itr_advance, arg_cmd_itr_key, arg_cmd_itr_value
- Returns:
A handle to the newly created sub-command iterator, or
NULL
if allocation fails.
-
void arg_cmd_itr_destroy(arg_cmd_itr_t itr)¶
Destroys the sub-command iterator and releases associated resources.
The
arg_cmd_itr_destroy
function deallocates any memory or resources associated with a sub-command iterator created byarg_cmd_itr_create
. After calling this function, the iterator is no longer valid and must not be used.This function should be called when you are finished iterating over sub-commands to prevent memory leaks and ensure proper cleanup.
Example usage:
arg_cmd_itr_t itr = arg_cmd_itr_create(); while (arg_cmd_itr_advance(itr)) { // process sub-commands } arg_cmd_itr_destroy(itr);
See also
arg_cmd_itr_create, arg_cmd_itr_advance, arg_cmd_itr_key, arg_cmd_itr_value
- Parameters:
itr – The sub-command iterator to destroy.
-
int arg_cmd_itr_advance(arg_cmd_itr_t itr)¶
Advances the sub-command iterator to the next entry.
The
arg_cmd_itr_advance
function moves the sub-command iterator to the next sub-command in the table. This allows you to iterate over all registered sub-commands in your application, enabling tasks such as listing available commands, generating help output, or performing batch operations.This function is typically used in a loop, where you repeatedly call
arg_cmd_itr_advance
and retrieve the current sub-command’s key or value usingarg_cmd_itr_key
orarg_cmd_itr_value
.Example usage:
arg_cmd_itr_t itr = arg_cmd_itr_create(); while (arg_cmd_itr_advance(itr)) { const char* key = arg_cmd_itr_key(itr); printf("Sub-command: %s\n", key); } arg_cmd_itr_destroy(itr);
See also
arg_cmd_itr_create, arg_cmd_itr_key, arg_cmd_itr_value, arg_cmd_info_t
- Parameters:
itr – The sub-command iterator.
- Returns:
1 if the iterator was advanced to a valid entry, 0 if there are no more entries (end of the sub-command table).
-
char *arg_cmd_itr_key(arg_cmd_itr_t itr)¶
Retrieves the key (name) of the sub-command at the current iterator position.
The
arg_cmd_itr_key
function returns a pointer to the key (typically the sub-command name as a null-terminated string) at the current position of the sub-command iterator. This allows you to access the identifier for the sub-command currently referenced by the iterator, which is useful for displaying, comparing, or processing sub-commands in applications that support multiple commands.This function is typically used when iterating over all registered sub-commands or after searching for a specific sub-command using the iterator.
Example usage:
arg_cmd_itr_t itr = arg_cmd_itr_create(); while (arg_cmd_itr_advance(itr)) { const char* key = arg_cmd_itr_key(itr); printf("Sub-command: %s\n", key); } arg_cmd_itr_destroy(itr);
See also
arg_cmd_itr_create, arg_cmd_itr_advance, arg_cmd_itr_value, arg_cmd_info_t
- Parameters:
itr – The sub-command iterator.
- Returns:
Pointer to the key (sub-command name) at the current iterator position, or
NULL
if the iterator is not valid or at the end.
-
arg_cmd_info_t *arg_cmd_itr_value(arg_cmd_itr_t itr)¶
Retrieves the value (sub-command information) at the current iterator position.
The
arg_cmd_itr_value
function returns a pointer to thearg_cmd_info_t
structure at the current position of the sub-command iterator. This allows you to access metadata and handler information for the sub-command found or iterated to by the iterator.This function is typically used after advancing the iterator or searching for a specific sub-command, enabling you to inspect the sub-command’s name, description, handler function, and context pointer.
Example usage:
arg_cmd_itr_t itr = arg_cmd_itr_create(); if (arg_cmd_itr_search(itr, "list")) { arg_cmd_info_t* info = arg_cmd_itr_value(itr); printf("Found sub-command: %s - %s\n", info->name, info->description); } arg_cmd_itr_destroy(itr);
See also
arg_cmd_itr_create, arg_cmd_itr_advance, arg_cmd_itr_search, arg_cmd_info_t
- Parameters:
itr – The sub-command iterator.
- Returns:
Pointer to the
arg_cmd_info_t
structure at the current iterator position, orNULL
if the iterator is not valid or at the end.
-
int arg_cmd_itr_search(arg_cmd_itr_t itr, void *k)¶
Searches for a sub-command by key using the sub-command iterator.
The
arg_cmd_itr_search
function searches the sub-command table for a sub-command whose key matches the specified value, starting from the current position of the iterator. If a match is found, the iterator is positioned at the found entry.This function is useful for efficiently locating a specific sub-command in applications that support multiple commands (such as
git
ordocker
-style interfaces), especially when iterating over or managing a dynamic set of sub-commands.Example usage:
arg_cmd_itr_t itr = arg_cmd_itr_create(); if (arg_cmd_itr_search(itr, "list")) { arg_cmd_info_t* info = arg_cmd_itr_value(itr); printf("Found sub-command: %s - %s\n", info->name, info->description); } arg_cmd_itr_destroy(itr);
See also
arg_cmd_itr_create, arg_cmd_itr_value, arg_cmd_info_t
- Parameters:
itr – The sub-command iterator.
k – The key to search for (typically a string with the sub-command name).
- Returns:
1 if the key is found and the iterator is positioned at the entry, 0 otherwise.