9 if (parser->toknext >= num_tokens) {
12 tok = &tokens[parser->toknext++];
13 tok->start = tok->end = -1;
15 #ifdef JSMN_PARENT_LINKS 24 static void jsmn_fill_token(
jsmntok_t *token, jsmntype_t type,
35 static int jsmn_parse_primitive(
jsmn_parser *parser,
const char *js,
36 size_t len,
jsmntok_t *tokens,
size_t num_tokens) {
42 for (; parser->pos < len && js[parser->pos] !=
'\0'; parser->pos++) {
43 switch (js[parser->pos]) {
48 case '\t' :
case '\r' :
case '\n' :
case ' ' :
49 case ',' :
case ']' :
case '}' :
52 if (js[parser->pos] < 32 || js[parser->pos] >= 127) {
54 return JSMN_ERROR_INVAL;
60 return JSMN_ERROR_PART;
68 token = jsmn_alloc_token(parser, tokens, num_tokens);
71 return JSMN_ERROR_NOMEM;
73 jsmn_fill_token(token, JSMN_PRIMITIVE, start, parser->pos);
74 #ifdef JSMN_PARENT_LINKS 75 token->parent = parser->toksuper;
84 static int jsmn_parse_string(
jsmn_parser *parser,
const char *js,
85 size_t len,
jsmntok_t *tokens,
size_t num_tokens) {
88 int start = parser->pos;
93 for (; parser->pos < len && js[parser->pos] !=
'\0'; parser->pos++) {
94 char c = js[parser->pos];
101 token = jsmn_alloc_token(parser, tokens, num_tokens);
104 return JSMN_ERROR_NOMEM;
106 jsmn_fill_token(token, JSMN_STRING, start+1, parser->pos);
107 #ifdef JSMN_PARENT_LINKS 108 token->parent = parser->toksuper;
114 if (c ==
'\\' && parser->pos + 1 < len) {
117 switch (js[parser->pos]) {
119 case '\"':
case '/' :
case '\\' :
case 'b' :
120 case 'f' :
case 'r' :
case 'n' :
case 't' :
125 for(i = 0; i < 4 && parser->pos < len && js[parser->pos] !=
'\0'; i++) {
127 if(!((js[parser->pos] >= 48 && js[parser->pos] <= 57) ||
128 (js[parser->pos] >= 65 && js[parser->pos] <= 70) ||
129 (js[parser->pos] >= 97 && js[parser->pos] <= 102))) {
131 return JSMN_ERROR_INVAL;
140 return JSMN_ERROR_INVAL;
145 return JSMN_ERROR_PART;
151 int jsmn_parse(
jsmn_parser *parser,
const char *js,
size_t len,
152 jsmntok_t *tokens,
unsigned int num_tokens) {
156 int count = parser->toknext;
158 for (; parser->pos < len && js[parser->pos] !=
'\0'; parser->pos++) {
166 if (tokens == NULL) {
169 token = jsmn_alloc_token(parser, tokens, num_tokens);
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;
178 token->type = (c ==
'{' ? JSMN_OBJECT : JSMN_ARRAY);
179 token->start = parser->pos;
180 parser->toksuper = parser->toknext - 1;
185 type = (c ==
'}' ? JSMN_OBJECT : JSMN_ARRAY);
186 #ifdef JSMN_PARENT_LINKS 187 if (parser->toknext < 1) {
188 return JSMN_ERROR_INVAL;
190 token = &tokens[parser->toknext - 1];
192 if (token->start != -1 && token->end == -1) {
193 if (token->type != type) {
194 return JSMN_ERROR_INVAL;
196 token->end = parser->pos + 1;
197 parser->toksuper = token->parent;
200 if (token->parent == -1) {
201 if(token->type != type || parser->toksuper == -1) {
202 return JSMN_ERROR_INVAL;
206 token = &tokens[token->parent];
209 for (i = parser->toknext - 1; i >= 0; i--) {
211 if (token->start != -1 && token->end == -1) {
212 if (token->type != type) {
213 return JSMN_ERROR_INVAL;
215 parser->toksuper = -1;
216 token->end = parser->pos + 1;
221 if (i == -1)
return JSMN_ERROR_INVAL;
222 for (; i >= 0; i--) {
224 if (token->start != -1 && token->end == -1) {
225 parser->toksuper = i;
232 r = jsmn_parse_string(parser, js, len, tokens, num_tokens);
235 if (parser->toksuper != -1 && tokens != NULL)
236 tokens[parser->toksuper].size++;
238 case '\t' :
case '\r' :
case '\n' :
case ' ':
241 parser->toksuper = parser->toknext - 1;
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;
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;
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' :
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;
278 r = jsmn_parse_primitive(parser, js, len, tokens, num_tokens);
281 if (parser->toksuper != -1 && tokens != NULL)
282 tokens[parser->toksuper].size++;
288 return JSMN_ERROR_INVAL;
293 if (tokens != NULL) {
294 for (i = parser->toknext - 1; i >= 0; i--) {
296 if (tokens[i].start != -1 && tokens[i].end == -1) {
297 return JSMN_ERROR_PART;
312 parser->toksuper = -1;