#include #include #include "cJSON/cJSON.h" #include "json_rpc.h" #include "log.h" #include "pawn_lsp.h" #define PAWN_LSP_VESRION "v0.0.1" #define PAWN_LSP_NAME "pawn_lsp" static int _request_handler(json_rpc_request_t *req, cJSON **resp, void *arg); static void _notify_handler(json_rpc_request_t *req, void *arg); static int _initialize(json_rpc_request_t *req, cJSON **resp, void *arg); static int _shutdown(json_rpc_request_t *req, cJSON **resp, void *arg); static void _exit_notf(json_rpc_request_t *req, void *arg); int pawn_lsp_init(pawn_lsp_t *pawn, json_rpc_t *jrpc, const char *pawncc, char **pawn_args, int pawn_argc) { pawn->jrpc = jrpc; pawn->pawncc = strdup(pawncc); /* execv(pawncc -d0 -v=2 -o/tmp/... [...args] )*/ pawn->pawn_args = calloc(pawn_argc + 5, sizeof(char *)); /* pawn->pawn_args[0] = , set when compiling */ pawn->pawn_args[1] = strdup("-d0"); pawn->pawn_args[2] = strdup("-v=2"); /* pawn->pawn_args[3] = -o/tmp/..., set when compiling */ for (int i = 0; i < pawn_argc; i++) { pawn->pawn_args[i + 4] = strdup(pawn_args[i]); } json_rpc_set_request_handler(jrpc, _request_handler, &pawn); json_rpc_set_notify_handler(jrpc, _notify_handler, &pawn); return (0); } void pawn_lsp_deinit(pawn_lsp_t *pawn) { free(pawn->pawncc); for (int i = 0; pawn->pawn_args[i] != NULL; i++) { free(pawn->pawn_args[i]); } free(pawn->pawn_args); } static int _request_handler(json_rpc_request_t *req, cJSON **resp, void *arg) { char *method = req->method->valuestring; log_info("Handle request \"%s\"\r\n", method); if (!strcmp(method, "initialize")) { return _initialize(req, resp, arg); } else if (!strcmp(method, "shutdown")) { return _shutdown(req, resp, arg); } else { log_warn("Unrecognized request method\r\n"); (*resp) = cJSON_CreateNull(); return (-1); } } static void _notify_handler(json_rpc_request_t *req, void *arg) { char *method = req->method->valuestring; log_info("Handle notification \"%s\"\r\n", method); if (!strcmp(method, "exit")) { _exit_notf(req, arg); } else { log_warn("Unrecognized notification method\r\n"); } } int _initialize(json_rpc_request_t *req, cJSON **resp, void *arg) { cJSON *val; (*resp) = cJSON_CreateObject(); val = cJSON_AddObjectToObject((*resp), "capabilities"); if (val == NULL) { return (-1); } if (cJSON_AddStringToObject(val, "positionEncoding", "utf-8") == NULL) { return (-1); } val = cJSON_AddObjectToObject((*resp), "serverInfo"); if (val == NULL) { return (-1); } if ((cJSON_AddStringToObject(val, "name", PAWN_LSP_NAME) == NULL) || (cJSON_AddStringToObject(val, "version", PAWN_LSP_VESRION) == NULL)) { return (-1); } return (0); } static int _shutdown(json_rpc_request_t *req, cJSON **resp, void *arg) { (*resp) = cJSON_CreateNull(); return (0); } static void _exit_notf(json_rpc_request_t *req, void *arg) { pawn_lsp_t *pawn = arg; json_rpc_cancel(pawn->jrpc); }