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