26 #include "CommandDispatcher.h" 31 const char CommandDispatcher::DELIMS[] =
" \t\n";
34 if (statusCode == STATUS_BUFFER_OVERFLOW) {
35 mPrinter.print(F(
"BufferOverflow: "));
36 mPrinter.println(line);
37 }
else if (statusCode == STATUS_FLUSH_TO_EOL) {
38 mPrinter.print(F(
"FlushToEOL: "));
39 mPrinter.println(line);
41 mPrinter.print(F(
"UnknownError: "));
42 mPrinter.print(statusCode);
43 mPrinter.print(F(
": "));
44 mPrinter.println(line);
50 Print& printer,
int argc,
const char** argv) {
52 const char* cmd = argv[1];
53 if (strcmp(cmd,
"help") == 0) {
54 printer.println(F(
"Usage: help [command]"));
60 printer.print(F(
"Unknown command: "));
63 printer.println(F(
"Usage: help [command]"));
64 printer.print(F(
"Commands: help "));
72 int argc =
tokenize(line, mArgv, mArgvSize);
73 if (argc == 0)
return;
74 const char* cmd = mArgv[0];
77 if (strcmp(cmd,
"help") == 0) {
87 char* token = strtok(line, DELIMS);
89 while (token !=
nullptr && argc < argvSize) {
92 token = strtok(
nullptr, DELIMS);
118 void CommandDispatcherC::helpGeneric(Print& printer) {
119 for (uint8_t i = 0; i < mNumCommands; i++) {
121 printer.print(record->name);
127 bool CommandDispatcherC::helpSpecific(Print& printer,
const char* cmd) {
129 findCommand(mDispatchTable, mNumCommands, cmd);
130 if (record !=
nullptr) {
131 printer.print(F(
"Usage: "));
134 printer.println(record->helpString);
140 void CommandDispatcherC::findAndRunCommand(
141 const char* cmd,
int argc,
const char** argv) {
143 findCommand(mDispatchTable, mNumCommands, cmd);
144 if (record !=
nullptr) {
145 record->command(mPrinter, argc, argv);
149 mPrinter.print(F(
"Unknown command: "));
150 mPrinter.println(cmd);
155 uint8_t numCommands,
const char* cmd) {
156 for (uint8_t i = 0; i < numCommands; i++) {
158 if (strcmp(cmd, record->name) == 0) {
167 void CommandDispatcherF::helpGeneric(Print& printer) {
168 for (uint8_t i = 0; i < mNumCommands; i++) {
170 printer.print(record->name);
176 bool CommandDispatcherF::helpSpecific(Print& printer,
const char* cmd) {
179 if (record !=
nullptr) {
180 printer.print(F(
"Usage: "));
183 printer.println(record->helpString);
189 void CommandDispatcherF::findAndRunCommand(
190 const char* cmd,
int argc,
const char** argv) {
192 findCommand(mDispatchTable, mNumCommands, cmd);
193 if (record !=
nullptr) {
194 record->command(mPrinter, argc, argv);
198 mPrinter.print(F(
"Unknown command: "));
199 mPrinter.println(cmd);
204 uint8_t numCommands,
const char* cmd) {
205 for (uint8_t i = 0; i < numCommands; i++) {
207 if (strcmp_P(cmd, (
const char*) record->name) == 0) {
#define COROUTINE_AWAIT(condition)
Yield until condition is true, then execution continues.
void runCommand(char *line)
Tokenize the given line and run the command handler.
void helpCommandHandler(Print &printer, int argc, const char **argv)
Handle the 'help' command.
bool getLine(bool *isError, char **line)
Get a line.
static const DispatchRecordF * findCommand(const DispatchRecordF *dispatchTable, uint8_t numCommands, const char *cmd)
Same as findCommand() except use DispatchTableF instead of DispatchTable.
#define COROUTINE_LOOP()
Mark the beginning of a coroutine loop.
static uint8_t tokenize(char *line, const char **argv, uint8_t argvSize)
Tokenize the line, and fill argv with each token until argvSize is reached.
static const DispatchRecordC * findCommand(const DispatchRecordC *dispatchTable, uint8_t numCommands, const char *cmd)
Find the CommandHandler of the given command name.
virtual void findAndRunCommand(const char *cmd, int argc, const char **argv)=0
Find and run the given command.
virtual int run() override
The body of the coroutine.
A record of the command name and its handler.
virtual bool helpSpecific(Print &printer, const char *cmd)=0
Print helpString of specific cmd.
Same as DispatchRecordC but uses FlashStrings instead of (const char*) to save static RAM on AVR boar...
virtual void helpGeneric(Print &printer)=0
Print generic help.
void printLineError(const char *line, uint8_t statusCode)
Print the error caused by the given line.