CDC Badge OS
Firmware for the CDC Badge v1.0 hardware security key
Loading...
Searching...
No Matches
SubCommand.h
Go to the documentation of this file.
1#pragma once
2
5
6#include <cctype>
7#include <cstddef>
8#include <cstdio>
9#include <cstring>
10
11namespace cdc::serial {
12
20inline void parseSubCommand(const char* args,
21 const char*& name,
22 size_t& name_len,
23 const char*& rest)
24{
25 while (*args == ' ' || *args == '\t') ++args;
26 name = args;
27 while (*args && !std::isspace(static_cast<unsigned char>(*args))) ++args;
28 name_len = static_cast<size_t>(args - name);
29 while (*args == ' ' || *args == '\t') ++args;
30 rest = args;
31}
32
36inline bool subCommandEquals(const char* token, size_t token_len, const char* word)
37{
38 return std::strlen(word) == token_len &&
39 strncasecmp(token, word, token_len) == 0;
40}
41
47inline void printSubCommandHelp(const char* parent, const SubCommand* table)
48{
49 if (!table) return;
50 Console::printf("Usage: %s <subcommand> [args]\r\n", parent);
51 Console::printf("Subcommands:\r\n");
52 for (const SubCommand* e = table; e->name; ++e) {
53 char head[kSubCommandHeadBufSize];
54 if (e->args && *e->args) {
55 std::snprintf(head, sizeof(head), "%s %s", e->name, e->args);
56 } else {
57 std::snprintf(head, sizeof(head), "%s", e->name);
58 }
59 Console::printf(" %-26s %s\r\n", head, e->help ? e->help : "");
60 }
61}
62
73inline void dispatchSubCommand(const char* parent,
74 const char* args,
75 const SubCommand* table)
76{
77 const char* sub = nullptr;
78 size_t sub_len = 0;
79 const char* rest = nullptr;
80 parseSubCommand(args ? args : "", sub, sub_len, rest);
81
82 if (sub_len == 0 || subCommandEquals(sub, sub_len, "HELP") ||
83 subCommandEquals(sub, sub_len, "?")) {
84 printSubCommandHelp(parent, table);
85 return;
86 }
87
88 for (const SubCommand* e = table; e->name; ++e) {
89 if (subCommandEquals(sub, sub_len, e->name)) {
90 if (e->handler) e->handler(rest);
91 return;
92 }
93 }
94
95 Console::printf("ERROR: Unknown %s subcommand '%.*s'\r\n",
96 parent, static_cast<int>(sub_len), sub);
97 printSubCommandHelp(parent, table);
98}
99
100} // namespace cdc::serial
char name[cdc::hal::ISecureElement::RMEM_NAME_LEN]
static void printf(const char *format,...) __attribute__((format(printf
Prints formatted text to console.
Definition Console.cpp:30
bool subCommandEquals(const char *token, size_t token_len, const char *word)
Case-insensitive compare of an unterminated token against a word.
Definition SubCommand.h:36
constexpr size_t kSubCommandHeadBufSize
Buffer size for the "<name> <args>" column built during HELP rendering.
void parseSubCommand(const char *args, const char *&name, size_t &name_len, const char *&rest)
Splits args into "<sub-command> <rest>".
Definition SubCommand.h:20
void printSubCommandHelp(const char *parent, const SubCommand *table)
Prints a sub-command summary block.
Definition SubCommand.h:47
void dispatchSubCommand(const char *parent, const char *args, const SubCommand *table)
Routes a sub-command line to its handler.
Definition SubCommand.h:73
const char * name
Sub-command keyword, e.g. "LIST". nullptr terminates the array.