summaryrefslogtreecommitdiff
path: root/src/uci/command.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/uci/command.c')
-rw-r--r--src/uci/command.c125
1 files changed, 125 insertions, 0 deletions
diff --git a/src/uci/command.c b/src/uci/command.c
new file mode 100644
index 0000000..d82c50c
--- /dev/null
+++ b/src/uci/command.c
@@ -0,0 +1,125 @@
+#include <assert.h>
+#include <stdlib.h>
+#include <string.h>
+#include "command.h"
+
+ucicmd ucicmd_init() {
+ ucicmd output = {0};
+
+ output.empty = true;
+ output.args_capacity = 32;
+ output.args = calloc(sizeof(char) * MAX_TOKEN_SIZE, output.args_capacity);
+
+ return output;
+}
+
+bool is_valid_cmd(const char *token) {
+ return
+ (strcmp(token, "uci") == 0) ||
+ (strcmp(token, "debug") == 0) ||
+ (strcmp(token, "isready") == 0) ||
+ (strcmp(token, "setoption") == 0) ||
+ (strcmp(token, "register") == 0) ||
+ (strcmp(token, "ucinewgame") == 0) ||
+ (strcmp(token, "position") == 0) ||
+ (strcmp(token, "go") == 0) ||
+ (strcmp(token, "stop") == 0) ||
+ (strcmp(token, "ponderhit") == 0) ||
+ (strcmp(token, "quit") == 0) ||
+
+ (strcmp(token, "id") == 0) ||
+ (strcmp(token, "uciok") == 0) ||
+ (strcmp(token, "readyok") == 0) ||
+ (strcmp(token, "bestmove") == 0) ||
+ (strcmp(token, "copyprotection") == 0) ||
+ (strcmp(token, "registration") == 0) ||
+ (strcmp(token, "info") == 0) ||
+ (strcmp(token, "option") == 0);
+}
+
+void ucicmd_add(ucicmd* cmd, const char* token) {
+ if (!cmd->empty) {
+ ucicmd_append_arg(cmd, token);
+ return;
+ }
+ if (is_valid_cmd(token) == 0) return;
+ ucicmd_set_root(cmd, token);
+}
+
+void ucicmd_set_root(ucicmd* cmd, const char* token) {
+ cmd->empty = false;
+ int i = 0;
+ for (; token[i] != 0; i++) {
+ assert(i < MAX_TOKEN_SIZE);
+ cmd->root[i] = token[i];
+ }
+ if (i < MAX_TOKEN_SIZE) cmd->root[i] = 0;
+}
+
+void ucicmd_append_arg(ucicmd* cmd, const char* token) {
+ if (cmd->args_count + 1 > cmd->args_capacity) {
+ cmd->args_capacity += 32;
+ // does realloc set all zeros, like calloc???
+ // NO: https://stackoverflow.com/questions/61237721/does-a-realloc-after-a-calloc-zero-out-bytes
+ cmd->args = realloc(
+ cmd->args,
+ sizeof(char) * MAX_TOKEN_SIZE * cmd->args_capacity
+ );
+ memset(
+ ucicmd_get_arg(*cmd, cmd->args_capacity - 32),
+ 0,
+ 32 * MAX_TOKEN_SIZE
+ );
+ }
+
+ int shift = cmd->args_count++ * sizeof(char) * MAX_TOKEN_SIZE;
+ int i = 0;
+ for (; token[i] != 0; i++) {
+ assert(i < MAX_TOKEN_SIZE);
+ cmd->args[shift + i] = token[i];
+ }
+ if (i < MAX_TOKEN_SIZE) cmd->args[shift + i] = 0;
+}
+
+char* ucicmd_get_arg(ucicmd cmd, int i) {
+ return cmd.args + i * MAX_TOKEN_SIZE;
+}
+
+void ucicmd_deinit(ucicmd cmd) {
+ free(cmd.args);
+}
+
+
+#ifdef TEST_MOD
+#include <stdbool.h>
+#include <string.h>
+
+bool test_ucicmd() {
+ ucicmd cmd = ucicmd_init();
+ ucicmd_set_root(&cmd, "root");
+ ucicmd_append_arg(&cmd, "arg1");
+ ucicmd_append_arg(&cmd, "arg2");
+ ucicmd_append_arg(&cmd, "arg3");
+
+ if (strncmp(cmd.root, "root", MAX_TOKEN_SIZE) != 0) return false;
+ if (strncmp(ucicmd_get_arg(cmd, 0), "arg1", MAX_TOKEN_SIZE) != 0)
+ return false;
+ if (strncmp(ucicmd_get_arg(cmd, 1), "arg2", MAX_TOKEN_SIZE) != 0)
+ return false;
+ if (strncmp(ucicmd_get_arg(cmd, 2), "arg3", MAX_TOKEN_SIZE) != 0)
+ return false;
+ return true;
+}
+
+bool test_invalid_cmd_ucicmd() {
+ ucicmd cmd = ucicmd_init();
+ ucicmd_add(&cmd, "john");
+ ucicmd_add(&cmd, "debug");
+ ucicmd_add(&cmd, "on");
+
+ if (strncmp(cmd.root, "debug", MAX_TOKEN_SIZE) != 0) return false;
+ if (strncmp(ucicmd_get_arg(cmd, 0), "on", MAX_TOKEN_SIZE) != 0)
+ return false;
+ return true;
+}
+#endif