1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
|
#include <assert.h>
#include <string.h>
#include <stdlib.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
|