• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

thoni56 / c-xrefactory / 1712

19 Jan 2026 10:56AM UTC coverage: 81.304% (-3.6%) from 84.87%
1712

push

travis-ci

thoni56
[tests] Fix include path for test_c-xref now we have 3pp'd cJSON

14490 of 17822 relevant lines covered (81.3%)

16115974.21 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

90.91
src/json_utils.c
1
#include "json_utils.h"
2

3
#include <string.h>
4

5

6
/* ====================== LSP =================================== */
7

8
double id_of_request(JSON *request) {
15✔
9
    return cJSON_GetObjectItem(request, "id")->valuedouble;
15✔
10
}
11

12
const char *get_lsp_uri_string_from_request(JSON *request) {
1✔
13
    cJSON *response_uri_item = cJSON_GetObjectItem(
1✔
14
        cJSON_GetObjectItem(cJSON_GetObjectItem(request, "params"), "textDocument"), "uri");
1✔
15
    return response_uri_item->valuestring;
1✔
16
}
17

18
JSON *create_lsp_message_with_id(double id) {
17✔
19
    cJSON *response = cJSON_CreateObject();
17✔
20
    cJSON_AddStringToObject(response, "jsonrpc", "2.0");
17✔
21
    cJSON_AddNumberToObject(response, "id", id);
17✔
22
    return response;
17✔
23
}
24

25
JSON *create_lsp_response(double id, JSON *result) {
3✔
26
    cJSON *response = create_lsp_message_with_id(id);
3✔
27
    cJSON_AddItemToObject(response, "result", result);
3✔
28
    return response;
3✔
29
}
30

31
JSON *add_lsp_action(JSON *target, const char *title, const char *kind) {
2✔
32
    cJSON *action = cJSON_CreateObject();
2✔
33
    cJSON_AddItemToArray(target, action);
2✔
34
    cJSON_AddStringToObject(action, "title", title);
2✔
35
    cJSON_AddStringToObject(action, "kind", kind);
2✔
36
    return action;
2✔
37
}
38

39
JSON *add_lsp_range(JSON *target, int start_line, int start_character,
4✔
40
                    int end_line, int end_character) {
41
    cJSON *range = cJSON_CreateObject();
4✔
42
    cJSON *start = cJSON_CreateObject();
4✔
43
    cJSON_AddNumberToObject(start, "line", start_line);
4✔
44
    cJSON_AddNumberToObject(start, "character", start_character);
4✔
45
    cJSON_AddItemToObject(range, "start", start);
4✔
46
    cJSON *end = cJSON_CreateObject();
4✔
47
    cJSON_AddNumberToObject(end, "line", end_line);
4✔
48
    cJSON_AddNumberToObject(end, "character", end_character);
4✔
49
    cJSON_AddItemToObject(range, "end", end);
4✔
50
    cJSON_AddItemToObject(target, "range", range);
4✔
51
    return range;
4✔
52
}
53

54
JSON *add_lsp_new_text(JSON *target, const char *new_text) {
1✔
55
    return cJSON_AddStringToObject(target, "newText", new_text);
1✔
56
}
57

58
void get_lsp_range_positions(JSON *json, int *start_line, int *start_character, int *end_line, int *end_character) {
1✔
59
    JSON *range = cJSON_GetObjectItem(json, "range");
1✔
60
    JSON *start = cJSON_GetObjectItem(range, "start");
1✔
61
    JSON *end   = cJSON_GetObjectItem(range, "end");
1✔
62

63
    *start_line = cJSON_GetObjectItem(start, "line")->valueint;
1✔
64
    *start_character = cJSON_GetObjectItem(start, "character")->valueint;
1✔
65
    *end_line   = cJSON_GetObjectItem(end, "line")->valueint;
1✔
66
    *end_character   = cJSON_GetObjectItem(end, "character")->valueint;
1✔
67
}
1✔
68

69

70
/* ======================= JSON ================================== */
71

72
JSON *add_json_array_as(JSON *target, const char *name) {
2✔
73
    cJSON *array = cJSON_CreateArray();
2✔
74
    cJSON_AddItemToObject(target, name, array);
2✔
75
    return array;
2✔
76
}
77

78
JSON *add_json_object_to_array(JSON *target) {
1✔
79
    cJSON *object = cJSON_CreateObject();
1✔
80
    cJSON_AddItemToArray(target, object);
1✔
81
    return object;
1✔
82
}
83

84
JSON *add_json_item(JSON *target, const char *name) {
17✔
85
    cJSON *item = cJSON_CreateObject();
17✔
86
    cJSON_AddItemToObject(target, name, item);
17✔
87
    return item;
17✔
88
}
89

90
JSON *add_json_string(JSON *target, const char *name, const char *value) {
7✔
91
    return cJSON_AddStringToObject(target, name, value);
7✔
92
}
93

94
JSON *add_json_bool(JSON *target, const char *name, bool value) {
6✔
95
    return cJSON_AddBoolToObject(target, name, value);
6✔
96
}
97

98
JSON *get_json_item(JSON *tree, const char *name) {
61✔
99
    return cJSON_GetObjectItem(tree, name);
61✔
100
}
101

102
char *get_json_string_item(JSON *textDocument, const char *name) {
40✔
103
    return cJSON_GetStringValue(get_json_item(textDocument, name));
40✔
104
}
105

106

107
/* =======================  UTILS  ============================== */
108

109
bool json_equals(const JSON *a, const JSON *b) {
39✔
110
    // Check for nulls or type mismatch
111
    if (a == NULL || b == NULL || a->type != b->type) {
39✔
112
        return false;
×
113
    }
114

115
    switch (a->type) {
39✔
116
        case cJSON_False:
×
117
        case cJSON_True:
118
            return true;  // Booleans are equal if they have the same type
×
119

120
        case cJSON_NULL:
×
121
            return true;  // NULLs are always equal
×
122

123
        case cJSON_Number:
11✔
124
            return a->valuedouble == b->valuedouble;
11✔
125

126
        case cJSON_String:
9✔
127
            return strcmp(a->valuestring, b->valuestring) == 0;
9✔
128

129
        case cJSON_Array: {
2✔
130
            const cJSON *a_item = a->child;
2✔
131
            const cJSON *b_item = b->child;
2✔
132
            while (a_item && b_item) {
5✔
133
                if (!json_equals(a_item, b_item)) {
3✔
134
                    return false;
×
135
                }
136
                a_item = a_item->next;
3✔
137
                b_item = b_item->next;
3✔
138
            }
139
            return a_item == NULL && b_item == NULL;  // Ensure arrays have the same length
140
        }
141

17✔
142
        case cJSON_Object: {
17✔
143
            const cJSON *a_item = NULL;
33✔
144
            cJSON_ArrayForEach(a_item, a) {
33✔
145
                const cJSON *b_item = cJSON_GetObjectItemCaseSensitive(b, a_item->string);
×
146
                if (!b_item || !json_equals(a_item, b_item)) {
147
                    return false;
148
                }
17✔
149
            }
150
            return true;
151
        }
×
152

×
153
        default:
154
            return false;  // Unsupported type
155
    }
156
}
36✔
157

36✔
158
JSON *parse_json(const char *string) {
159
    return cJSON_Parse(string);
160
}
18✔
161

18✔
162
char *print_json(JSON *tree) {
163
    return cJSON_PrintUnformatted(tree);
164
}
44✔
165

44✔
166
void delete_json(JSON *tree) {
44✔
167
    cJSON_Delete(tree);
168
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc