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
|
typedef struct {
Process process;
} LSP;
typedef struct {
u32 pos;
u32 len;
} JSONString;
typedef struct JSONValue JSONValue;
typedef struct {
u32 len;
u32 properties;
u32 values;
} JSONObject;
typedef struct {
u32 len;
u32 values;
} JSONArray;
enum {
JSON_NULL,
JSON_FALSE,
JSON_TRUE,
JSON_NUMBER,
JSON_STRING,
JSON_OBJECT,
JSON_ARRAY
};
struct JSONValue {
u8 type;
union {
double number;
JSONString string;
JSONArray array;
JSONObject object;
} val;
};
typedef struct {
const char *text;
// root = values[0]
JSONValue *values;
} JSON;
static bool json_parse_value(JSON *json, u32 *p_index, JSONValue *val) {
const char *text = json->text;
u32 index = *p_index;
while (isspace(text[index])) ++index;
switch (text[index]) {
case '{':
val->type = JSON_OBJECT;
json_parse_object(json, &index, &val->val.object);
break;
case '[':
val->type = JSON_ARRAY;
json_parse_array(json, &index, &val->val.array);
break;
case '"':
val->type = JSON_STRING;
json_parse_string(json, &index, &val->val.string);
break;
case ANY_DIGIT:
json_parse_number(json, &index, &val->val.number);
break;
case 'f':
if (!str_is_prefix(&text[index], "false", 5) != 0) {
}
}
}
// NOTE: text must live as long as json!!!
static bool json_parse(JSON *json, const char *text) {
memset(json, 0, sizeof *json);
json->text = text;
// @TODO: is this a good capacity?
arr_reserve(json->values, strlen(text) / 8);
arr_addp(json->values); // add root
JSONValue val = {0};
u32 index = 0;
if (!json_parse_value(json, &index, &val))
return false;
while (isspace(text[index])) ++index;
if (text[index]) {
// more text after end of object
// @TODO error message
return false;
}
json->values[0] = val;
}
static void send_message(LSP *lsp, const char *content) {
char header[128];
size_t content_size = strlen(content);
strbuf_printf(header, "Content-Length: %zu\r\n\r\n", content_size);
process_write(&lsp->process, header, strlen(header));
process_write(&lsp->process, content, content_size);
}
void lsp_create(LSP *lsp, const char *analyzer_command) {
ProcessSettings settings = {
.stdin_blocking = true,
.stdout_blocking = true
};
process_run_ex(&lsp->process, analyzer_command, &settings);
char init_request[1024];
strbuf_printf(init_request,
"{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"initialize\",\"params\":{"
"\"processId\":%d,"
"\"capabilities\":{}"
"}}",
process_get_id());
send_message(lsp, init_request);
char init_response[4096] = {0};
process_read(&lsp->process, init_response, sizeof init_response);
printf("%s\n",init_response);
}
|