From cf0434b8ade7cf9231ad089305a3c148f4fce9ec Mon Sep 17 00:00:00 2001 From: Michael Garrison Stuber Date: Mon, 13 Nov 2023 22:07:40 -0800 Subject: [PATCH 1/3] Added linux-example/main.cpp This example uses raw terminal mode to allow the embedded-cli to work in Linux. Compiles using g++ with suitable arguments to reference the embedded-cli library. --- examples/linux-example/main.cpp | 129 ++++++++++++++++++++++++++++++++ 1 file changed, 129 insertions(+) create mode 100644 examples/linux-example/main.cpp diff --git a/examples/linux-example/main.cpp b/examples/linux-example/main.cpp new file mode 100644 index 0000000..735424e --- /dev/null +++ b/examples/linux-example/main.cpp @@ -0,0 +1,129 @@ +/** + * Simple example of using embedded-cli in win32 application. + * Create emulator of terminal which prints entered commands and args + */ + +#include +#include +#include + +#include +#include +#include + +#define EMBEDDED_CLI_IMPL +#include "embedded_cli.h" + +static bool exitFlag = false; + +void onCommand(const std::string &name, char *tokens); + +void onExit(EmbeddedCli *cli, char *args, void *context); + +void onHello(EmbeddedCli *cli, char *args, void *context); + +void onLed(EmbeddedCli *cli, char *args, void *context); + +void onAdc(EmbeddedCli *cli, char *args, void *context); + +int main() { + /* single character buffer for reading keystrokes */ + unsigned char c; + + /* Structures to save the terminal settings for original settings & raw mode */ + struct termios original_stdin; + struct termios raw_stdin; + + /* Backup the terminal settings, and switch to raw mode */ + tcgetattr(STDIN_FILENO, &original_stdin); + raw_stdin = original_stdin; + cfmakeraw(&raw_stdin); + tcsetattr(STDIN_FILENO, TCSANOW, &raw_stdin); + + EmbeddedCli *cli = embeddedCliNewDefault(); + + cli->onCommand = [](EmbeddedCli *embeddedCli, CliCommand *command) { + embeddedCliTokenizeArgs(command->args); + onCommand(command->name == nullptr ? "" : command->name, command->args); + }; + cli->writeChar = [](EmbeddedCli *embeddedCli, char c) { + write(STDOUT_FILENO, &c, 1); + }; + + embeddedCliAddBinding(cli, { + "exit", + "Stop CLI and exit", + false, + nullptr, + onExit + }); + embeddedCliAddBinding(cli, { + "get-led", + "Get current led status", + false, + nullptr, + onLed + }); + embeddedCliAddBinding(cli, { + "get-adc", + "Get current adc value", + false, + nullptr, + onAdc + }); + embeddedCliAddBinding(cli, { + "hello", + "Print hello message", + true, + (void *) "World", + onHello + }); + + std::cout << "Cli is running. Press 'Esc' to exit\r\n"; + std::cout << "Type \"help\" for a list of commands\r\n"; + std::cout << "Use backspace and tab to remove chars and autocomplete\r\n"; + + embeddedCliProcess(cli); + + while (!exitFlag) { + if(read(STDIN_FILENO,&c,1)>0) { + embeddedCliReceiveChar(cli, c); + embeddedCliProcess(cli); + } + } + + /* restore terminal settings */ + tcsetattr(STDIN_FILENO, TCSANOW, &original_stdin); + + return 0; +} + +void onCommand(const std::string &name, char *tokens) { + std::cout << "Received command: " << name << "\n"; + + for (int i = 0; i < embeddedCliGetTokenCount(tokens); ++i) { + std::cout << "Arg " << i << ": " << embeddedCliGetToken(tokens, i + 1) << "\n"; + } +} + +void onExit(EmbeddedCli *cli, char *args, void *context) { + exitFlag = true; + std::cout << "Cli will shutdown now...\r\n"; +} + +void onHello(EmbeddedCli *cli, char *args, void *context) { + std::cout << "Hello, "; + if (embeddedCliGetTokenCount(args) == 0) + std::cout << (const char *) context; + else + std::cout << embeddedCliGetToken(args, 1); + std::cout << "\r\n"; +} + +void onLed(EmbeddedCli *cli, char *args, void *context) { + std::cout << "Current led brightness: " << std::rand() % 256 << "\r\n"; +} + +void onAdc(EmbeddedCli *cli, char *args, void *context) { + std::cout << "Current adc readings: " << std::rand() % 1024 << "\r\n"; +} From d0e780765152d0705da4f992f596e11cab0b6c04 Mon Sep 17 00:00:00 2001 From: Michael Garrison Stuber Date: Mon, 13 Nov 2023 22:42:50 -0800 Subject: [PATCH 2/3] Updated comment and removed unnecessary thread include --- examples/linux-example/main.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/linux-example/main.cpp b/examples/linux-example/main.cpp index 735424e..1a51733 100644 --- a/examples/linux-example/main.cpp +++ b/examples/linux-example/main.cpp @@ -1,5 +1,6 @@ /** - * Simple example of using embedded-cli in win32 application. + * Simple example of using embedded-cli in Linux application. + * Shameless stolen from Win32 version and modified to run under Linux * Create emulator of terminal which prints entered commands and args */ @@ -8,7 +9,6 @@ #include #include -#include #include #define EMBEDDED_CLI_IMPL From 11fe7d256e233f9ec0ddd3c3ac158d38ccd4c1dd Mon Sep 17 00:00:00 2001 From: Michael Garrison Stuber Date: Mon, 13 Nov 2023 22:47:02 -0800 Subject: [PATCH 3/3] Updated comments --- examples/linux-example/main.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/examples/linux-example/main.cpp b/examples/linux-example/main.cpp index 1a51733..797b11e 100644 --- a/examples/linux-example/main.cpp +++ b/examples/linux-example/main.cpp @@ -1,7 +1,7 @@ /** * Simple example of using embedded-cli in Linux application. - * Shameless stolen from Win32 version and modified to run under Linux - * Create emulator of terminal which prints entered commands and args + * Shamelessly stolen from Win32 version and modified to run under Linux + * Runs in terminal / console, using stdio, prints entered commands and args */ #include @@ -86,6 +86,7 @@ int main() { embeddedCliProcess(cli); while (!exitFlag) { + /* grab the next character and feed it to the CLI processor */ if(read(STDIN_FILENO,&c,1)>0) { embeddedCliReceiveChar(cli, c); embeddedCliProcess(cli);