simple-gtp.c
Raw
1#include <simple-go/simple-gtp.h>
2#include <simple-go/simple-gtp-func.h>
3
4typedef struct msg_formatted
5{
6 char* command;
7 Vector* arguments;
8 char* id;
9} msg_formatted;
10
11
12static msg_formatted format_msg(const char* msg)
13{
14 msg_formatted formatted = {0};
15
16 size_t index = 0;
17
18 while(isdigit(msg[index]) || msg[index] == '-')
19 index++;
20
21 if(index)
22 {
23 formatted.id = malloc(index+1);
24 strncpy(formatted.id, msg, index);
25 formatted.id[index] = '\0';
26 }
27
28 formatted.command = malloc(strlen(msg+index) + 1);
29 sscanf(msg+index, "%s", formatted.command);
30
31 formatted.arguments = new_vector();
32
33 char* tmp_msg = malloc(strlen(msg+index)+1);
34 strcpy(tmp_msg, msg+index);
35
36
37 char* current = strtok(tmp_msg, " ");
38 char* tmp_arg;
39
40 while(current)
41 {
42 tmp_arg = malloc(strlen(current)+1);
43 strcpy(tmp_arg, current);
44 vector_push(formatted.arguments, tmp_arg);
45 current = strtok(NULL, " ");
46 }
47
48 if(formatted.arguments->length > 1)
49 vector_remove(formatted.arguments, 0, free);
50
51 free(tmp_msg);
52
53 return formatted;
54}
55
56static char* sanitize(const char* msg)
57{
58 char* ret = calloc(strlen(msg)+1, 1);
59
60 for(size_t i = 0, reti = 0; i < strlen(msg); i++)
61 {
62 if(msg[i] == '\t')
63 {
64 ret[reti++] = ' ';
65 } else if(iscntrl(msg[i])){
66 ++reti;
67 } else if(msg[i] == '#'){
68 break;
69 } else {
70 ret[reti++] = msg[i];
71 }
72 }
73
74 return ret;
75}
76
77char* handle_gtp_cmd(const char* msg, game_state* game)
78{
79 if(!msg || !strlen(msg))
80 {
81 char* ret = calloc(1,1);
82 return ret;
83 }
84 char* msg_san = sanitize(msg);
85
86 msg_formatted formatted = format_msg(msg_san);
87 char* command = formatted.command;
88 Vector* arguments = formatted.arguments;
89 char* id = formatted.id;
90
91 char* ret;
92 char* (*func_ptr)(const Vector*, const char*, game_state*) = unkown_command_func;
93
94 if(strcmp(command, "protocol_version") == 0)
95 {
96 func_ptr = protocol_version_func;
97 } else if(strcmp(command, "name") == 0) {
98 func_ptr = name_func;
99 } else if(strcmp(command, "version") == 0) {
100 func_ptr = version_func;
101 } else if(strcmp(command, "known_command") == 0) {
102 func_ptr = known_command_func;
103 } else if(strcmp(command, "list_commands") == 0) {
104 func_ptr = list_commands_func;
105 } else if(strcmp(command, "boardsize") == 0) {
106 func_ptr = boardsize_func;
107 } else if(strcmp(command, "komi") == 0) {
108 func_ptr = komi_func;
109 } else if(strcmp(command, "clear_board") == 0) {
110 func_ptr = clear_board_func;
111 } else if(strcmp(command, "play") == 0) {
112 func_ptr = play_func;
113 } else if(strcmp(command, "genmove") == 0) {
114 func_ptr = genmove_func;
115 } else if(strcmp(command, "showboard") == 0) {
116 func_ptr = show_board_func;
117 } else if(strcmp(command, "final_score") == 0) {
118 func_ptr = final_score_func;
119 }
120
121 ret = func_ptr(arguments, id, game);
122
123 free(command);
124 free(msg_san);
125 free(id);
126 delete_vector(arguments, free);
127
128 return ret;
129}
130