GCC Code Coverage Report


Directory: ./
File: src/util.c
Date: 2021-09-04 00:13:15
Exec Total Coverage
Lines: 67 68 98.5%
Branches: 47 52 90.4%

Line Branch Exec Source
1 /***************************************************************************/ /**
2
3 @file util.c
4
5 @author Stephen Brennan
6
7 @date Created Wednesday, 9 December 2015
8
9 @brief JSON manipulation utilities.
10
11 @copyright Copyright (c) 2015, Stephen Brennan. Released under the
12 Revised BSD License. See LICENSE.txt for details.
13
14 *******************************************************************************/
15
16 #include <stdio.h>
17 #include <stdlib.h>
18
19 #include "nosj.h"
20
21 22 size_t json_object_get(const char *json, const struct json_token *tokens,
22 size_t index, const char *key)
23 {
24
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 22 times.
22 if (tokens[index].type != JSON_OBJECT)
25 return 0;
26
27 22 index = tokens[index].child;
28
29
2/2
✓ Branch 0 taken 173 times.
✓ Branch 1 taken 2 times.
175 while (index != 0) {
30
2/2
✓ Branch 1 taken 20 times.
✓ Branch 2 taken 153 times.
173 if (json_string_match(json, tokens, index, key)) {
31 20 return tokens[index].child;
32 }
33 153 index = tokens[index].next;
34 }
35
36 2 return 0;
37 }
38
39 14 size_t json_array_get(const char *json, const struct json_token *tokens,
40 size_t index, size_t array_index)
41 {
42 (void)json;
43
44
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 11 times.
14 if (array_index >= tokens[index].length) {
45 3 return 0;
46 }
47
48 11 index = tokens[index].child;
49
2/2
✓ Branch 0 taken 24 times.
✓ Branch 1 taken 11 times.
35 while (array_index--) {
50 24 index = tokens[index].next;
51 }
52
53 11 return index;
54 }
55
56 17 double json_number_get(const char *json, const struct json_token *tokens,
57 size_t index)
58 {
59 double result;
60 17 sscanf(json + tokens[index].start, "%lf", &result);
61 17 return result;
62 }
63
64 /**
65 * Lookup key within the parsed json_token buffer. Note that in this case, "key"
66 * is not simply an object key. It can express a dotted notation for traversing
67 * JSON objects:
68 *
69 * keyname.nextkey[123].blah
70 */
71 10 size_t json_lookup(const char *json, const struct json_token *arr, size_t tok,
72 const char *key)
73 {
74 10 size_t start = 0, i = 0;
75 10 int state = 0;
76 long index;
77 10 char *keymut = strdup(key);
78 char c;
79
80 159 for (i = 0;; i++) {
81 159 c = keymut[i];
82
8/8
✓ Branch 0 taken 141 times.
✓ Branch 1 taken 18 times.
✓ Branch 2 taken 131 times.
✓ Branch 3 taken 10 times.
✓ Branch 4 taken 123 times.
✓ Branch 5 taken 8 times.
✓ Branch 6 taken 3 times.
✓ Branch 7 taken 120 times.
159 if (state == 0 && (c == '.' || c == '[' || c == '\0')) {
83
3/4
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 20 times.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
21 if (i == 0 && c == '[') {
84 /* Exception: allow the string to start with
85 * [indexing] */
86 1 state = 1;
87 1 start = 1;
88 1 continue;
89 }
90
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 19 times.
20 if (arr[tok].type != JSON_OBJECT) {
91 1 tok = 0;
92 1 goto out;
93 }
94 19 keymut[i] = '\0';
95 // printf("Get key \"%s\"\n", &keymut[start]);
96 19 tok = json_object_get(json, arr, tok, &keymut[start]);
97
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 18 times.
19 if (tok == 0) {
98 // printf("not found\n");
99 1 goto out;
100 }
101 18 start = i + 1;
102
2/2
✓ Branch 0 taken 7 times.
✓ Branch 1 taken 11 times.
18 if (c == '[')
103 7 state = 1;
104
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 10 times.
11 else if (c == '\0')
105 1 goto out;
106 // else if (c == '.') stay in state 0
107
2/2
✓ Branch 0 taken 18 times.
✓ Branch 1 taken 120 times.
138 } else if (state == 0) {
108 // do nothing
109
3/4
✓ Branch 0 taken 18 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 8 times.
✓ Branch 3 taken 10 times.
18 } else if (state == 1 && c == ']') {
110
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 7 times.
8 if (arr[tok].type != JSON_ARRAY) {
111 1 tok = 0;
112 1 goto out;
113 }
114 7 keymut[i] = '\0';
115 7 index = strtol(&keymut[start], NULL, 10);
116 // printf("Get ix %ld\n", index);
117 7 tok = json_array_get(json, arr, tok, (size_t)index);
118
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 6 times.
7 if (tok == 0) {
119 // printf("Not found\n");
120 1 goto out;
121 }
122 6 i += 1;
123 6 start = i + 1;
124
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 5 times.
6 if (keymut[i] == '.') {
125 1 state = 0;
126
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 4 times.
5 } else if (keymut[i] == '[') {
127 1 state = 1;
128
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 1 times.
4 } else if (keymut[i] == '\0') {
129 3 goto out;
130 } else {
131 1 tok = 0;
132 1 goto out;
133 }
134
4/6
✓ Branch 0 taken 10 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 10 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
✓ Branch 5 taken 9 times.
10 } else if (state == 1 && (c < '0' || c > '9')) {
135 // bad character
136 1 tok = 0;
137 1 goto out;
138 }
139 }
140
141 10 out:
142 10 free(keymut);
143 10 return tok;
144 }
145