aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--client/cmd.cpp14
-rw-r--r--client/cmd.h33
-rw-r--r--client/parse.cpp9
-rw-r--r--client/pbc.10
-rw-r--r--client/rl.cpp25
-rw-r--r--client/rl.h2
6 files changed, 62 insertions, 21 deletions
diff --git a/client/cmd.cpp b/client/cmd.cpp
index ab101e9..2871daf 100644
--- a/client/cmd.cpp
+++ b/client/cmd.cpp
@@ -1,9 +1,11 @@
#include <cstdio>
#include <cstdlib>
+#include <readline/readline.h>
#include <string.h>
#include "cmd.h"
#include "i2ctcpv1.h"
+#include "rl.h"
#include "sock.h"
#include "parse.h"
@@ -35,7 +37,8 @@ void cmd_help(char*) {
printf(
"\n"
- "You can also use the TAB key to autocomplete commands\n"
+ "See man pbc(1) for more info about specific commands\n"
+ "Hint: you can use the TAB key to autocomplete commands\n"
);
}
@@ -83,6 +86,15 @@ void cmd_reset(char*) {
i2c_send(BUSADDR_MAIN, msg, sizeof(msg));
}
+void cmd_skip(char*) {
+ const char msg[] = {
+ PB_CMD_WRITE,
+ 0x00,
+ PB_GS_SOLVED,
+ };
+ i2c_send(BUSADDR_MAIN, msg, sizeof(msg));
+}
+
void cmd_ls(char*) {
return;
const char msg[] = {
diff --git a/client/cmd.h b/client/cmd.h
index 932f3a2..9c58fb6 100644
--- a/client/cmd.h
+++ b/client/cmd.h
@@ -2,24 +2,28 @@
#include <stddef.h>
-typedef void cmd_fn_t(char *);
+typedef void cmd_handle_t(char *);
+typedef char** cmd_complete_t(const char*, int, int);
struct cmd {
- void (* handle)(char *);
+ cmd_handle_t * handle;
const char* name;
const char* info;
- // TODO: tab completion function?
+ cmd_complete_t * complete;
};
+typedef struct cmd cmd_t;
-cmd_fn_t cmd_exit;
-cmd_fn_t cmd_test;
-cmd_fn_t cmd_help;
-cmd_fn_t cmd_status;
-cmd_fn_t cmd_reset;
-cmd_fn_t cmd_ls;
-cmd_fn_t cmd_send;
+cmd_handle_t cmd_exit;
+cmd_handle_t cmd_test;
+cmd_handle_t cmd_help;
+cmd_complete_t cmd_help_complete;
+cmd_handle_t cmd_status;
+cmd_handle_t cmd_reset;
+cmd_handle_t cmd_ls;
+cmd_handle_t cmd_send;
+cmd_handle_t cmd_skip;
-static const struct cmd cmds[] = {
+static const cmd_t cmds[] = {
{
.handle = cmd_exit,
.name = "exit",
@@ -43,7 +47,12 @@ static const struct cmd cmds[] = {
{
.handle = cmd_reset,
.name = "reset",
- .info = "reset entire game state",
+ .info = "set game state to 'idle' for one or more puzzle modules",
+ },
+ {
+ .handle = cmd_skip,
+ .name = "skip",
+ .info = "set game state to 'solved' for one or more puzzle modules",
},
{
.handle = cmd_ls,
diff --git a/client/parse.cpp b/client/parse.cpp
index f31e802..56d1137 100644
--- a/client/parse.cpp
+++ b/client/parse.cpp
@@ -38,8 +38,7 @@ static int parse_string(const char * str, char * data, size_t * offset) {
}
static int parse_hexstr(const char * str, char * data, size_t * offset) {
- const char* ifs = IFS;
- size_t len = strcspn(str, ifs);
+ size_t len = strcspn(str, IFS);
int i = 0;
// check if token contains at least one colon
@@ -74,8 +73,7 @@ static int parse_hexstr(const char * str, char * data, size_t * offset) {
}
static int parse_number(const char * str, char * data, size_t * offset) {
- const char* ifs = IFS;
- size_t len = strcspn(str, ifs);
+ size_t len = strcspn(str, IFS);
int i = 0;
int base = 10;
bool bytestring = false;
@@ -142,12 +140,11 @@ static int parse_number(const char * str, char * data, size_t * offset) {
}
static int _strtodata_main(const char * str, char* data, size_t * offset) {
- const char* ifs = IFS;
size_t len = strlen(str);
int i, run;
for (i = 0; i < len; i += run) {
- i += strspn(&str[i], ifs); // skip whitespace
+ i += strspn(&str[i], IFS); // skip whitespace
if (str[i] == '\0') break; // end of string
if ((run = parse_string(str + i, data, offset)) > 0) continue;
diff --git a/client/pbc.1 b/client/pbc.1
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/client/pbc.1
diff --git a/client/rl.cpp b/client/rl.cpp
index 3f93e99..2fdd356 100644
--- a/client/rl.cpp
+++ b/client/rl.cpp
@@ -38,6 +38,7 @@ void rl_printf(const char *fmt, ...) {
}
static void cli_cmd(char* cmd) {
+ cmd += strspn(cmd, IFS); // skip leading whitespace
char* line = consume_token(cmd, IFS);
for (size_t i = 0; i < cmds_length; i++) {
@@ -66,9 +67,31 @@ static char* rl_completion_entries(const char *text, int state) {
return NULL;
}
+static char** rl_attempted_completion(const char * text, int start, int end) {
+ // do not suggest filenames
+ rl_attempted_completion_over = 1;
+
+ // if first word in line buffer -> complete commands from cmds[]
+ size_t cmd_start = strspn(rl_line_buffer, IFS);
+ if (start == cmd_start)
+ return rl_completion_matches(text, rl_completion_entries);
+
+ // else, check specialized completion functions
+ size_t cmd_len = strcspn(rl_line_buffer + cmd_start, IFS);
+ for (size_t i = 0; i < cmds_length; i++) {
+ cmd_t cmd = cmds[i];
+ if (cmd.complete == NULL) continue;
+ if (strncmp(cmd.name, rl_line_buffer + cmd_start, cmd_len) != 0) continue;
+ return cmd.complete(rl_line_buffer, start, end);
+ }
+
+ // else, no completion available
+ return NULL;
+}
+
int cli_main() {
char* input = NULL;
- rl_completion_entry_function = rl_completion_entries;
+ rl_attempted_completion_function = rl_attempted_completion;
while (1) {
if (input != NULL) free(input);
diff --git a/client/rl.h b/client/rl.h
index 503225f..5e80d1a 100644
--- a/client/rl.h
+++ b/client/rl.h
@@ -6,5 +6,5 @@
#define CLI_PROMPT "(" COLOR_BOLD "pbc" COLOR_OFF ") "
int cli_main();
-void rl_printf(const char *fmt, ...);
+void rl_printf(const char * fmt, ...);