Skip to content

Commit

Permalink
Add linux example
Browse files Browse the repository at this point in the history
Co-authored-by: Michael Garrison Stuber <[email protected]>
  • Loading branch information
funbiscuit and Michael Garrison Stuber committed Nov 17, 2023
1 parent e8e05cd commit 3667454
Show file tree
Hide file tree
Showing 3 changed files with 146 additions and 0 deletions.
3 changes: 3 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@ if (BUILD_EXAMPLES)
if (WIN32)
add_subdirectory(examples/win32-example)
endif (WIN32)
IF(${CMAKE_SYSTEM_NAME} MATCHES "Linux")
add_subdirectory(examples/linux-example)
ENDIF()
endif ()

if (${BUILD_TESTS})
Expand Down
11 changes: 11 additions & 0 deletions examples/linux-example/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
add_executable(embedded_cli_linux main.cpp)

target_include_directories(embedded_cli_linux PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}
)

if (${BUILD_SINGLE_HEADER})
target_link_libraries(embedded_cli_linux PRIVATE EmbeddedCLI::SingleHeader)
else ()
target_link_libraries(embedded_cli_linux PRIVATE EmbeddedCLI::EmbeddedCLI)
endif ()
132 changes: 132 additions & 0 deletions examples/linux-example/main.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
/**
* Simple example of using embedded-cli in Linux application.
* Shamelessly stolen from Win32 version and modified to run under Linux
* Runs in terminal / console, using stdio, prints entered commands and args
*/

#include <stdio.h>
#include <unistd.h>
#include <termios.h>

#include <iostream>
#include <string>

#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) {
// grab the next character and feed it to the CLI processor
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";
}

0 comments on commit 3667454

Please sign in to comment.