prometheus-client-mmap 0.20.3-arm64-darwin

Sign up to get free protection for your applications and to get access to all the features.
Files changed (92) hide show
  1. checksums.yaml +7 -0
  2. data/README.md +253 -0
  3. data/ext/fast_mmaped_file/extconf.rb +30 -0
  4. data/ext/fast_mmaped_file/fast_mmaped_file.c +122 -0
  5. data/ext/fast_mmaped_file/file_format.c +5 -0
  6. data/ext/fast_mmaped_file/file_format.h +11 -0
  7. data/ext/fast_mmaped_file/file_parsing.c +195 -0
  8. data/ext/fast_mmaped_file/file_parsing.h +27 -0
  9. data/ext/fast_mmaped_file/file_reading.c +102 -0
  10. data/ext/fast_mmaped_file/file_reading.h +30 -0
  11. data/ext/fast_mmaped_file/globals.h +14 -0
  12. data/ext/fast_mmaped_file/mmap.c +427 -0
  13. data/ext/fast_mmaped_file/mmap.h +61 -0
  14. data/ext/fast_mmaped_file/rendering.c +199 -0
  15. data/ext/fast_mmaped_file/rendering.h +8 -0
  16. data/ext/fast_mmaped_file/utils.c +56 -0
  17. data/ext/fast_mmaped_file/utils.h +22 -0
  18. data/ext/fast_mmaped_file/value_access.c +242 -0
  19. data/ext/fast_mmaped_file/value_access.h +15 -0
  20. data/ext/fast_mmaped_file_rs/.cargo/config.toml +23 -0
  21. data/ext/fast_mmaped_file_rs/Cargo.lock +790 -0
  22. data/ext/fast_mmaped_file_rs/Cargo.toml +30 -0
  23. data/ext/fast_mmaped_file_rs/README.md +52 -0
  24. data/ext/fast_mmaped_file_rs/extconf.rb +30 -0
  25. data/ext/fast_mmaped_file_rs/src/error.rs +174 -0
  26. data/ext/fast_mmaped_file_rs/src/file_entry.rs +579 -0
  27. data/ext/fast_mmaped_file_rs/src/file_info.rs +190 -0
  28. data/ext/fast_mmaped_file_rs/src/lib.rs +79 -0
  29. data/ext/fast_mmaped_file_rs/src/macros.rs +14 -0
  30. data/ext/fast_mmaped_file_rs/src/map.rs +492 -0
  31. data/ext/fast_mmaped_file_rs/src/mmap.rs +151 -0
  32. data/ext/fast_mmaped_file_rs/src/parser.rs +346 -0
  33. data/ext/fast_mmaped_file_rs/src/raw_entry.rs +473 -0
  34. data/ext/fast_mmaped_file_rs/src/testhelper.rs +222 -0
  35. data/ext/fast_mmaped_file_rs/src/util.rs +121 -0
  36. data/lib/2.7/fast_mmaped_file.bundle +0 -0
  37. data/lib/2.7/fast_mmaped_file_rs.bundle +0 -0
  38. data/lib/3.0/fast_mmaped_file.bundle +0 -0
  39. data/lib/3.0/fast_mmaped_file_rs.bundle +0 -0
  40. data/lib/3.1/fast_mmaped_file.bundle +0 -0
  41. data/lib/3.1/fast_mmaped_file_rs.bundle +0 -0
  42. data/lib/3.2/fast_mmaped_file.bundle +0 -0
  43. data/lib/3.2/fast_mmaped_file_rs.bundle +0 -0
  44. data/lib/prometheus/client/configuration.rb +23 -0
  45. data/lib/prometheus/client/counter.rb +27 -0
  46. data/lib/prometheus/client/formats/text.rb +118 -0
  47. data/lib/prometheus/client/gauge.rb +40 -0
  48. data/lib/prometheus/client/helper/entry_parser.rb +132 -0
  49. data/lib/prometheus/client/helper/file_locker.rb +50 -0
  50. data/lib/prometheus/client/helper/json_parser.rb +23 -0
  51. data/lib/prometheus/client/helper/metrics_processing.rb +45 -0
  52. data/lib/prometheus/client/helper/metrics_representation.rb +51 -0
  53. data/lib/prometheus/client/helper/mmaped_file.rb +64 -0
  54. data/lib/prometheus/client/helper/plain_file.rb +29 -0
  55. data/lib/prometheus/client/histogram.rb +80 -0
  56. data/lib/prometheus/client/label_set_validator.rb +86 -0
  57. data/lib/prometheus/client/metric.rb +80 -0
  58. data/lib/prometheus/client/mmaped_dict.rb +79 -0
  59. data/lib/prometheus/client/mmaped_value.rb +154 -0
  60. data/lib/prometheus/client/page_size.rb +17 -0
  61. data/lib/prometheus/client/push.rb +203 -0
  62. data/lib/prometheus/client/rack/collector.rb +88 -0
  63. data/lib/prometheus/client/rack/exporter.rb +96 -0
  64. data/lib/prometheus/client/registry.rb +65 -0
  65. data/lib/prometheus/client/simple_value.rb +31 -0
  66. data/lib/prometheus/client/summary.rb +69 -0
  67. data/lib/prometheus/client/support/unicorn.rb +35 -0
  68. data/lib/prometheus/client/uses_value_type.rb +20 -0
  69. data/lib/prometheus/client/version.rb +5 -0
  70. data/lib/prometheus/client.rb +58 -0
  71. data/lib/prometheus.rb +3 -0
  72. data/vendor/c/hashmap/.gitignore +52 -0
  73. data/vendor/c/hashmap/LICENSE +21 -0
  74. data/vendor/c/hashmap/README.md +90 -0
  75. data/vendor/c/hashmap/_config.yml +1 -0
  76. data/vendor/c/hashmap/src/hashmap.c +692 -0
  77. data/vendor/c/hashmap/src/hashmap.h +267 -0
  78. data/vendor/c/hashmap/test/Makefile +22 -0
  79. data/vendor/c/hashmap/test/hashmap_test.c +608 -0
  80. data/vendor/c/jsmn/.travis.yml +4 -0
  81. data/vendor/c/jsmn/LICENSE +20 -0
  82. data/vendor/c/jsmn/Makefile +41 -0
  83. data/vendor/c/jsmn/README.md +168 -0
  84. data/vendor/c/jsmn/example/jsondump.c +126 -0
  85. data/vendor/c/jsmn/example/simple.c +76 -0
  86. data/vendor/c/jsmn/jsmn.c +314 -0
  87. data/vendor/c/jsmn/jsmn.h +76 -0
  88. data/vendor/c/jsmn/library.json +16 -0
  89. data/vendor/c/jsmn/test/test.h +27 -0
  90. data/vendor/c/jsmn/test/tests.c +407 -0
  91. data/vendor/c/jsmn/test/testutil.h +94 -0
  92. metadata +243 -0
