prometheus-client-mmap 0.25.0 → 1.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (55) hide show
  1. checksums.yaml +4 -4
  2. data/.tool-versions +1 -1
  3. data/README.md +32 -28
  4. data/ext/fast_mmaped_file_rs/Cargo.lock +195 -234
  5. data/ext/fast_mmaped_file_rs/Cargo.toml +7 -7
  6. data/ext/fast_mmaped_file_rs/extconf.rb +1 -3
  7. data/ext/fast_mmaped_file_rs/src/file_info.rs +51 -1
  8. data/ext/fast_mmaped_file_rs/src/mmap/inner.rs +0 -10
  9. data/ext/fast_mmaped_file_rs/src/mmap.rs +2 -5
  10. data/lib/prometheus/client/configuration.rb +1 -2
  11. data/lib/prometheus/client/formats/text.rb +1 -12
  12. data/lib/prometheus/client/helper/mmaped_file.rb +3 -14
  13. data/lib/prometheus/client/label_set_validator.rb +1 -2
  14. data/lib/prometheus/client/rack/exporter.rb +1 -3
  15. data/lib/prometheus/client/support/puma.rb +44 -0
  16. data/lib/prometheus/client/version.rb +1 -1
  17. metadata +9 -47
  18. data/ext/fast_mmaped_file/extconf.rb +0 -30
  19. data/ext/fast_mmaped_file/fast_mmaped_file.c +0 -122
  20. data/ext/fast_mmaped_file/file_format.c +0 -5
  21. data/ext/fast_mmaped_file/file_format.h +0 -11
  22. data/ext/fast_mmaped_file/file_parsing.c +0 -195
  23. data/ext/fast_mmaped_file/file_parsing.h +0 -27
  24. data/ext/fast_mmaped_file/file_reading.c +0 -102
  25. data/ext/fast_mmaped_file/file_reading.h +0 -30
  26. data/ext/fast_mmaped_file/globals.h +0 -14
  27. data/ext/fast_mmaped_file/mmap.c +0 -438
  28. data/ext/fast_mmaped_file/mmap.h +0 -61
  29. data/ext/fast_mmaped_file/rendering.c +0 -199
  30. data/ext/fast_mmaped_file/rendering.h +0 -8
  31. data/ext/fast_mmaped_file/utils.c +0 -56
  32. data/ext/fast_mmaped_file/utils.h +0 -22
  33. data/ext/fast_mmaped_file/value_access.c +0 -242
  34. data/ext/fast_mmaped_file/value_access.h +0 -15
  35. data/lib/prometheus/client/helper/loader.rb +0 -40
  36. data/vendor/c/hashmap/.gitignore +0 -52
  37. data/vendor/c/hashmap/LICENSE +0 -21
  38. data/vendor/c/hashmap/README.md +0 -90
  39. data/vendor/c/hashmap/_config.yml +0 -1
  40. data/vendor/c/hashmap/src/hashmap.c +0 -692
  41. data/vendor/c/hashmap/src/hashmap.h +0 -267
  42. data/vendor/c/hashmap/test/Makefile +0 -22
  43. data/vendor/c/hashmap/test/hashmap_test.c +0 -608
  44. data/vendor/c/jsmn/.travis.yml +0 -4
  45. data/vendor/c/jsmn/LICENSE +0 -20
  46. data/vendor/c/jsmn/Makefile +0 -41
  47. data/vendor/c/jsmn/README.md +0 -168
  48. data/vendor/c/jsmn/example/jsondump.c +0 -126
  49. data/vendor/c/jsmn/example/simple.c +0 -76
  50. data/vendor/c/jsmn/jsmn.c +0 -314
  51. data/vendor/c/jsmn/jsmn.h +0 -76
  52. data/vendor/c/jsmn/library.json +0 -16
  53. data/vendor/c/jsmn/test/test.h +0 -27
  54. data/vendor/c/jsmn/test/tests.c +0 -407
  55. data/vendor/c/jsmn/test/testutil.h +0 -94
@@ -1,168 +0,0 @@
1
- JSMN
2
- ====
3
-
4
- [![Build Status](https://travis-ci.org/zserge/jsmn.svg?branch=master)](https://travis-ci.org/zserge/jsmn)
5
-
6
- jsmn (pronounced like 'jasmine') is a minimalistic JSON parser in C. It can be
7
- easily integrated into resource-limited or embedded projects.
8
-
9
- You can find more information about JSON format at [json.org][1]
10
-
11
- Library sources are available at https://github.com/zserge/jsmn
12
-
13
- The web page with some information about jsmn can be found at
14
- [http://zserge.com/jsmn.html][2]
15
-
16
- Philosophy
17
- ----------
18
-
19
- Most JSON parsers offer you a bunch of functions to load JSON data, parse it
20
- and extract any value by its name. jsmn proves that checking the correctness of
21
- every JSON packet or allocating temporary objects to store parsed JSON fields
22
- often is an overkill.
23
-
24
- JSON format itself is extremely simple, so why should we complicate it?
25
-
26
- jsmn is designed to be **robust** (it should work fine even with erroneous
27
- data), **fast** (it should parse data on the fly), **portable** (no superfluous
28
- dependencies or non-standard C extensions). And of course, **simplicity** is a
29
- key feature - simple code style, simple algorithm, simple integration into
30
- other projects.
31
-
32
- Features
33
- --------
34
-
35
- * compatible with C89
36
- * no dependencies (even libc!)
37
- * highly portable (tested on x86/amd64, ARM, AVR)
38
- * about 200 lines of code
39
- * extremely small code footprint
40
- * API contains only 2 functions
41
- * no dynamic memory allocation
42
- * incremental single-pass parsing
43
- * library code is covered with unit-tests
44
-
45
- Design
46
- ------
47
-
48
- The rudimentary jsmn object is a **token**. Let's consider a JSON string:
49
-
50
- '{ "name" : "Jack", "age" : 27 }'
51
-
52
- It holds the following tokens:
53
-
54
- * Object: `{ "name" : "Jack", "age" : 27}` (the whole object)
55
- * Strings: `"name"`, `"Jack"`, `"age"` (keys and some values)
56
- * Number: `27`
57
-
58
- In jsmn, tokens do not hold any data, but point to token boundaries in JSON
59
- string instead. In the example above jsmn will create tokens like: Object
60
- [0..31], String [3..7], String [12..16], String [20..23], Number [27..29].
61
-
62
- Every jsmn token has a type, which indicates the type of corresponding JSON
63
- token. jsmn supports the following token types:
64
-
65
- * Object - a container of key-value pairs, e.g.:
66
- `{ "foo":"bar", "x":0.3 }`
67
- * Array - a sequence of values, e.g.:
68
- `[ 1, 2, 3 ]`
69
- * String - a quoted sequence of chars, e.g.: `"foo"`
70
- * Primitive - a number, a boolean (`true`, `false`) or `null`
71
-
72
- Besides start/end positions, jsmn tokens for complex types (like arrays
73
- or objects) also contain a number of child items, so you can easily follow
74
- object hierarchy.
75
-
76
- This approach provides enough information for parsing any JSON data and makes
77
- it possible to use zero-copy techniques.
78
-
79
- Install
80
- -------
81
-
82
- To clone the repository you should have Git installed. Just run:
83
-
84
- $ git clone https://github.com/zserge/jsmn
85
-
86
- Repository layout is simple: jsmn.c and jsmn.h are library files, tests are in
87
- the jsmn\_test.c, you will also find README, LICENSE and Makefile files inside.
88
-
89
- To build the library, run `make`. It is also recommended to run `make test`.
90
- Let me know, if some tests fail.
91
-
92
- If build was successful, you should get a `libjsmn.a` library.
93
- The header file you should include is called `"jsmn.h"`.
94
-
95
- API
96
- ---
97
-
98
- Token types are described by `jsmntype_t`:
99
-
100
- typedef enum {
101
- JSMN_UNDEFINED = 0,
102
- JSMN_OBJECT = 1,
103
- JSMN_ARRAY = 2,
104
- JSMN_STRING = 3,
105
- JSMN_PRIMITIVE = 4
106
- } jsmntype_t;
107
-
108
- **Note:** Unlike JSON data types, primitive tokens are not divided into
109
- numbers, booleans and null, because one can easily tell the type using the
110
- first character:
111
-
112
- * <code>'t', 'f'</code> - boolean
113
- * <code>'n'</code> - null
114
- * <code>'-', '0'..'9'</code> - number
115
-
116
- Token is an object of `jsmntok_t` type:
117
-
118
- typedef struct {
119
- jsmntype_t type; // Token type
120
- int start; // Token start position
121
- int end; // Token end position
122
- int size; // Number of child (nested) tokens
123
- } jsmntok_t;
124
-
125
- **Note:** string tokens point to the first character after
126
- the opening quote and the previous symbol before final quote. This was made
127
- to simplify string extraction from JSON data.
128
-
129
- All job is done by `jsmn_parser` object. You can initialize a new parser using:
130
-
131
- jsmn_parser parser;
132
- jsmntok_t tokens[10];
133
-
134
- jsmn_init(&parser);
135
-
136
- // js - pointer to JSON string
137
- // tokens - an array of tokens available
138
- // 10 - number of tokens available
139
- jsmn_parse(&parser, js, strlen(js), tokens, 10);
140
-
141
- This will create a parser, and then it tries to parse up to 10 JSON tokens from
142
- the `js` string.
143
-
144
- A non-negative return value of `jsmn_parse` is the number of tokens actually
145
- used by the parser.
146
- Passing NULL instead of the tokens array would not store parsing results, but
147
- instead the function will return the value of tokens needed to parse the given
148
- string. This can be useful if you don't know yet how many tokens to allocate.
149
-
150
- If something goes wrong, you will get an error. Error will be one of these:
151
-
152
- * `JSMN_ERROR_INVAL` - bad token, JSON string is corrupted
153
- * `JSMN_ERROR_NOMEM` - not enough tokens, JSON string is too large
154
- * `JSMN_ERROR_PART` - JSON string is too short, expecting more JSON data
155
-
156
- If you get `JSON_ERROR_NOMEM`, you can re-allocate more tokens and call
157
- `jsmn_parse` once more. If you read json data from the stream, you can
158
- periodically call `jsmn_parse` and check if return value is `JSON_ERROR_PART`.
159
- You will get this error until you reach the end of JSON data.
160
-
161
- Other info
162
- ----------
163
-
164
- This software is distributed under [MIT license](http://www.opensource.org/licenses/mit-license.php),
165
- so feel free to integrate it in your commercial products.
166
-
167
- [1]: http://www.json.org/
168
- [2]: http://zserge.com/jsmn.html
@@ -1,126 +0,0 @@
1
- #include <stdio.h>
2
- #include <stdlib.h>
3
- #include <unistd.h>
4
- #include <string.h>
5
- #include <errno.h>
6
- #include "../jsmn.h"
7
-
8
- /* Function realloc_it() is a wrapper function for standart realloc()
9
- * with one difference - it frees old memory pointer in case of realloc
10
- * failure. Thus, DO NOT use old data pointer in anyway after call to
11
- * realloc_it(). If your code has some kind of fallback algorithm if
12
- * memory can't be re-allocated - use standart realloc() instead.
13
- */
14
- static inline void *realloc_it(void *ptrmem, size_t size) {
15
- void *p = realloc(ptrmem, size);
16
- if (!p) {
17
- free (ptrmem);
18
- fprintf(stderr, "realloc(): errno=%d\n", errno);
19
- }
20
- return p;
21
- }
22
-
23
- /*
24
- * An example of reading JSON from stdin and printing its content to stdout.
25
- * The output looks like YAML, but I'm not sure if it's really compatible.
26
- */
27
-
28
- static int dump(const char *js, jsmntok_t *t, size_t count, int indent) {
29
- int i, j, k;
30
- if (count == 0) {
31
- return 0;
32
- }
33
- if (t->type == JSMN_PRIMITIVE) {
34
- printf("%.*s", t->end - t->start, js+t->start);
35
- return 1;
36
- } else if (t->type == JSMN_STRING) {
37
- printf("'%.*s'", t->end - t->start, js+t->start);
38
- return 1;
39
- } else if (t->type == JSMN_OBJECT) {
40
- printf("\n");
41
- j = 0;
42
- for (i = 0; i < t->size; i++) {
43
- for (k = 0; k < indent; k++) printf(" ");
44
- j += dump(js, t+1+j, count-j, indent+1);
45
- printf(": ");
46
- j += dump(js, t+1+j, count-j, indent+1);
47
- printf("\n");
48
- }
49
- return j+1;
50
- } else if (t->type == JSMN_ARRAY) {
51
- j = 0;
52
- printf("\n");
53
- for (i = 0; i < t->size; i++) {
54
- for (k = 0; k < indent-1; k++) printf(" ");
55
- printf(" - ");
56
- j += dump(js, t+1+j, count-j, indent+1);
57
- printf("\n");
58
- }
59
- return j+1;
60
- }
61
- return 0;
62
- }
63
-
64
- int main() {
65
- int r;
66
- int eof_expected = 0;
67
- char *js = NULL;
68
- size_t jslen = 0;
69
- char buf[BUFSIZ];
70
-
71
- jsmn_parser p;
72
- jsmntok_t *tok;
73
- size_t tokcount = 2;
74
-
75
- /* Prepare parser */
76
- jsmn_init(&p);
77
-
78
- /* Allocate some tokens as a start */
79
- tok = malloc(sizeof(*tok) * tokcount);
80
- if (tok == NULL) {
81
- fprintf(stderr, "malloc(): errno=%d\n", errno);
82
- return 3;
83
- }
84
-
85
- for (;;) {
86
- /* Read another chunk */
87
- r = fread(buf, 1, sizeof(buf), stdin);
88
- if (r < 0) {
89
- fprintf(stderr, "fread(): %d, errno=%d\n", r, errno);
90
- return 1;
91
- }
92
- if (r == 0) {
93
- if (eof_expected != 0) {
94
- return 0;
95
- } else {
96
- fprintf(stderr, "fread(): unexpected EOF\n");
97
- return 2;
98
- }
99
- }
100
-
101
- js = realloc_it(js, jslen + r + 1);
102
- if (js == NULL) {
103
- return 3;
104
- }
105
- strncpy(js + jslen, buf, r);
106
- jslen = jslen + r;
107
-
108
- again:
109
- r = jsmn_parse(&p, js, jslen, tok, tokcount);
110
- if (r < 0) {
111
- if (r == JSMN_ERROR_NOMEM) {
112
- tokcount = tokcount * 2;
113
- tok = realloc_it(tok, sizeof(*tok) * tokcount);
114
- if (tok == NULL) {
115
- return 3;
116
- }
117
- goto again;
118
- }
119
- } else {
120
- dump(js, tok, p.toknext, 0);
121
- eof_expected = 1;
122
- }
123
- }
124
-
125
- return EXIT_SUCCESS;
126
- }
@@ -1,76 +0,0 @@
1
- #include <stdio.h>
2
- #include <stdlib.h>
3
- #include <string.h>
4
- #include "../jsmn.h"
5
-
6
- /*
7
- * A small example of jsmn parsing when JSON structure is known and number of
8
- * tokens is predictable.
9
- */
10
-
11
- static const char *JSON_STRING =
12
- "{\"user\": \"johndoe\", \"admin\": false, \"uid\": 1000,\n "
13
- "\"groups\": [\"users\", \"wheel\", \"audio\", \"video\"]}";
14
-
15
- static int jsoneq(const char *json, jsmntok_t *tok, const char *s) {
16
- if (tok->type == JSMN_STRING && (int) strlen(s) == tok->end - tok->start &&
17
- strncmp(json + tok->start, s, tok->end - tok->start) == 0) {
18
- return 0;
19
- }
20
- return -1;
21
- }
22
-
23
- int main() {
24
- int i;
25
- int r;
26
- jsmn_parser p;
27
- jsmntok_t t[128]; /* We expect no more than 128 tokens */
28
-
29
- jsmn_init(&p);
30
- r = jsmn_parse(&p, JSON_STRING, strlen(JSON_STRING), t, sizeof(t)/sizeof(t[0]));
31
- if (r < 0) {
32
- printf("Failed to parse JSON: %d\n", r);
33
- return 1;
34
- }
35
-
36
- /* Assume the top-level element is an object */
37
- if (r < 1 || t[0].type != JSMN_OBJECT) {
38
- printf("Object expected\n");
39
- return 1;
40
- }
41
-
42
- /* Loop over all keys of the root object */
43
- for (i = 1; i < r; i++) {
44
- if (jsoneq(JSON_STRING, &t[i], "user") == 0) {
45
- /* We may use strndup() to fetch string value */
46
- printf("- User: %.*s\n", t[i+1].end-t[i+1].start,
47
- JSON_STRING + t[i+1].start);
48
- i++;
49
- } else if (jsoneq(JSON_STRING, &t[i], "admin") == 0) {
50
- /* We may additionally check if the value is either "true" or "false" */
51
- printf("- Admin: %.*s\n", t[i+1].end-t[i+1].start,
52
- JSON_STRING + t[i+1].start);
53
- i++;
54
- } else if (jsoneq(JSON_STRING, &t[i], "uid") == 0) {
55
- /* We may want to do strtol() here to get numeric value */
56
- printf("- UID: %.*s\n", t[i+1].end-t[i+1].start,
57
- JSON_STRING + t[i+1].start);
58
- i++;
59
- } else if (jsoneq(JSON_STRING, &t[i], "groups") == 0) {
60
- int j;
61
- printf("- Groups:\n");
62
- if (t[i+1].type != JSMN_ARRAY) {
63
- continue; /* We expect groups to be an array of strings */
64
- }
65
- for (j = 0; j < t[i+1].size; j++) {
66
- jsmntok_t *g = &t[i+j+2];
67
- printf(" * %.*s\n", g->end - g->start, JSON_STRING + g->start);
68
- }
69
- i += t[i+1].size + 1;
70
- } else {
71
- printf("Unexpected key: %.*s\n", t[i].end-t[i].start,
72
- JSON_STRING + t[i].start);
73
- }
74
- }
75
- return EXIT_SUCCESS;
76
- }
data/vendor/c/jsmn/jsmn.c DELETED
@@ -1,314 +0,0 @@
1
- #include "jsmn.h"
2
-
3
- /**
4
- * Allocates a fresh unused token from the token pull.
5
- */
6
- static jsmntok_t *jsmn_alloc_token(jsmn_parser *parser,
7
- jsmntok_t *tokens, size_t num_tokens) {
8
- jsmntok_t *tok;
9
- if (parser->toknext >= num_tokens) {
10
- return NULL;
11
- }
12
- tok = &tokens[parser->toknext++];
13
- tok->start = tok->end = -1;
14
- tok->size = 0;
15
- #ifdef JSMN_PARENT_LINKS
16
- tok->parent = -1;
17
- #endif
18
- return tok;
19
- }
20
-
21
- /**
22
- * Fills token type and boundaries.
23
- */
24
- static void jsmn_fill_token(jsmntok_t *token, jsmntype_t type,
25
- int start, int end) {
26
- token->type = type;
27
- token->start = start;
28
- token->end = end;
29
- token->size = 0;
30
- }
31
-
32
- /**
33
- * Fills next available token with JSON primitive.
34
- */
35
- static int jsmn_parse_primitive(jsmn_parser *parser, const char *js,
36
- size_t len, jsmntok_t *tokens, size_t num_tokens) {
37
- jsmntok_t *token;
38
- int start;
39
-
40
- start = parser->pos;
41
-
42
- for (; parser->pos < len && js[parser->pos] != '\0'; parser->pos++) {
43
- switch (js[parser->pos]) {
44
- #ifndef JSMN_STRICT
45
- /* In strict mode primitive must be followed by "," or "}" or "]" */
46
- case ':':
47
- #endif
48
- case '\t' : case '\r' : case '\n' : case ' ' :
49
- case ',' : case ']' : case '}' :
50
- goto found;
51
- }
52
- if (js[parser->pos] < 32 || js[parser->pos] >= 127) {
53
- parser->pos = start;
54
- return JSMN_ERROR_INVAL;
55
- }
56
- }
57
- #ifdef JSMN_STRICT
58
- /* In strict mode primitive must be followed by a comma/object/array */
59
- parser->pos = start;
60
- return JSMN_ERROR_PART;
61
- #endif
62
-
63
- found:
64
- if (tokens == NULL) {
65
- parser->pos--;
66
- return 0;
67
- }
68
- token = jsmn_alloc_token(parser, tokens, num_tokens);
69
- if (token == NULL) {
70
- parser->pos = start;
71
- return JSMN_ERROR_NOMEM;
72
- }
73
- jsmn_fill_token(token, JSMN_PRIMITIVE, start, parser->pos);
74
- #ifdef JSMN_PARENT_LINKS
75
- token->parent = parser->toksuper;
76
- #endif
77
- parser->pos--;
78
- return 0;
79
- }
80
-
81
- /**
82
- * Fills next token with JSON string.
83
- */
84
- static int jsmn_parse_string(jsmn_parser *parser, const char *js,
85
- size_t len, jsmntok_t *tokens, size_t num_tokens) {
86
- jsmntok_t *token;
87
-
88
- int start = parser->pos;
89
-
90
- parser->pos++;
91
-
92
- /* Skip starting quote */
93
- for (; parser->pos < len && js[parser->pos] != '\0'; parser->pos++) {
94
- char c = js[parser->pos];
95
-
96
- /* Quote: end of string */
97
- if (c == '\"') {
98
- if (tokens == NULL) {
99
- return 0;
100
- }
101
- token = jsmn_alloc_token(parser, tokens, num_tokens);
102
- if (token == NULL) {
103
- parser->pos = start;
104
- return JSMN_ERROR_NOMEM;
105
- }
106
- jsmn_fill_token(token, JSMN_STRING, start+1, parser->pos);
107
- #ifdef JSMN_PARENT_LINKS
108
- token->parent = parser->toksuper;
109
- #endif
110
- return 0;
111
- }
112
-
113
- /* Backslash: Quoted symbol expected */
114
- if (c == '\\' && parser->pos + 1 < len) {
115
- int i;
116
- parser->pos++;
117
- switch (js[parser->pos]) {
118
- /* Allowed escaped symbols */
119
- case '\"': case '/' : case '\\' : case 'b' :
120
- case 'f' : case 'r' : case 'n' : case 't' :
121
- break;
122
- /* Allows escaped symbol \uXXXX */
123
- case 'u':
124
- parser->pos++;
125
- for(i = 0; i < 4 && parser->pos < len && js[parser->pos] != '\0'; i++) {
126
- /* If it isn't a hex character we have an error */
127
- if(!((js[parser->pos] >= 48 && js[parser->pos] <= 57) || /* 0-9 */
128
- (js[parser->pos] >= 65 && js[parser->pos] <= 70) || /* A-F */
129
- (js[parser->pos] >= 97 && js[parser->pos] <= 102))) { /* a-f */
130
- parser->pos = start;
131
- return JSMN_ERROR_INVAL;
132
- }
133
- parser->pos++;
134
- }
135
- parser->pos--;
136
- break;
137
- /* Unexpected symbol */
138
- default:
139
- parser->pos = start;
140
- return JSMN_ERROR_INVAL;
141
- }
142
- }
143
- }
144
- parser->pos = start;
145
- return JSMN_ERROR_PART;
146
- }
147
-
148
- /**
149
- * Parse JSON string and fill tokens.
150
- */
151
- int jsmn_parse(jsmn_parser *parser, const char *js, size_t len,
152
- jsmntok_t *tokens, unsigned int num_tokens) {
153
- int r;
154
- int i;
155
- jsmntok_t *token;
156
- int count = parser->toknext;
157
-
158
- for (; parser->pos < len && js[parser->pos] != '\0'; parser->pos++) {
159
- char c;
160
- jsmntype_t type;
161
-
162
- c = js[parser->pos];
163
- switch (c) {
164
- case '{': case '[':
165
- count++;
166
- if (tokens == NULL) {
167
- break;
168
- }
169
- token = jsmn_alloc_token(parser, tokens, num_tokens);
170
- if (token == NULL)
171
- return JSMN_ERROR_NOMEM;
172
- if (parser->toksuper != -1) {
173
- tokens[parser->toksuper].size++;
174
- #ifdef JSMN_PARENT_LINKS
175
- token->parent = parser->toksuper;
176
- #endif
177
- }
178
- token->type = (c == '{' ? JSMN_OBJECT : JSMN_ARRAY);
179
- token->start = parser->pos;
180
- parser->toksuper = parser->toknext - 1;
181
- break;
182
- case '}': case ']':
183
- if (tokens == NULL)
184
- break;
185
- type = (c == '}' ? JSMN_OBJECT : JSMN_ARRAY);
186
- #ifdef JSMN_PARENT_LINKS
187
- if (parser->toknext < 1) {
188
- return JSMN_ERROR_INVAL;
189
- }
190
- token = &tokens[parser->toknext - 1];
191
- for (;;) {
192
- if (token->start != -1 && token->end == -1) {
193
- if (token->type != type) {
194
- return JSMN_ERROR_INVAL;
195
- }
196
- token->end = parser->pos + 1;
197
- parser->toksuper = token->parent;
198
- break;
199
- }
200
- if (token->parent == -1) {
201
- if(token->type != type || parser->toksuper == -1) {
202
- return JSMN_ERROR_INVAL;
203
- }
204
- break;
205
- }
206
- token = &tokens[token->parent];
207
- }
208
- #else
209
- for (i = parser->toknext - 1; i >= 0; i--) {
210
- token = &tokens[i];
211
- if (token->start != -1 && token->end == -1) {
212
- if (token->type != type) {
213
- return JSMN_ERROR_INVAL;
214
- }
215
- parser->toksuper = -1;
216
- token->end = parser->pos + 1;
217
- break;
218
- }
219
- }
220
- /* Error if unmatched closing bracket */
221
- if (i == -1) return JSMN_ERROR_INVAL;
222
- for (; i >= 0; i--) {
223
- token = &tokens[i];
224
- if (token->start != -1 && token->end == -1) {
225
- parser->toksuper = i;
226
- break;
227
- }
228
- }
229
- #endif
230
- break;
231
- case '\"':
232
- r = jsmn_parse_string(parser, js, len, tokens, num_tokens);
233
- if (r < 0) return r;
234
- count++;
235
- if (parser->toksuper != -1 && tokens != NULL)
236
- tokens[parser->toksuper].size++;
237
- break;
238
- case '\t' : case '\r' : case '\n' : case ' ':
239
- break;
240
- case ':':
241
- parser->toksuper = parser->toknext - 1;
242
- break;
243
- case ',':
244
- if (tokens != NULL && parser->toksuper != -1 &&
245
- tokens[parser->toksuper].type != JSMN_ARRAY &&
246
- tokens[parser->toksuper].type != JSMN_OBJECT) {
247
- #ifdef JSMN_PARENT_LINKS
248
- parser->toksuper = tokens[parser->toksuper].parent;
249
- #else
250
- for (i = parser->toknext - 1; i >= 0; i--) {
251
- if (tokens[i].type == JSMN_ARRAY || tokens[i].type == JSMN_OBJECT) {
252
- if (tokens[i].start != -1 && tokens[i].end == -1) {
253
- parser->toksuper = i;
254
- break;
255
- }
256
- }
257
- }
258
- #endif
259
- }
260
- break;
261
- #ifdef JSMN_STRICT
262
- /* In strict mode primitives are: numbers and booleans */
263
- case '-': case '0': case '1' : case '2': case '3' : case '4':
264
- case '5': case '6': case '7' : case '8': case '9':
265
- case 't': case 'f': case 'n' :
266
- /* And they must not be keys of the object */
267
- if (tokens != NULL && parser->toksuper != -1) {
268
- jsmntok_t *t = &tokens[parser->toksuper];
269
- if (t->type == JSMN_OBJECT ||
270
- (t->type == JSMN_STRING && t->size != 0)) {
271
- return JSMN_ERROR_INVAL;
272
- }
273
- }
274
- #else
275
- /* In non-strict mode every unquoted value is a primitive */
276
- default:
277
- #endif
278
- r = jsmn_parse_primitive(parser, js, len, tokens, num_tokens);
279
- if (r < 0) return r;
280
- count++;
281
- if (parser->toksuper != -1 && tokens != NULL)
282
- tokens[parser->toksuper].size++;
283
- break;
284
-
285
- #ifdef JSMN_STRICT
286
- /* Unexpected char in strict mode */
287
- default:
288
- return JSMN_ERROR_INVAL;
289
- #endif
290
- }
291
- }
292
-
293
- if (tokens != NULL) {
294
- for (i = parser->toknext - 1; i >= 0; i--) {
295
- /* Unmatched opened object or array */
296
- if (tokens[i].start != -1 && tokens[i].end == -1) {
297
- return JSMN_ERROR_PART;
298
- }
299
- }
300
- }
301
-
302
- return count;
303
- }
304
-
305
- /**
306
- * Creates a new parser based over a given buffer with an array of tokens
307
- * available.
308
- */
309
- void jsmn_init(jsmn_parser *parser) {
310
- parser->pos = 0;
311
- parser->toknext = 0;
312
- parser->toksuper = -1;
313
- }
314
-