Getting Started
Wire up TinyCLI to a character stream and register a command
The smallest useful TinyCLI integration consists of reading input characters from some source (e.g. getchar, a UART RX, or a Telnet socket), feeding them to the library, and forwarding the library’s output to the corresponding sink.
1. Output Callback
TinyCLI does not write anywhere directly. A single callback is provided at initialization and the library routes all output through it: the prompt, echoed input, command output, and formatting escape sequences.
#include <stdio.h>
#include "tclie.h"
void out(void *arg, const char *str)
{
/* arg is the third argument passed to tclie_init. Below we pass &t so
command callbacks can call tclie_out; in production it is more often
a pointer to a UART or socket context, used here as e.g.
uart_write(arg, str) or telnet_send(arg, str). */
printf("%s", str);
}2. Command Definitions
A command consists of a name, a callback, and a short description used by the built-in help command. The callback receives the conventional argc/argv pair along with the arg value supplied to tclie_init.
int cmd_echo(void *arg, int argc, const char **argv)
{
tclie_t *t = arg;
for (int i = 1; i < argc; i++) {
tclie_out(t, argv[i]);
tclie_out(t, i + 1 < argc ? " " : "\n");
}
/* zero = success; non-zero switches the prompt to the error variant */
return 0;
}
int cmd_reboot(void *arg, int argc, const char **argv)
{
tclie_t *t = arg;
tclie_out(t, "rebooting...\n");
/* hardware_reset(); */
return 0;
}
static const tclie_cmd_t cmds[] = {
{ .name = "echo", .fn = cmd_echo, .desc = "Print arguments back" },
{ .name = "reboot", .fn = cmd_reboot, .desc = "Reset the device" },
};Additional fields on tclie_cmd_t (min_user_level, pattern, options) are described in The tclie Wrapper and Pattern Matching. They can be omitted when users and argument validation are not required.
3. Initialization and Input
int main(void)
{
tclie_t t;
tclie_init(&t, out, &t);
tclie_reg_cmds(&t, cmds, sizeof(cmds) / sizeof(*cmds));
int c;
while ((c = getchar()) != EOF)
tclie_in_char(&t, (char) c);
return 0;
}The above is a complete CLI with tab-completion and command history. The built-in help command lists registered commands, Tab completes partial commands, Up/Down walks the history, and Ctrl+r performs a backwards history search.
4. Next Steps
A SIGINT handler can be registered to catch Ctrl+c (see tclie_set_sigint).
Commands can be restricted to certain user levels by enabling the optional users feature:
static const tclie_user_t users[] = {
{ .name = "admin", .password = "12345", .level = 2 },
};
tclie_reg_users(&t, users, sizeof(users) / sizeof(*users));A command with min_user_level = 2 then only runs after login admin (see The tclie Wrapper).
Argument shape can be validated with patterns instead of inspecting argc manually:
{ .name = "set", .fn = cmd_set, .desc = "Set value", .pattern = "set <key> <value>" }The pattern is also used to drive context-aware tab-completion (see Pattern Matching).
Log output that does not interfere with the current prompt is provided by tclie_log and tclie_log_printf (see Logging and Output).