34#define JSMN_API static
36#define JSMN_API extern
56 JSMN_ERROR_NOMEM = -1,
58 JSMN_ERROR_INVAL = -2,
74#ifdef JSMN_PARENT_LINKS
99JSMN_API
int jsmn_parse(
jsmn_parser *parser,
const char *js,
const size_t len,
100 jsmntok_t *tokens,
const unsigned int num_tokens);
107 const size_t num_tokens) {
109 if (parser->toknext >= num_tokens) {
112 tok = &tokens[parser->toknext++];
113 tok->start = tok->end = -1;
115#ifdef JSMN_PARENT_LINKS
124static void jsmn_fill_token(
jsmntok_t *token,
const jsmntype_t type,
125 const int start,
const int end) {
127 token->start = start;
135static int jsmn_parse_primitive(
jsmn_parser *parser,
const char *js,
137 const size_t num_tokens) {
143 for (; parser->pos < len && js[parser->pos] !=
'\0'; parser->pos++) {
144 switch (js[parser->pos]) {
161 if (js[parser->pos] < 32 || js[parser->pos] >= 127) {
163 return JSMN_ERROR_INVAL;
169 return JSMN_ERROR_PART;
173 if (tokens ==
NULL) {
177 token = jsmn_alloc_token(parser, tokens, num_tokens);
180 return JSMN_ERROR_NOMEM;
182 jsmn_fill_token(token, JSMN_PRIMITIVE, start, parser->pos);
183#ifdef JSMN_PARENT_LINKS
184 token->parent = parser->toksuper;
193static int jsmn_parse_string(
jsmn_parser *parser,
const char *js,
195 const size_t num_tokens) {
198 int start = parser->pos;
203 for (; parser->pos < len && js[parser->pos] !=
'\0'; parser->pos++) {
204 char c = js[parser->pos];
208 if (tokens ==
NULL) {
211 token = jsmn_alloc_token(parser, tokens, num_tokens);
214 return JSMN_ERROR_NOMEM;
216 jsmn_fill_token(token, JSMN_STRING, start + 1, parser->pos);
217#ifdef JSMN_PARENT_LINKS
218 token->parent = parser->toksuper;
224 if (c ==
'\\' && parser->pos + 1 < len) {
227 switch (js[parser->pos]) {
241 for (i = 0; i < 4 && parser->pos < len && js[parser->pos] !=
'\0';
244 if (!((js[parser->pos] >= 48 && js[parser->pos] <= 57) ||
245 (js[parser->pos] >= 65 && js[parser->pos] <= 70) ||
246 (js[parser->pos] >= 97 && js[parser->pos] <= 102))) {
248 return JSMN_ERROR_INVAL;
257 return JSMN_ERROR_INVAL;
262 return JSMN_ERROR_PART;
268JSMN_API
int jsmn_parse(
jsmn_parser *parser,
const char *js,
const size_t len,
269 jsmntok_t *tokens,
const unsigned int num_tokens) {
273 int count = parser->toknext;
275 for (; parser->pos < len && js[parser->pos] !=
'\0'; parser->pos++) {
284 if (tokens ==
NULL) {
287 token = jsmn_alloc_token(parser, tokens, num_tokens);
289 return JSMN_ERROR_NOMEM;
291 if (parser->toksuper != -1) {
292 jsmntok_t *t = &tokens[parser->toksuper];
295 if (t->type == JSMN_OBJECT) {
296 return JSMN_ERROR_INVAL;
300#ifdef JSMN_PARENT_LINKS
301 token->parent = parser->toksuper;
304 token->type = (c ==
'{' ? JSMN_OBJECT : JSMN_ARRAY);
305 token->start = parser->pos;
306 parser->toksuper = parser->toknext - 1;
310 if (tokens ==
NULL) {
313 type = (c ==
'}' ? JSMN_OBJECT : JSMN_ARRAY);
314#ifdef JSMN_PARENT_LINKS
315 if (parser->toknext < 1) {
316 return JSMN_ERROR_INVAL;
318 token = &tokens[parser->toknext - 1];
320 if (token->start != -1 && token->end == -1) {
321 if (token->type != type) {
322 return JSMN_ERROR_INVAL;
324 token->end = parser->pos + 1;
325 parser->toksuper = token->parent;
328 if (token->parent == -1) {
329 if (token->type != type || parser->toksuper == -1) {
330 return JSMN_ERROR_INVAL;
334 token = &tokens[token->parent];
337 for (i = parser->toknext - 1; i >= 0; i--) {
339 if (token->start != -1 && token->end == -1) {
340 if (token->type != type) {
341 return JSMN_ERROR_INVAL;
343 parser->toksuper = -1;
344 token->end = parser->pos + 1;
350 return JSMN_ERROR_INVAL;
352 for (; i >= 0; i--) {
354 if (token->start != -1 && token->end == -1) {
355 parser->toksuper = i;
362 r = jsmn_parse_string(parser, js, len, tokens, num_tokens);
367 if (parser->toksuper != -1 && tokens !=
NULL) {
368 tokens[parser->toksuper].size++;
377 parser->toksuper = parser->toknext - 1;
380 if (tokens !=
NULL && parser->toksuper != -1 &&
381 tokens[parser->toksuper].type != JSMN_ARRAY &&
382 tokens[parser->toksuper].type != JSMN_OBJECT) {
383#ifdef JSMN_PARENT_LINKS
384 parser->toksuper = tokens[parser->toksuper].parent;
386 for (i = parser->toknext - 1; i >= 0; i--) {
387 if (tokens[i].type == JSMN_ARRAY || tokens[i].type == JSMN_OBJECT) {
388 if (tokens[i].start != -1 && tokens[i].end == -1) {
389 parser->toksuper = i;
414 if (tokens !=
NULL && parser->toksuper != -1) {
415 const jsmntok_t *t = &tokens[parser->toksuper];
416 if (t->type == JSMN_OBJECT ||
417 (t->type == JSMN_STRING && t->size != 0)) {
418 return JSMN_ERROR_INVAL;
425 r = jsmn_parse_primitive(parser, js, len, tokens, num_tokens);
430 if (parser->toksuper != -1 && tokens !=
NULL) {
431 tokens[parser->toksuper].size++;
438 return JSMN_ERROR_INVAL;
443 if (tokens !=
NULL) {
444 for (i = parser->toknext - 1; i >= 0; i--) {
446 if (tokens[i].start != -1 && tokens[i].end == -1) {
447 return JSMN_ERROR_PART;
462 parser->toksuper = -1;
#define NULL
NULL Pointer.