aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorlonkaars <loek@pipeframe.xyz>2024-05-22 19:32:21 +0200
committerlonkaars <loek@pipeframe.xyz>2024-05-22 19:32:21 +0200
commit53d27ebf10225274a50dc4a7c2343d4efce55a8a (patch)
treebdf1a5d9b3900d86a999bc396e7815bd7372a549
parentdb8906d54cd9afbc57f0b40a0d618335c552f704 (diff)
clean up command handling
-rw-r--r--client/.gitignore1
-rw-r--r--client/CMakeLists.txt5
-rw-r--r--client/cmd.cpp15
-rw-r--r--client/cmd.h23
l---------client/pbc1
-rw-r--r--client/readme.md14
-rw-r--r--client/rl.cpp27
7 files changed, 68 insertions, 18 deletions
diff --git a/client/.gitignore b/client/.gitignore
deleted file mode 100644
index ba2906d..0000000
--- a/client/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-main
diff --git a/client/CMakeLists.txt b/client/CMakeLists.txt
index cae0111..c526345 100644
--- a/client/CMakeLists.txt
+++ b/client/CMakeLists.txt
@@ -8,13 +8,14 @@ project(puzzlebox_client C CXX)
include(../proto/include.cmake)
-add_executable(main
+add_executable(pbc
main.cpp
rl.cpp
sock.cpp
+ cmd.cpp
)
-target_link_libraries(main
+target_link_libraries(pbc
puzbus
mpack
readline # this is such a common library that I did not bother adding it as a submodule
diff --git a/client/cmd.cpp b/client/cmd.cpp
new file mode 100644
index 0000000..99a4dd6
--- /dev/null
+++ b/client/cmd.cpp
@@ -0,0 +1,15 @@
+#include <cstdlib>
+#include <string.h>
+
+#include "cmd.h"
+#include "sock.h"
+
+void cmd_exit(char*) {
+ exit(EXIT_SUCCESS);
+}
+
+void cmd_test(char*) {
+ const char* data = "Hello world!";
+ i2c_send(0x39, (char*) data, strlen(data));
+}
+
diff --git a/client/cmd.h b/client/cmd.h
new file mode 100644
index 0000000..509104a
--- /dev/null
+++ b/client/cmd.h
@@ -0,0 +1,23 @@
+#pragma once
+
+#include <stddef.h>
+
+typedef void cmd_fn_t(char *);
+
+struct cmd {
+ const char* name;
+ void (* handle)(char *);
+ const char* info;
+ // TODO: tab completion function?
+};
+
+cmd_fn_t cmd_exit;
+cmd_fn_t cmd_test;
+
+static const struct cmd cmds[] = {
+ (struct cmd){ .name = "exit", .handle = cmd_exit, .info = NULL, },
+ (struct cmd){ .name = "test", .handle = cmd_test, .info = NULL, },
+};
+
+static const size_t cmds_length = sizeof(cmds) / sizeof(cmds[0]);
+
diff --git a/client/pbc b/client/pbc
new file mode 120000
index 0000000..51eda50
--- /dev/null
+++ b/client/pbc
@@ -0,0 +1 @@
+build/pbc \ No newline at end of file
diff --git a/client/readme.md b/client/readme.md
new file mode 100644
index 0000000..9d755aa
--- /dev/null
+++ b/client/readme.md
@@ -0,0 +1,14 @@
+# puzzle box client
+
+goal (in order of implementation):
+```
+(pbc) help
+ exit exit pbc
+ test send a test puzbus message
+ help show this help
+ send <addr> <data> [debug] send raw message
+ status show global puzzle box state (main controller state)
+ reset reset entire game state
+ ls list connected puzzle modules
+```
+
diff --git a/client/rl.cpp b/client/rl.cpp
index 32a4df0..b016370 100644
--- a/client/rl.cpp
+++ b/client/rl.cpp
@@ -7,7 +7,7 @@
#include <readline/history.h>
#include "rl.h"
-#include "sock.h"
+#include "cmd.h"
void rl_printf(const char *fmt, ...) {
// save line
@@ -36,9 +36,13 @@ void rl_printf(const char *fmt, ...) {
free(saved_line);
}
-void cmd_test() {
- const char* data = "Hello world!";
- i2c_send(0x39, (char*) data, strlen(data));
+static bool cli_cmd(char* line) {
+ for (size_t i = 0; i < cmds_length; i++) {
+ if (strcmp(line, cmds[i].name) != 0) continue;
+ cmds[i].handle(line);
+ return true;
+ }
+ return false;
}
int cli_main() {
@@ -47,18 +51,11 @@ int cli_main() {
if (input != NULL) free(input);
input = readline(CLI_PROMPT);
- // exit on ^D or ^C (EOF)
- if (input == NULL) return EXIT_SUCCESS;
+ if (input == NULL) return EXIT_SUCCESS; // exit on ^D (EOF)
+ if (*input == '\0') continue; // ignore empty lines
+ add_history(input);
- // add non-empty line to history
- if (*input) add_history(input);
-
- if (strcmp(input, "exit") == 0) return EXIT_SUCCESS;
-
- if (strcmp(input, "test") == 0) {
- cmd_test();
- continue;
- }
+ if (cli_cmd(input)) continue;
printf("unknown command!\n");
}