@@ -0,0 +1,76 @@
1
+ #ifndef __JSMN_H_
2
+ #define __JSMN_H_
3
+
4
+ #include <stddef.h>
5
+
6
+ #ifdef __cplusplus
7
+ extern "C" {
8
+ #endif
9
+
10
+ /**
11
+ * JSON type identifier. Basic types are:
12
+ * o Object
13
+ * o Array
14
+ * o String
15
+ * o Other primitive: number, boolean (true/false) or null
16
+ */
17
+ typedef enum {
18
+ JSMN_UNDEFINED = 0,
19
+ JSMN_OBJECT = 1,
20
+ JSMN_ARRAY = 2,
21
+ JSMN_STRING = 3,
22
+ JSMN_PRIMITIVE = 4
23
+ } jsmntype_t;
24
+
25
+ enum jsmnerr {
26
+ /* Not enough tokens were provided */
27
+ JSMN_ERROR_NOMEM = -1,
28
+ /* Invalid character inside JSON string */
29
+ JSMN_ERROR_INVAL = -2,
30
+ /* The string is not a full JSON packet, more bytes expected */
31
+ JSMN_ERROR_PART = -3
32
+ };
33
+
34
+ /**
35
+ * JSON token description.
36
+ * type type (object, array, string etc.)
37
+ * start start position in JSON data string
38
+ * end end position in JSON data string
39
+ */
40
+ typedef struct {
41
+ jsmntype_t type;
42
+ int start;
43
+ int end;
44
+ int size;
45
+ #ifdef JSMN_PARENT_LINKS
46
+ int parent;
47
+ #endif
48
+ } jsmntok_t;
49
+
50
+ /**
51
+ * JSON parser. Contains an array of token blocks available. Also stores
52
+ * the string being parsed now and current position in that string
53
+ */
54
+ typedef struct {
55
+ unsigned int pos; /* offset in the JSON string */
56
+ unsigned int toknext; /* next token to allocate */
57
+ int toksuper; /* superior token node, e.g parent object or array */
58
+ } jsmn_parser;
59
+
60
+ /**
61
+ * Create JSON parser over an array of tokens
62
+ */
63
+ void jsmn_init(jsmn_parser *parser);
64
+
65
+ /**
66
+ * Run JSON parser. It parses a JSON data string into and array of tokens, each describing
67
+ * a single JSON object.
68
+ */
69
+ int jsmn_parse(jsmn_parser *parser, const char *js, size_t len,
70
+ jsmntok_t *tokens, unsigned int num_tokens);
71
+
72
+ #ifdef __cplusplus
73
+ }
74
+ #endif
75
+
76
+ #endif /* __JSMN_H_ */
@@ -0,0 +1,16 @@
1
+ {
2
+ "name": "jsmn",
3
+ "keywords": "json",
4
+ "description": "Minimalistic JSON parser/tokenizer in C. It can be easily integrated into resource-limited or embedded projects",
5
+ "repository":
6
+ {
7
+ "type": "git",
8
+ "url": "https://github.com/zserge/jsmn.git"
9
+ },
10
+ "frameworks": "*",
11
+ "platforms": "*",
12
+ "examples": [
13
+ "example/*.c"
14
+ ],
15
+ "exclude": "test"
16
+ }
@@ -0,0 +1,27 @@
1
+ #ifndef __TEST_H__
2
+ #define __TEST_H__
3
+
4
+ static int test_passed = 0;
5
+ static int test_failed = 0;
6
+
7
+ /* Terminate current test with error */
8
+ #define fail() return __LINE__
9
+
10
+ /* Successful end of the test case */
11
+ #define done() return 0
12
+
13
+ /* Check single condition */
14
+ #define check(cond) do { if (!(cond)) fail(); } while (0)
15
+
16
+ /* Test runner */
17
+ static void test(int (*func)(void), const char *name) {
18
+ int r = func();
19
+ if (r == 0) {
20
+ test_passed++;
21
+ } else {
22
+ test_failed++;
23
+ printf("FAILED: %s (at line %d)\n", name, r);
24
+ }
25
+ }
26
+
27
+ #endif /* __TEST_H__ */
@@ -0,0 +1,407 @@
1
+ #include <stdio.h>
2
+ #include <stdlib.h>
3
+ #include <string.h>
4
+ #include <stdarg.h>
5
+
6
+ #include "test.h"
7
+ #include "testutil.h"
8
+
9
+ int test_empty(void) {
10
+ check(parse("{}", 1, 1,
11
+ JSMN_OBJECT, 0, 2, 0));
12
+ check(parse("[]", 1, 1,
13
+ JSMN_ARRAY, 0, 2, 0));
14
+ check(parse("[{},{}]", 3, 3,
15
+ JSMN_ARRAY, 0, 7, 2,
16
+ JSMN_OBJECT, 1, 3, 0,
17
+ JSMN_OBJECT, 4, 6, 0));
18
+ return 0;
19
+ }
20
+
21
+ int test_object(void) {
22
+ check(parse("{\"a\":0}", 3, 3,
23
+ JSMN_OBJECT, 0, 7, 1,
24
+ JSMN_STRING, "a", 1,
25
+ JSMN_PRIMITIVE, "0"));
26
+ check(parse("{\"a\":[]}", 3, 3,
27
+ JSMN_OBJECT, 0, 8, 1,
28
+ JSMN_STRING, "a", 1,
29
+ JSMN_ARRAY, 5, 7, 0));
30
+ check(parse("{\"a\":{},\"b\":{}}", 5, 5,
31
+ JSMN_OBJECT, -1, -1, 2,
32
+ JSMN_STRING, "a", 1,
33
+ JSMN_OBJECT, -1, -1, 0,
34
+ JSMN_STRING, "b", 1,
35
+ JSMN_OBJECT, -1, -1, 0));
36
+ check(parse("{\n \"Day\": 26,\n \"Month\": 9,\n \"Year\": 12\n }", 7, 7,
37
+ JSMN_OBJECT, -1, -1, 3,
38
+ JSMN_STRING, "Day", 1,
39
+ JSMN_PRIMITIVE, "26",
40
+ JSMN_STRING, "Month", 1,
41
+ JSMN_PRIMITIVE, "9",
42
+ JSMN_STRING, "Year", 1,
43
+ JSMN_PRIMITIVE, "12"));
44
+ check(parse("{\"a\": 0, \"b\": \"c\"}", 5, 5,
45
+ JSMN_OBJECT, -1, -1, 2,
46
+ JSMN_STRING, "a", 1,
47
+ JSMN_PRIMITIVE, "0",
48
+ JSMN_STRING, "b", 1,
49
+ JSMN_STRING, "c", 0));
50
+
51
+ #ifdef JSMN_STRICT
52
+ check(parse("{\"a\"\n0}", JSMN_ERROR_INVAL, 3));
53
+ check(parse("{\"a\", 0}", JSMN_ERROR_INVAL, 3));
54
+ check(parse("{\"a\": {2}}", JSMN_ERROR_INVAL, 3));
55
+ check(parse("{\"a\": {2: 3}}", JSMN_ERROR_INVAL, 3));
56
+ check(parse("{\"a\": {\"a\": 2 3}}", JSMN_ERROR_INVAL, 5));
57
+ /* FIXME */
58
+ /*check(parse("{\"a\"}", JSMN_ERROR_INVAL, 2));*/
59
+ /*check(parse("{\"a\": 1, \"b\"}", JSMN_ERROR_INVAL, 4));*/
60
+ /*check(parse("{\"a\",\"b\":1}", JSMN_ERROR_INVAL, 4));*/
61
+ /*check(parse("{\"a\":1,}", JSMN_ERROR_INVAL, 4));*/
62
+ /*check(parse("{\"a\":\"b\":\"c\"}", JSMN_ERROR_INVAL, 4));*/
63
+ /*check(parse("{,}", JSMN_ERROR_INVAL, 4));*/
64
+ #endif
65
+ return 0;
66
+ }
67
+
68
+ int test_array(void) {
69
+ /* FIXME */
70
+ /*check(parse("[10}", JSMN_ERROR_INVAL, 3));*/
71
+ /*check(parse("[1,,3]", JSMN_ERROR_INVAL, 3)*/
72
+ check(parse("[10]", 2, 2,
73
+ JSMN_ARRAY, -1, -1, 1,
74
+ JSMN_PRIMITIVE, "10"));
75
+ check(parse("{\"a\": 1]", JSMN_ERROR_INVAL, 3));
76
+ /* FIXME */
77
+ /*check(parse("[\"a\": 1]", JSMN_ERROR_INVAL, 3));*/
78
+ return 0;
79
+ }
80
+
81
+ int test_primitive(void) {
82
+ check(parse("{\"boolVar\" : true }", 3, 3,
83
+ JSMN_OBJECT, -1, -1, 1,
84
+ JSMN_STRING, "boolVar", 1,
85
+ JSMN_PRIMITIVE, "true"));
86
+ check(parse("{\"boolVar\" : false }", 3, 3,
87
+ JSMN_OBJECT, -1, -1, 1,
88
+ JSMN_STRING, "boolVar", 1,
89
+ JSMN_PRIMITIVE, "false"));
90
+ check(parse("{\"nullVar\" : null }", 3, 3,
91
+ JSMN_OBJECT, -1, -1, 1,
92
+ JSMN_STRING, "nullVar", 1,
93
+ JSMN_PRIMITIVE, "null"));
94
+ check(parse("{\"intVar\" : 12}", 3, 3,
95
+ JSMN_OBJECT, -1, -1, 1,
96
+ JSMN_STRING, "intVar", 1,
97
+ JSMN_PRIMITIVE, "12"));
98
+ check(parse("{\"floatVar\" : 12.345}", 3, 3,
99
+ JSMN_OBJECT, -1, -1, 1,
100
+ JSMN_STRING, "floatVar", 1,
101
+ JSMN_PRIMITIVE, "12.345"));
102
+ return 0;
103
+ }
104
+
105
+ int test_string(void) {
106
+ check(parse("{\"strVar\" : \"hello world\"}", 3, 3,
107
+ JSMN_OBJECT, -1, -1, 1,
108
+ JSMN_STRING, "strVar", 1,
109
+ JSMN_STRING, "hello world", 0));
110
+ check(parse("{\"strVar\" : \"escapes: \\/\\r\\n\\t\\b\\f\\\"\\\\\"}", 3, 3,
111
+ JSMN_OBJECT, -1, -1, 1,
112
+ JSMN_STRING, "strVar", 1,
113
+ JSMN_STRING, "escapes: \\/\\r\\n\\t\\b\\f\\\"\\\\", 0));
114
+ check(parse("{\"strVar\": \"\"}", 3, 3,
115
+ JSMN_OBJECT, -1, -1, 1,
116
+ JSMN_STRING, "strVar", 1,
117
+ JSMN_STRING, "", 0));
118
+ check(parse("{\"a\":\"\\uAbcD\"}", 3, 3,
119
+ JSMN_OBJECT, -1, -1, 1,
120
+ JSMN_STRING, "a", 1,
121
+ JSMN_STRING, "\\uAbcD", 0));
122
+ check(parse("{\"a\":\"str\\u0000\"}", 3, 3,
123
+ JSMN_OBJECT, -1, -1, 1,
124
+ JSMN_STRING, "a", 1,
125
+ JSMN_STRING, "str\\u0000", 0));
126
+ check(parse("{\"a\":\"\\uFFFFstr\"}", 3, 3,
127
+ JSMN_OBJECT, -1, -1, 1,
128
+ JSMN_STRING, "a", 1,
129
+ JSMN_STRING, "\\uFFFFstr", 0));
130
+ check(parse("{\"a\":[\"\\u0280\"]}", 4, 4,
131
+ JSMN_OBJECT, -1, -1, 1,
132
+ JSMN_STRING, "a", 1,
133
+ JSMN_ARRAY, -1, -1, 1,
134
+ JSMN_STRING, "\\u0280", 0));
135
+
136
+ check(parse("{\"a\":\"str\\uFFGFstr\"}", JSMN_ERROR_INVAL, 3));
137
+ check(parse("{\"a\":\"str\\u@FfF\"}", JSMN_ERROR_INVAL, 3));
138
+ check(parse("{{\"a\":[\"\\u028\"]}", JSMN_ERROR_INVAL, 4));
139
+ return 0;
140
+ }
141
+
142
+ int test_partial_string(void) {
143
+ int i;
144
+ int r;
145
+ jsmn_parser p;
146
+ jsmntok_t tok[5];
147
+ const char *js = "{\"x\": \"va\\\\ue\", \"y\": \"value y\"}";
148
+
149
+ jsmn_init(&p);
150
+ for (i = 1; i <= strlen(js); i++) {
151
+ r = jsmn_parse(&p, js, i, tok, sizeof(tok)/sizeof(tok[0]));
152
+ if (i == strlen(js)) {
153
+ check(r == 5);
154
+ check(tokeq(js, tok, 5,
155
+ JSMN_OBJECT, -1, -1, 2,
156
+ JSMN_STRING, "x", 1,
157
+ JSMN_STRING, "va\\\\ue", 0,
158
+ JSMN_STRING, "y", 1,
159
+ JSMN_STRING, "value y", 0));
160
+ } else {
161
+ check(r == JSMN_ERROR_PART);
162
+ }
163
+ }
164
+ return 0;
165
+ }
166
+
167
+ int test_partial_array(void) {
168
+ #ifdef JSMN_STRICT
169
+ int r;
170
+ int i;
171
+ jsmn_parser p;
172
+ jsmntok_t tok[10];
173
+ const char *js = "[ 1, true, [123, \"hello\"]]";
174
+
175
+ jsmn_init(&p);
176
+ for (i = 1; i <= strlen(js); i++) {
177
+ r = jsmn_parse(&p, js, i, tok, sizeof(tok)/sizeof(tok[0]));
178
+ if (i == strlen(js)) {
179
+ check(r == 6);
180
+ check(tokeq(js, tok, 6,
181
+ JSMN_ARRAY, -1, -1, 3,
182
+ JSMN_PRIMITIVE, "1",
183
+ JSMN_PRIMITIVE, "true",
184
+ JSMN_ARRAY, -1, -1, 2,
185
+ JSMN_PRIMITIVE, "123",
186
+ JSMN_STRING, "hello", 0));
187
+ } else {
188
+ check(r == JSMN_ERROR_PART);
189
+ }
190
+ }
191
+ #endif
192
+ return 0;
193
+ }
194
+
195
+ int test_array_nomem(void) {
196
+ int i;
197
+ int r;
198
+ jsmn_parser p;
199
+ jsmntok_t toksmall[10], toklarge[10];
200
+ const char *js;
201
+
202
+ js = " [ 1, true, [123, \"hello\"]]";
203
+
204
+ for (i = 0; i < 6; i++) {
205
+ jsmn_init(&p);
206
+ memset(toksmall, 0, sizeof(toksmall));
207
+ memset(toklarge, 0, sizeof(toklarge));
208
+ r = jsmn_parse(&p, js, strlen(js), toksmall, i);
209
+ check(r == JSMN_ERROR_NOMEM);
210
+
211
+ memcpy(toklarge, toksmall, sizeof(toksmall));
212
+
213
+ r = jsmn_parse(&p, js, strlen(js), toklarge, 10);
214
+ check(r >= 0);
215
+ check(tokeq(js, toklarge, 4,
216
+ JSMN_ARRAY, -1, -1, 3,
217
+ JSMN_PRIMITIVE, "1",
218
+ JSMN_PRIMITIVE, "true",
219
+ JSMN_ARRAY, -1, -1, 2,
220
+ JSMN_PRIMITIVE, "123",
221
+ JSMN_STRING, "hello", 0));
222
+ }
223
+ return 0;
224
+ }
225
+
226
+ int test_unquoted_keys(void) {
227
+ #ifndef JSMN_STRICT
228
+ int r;
229
+ jsmn_parser p;
230
+ jsmntok_t tok[10];
231
+ const char *js;
232
+
233
+ jsmn_init(&p);
234
+ js = "key1: \"value\"\nkey2 : 123";
235
+
236
+ r = jsmn_parse(&p, js, strlen(js), tok, 10);
237
+ check(r >= 0);
238
+ check(tokeq(js, tok, 4,
239
+ JSMN_PRIMITIVE, "key1",
240
+ JSMN_STRING, "value", 0,
241
+ JSMN_PRIMITIVE, "key2",
242
+ JSMN_PRIMITIVE, "123"));
243
+ #endif
244
+ return 0;
245
+ }
246
+
247
+ int test_issue_22(void) {
248
+ int r;
249
+ jsmn_parser p;
250
+ jsmntok_t tokens[128];
251
+ const char *js;
252
+
253
+ js = "{ \"height\":10, \"layers\":[ { \"data\":[6,6], \"height\":10, "
254
+ "\"name\":\"Calque de Tile 1\", \"opacity\":1, \"type\":\"tilelayer\", "
255
+ "\"visible\":true, \"width\":10, \"x\":0, \"y\":0 }], "
256
+ "\"orientation\":\"orthogonal\", \"properties\": { }, \"tileheight\":32, "
257
+ "\"tilesets\":[ { \"firstgid\":1, \"image\":\"..\\/images\\/tiles.png\", "
258
+ "\"imageheight\":64, \"imagewidth\":160, \"margin\":0, \"name\":\"Tiles\", "
259
+ "\"properties\":{}, \"spacing\":0, \"tileheight\":32, \"tilewidth\":32 }], "
260
+ "\"tilewidth\":32, \"version\":1, \"width\":10 }";
261
+ jsmn_init(&p);
262
+ r = jsmn_parse(&p, js, strlen(js), tokens, 128);
263
+ check(r >= 0);
264
+ return 0;
265
+ }
266
+
267
+ int test_issue_27(void) {
268
+ const char *js =
269
+ "{ \"name\" : \"Jack\", \"age\" : 27 } { \"name\" : \"Anna\", ";
270
+ check(parse(js, JSMN_ERROR_PART, 8));
271
+ return 0;
272
+ }
273
+
274
+ int test_input_length(void) {
275
+ const char *js;
276
+ int r;
277
+ jsmn_parser p;
278
+ jsmntok_t tokens[10];
279
+
280
+ js = "{\"a\": 0}garbage";
281
+
282
+ jsmn_init(&p);
283
+ r = jsmn_parse(&p, js, 8, tokens, 10);
284
+ check(r == 3);
285
+ check(tokeq(js, tokens, 3,
286
+ JSMN_OBJECT, -1, -1, 1,
287
+ JSMN_STRING, "a", 1,
288
+ JSMN_PRIMITIVE, "0"));
289
+ return 0;
290
+ }
291
+
292
+ int test_count(void) {
293
+ jsmn_parser p;
294
+ const char *js;
295
+
296
+ js = "{}";
297
+ jsmn_init(&p);
298
+ check(jsmn_parse(&p, js, strlen(js), NULL, 0) == 1);
299
+
300
+ js = "[]";
301
+ jsmn_init(&p);
302
+ check(jsmn_parse(&p, js, strlen(js), NULL, 0) == 1);
303
+
304
+ js = "[[]]";
305
+ jsmn_init(&p);
306
+ check(jsmn_parse(&p, js, strlen(js), NULL, 0) == 2);
307
+
308
+ js = "[[], []]";
309
+ jsmn_init(&p);
310
+ check(jsmn_parse(&p, js, strlen(js), NULL, 0) == 3);
311
+
312
+ js = "[[], []]";
313
+ jsmn_init(&p);
314
+ check(jsmn_parse(&p, js, strlen(js), NULL, 0) == 3);
315
+
316
+ js = "[[], [[]], [[], []]]";
317
+ jsmn_init(&p);
318
+ check(jsmn_parse(&p, js, strlen(js), NULL, 0) == 7);
319
+
320
+ js = "[\"a\", [[], []]]";
321
+ jsmn_init(&p);
322
+ check(jsmn_parse(&p, js, strlen(js), NULL, 0) == 5);
323
+
324
+ js = "[[], \"[], [[]]\", [[]]]";
325
+ jsmn_init(&p);
326
+ check(jsmn_parse(&p, js, strlen(js), NULL, 0) == 5);
327
+
328
+ js = "[1, 2, 3]";
329
+ jsmn_init(&p);
330
+ check(jsmn_parse(&p, js, strlen(js), NULL, 0) == 4);
331
+
332
+ js = "[1, 2, [3, \"a\"], null]";
333
+ jsmn_init(&p);
334
+ check(jsmn_parse(&p, js, strlen(js), NULL, 0) == 7);
335
+
336
+ return 0;
337
+ }
338
+
339
+
340
+ int test_nonstrict(void) {
341
+ #ifndef JSMN_STRICT
342
+ const char *js;
343
+ js = "a: 0garbage";
344
+ check(parse(js, 2, 2,
345
+ JSMN_PRIMITIVE, "a",
346
+ JSMN_PRIMITIVE, "0garbage"));
347
+
348
+ js = "Day : 26\nMonth : Sep\n\nYear: 12";
349
+ check(parse(js, 6, 6,
350
+ JSMN_PRIMITIVE, "Day",
351
+ JSMN_PRIMITIVE, "26",
352
+ JSMN_PRIMITIVE, "Month",
353
+ JSMN_PRIMITIVE, "Sep",
354
+ JSMN_PRIMITIVE, "Year",
355
+ JSMN_PRIMITIVE, "12"));
356
+
357
+ //nested {s don't cause a parse error.
358
+ js = "\"key {1\": 1234";
359
+ check(parse(js, 2, 2,
360
+ JSMN_STRING, "key {1", 1,
361
+ JSMN_PRIMITIVE, "1234"));
362
+
363
+
364
+ #endif
365
+ return 0;
366
+ }
367
+
368
+ int test_unmatched_brackets(void) {
369
+ const char *js;
370
+ js = "\"key 1\": 1234}";
371
+ check(parse(js, JSMN_ERROR_INVAL, 2));
372
+ js = "{\"key 1\": 1234";
373
+ check(parse(js, JSMN_ERROR_PART, 3));
374
+ js = "{\"key 1\": 1234}}";
375
+ check(parse(js, JSMN_ERROR_INVAL, 3));
376
+ js = "\"key 1\"}: 1234";
377
+ check(parse(js, JSMN_ERROR_INVAL, 3));
378
+ js = "{\"key {1\": 1234}";
379
+ check(parse(js, 3, 3,
380
+ JSMN_OBJECT, 0, 16, 1,
381
+ JSMN_STRING, "key {1", 1,
382
+ JSMN_PRIMITIVE, "1234"));
383
+ js = "{{\"key 1\": 1234}";
384
+ check(parse(js, JSMN_ERROR_PART, 4));
385
+ return 0;
386
+ }
387
+
388
+ int main(void) {
389
+ test(test_empty, "test for a empty JSON objects/arrays");
390
+ test(test_object, "test for a JSON objects");
391
+ test(test_array, "test for a JSON arrays");
392
+ test(test_primitive, "test primitive JSON data types");
393
+ test(test_string, "test string JSON data types");
394
+
395
+ test(test_partial_string, "test partial JSON string parsing");
396
+ test(test_partial_array, "test partial array reading");
397
+ test(test_array_nomem, "test array reading with a smaller number of tokens");
398
+ test(test_unquoted_keys, "test unquoted keys (like in JavaScript)");
399
+ test(test_input_length, "test strings that are not null-terminated");
400
+ test(test_issue_22, "test issue #22");
401
+ test(test_issue_27, "test issue #27");
402
+ test(test_count, "test tokens count estimation");
403
+ test(test_nonstrict, "test for non-strict mode");
404
+ test(test_unmatched_brackets, "test for unmatched brackets");
405
+ printf("\nPASSED: %d\nFAILED: %d\n", test_passed, test_failed);
406
+ return (test_failed > 0);
407
+ }
@@ -0,0 +1,94 @@
1
+ #ifndef __TEST_UTIL_H__
2
+ #define __TEST_UTIL_H__
3
+
4
+ #include "../jsmn.c"
5
+
6
+ static int vtokeq(const char *s, jsmntok_t *t, int numtok, va_list ap) {
7
+ if (numtok > 0) {
8
+ int i, start, end, size;
9
+ int type;
10
+ char *value;
11
+
12
+ size = -1;
13
+ value = NULL;
14
+ for (i = 0; i < numtok; i++) {
15
+ type = va_arg(ap, int);
16
+ if (type == JSMN_STRING) {
17
+ value = va_arg(ap, char *);
18
+ size = va_arg(ap, int);
19
+ start = end = -1;
20
+ } else if (type == JSMN_PRIMITIVE) {
21
+ value = va_arg(ap, char *);
22
+ start = end = size = -1;
23
+ } else {
24
+ start = va_arg(ap, int);
25
+ end = va_arg(ap, int);
26
+ size = va_arg(ap, int);
27
+ value = NULL;
28
+ }
29
+ if (t[i].type != type) {
30
+ printf("token %d type is %d, not %d\n", i, t[i].type, type);
31
+ return 0;
32
+ }
33
+ if (start != -1 && end != -1) {
34
+ if (t[i].start != start) {
35
+ printf("token %d start is %d, not %d\n", i, t[i].start, start);
36
+ return 0;
37
+ }
38
+ if (t[i].end != end ) {
39
+ printf("token %d end is %d, not %d\n", i, t[i].end, end);
40
+ return 0;
41
+ }
42
+ }
43
+ if (size != -1 && t[i].size != size) {
44
+ printf("token %d size is %d, not %d\n", i, t[i].size, size);
45
+ return 0;
46
+ }
47
+
48
+ if (s != NULL && value != NULL) {
49
+ const char *p = s + t[i].start;
50
+ if (strlen(value) != t[i].end - t[i].start ||
51
+ strncmp(p, value, t[i].end - t[i].start) != 0) {
52
+ printf("token %d value is %.*s, not %s\n", i, t[i].end-t[i].start,
53
+ s+t[i].start, value);
54
+ return 0;
55
+ }
56
+ }
57
+ }
58
+ }
59
+ return 1;
60
+ }
61
+
62
+ static int tokeq(const char *s, jsmntok_t *tokens, int numtok, ...) {
63
+ int ok;
64
+ va_list args;
65
+ va_start(args, numtok);
66
+ ok = vtokeq(s, tokens, numtok, args);
67
+ va_end(args);
68
+ return ok;
69
+ }
70
+
71
+ static int parse(const char *s, int status, int numtok, ...) {
72
+ int r;
73
+ int ok = 1;
74
+ va_list args;
75
+ jsmn_parser p;
76
+ jsmntok_t *t = malloc(numtok * sizeof(jsmntok_t));
77
+
78
+ jsmn_init(&p);
79
+ r = jsmn_parse(&p, s, strlen(s), t, numtok);
80
+ if (r != status) {
81
+ printf("status is %d, not %d\n", r, status);
82
+ return 0;
83
+ }
84
+
85
+ if (status >= 0) {
86
+ va_start(args, numtok);
87
+ ok = vtokeq(s, t, numtok, args);
88
+ va_end(args);
89
+ }
90
+ free(t);
91
+ return ok;
92
+ }
93
+
94
+ #endif /* __TEST_UTIL_H__ */