#include #include typedef struct msg_formatted { char* command; Vector arguments; char* id; } msg_formatted; static msg_formatted format_msg(const char* msg) { msg_formatted formatted = {0}; size_t index = 0; while(isdigit(msg[index]) || msg[index] == '-') index++; if(index) { formatted.id = malloc_die(index+1); strncpy(formatted.id, msg, index); formatted.id[index] = '\0'; } formatted.command = malloc_die(strlen(msg+index) + 1); sscanf(msg+index, "%s", formatted.command); if(!new_vector_adv(&formatted.arguments, VECTOR_DEFAULT_SIZE, free)) { perror("malloc"); exit(EXIT_FAILURE); } char* tmp_msg = malloc_die(strlen(msg+index)+1); strcpy(tmp_msg, msg+index); char* current = strtok(tmp_msg, " "); char* tmp_arg; while(current) { tmp_arg = malloc_die(strlen(current)+1); strcpy(tmp_arg, current); vector_push(&formatted.arguments, tmp_arg); current = strtok(NULL, " "); } if(formatted.arguments.length > 1) vector_remove(&formatted.arguments, 0); free(tmp_msg); return formatted; } static char* sanitize(const char* msg) { char* ret = calloc(strlen(msg)+1, 1); for(size_t i = 0, reti = 0; i < strlen(msg); i++) { if(msg[i] == '\t') { ret[reti++] = ' '; } else if(iscntrl(msg[i])){ ++reti; } else if(msg[i] == '#'){ break; } else { ret[reti++] = msg[i]; } } return ret; } char* handle_gtp_cmd(const char* msg, game_state* game) { if(!msg || !strlen(msg)) { char* ret = calloc(1,1); return ret; } char* msg_san = sanitize(msg); msg_formatted formatted = format_msg(msg_san); char* command = formatted.command; Vector arguments = formatted.arguments; char* id = formatted.id; char* ret; char* (*func_ptr)(const Vector*, const char*, game_state*) = unkown_command_func; if(strcmp(command, "protocol_version") == 0) { func_ptr = protocol_version_func; } else if(strcmp(command, "name") == 0) { func_ptr = name_func; } else if(strcmp(command, "version") == 0) { func_ptr = version_func; } else if(strcmp(command, "known_command") == 0) { func_ptr = known_command_func; } else if(strcmp(command, "list_commands") == 0) { func_ptr = list_commands_func; } else if(strcmp(command, "boardsize") == 0) { func_ptr = boardsize_func; } else if(strcmp(command, "komi") == 0) { func_ptr = komi_func; } else if(strcmp(command, "clear_board") == 0) { func_ptr = clear_board_func; } else if(strcmp(command, "play") == 0) { func_ptr = play_func; } else if(strcmp(command, "genmove") == 0) { func_ptr = genmove_func; } else if(strcmp(command, "showboard") == 0) { func_ptr = show_board_func; } else if(strcmp(command, "final_score") == 0) { func_ptr = final_score_func; } ret = func_ptr(&arguments, id, game); free(command); free(msg_san); free(id); delete_vector(&arguments); return ret; }