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
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
|
#include <assert.h>
#include <string.h>
#include <stdlib.h>
#include "uci/internals/command.h"
uci_cmd_t uci_cmd_init() {
uci_cmd_t 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 uci_cmd_add(uci_cmd_t* cmd, const char* token) {
if (!cmd->empty) {
uci_cmd_append_arg(cmd, token);
return;
}
if (is_valid_cmd(token) == 0) return;
uci_cmd_set_root(cmd, token);
}
void uci_cmd_set_root(uci_cmd_t* 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 uci_cmd_append_arg(uci_cmd_t* 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(
uci_cmd_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* uci_cmd_get_arg(uci_cmd_t cmd, int i) {
return cmd.args + i * MAX_TOKEN_SIZE;
}
void uci_cmd_deinit(uci_cmd_t cmd) {
free(cmd.args);
}
#ifdef TEST_MOD
#include <stdbool.h>
#include <string.h>
bool test_uci_cmd_t() {
uci_cmd_t cmd = uci_cmd_init();
uci_cmd_set_root(&cmd, "root");
uci_cmd_append_arg(&cmd, "arg1");
uci_cmd_append_arg(&cmd, "arg2");
uci_cmd_append_arg(&cmd, "arg3");
if (strncmp(cmd.root, "root", MAX_TOKEN_SIZE) != 0) {
uci_cmd_deinit(cmd);
return false;
}
if (strncmp(uci_cmd_get_arg(cmd, 0), "arg1", MAX_TOKEN_SIZE) != 0) {
uci_cmd_deinit(cmd);
return false;
}
if (strncmp(uci_cmd_get_arg(cmd, 1), "arg2", MAX_TOKEN_SIZE) != 0) {
uci_cmd_deinit(cmd);
return false;
}
if (strncmp(uci_cmd_get_arg(cmd, 2), "arg3", MAX_TOKEN_SIZE) != 0) {
uci_cmd_deinit(cmd);
return false;
}
uci_cmd_deinit(cmd);
return true;
}
bool test_invalid_cmd_uci_cmd_t() {
uci_cmd_t cmd = uci_cmd_init();
uci_cmd_add(&cmd, "john");
uci_cmd_add(&cmd, "debug");
uci_cmd_add(&cmd, "on");
if (strncmp(cmd.root, "debug", MAX_TOKEN_SIZE) != 0) {
uci_cmd_deinit(cmd);
return false;
}
if (strncmp(uci_cmd_get_arg(cmd, 0), "on", MAX_TOKEN_SIZE) != 0) {
uci_cmd_deinit(cmd);
return false;
}
uci_cmd_deinit(cmd);
return true;
}
#endif
|