From b7681a46464200ed66d2e7f7aa1cc5360875aa39 Mon Sep 17 00:00:00 2001 From: gunboy001 Date: Thu, 21 Nov 2019 22:28:04 +0100 Subject: [PATCH] organization --- .sconsign.dblite | Bin 0 -> 3019 bytes Makefile | 19 -- Sconstruct | 8 + lib/jsmn/.clang-format | 90 ++++++ lib/jsmn/.travis.yml | 4 + lib/jsmn/LICENSE | 20 ++ lib/jsmn/Makefile | 36 +++ lib/jsmn/README.md | 182 ++++++++++++ lib/jsmn/example/jsondump.c | 134 +++++++++ lib/jsmn/example/simple.c | 77 ++++++ lib/jsmn/jsmn.h | 471 ++++++++++++++++++++++++++++++++ lib/jsmn/library.json | 16 ++ lib/jsmn/test/test.h | 31 +++ lib/jsmn/test/test_default | Bin 0 -> 30288 bytes lib/jsmn/test/test_links | Bin 0 -> 30288 bytes lib/jsmn/test/test_strict | Bin 0 -> 30288 bytes lib/jsmn/test/test_strict_links | Bin 0 -> 30288 bytes lib/jsmn/test/tests.c | 359 ++++++++++++++++++++++++ lib/jsmn/test/testutil.h | 96 +++++++ config.h => src/config.h | 0 fbuffer.c => src/fbuffer.c | 0 fbuffer.h => src/fbuffer.h | 0 fbuffer.o => src/fbuffer.o | Bin ste.c => src/ste.c | 14 +- ste.o => src/ste.o | Bin 25 files changed, 1531 insertions(+), 26 deletions(-) create mode 100644 .sconsign.dblite delete mode 100644 Makefile create mode 100644 Sconstruct create mode 100644 lib/jsmn/.clang-format create mode 100644 lib/jsmn/.travis.yml create mode 100644 lib/jsmn/LICENSE create mode 100644 lib/jsmn/Makefile create mode 100644 lib/jsmn/README.md create mode 100644 lib/jsmn/example/jsondump.c create mode 100644 lib/jsmn/example/simple.c create mode 100644 lib/jsmn/jsmn.h create mode 100644 lib/jsmn/library.json create mode 100644 lib/jsmn/test/test.h create mode 100755 lib/jsmn/test/test_default create mode 100755 lib/jsmn/test/test_links create mode 100755 lib/jsmn/test/test_strict create mode 100755 lib/jsmn/test/test_strict_links create mode 100644 lib/jsmn/test/tests.c create mode 100644 lib/jsmn/test/testutil.h rename config.h => src/config.h (100%) rename fbuffer.c => src/fbuffer.c (100%) rename fbuffer.h => src/fbuffer.h (100%) rename fbuffer.o => src/fbuffer.o (100%) rename ste.c => src/ste.c (95%) rename ste.o => src/ste.o (100%) diff --git a/.sconsign.dblite b/.sconsign.dblite new file mode 100644 index 0000000000000000000000000000000000000000..3d0adeb7cb5654fccc554685063d4be021ff8d6c GIT binary patch literal 3019 zcmcIm*>V#{6g9RCwqyYY48~v(Ac)xH*%y|8Eo@`U8+eZbhl=t5m50{s$BMH#_DtKIrrW(Z-yBhD|jQVLsb1| zbZF>J_wyKPHb{N9NKvKKY_y8GPy0SdLycVWUywd&tt$d+Gq0&g^s;3q!- zzR;=fgK;t~fTqN><1QAk2g1sM)DaR76ai=Y%_Nh$+PloZ=cGjxJV zVHG{P$unpq5Nal*C6 zFFnl&(G82(hGO}qk2RIkGBm?+k>;wdYdGN0?5gr$a;OtvFD1ML*R%4aQto~;m#@xm zFE3Ve_faliT3VZ5uJFI{#ZIYI+Fa*9xqM~Q+b%6u-~r_ZKa^Y^F?cMv{5adM##chc zFdV~n4NVV16=UKeLm{rEYQABs@G-CE=c!KM5B3O^9rA?1(`1LtGguhZi}uv$`d?!3 zO!~hl++Gs)Eywmfr!yPEn-xKMbr26hSt716SWhBuFxVWdiN=hhj@x4JLLzPp#EL+y z#)w{o_=!OLR3eVH+PK)1Sf4TYJc;#^!50GS&$qwzywp_PFtM!$mf|`tCYI0J9&04P zDki3F!$5^qolGcNtK@`-eaJyos(7oilW8I|vAJ6{6}P zR%~6d+%R+Vf{@}SA!KvoUHgG1p#E3U5{ zdC(CaycQmGie5^LcomLCG2o4eX&*i!0!H|}r5KF969LEj5pd!ITeu$qWBmK$4AKJ; zkm-)DIHVf^6JGAf0nSDda55U>I0a6906&oer#XR124|8faJB~Lk|{7%gY$_LxKM*> zD##6_z{MKO^i$x{dns_a2D5`HaHR%Uh4!tYcdS@-Q@#96SNJM!wGTU}eT4k~Qv%xI6a)9>ji^&Uu7 zK8=^EoHBC3* z2Fc4er;u= zoJ=@*BTBfPo$amp>hoT#{LRY2h&YC3V|YR{W&T't', 'f' - boolean +* 'n' - null +* '-', '0'..'9' - number + +Token is an object of `jsmntok_t` type: + + typedef struct { + jsmntype_t type; // Token type + int start; // Token start position + int end; // Token end position + int size; // Number of child (nested) tokens + } jsmntok_t; + +**Note:** string tokens point to the first character after +the opening quote and the previous symbol before final quote. This was made +to simplify string extraction from JSON data. + +All job is done by `jsmn_parser` object. You can initialize a new parser using: + + jsmn_parser parser; + jsmntok_t tokens[10]; + + jsmn_init(&parser); + + // js - pointer to JSON string + // tokens - an array of tokens available + // 10 - number of tokens available + jsmn_parse(&parser, js, strlen(js), tokens, 10); + +This will create a parser, and then it tries to parse up to 10 JSON tokens from +the `js` string. + +A non-negative return value of `jsmn_parse` is the number of tokens actually +used by the parser. +Passing NULL instead of the tokens array would not store parsing results, but +instead the function will return the value of tokens needed to parse the given +string. This can be useful if you don't know yet how many tokens to allocate. + +If something goes wrong, you will get an error. Error will be one of these: + +* `JSMN_ERROR_INVAL` - bad token, JSON string is corrupted +* `JSMN_ERROR_NOMEM` - not enough tokens, JSON string is too large +* `JSMN_ERROR_PART` - JSON string is too short, expecting more JSON data + +If you get `JSMN_ERROR_NOMEM`, you can re-allocate more tokens and call +`jsmn_parse` once more. If you read json data from the stream, you can +periodically call `jsmn_parse` and check if return value is `JSMN_ERROR_PART`. +You will get this error until you reach the end of JSON data. + +Other info +---------- + +This software is distributed under [MIT license](http://www.opensource.org/licenses/mit-license.php), + so feel free to integrate it in your commercial products. + +[1]: http://www.json.org/ +[2]: http://zserge.com/jsmn.html diff --git a/lib/jsmn/example/jsondump.c b/lib/jsmn/example/jsondump.c new file mode 100644 index 0000000..1eb6206 --- /dev/null +++ b/lib/jsmn/example/jsondump.c @@ -0,0 +1,134 @@ +#include "../jsmn.h" +#include +#include +#include +#include +#include + +/* Function realloc_it() is a wrapper function for standard realloc() + * with one difference - it frees old memory pointer in case of realloc + * failure. Thus, DO NOT use old data pointer in anyway after call to + * realloc_it(). If your code has some kind of fallback algorithm if + * memory can't be re-allocated - use standard realloc() instead. + */ +static inline void *realloc_it(void *ptrmem, size_t size) { + void *p = realloc(ptrmem, size); + if (!p) { + free(ptrmem); + fprintf(stderr, "realloc(): errno=%d\n", errno); + } + return p; +} + +/* + * An example of reading JSON from stdin and printing its content to stdout. + * The output looks like YAML, but I'm not sure if it's really compatible. + */ + +static int dump(const char *js, jsmntok_t *t, size_t count, int indent) { + int i, j, k; + jsmntok_t *key; + if (count == 0) { + return 0; + } + if (t->type == JSMN_PRIMITIVE) { + printf("%.*s", t->end - t->start, js + t->start); + return 1; + } else if (t->type == JSMN_STRING) { + printf("'%.*s'", t->end - t->start, js + t->start); + return 1; + } else if (t->type == JSMN_OBJECT) { + printf("\n"); + j = 0; + for (i = 0; i < t->size; i++) { + for (k = 0; k < indent; k++) { + printf(" "); + } + key = t + 1 + j; + j += dump(js, key, count - j, indent + 1); + if (key->size > 0) { + printf(": "); + j += dump(js, t + 1 + j, count - j, indent + 1); + } + printf("\n"); + } + return j + 1; + } else if (t->type == JSMN_ARRAY) { + j = 0; + printf("\n"); + for (i = 0; i < t->size; i++) { + for (k = 0; k < indent - 1; k++) { + printf(" "); + } + printf(" - "); + j += dump(js, t + 1 + j, count - j, indent + 1); + printf("\n"); + } + return j + 1; + } + return 0; +} + +int main() { + int r; + int eof_expected = 0; + char *js = NULL; + size_t jslen = 0; + char buf[BUFSIZ]; + + jsmn_parser p; + jsmntok_t *tok; + size_t tokcount = 2; + + /* Prepare parser */ + jsmn_init(&p); + + /* Allocate some tokens as a start */ + tok = malloc(sizeof(*tok) * tokcount); + if (tok == NULL) { + fprintf(stderr, "malloc(): errno=%d\n", errno); + return 3; + } + + for (;;) { + /* Read another chunk */ + r = fread(buf, 1, sizeof(buf), stdin); + if (r < 0) { + fprintf(stderr, "fread(): %d, errno=%d\n", r, errno); + return 1; + } + if (r == 0) { + if (eof_expected != 0) { + return 0; + } else { + fprintf(stderr, "fread(): unexpected EOF\n"); + return 2; + } + } + + js = realloc_it(js, jslen + r + 1); + if (js == NULL) { + return 3; + } + strncpy(js + jslen, buf, r); + jslen = jslen + r; + + again: + r = jsmn_parse(&p, js, jslen, tok, tokcount); + if (r < 0) { + if (r == JSMN_ERROR_NOMEM) { + tokcount = tokcount * 2; + tok = realloc_it(tok, sizeof(*tok) * tokcount); + if (tok == NULL) { + return 3; + } + goto again; + } + } else { + dump(js, tok, p.toknext, 0); + eof_expected = 1; + } + } + + return EXIT_SUCCESS; +} diff --git a/lib/jsmn/example/simple.c b/lib/jsmn/example/simple.c new file mode 100644 index 0000000..1254575 --- /dev/null +++ b/lib/jsmn/example/simple.c @@ -0,0 +1,77 @@ +#include "../jsmn.h" +#include +#include +#include + +/* + * A small example of jsmn parsing when JSON structure is known and number of + * tokens is predictable. + */ + +static const char *JSON_STRING = + "{\"user\": \"johndoe\", \"admin\": false, \"uid\": 1000,\n " + "\"groups\": [\"users\", \"wheel\", \"audio\", \"video\"]}"; + +static int jsoneq(const char *json, jsmntok_t *tok, const char *s) { + if (tok->type == JSMN_STRING && (int)strlen(s) == tok->end - tok->start && + strncmp(json + tok->start, s, tok->end - tok->start) == 0) { + return 0; + } + return -1; +} + +int main() { + int i; + int r; + jsmn_parser p; + jsmntok_t t[128]; /* We expect no more than 128 tokens */ + + jsmn_init(&p); + r = jsmn_parse(&p, JSON_STRING, strlen(JSON_STRING), t, + sizeof(t) / sizeof(t[0])); + if (r < 0) { + printf("Failed to parse JSON: %d\n", r); + return 1; + } + + /* Assume the top-level element is an object */ + if (r < 1 || t[0].type != JSMN_OBJECT) { + printf("Object expected\n"); + return 1; + } + + /* Loop over all keys of the root object */ + for (i = 1; i < r; i++) { + if (jsoneq(JSON_STRING, &t[i], "user") == 0) { + /* We may use strndup() to fetch string value */ + printf("- User: %.*s\n", t[i + 1].end - t[i + 1].start, + JSON_STRING + t[i + 1].start); + i++; + } else if (jsoneq(JSON_STRING, &t[i], "admin") == 0) { + /* We may additionally check if the value is either "true" or "false" */ + printf("- Admin: %.*s\n", t[i + 1].end - t[i + 1].start, + JSON_STRING + t[i + 1].start); + i++; + } else if (jsoneq(JSON_STRING, &t[i], "uid") == 0) { + /* We may want to do strtol() here to get numeric value */ + printf("- UID: %.*s\n", t[i + 1].end - t[i + 1].start, + JSON_STRING + t[i + 1].start); + i++; + } else if (jsoneq(JSON_STRING, &t[i], "groups") == 0) { + int j; + printf("- Groups:\n"); + if (t[i + 1].type != JSMN_ARRAY) { + continue; /* We expect groups to be an array of strings */ + } + for (j = 0; j < t[i + 1].size; j++) { + jsmntok_t *g = &t[i + j + 2]; + printf(" * %.*s\n", g->end - g->start, JSON_STRING + g->start); + } + i += t[i + 1].size + 1; + } else { + printf("Unexpected key: %.*s\n", t[i].end - t[i].start, + JSON_STRING + t[i].start); + } + } + return EXIT_SUCCESS; +} diff --git a/lib/jsmn/jsmn.h b/lib/jsmn/jsmn.h new file mode 100644 index 0000000..cb27ca1 --- /dev/null +++ b/lib/jsmn/jsmn.h @@ -0,0 +1,471 @@ +/* + * MIT License + * + * Copyright (c) 2010 Serge Zaitsev + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef JSMN_H +#define JSMN_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef JSMN_STATIC +#define JSMN_API static +#else +#define JSMN_API extern +#endif + +/** + * JSON type identifier. Basic types are: + * o Object + * o Array + * o String + * o Other primitive: number, boolean (true/false) or null + */ +typedef enum { + JSMN_UNDEFINED = 0, + JSMN_OBJECT = 1, + JSMN_ARRAY = 2, + JSMN_STRING = 3, + JSMN_PRIMITIVE = 4 +} jsmntype_t; + +enum jsmnerr { + /* Not enough tokens were provided */ + JSMN_ERROR_NOMEM = -1, + /* Invalid character inside JSON string */ + JSMN_ERROR_INVAL = -2, + /* The string is not a full JSON packet, more bytes expected */ + JSMN_ERROR_PART = -3 +}; + +/** + * JSON token description. + * type type (object, array, string etc.) + * start start position in JSON data string + * end end position in JSON data string + */ +typedef struct { + jsmntype_t type; + int start; + int end; + int size; +#ifdef JSMN_PARENT_LINKS + int parent; +#endif +} jsmntok_t; + +/** + * JSON parser. Contains an array of token blocks available. Also stores + * the string being parsed now and current position in that string. + */ +typedef struct { + unsigned int pos; /* offset in the JSON string */ + unsigned int toknext; /* next token to allocate */ + int toksuper; /* superior token node, e.g. parent object or array */ +} jsmn_parser; + +/** + * Create JSON parser over an array of tokens + */ +JSMN_API void jsmn_init(jsmn_parser *parser); + +/** + * Run JSON parser. It parses a JSON data string into and array of tokens, each + * describing + * a single JSON object. + */ +JSMN_API int jsmn_parse(jsmn_parser *parser, const char *js, const size_t len, + jsmntok_t *tokens, const unsigned int num_tokens); + +#ifndef JSMN_HEADER +/** + * Allocates a fresh unused token from the token pool. + */ +static jsmntok_t *jsmn_alloc_token(jsmn_parser *parser, jsmntok_t *tokens, + const size_t num_tokens) { + jsmntok_t *tok; + if (parser->toknext >= num_tokens) { + return NULL; + } + tok = &tokens[parser->toknext++]; + tok->start = tok->end = -1; + tok->size = 0; +#ifdef JSMN_PARENT_LINKS + tok->parent = -1; +#endif + return tok; +} + +/** + * Fills token type and boundaries. + */ +static void jsmn_fill_token(jsmntok_t *token, const jsmntype_t type, + const int start, const int end) { + token->type = type; + token->start = start; + token->end = end; + token->size = 0; +} + +/** + * Fills next available token with JSON primitive. + */ +static int jsmn_parse_primitive(jsmn_parser *parser, const char *js, + const size_t len, jsmntok_t *tokens, + const size_t num_tokens) { + jsmntok_t *token; + int start; + + start = parser->pos; + + for (; parser->pos < len && js[parser->pos] != '\0'; parser->pos++) { + switch (js[parser->pos]) { +#ifndef JSMN_STRICT + /* In strict mode primitive must be followed by "," or "}" or "]" */ + case ':': +#endif + case '\t': + case '\r': + case '\n': + case ' ': + case ',': + case ']': + case '}': + goto found; + default: + /* to quiet a warning from gcc*/ + break; + } + if (js[parser->pos] < 32 || js[parser->pos] >= 127) { + parser->pos = start; + return JSMN_ERROR_INVAL; + } + } +#ifdef JSMN_STRICT + /* In strict mode primitive must be followed by a comma/object/array */ + parser->pos = start; + return JSMN_ERROR_PART; +#endif + +found: + if (tokens == NULL) { + parser->pos--; + return 0; + } + token = jsmn_alloc_token(parser, tokens, num_tokens); + if (token == NULL) { + parser->pos = start; + return JSMN_ERROR_NOMEM; + } + jsmn_fill_token(token, JSMN_PRIMITIVE, start, parser->pos); +#ifdef JSMN_PARENT_LINKS + token->parent = parser->toksuper; +#endif + parser->pos--; + return 0; +} + +/** + * Fills next token with JSON string. + */ +static int jsmn_parse_string(jsmn_parser *parser, const char *js, + const size_t len, jsmntok_t *tokens, + const size_t num_tokens) { + jsmntok_t *token; + + int start = parser->pos; + + parser->pos++; + + /* Skip starting quote */ + for (; parser->pos < len && js[parser->pos] != '\0'; parser->pos++) { + char c = js[parser->pos]; + + /* Quote: end of string */ + if (c == '\"') { + if (tokens == NULL) { + return 0; + } + token = jsmn_alloc_token(parser, tokens, num_tokens); + if (token == NULL) { + parser->pos = start; + return JSMN_ERROR_NOMEM; + } + jsmn_fill_token(token, JSMN_STRING, start + 1, parser->pos); +#ifdef JSMN_PARENT_LINKS + token->parent = parser->toksuper; +#endif + return 0; + } + + /* Backslash: Quoted symbol expected */ + if (c == '\\' && parser->pos + 1 < len) { + int i; + parser->pos++; + switch (js[parser->pos]) { + /* Allowed escaped symbols */ + case '\"': + case '/': + case '\\': + case 'b': + case 'f': + case 'r': + case 'n': + case 't': + break; + /* Allows escaped symbol \uXXXX */ + case 'u': + parser->pos++; + for (i = 0; i < 4 && parser->pos < len && js[parser->pos] != '\0'; + i++) { + /* If it isn't a hex character we have an error */ + if (!((js[parser->pos] >= 48 && js[parser->pos] <= 57) || /* 0-9 */ + (js[parser->pos] >= 65 && js[parser->pos] <= 70) || /* A-F */ + (js[parser->pos] >= 97 && js[parser->pos] <= 102))) { /* a-f */ + parser->pos = start; + return JSMN_ERROR_INVAL; + } + parser->pos++; + } + parser->pos--; + break; + /* Unexpected symbol */ + default: + parser->pos = start; + return JSMN_ERROR_INVAL; + } + } + } + parser->pos = start; + return JSMN_ERROR_PART; +} + +/** + * Parse JSON string and fill tokens. + */ +JSMN_API int jsmn_parse(jsmn_parser *parser, const char *js, const size_t len, + jsmntok_t *tokens, const unsigned int num_tokens) { + int r; + int i; + jsmntok_t *token; + int count = parser->toknext; + + for (; parser->pos < len && js[parser->pos] != '\0'; parser->pos++) { + char c; + jsmntype_t type; + + c = js[parser->pos]; + switch (c) { + case '{': + case '[': + count++; + if (tokens == NULL) { + break; + } + token = jsmn_alloc_token(parser, tokens, num_tokens); + if (token == NULL) { + return JSMN_ERROR_NOMEM; + } + if (parser->toksuper != -1) { + jsmntok_t *t = &tokens[parser->toksuper]; +#ifdef JSMN_STRICT + /* In strict mode an object or array can't become a key */ + if (t->type == JSMN_OBJECT) { + return JSMN_ERROR_INVAL; + } +#endif + t->size++; +#ifdef JSMN_PARENT_LINKS + token->parent = parser->toksuper; +#endif + } + token->type = (c == '{' ? JSMN_OBJECT : JSMN_ARRAY); + token->start = parser->pos; + parser->toksuper = parser->toknext - 1; + break; + case '}': + case ']': + if (tokens == NULL) { + break; + } + type = (c == '}' ? JSMN_OBJECT : JSMN_ARRAY); +#ifdef JSMN_PARENT_LINKS + if (parser->toknext < 1) { + return JSMN_ERROR_INVAL; + } + token = &tokens[parser->toknext - 1]; + for (;;) { + if (token->start != -1 && token->end == -1) { + if (token->type != type) { + return JSMN_ERROR_INVAL; + } + token->end = parser->pos + 1; + parser->toksuper = token->parent; + break; + } + if (token->parent == -1) { + if (token->type != type || parser->toksuper == -1) { + return JSMN_ERROR_INVAL; + } + break; + } + token = &tokens[token->parent]; + } +#else + for (i = parser->toknext - 1; i >= 0; i--) { + token = &tokens[i]; + if (token->start != -1 && token->end == -1) { + if (token->type != type) { + return JSMN_ERROR_INVAL; + } + parser->toksuper = -1; + token->end = parser->pos + 1; + break; + } + } + /* Error if unmatched closing bracket */ + if (i == -1) { + return JSMN_ERROR_INVAL; + } + for (; i >= 0; i--) { + token = &tokens[i]; + if (token->start != -1 && token->end == -1) { + parser->toksuper = i; + break; + } + } +#endif + break; + case '\"': + r = jsmn_parse_string(parser, js, len, tokens, num_tokens); + if (r < 0) { + return r; + } + count++; + if (parser->toksuper != -1 && tokens != NULL) { + tokens[parser->toksuper].size++; + } + break; + case '\t': + case '\r': + case '\n': + case ' ': + break; + case ':': + parser->toksuper = parser->toknext - 1; + break; + case ',': + if (tokens != NULL && parser->toksuper != -1 && + tokens[parser->toksuper].type != JSMN_ARRAY && + tokens[parser->toksuper].type != JSMN_OBJECT) { +#ifdef JSMN_PARENT_LINKS + parser->toksuper = tokens[parser->toksuper].parent; +#else + for (i = parser->toknext - 1; i >= 0; i--) { + if (tokens[i].type == JSMN_ARRAY || tokens[i].type == JSMN_OBJECT) { + if (tokens[i].start != -1 && tokens[i].end == -1) { + parser->toksuper = i; + break; + } + } + } +#endif + } + break; +#ifdef JSMN_STRICT + /* In strict mode primitives are: numbers and booleans */ + case '-': + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + case 't': + case 'f': + case 'n': + /* And they must not be keys of the object */ + if (tokens != NULL && parser->toksuper != -1) { + const jsmntok_t *t = &tokens[parser->toksuper]; + if (t->type == JSMN_OBJECT || + (t->type == JSMN_STRING && t->size != 0)) { + return JSMN_ERROR_INVAL; + } + } +#else + /* In non-strict mode every unquoted value is a primitive */ + default: +#endif + r = jsmn_parse_primitive(parser, js, len, tokens, num_tokens); + if (r < 0) { + return r; + } + count++; + if (parser->toksuper != -1 && tokens != NULL) { + tokens[parser->toksuper].size++; + } + break; + +#ifdef JSMN_STRICT + /* Unexpected char in strict mode */ + default: + return JSMN_ERROR_INVAL; +#endif + } + } + + if (tokens != NULL) { + for (i = parser->toknext - 1; i >= 0; i--) { + /* Unmatched opened object or array */ + if (tokens[i].start != -1 && tokens[i].end == -1) { + return JSMN_ERROR_PART; + } + } + } + + return count; +} + +/** + * Creates a new parser based over a given buffer with an array of tokens + * available. + */ +JSMN_API void jsmn_init(jsmn_parser *parser) { + parser->pos = 0; + parser->toknext = 0; + parser->toksuper = -1; +} + +#endif /* JSMN_HEADER */ + +#ifdef __cplusplus +} +#endif + +#endif /* JSMN_H */ diff --git a/lib/jsmn/library.json b/lib/jsmn/library.json new file mode 100644 index 0000000..8e2f5c2 --- /dev/null +++ b/lib/jsmn/library.json @@ -0,0 +1,16 @@ +{ + "name": "jsmn", + "keywords": "json", + "description": "Minimalistic JSON parser/tokenizer in C. It can be easily integrated into resource-limited or embedded projects", + "repository": + { + "type": "git", + "url": "https://github.com/zserge/jsmn.git" + }, + "frameworks": "*", + "platforms": "*", + "examples": [ + "example/*.c" + ], + "exclude": "test" +} diff --git a/lib/jsmn/test/test.h b/lib/jsmn/test/test.h new file mode 100644 index 0000000..a1c0957 --- /dev/null +++ b/lib/jsmn/test/test.h @@ -0,0 +1,31 @@ +#ifndef __TEST_H__ +#define __TEST_H__ + +static int test_passed = 0; +static int test_failed = 0; + +/* Terminate current test with error */ +#define fail() return __LINE__ + +/* Successful end of the test case */ +#define done() return 0 + +/* Check single condition */ +#define check(cond) \ + do { \ + if (!(cond)) \ + fail(); \ + } while (0) + +/* Test runner */ +static void test(int (*func)(void), const char *name) { + int r = func(); + if (r == 0) { + test_passed++; + } else { + test_failed++; + printf("FAILED: %s (at line %d)\n", name, r); + } +} + +#endif /* __TEST_H__ */ diff --git a/lib/jsmn/test/test_default b/lib/jsmn/test/test_default new file mode 100755 index 0000000000000000000000000000000000000000..e5bb476ff1c4de658b2f16213c5e71c6173cd277 GIT binary patch literal 30288 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 ORNheLrx~PWwf_Udjj>Ar literal 0 HcmV?d00001 diff --git a/lib/jsmn/test/test_links b/lib/jsmn/test/test_links new file mode 100755 index 0000000000000000000000000000000000000000..9f1b9d93a21f44e5e29f30fb960f5079750a04c8 GIT binary patch literal 30288 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 Nq}P0#x0I^(e*jJKUJU>M literal 0 HcmV?d00001 diff --git a/lib/jsmn/test/test_strict b/lib/jsmn/test/test_strict new file mode 100755 index 0000000000000000000000000000000000000000..7c0841ab4851f6c75eee5af1c8d31ea884fdd06e GIT binary patch literal 30288 zcmeHwe|%fjmFM%X*fEJ^XaeEKG{S^V42k0(A&CP4J6O&Oje|*I3KKhuY|FNSZMl|| z*fl0jWm8mD;4XyHF0|>ES(t9iq!c=anWPS+I50EaK>6W;Kn)v;gfrmMKn(@7-*fK0 zPfxP!=CkeYKkN7TNax=3>z;e=dFS1G-;>^6+osCYloU-JY1-8q)ehzgOqnDcZoGwdYJ&AilZep9%e~=8X(C%Ea{2x0?DVKvXCIjO?QluK{yoD zWIsqQg9x&o2Pv(bpwXcq@zPQKwzrYWwO{7y6gW?|r=XI%0dmsSLh#Rg zE4Ocv?M>&GMbdr+W%JsKR#*Ls*2d+nu6AG7@~$YS-)oF~cgw*qfX!hiWR{9l*`zhoLb`6Zb>*H44L4|pp+iAO0A$@Dw~yfu*- z^)h_&lHfIrUjq%;D$V2VY;S1m(Cl`P*U@l`y`kk6dy~V}s&#a_+PzIgZ*{h7ZO%52 z)2p>PT3g)>U~cGg*qdDKj#k&#oT!pMQqbwOw>ezxT2rUfscqP_as9RS;)0b%skq<@ z&AxG4mA%o~>1=j+yw1*TRoAw<+nw7S^{u3+xy{`!71;%AQbzPCm7^sUaYH4F81VwU1r z9b+cEk|A2ygoi=KF=4_}%&KG3gs1aE9gCzrnLtp#)nPT^$vf&;YQn1=LbO5?p7XO5 zSYyJQ^GuluPi?D1H{r7tau&{dVAcb(9+>sOtOsU2FzbO?4@~iZ?mv~K2Qyx`YnnbV z>`jdx*ZoJco;LWRSG)yM^wN{~wk$3~iRvvxkBmieT>2{2X$lxQ&h;0lPE)_gFxQ`> zI!#R@2f6+f)oBVCIl%QNsZLYB$RO7rr8-UdB7I!nf_l>+>U7n_*xs1TNo%yhK;T*`Ewk)n-R5vPmD5H}=>7;idy8Ffsl+oR}(J{;7 zK2rR&gix`O`L9?{ApdhcFrgoL?;8EcWSXAxjQ;%R-UU$bxKxl89c$utlziX1xscO* zD{6HAx_iN;>4CSs^Yq}lcTov1N0-7a_EzTJDBlf$ohv<0vSIGfK*XW$A%oz0@|kCzE-{t0Xq0r|7|&aNs(k9~n#615dH)l;e89 zHi_coNLdyQ6BUEi2qoKOpgLU;c)dWyI@Rc8z;`-OGZCmd#r!p=1G%CwA%%i9rvgID zNEwR{N?HG@HHJ6H=s?x+O#$06NQZ-3z;-(F6LPhvDHAQf&@6|C{gb_x{%1i&VeeZ1 z-$2m<}?ukxkGSzH1Zte1!Jfh4kdz=W3TVNK-Nr_lLgBl8`Ja|Y3gH3 z{JqCDpKLl*P0pvLK+?wRF)p0`VfnV!^k?>p?!QVw|wJED5HVUf&m&Ps5G*wWi>Ny1x}l(+J>Ym)HpOv>AIo5|rE*8jsW z%dpsQn@I8ZPNeN!D)q8YIlvR_qyS%vVH12J!Z4KM3q%;ws8S>28wbZz=-h+2(aM?V z{x*g?rixA;BW`a(+#+6m!-(4<#O=X~fbA#Hd5rR)?L=e`&H%0o#}2DVeZ_Lv_KH7@ zoZz*5BOgq01G)~E9yOpvDD!~&Z6{I?*#|XCe+C4CHE5^mASst2-S!EGbQnxw3V+xc zjohXTD9iFsM!n_2wk*Vok%JFHJx+xQkS2nNz!b>xpsW|N6Tz~1!e7X(^ZI&U>G5T9 z${WvklCI8>6Itk(44<$_!Q=yfIE5qX7;Wo;;gAoPnm=$YdZdfl))akQM9ZEtvsoh`Gm_$O5y>?9HQhnK41C0`-!0K zgfUMPlROyCfr;rJ(u*qc%r7=Wt4>U-FmecqZysj%BQ{E4_uc8UOpAmECUY;^Zrte zdJvNaPOpEdCbDg8#CC!*J3NaF8PO4XNF3?DdePCpsPEEJ>0wO#aS4;{jQw?dK|L7# zD_BZ;PW+Yhj2WSXOG50jND&jvMLI5h%3F%2rjn{oGMX1hJ1$X+qsHH>$zcPfaa>a@ z{g1+X{@xQPJuLi~sH`jU=X#+5WJh^C6C_v8Z=j5}V5A(Iqyiwex~iV=>JS8k#p7nybiKfA2Az&X5$=2f;1r z`OgQQ(;HsUOON~XB;Da1)Bl`9SlNrHS8buS}pmuK1+Vppe4WNfF-}~ zpe5fqY{_psZprtJS@L@)8ueiMrAsMd0|Po_iiSr93IP`ZH8QXgr9vWxY`I`qgQ^}H zs3s5?C<6!%aO)VrP>96zARDCz2ZV_u;rTT45sOp))`N$rokqRnDsI=C5zcr|O}Dq| z`%YzvE>2>88hHFPeea*Zw;l-H1Ud9@Cj;&;dU%N?pZknXqN6qFXdOE0L`U1uQ6DIKbNF40I&?@PBgW=xT+oE+Bwlyy#=}^#SG#4v=YtT*s^
8; z2OnpG5GoIhQs4$YA;w4lKt4!^t{{J3IY9mLekr)0pullZ+`m`_MGAC_pxEO-L|j_e z%_9R=s1PHw1SQkREG0WbJR}$y8VT7i9vKqD$OtP9^F5Pf75M?f#Wa|@@f3*)+`I7}sMD!u+i)v5EzasH#Z1H)K< zWP=*{4zXZYF+m5Zi_>wxq2ndYKctS#A-efIexp#ZYtF9pT`9Y?U1|7E*_B%U1l{tL zMzKQ7_cgJ=53Sp5DC`#st6@~;5N#u2rGjrwo^zp$60la2ZatKd&t@#z+6%eM^lU_AH*A5GnY%J}rLxYKz+6pMmp_pO2D2N@Iu9B;U-*<=P{umxS(Zp1 zbV@HocSWiHu=PHvR|7`jToMQGU~Hr1L-Z|%jCNHI(-(%U%4n;J+d9?9ZJkSP{Q|v( z_Fb$=c*P;K0$XdsZZWW%O<0@2?n;|#0gcyT`ho>-UZgyDk|(gzg7e9Om9StJ*^n!B zQEz_?0eBH5KbM4M-2zL|FjIdYGg{lttsULT{e^lh@(jM7ca zj1MF-_85#-!I(L833$f$#Hrh1aD9SQ33Zu6ONi@+IIe3At``;8rNnjllRR$Hw95^y zM-&$}D-$A`Ht|Cl=Yf@@I?gkEp3v7}`a);NFI3}D3ynDOtZd;b(YDzw&l;S?s_oTN z+74y>5^U;h8saiXe&XnuBfrbgJc=|78^qakHMB>*BBC*9(prCJTCX*KGZy>@+Df}{$w)8;ePzAJ(-vmR) zOe$aF@}G6;cMO%-dx)v5B$aUqkh3$|cu46rm*av5PLpQ}jUIyMW}}V8q79L z5CJAq7W93~r2EUNJhN`{qHxL6SbW1JLic9Ut($d|5u9Gp&ilw8GS$u$aOWAio6Wj! zAl;`ZG?Y)~n{?+aIwRfx3KN9gXPI?xCEbH&-OnjoVfUlwossSVL-#*^Wbz3;z{p9{ zu=|@P-8Y_@ZkwTdt6BF~NcSkd4BZ=*Zoce@OWX&za!liQEa^3I6Ct$jGq_Or=KT-Z zeoDicLpOsZA!&{qoWBAmbJY=7eA0Z?;QE2$+Cf~GKgq4ir1^}&)vdVbu3Y?CuBlANDW9fefX2|!@RPPU%%VM$FN9RK11$^nDssmWN^kD(OOyxs-jRoud z5t@J9N*9$N6aaJTEtE?!VIS~A(tn6(8Q6iM$EhO+SeXyXz$^oB;d(T`h2{>pFL1Ri zqsfIUP52eEJk2!_4G%%J7XB_~sW^{1;LY=f=t;iuLSe#Z-pnBn)vZ{c^wIi+t-V@V zd;22T$vUuIJ&6h9JT+mw94yA#Weh5&I`D3UpKdHID##n~#7}5yEmk7z$#KYHiNPz6 z;C{K%SVPRA0g@@_=_E;3hRLhTh!hkH79j6_6V+0l7h49t0bTw>#4!iH9Y8JeQ&#`D zP|s2{zgTzwdNoE;dXb9gCTM`^N~`q>g?HT*A?`gzAFN%$^Q&s8+*Hc=`_L z7#ZlpH=5KU+bLIu2JS(f+*d+V{LsJwRG&Nm`e9-sLLb>7Rv7VwW)Ol8kUm&V%85IV zxC0}4Xg_Jf+JgzAnYg9VcYa61)ek2BA^MJDNPd7OBQH@d46-3uU_H!w<@#p7E=Knt ztKLuBrRWzAUSR)Cf;KE@#{_LBAp`qc1nsz>jS5E7qSjK#DPLu(!mYCPS9q&i2JA3Fs@?(g`FZ8(3z^Xa4S9ADMXqSjUHih;@ zSf_~4zEINQC+i&AltE#fNF6(9uSSG+=Fs1RGJd|FLoCIAh$17ya_4leWwbsATkHC$hm)y=i4#hqjdcY4V)x^kn2V|g-aQW>Vel84d+b| zL-27Ed-+fwTd$mV&Pj6Ki{SGgqHnD`bLe^Mg_sB>X0;lqmRZezDpwC>oP?Xyy@V%e z4R;uwC8LCQ@_0W97qZcqP9rNG2X1N?pJ9z635X0wUAz~$4ISc04?fOO6QBN`=hlh! zn*T*zqWv5HA^J{3j`YsX)ME=ps&%S@6H+ZzRetJut(arz@+c$8TB2;C5P^SWei zX$ks{BK@iUzW3@({cUG`Y0&pM>H96E$56)4ajGKn4Eww$eczu^-xm#isZbTUOXzD& z(6_{-Z}W`$emzG0&4hh(NZ&O=Ur~a-7m=n^e?R|^nfiMh>!aCEHtBmGoko9uk6$>L z``d5Q_sER;3JiTYq>rvK&^MHzZ>34!jv4j6@muO|I!>!|pl^H&l=%{ry@Rx(I(znv z%D&CYGNJ5TQkFdJyfLcIC3BJ#8R%@$G~a*YJNAc>bz>Rmz`JszqKNulh%cCXDwlmJ zWO%(Dm$h1zObN++D*QDvMJBGDHA?0Rk~t=19-LVwUCFE_nR|rHUXu*c(mqsaibW~v zYh30Oh0-+JWh(VPL>C2>r%KVl_$u`LYLj-ce-hX8P6+Xm;wlnISPWCXKhGo&i$27z zp|UPBW*u#CCg03c*3FGsmpxQL-Tyby{a+ys8y6HFnm9Ki^OsrI-wD(Wm|};=1*%1$ z_F`2N9u+9BK)rMts9y=xcLi$SAAx#QpdJyZ+DV{(AW%FWp><8f^(}!qBDg*xRJTAK z5~!Syfoc+{5rNu(UDWVaf%UJg`n;U_C`XCh+)-+W(y)QGu6 z?}bILSr%)X0v~J&yjKx;r#!mgx4Qr76utCy-@7<(vbNWi z*Ou3n?hN0eGi#^y z(#Cwc;Avk+{&FYzB;ph6i86_FRVR4MOVQ}tn2plsHTf}@74H8ODqZ(r#&sq-7GrXE zfyovspUEc^a%ZCd|0d6i@F(g29aCam$v$>-tG>k z)#X7{Ewi?}y?_*4F*^U2JCPwqcD6T8PxRn7;fYj=T(kb&j#i&wD!9xeP4Hyn*X9nd z&yy(J(~H~T+V-B_Wj(!hT2G!MZ*5_(R;W2dd3#;2D1afaK5uPLZ?9I*?e%0^^C}$O zd26l3tCpc$RRAU~kc$Ef0q1IZs%u0H#c@25J zS_31qVE`Gj%qk0Otv$tPmyJVlt+gapBZIBQjM-jPSf>>gO1>iMO}*RQdLvA+uC;nQ z;gnvDfF{xL3{8$!4{LMh4WgR_~E~GkGr$A5k4^0=nn#@DdBIkh||;H=x}=0T5DI-cGkAndTZ-z zn`-lFYoTCTTC7#L8;q#Kd3m+I^7@7f)I~vJ(R8h^5C;fG*^sEj0W1s2vY>5;y29c$ zg?We@Q8MeRtlS{QMANLetg@*Rih39&kw3GZS!O0*))YMp^m>meyubBi}`Z4m`&tE1c5 z>B(EW-3m&h!wc7KU$tyi9cwr7wL99J@anaW)~~|CMyGX~tJP^OBFo(!js}+(_QSk9 z$`au7g379iVYkcU!hbd7t)(bMeUGb=&M9smULZ3dU1;s4R^6R0XFJYmm%AN$+@0PQ zce5M+8bOLWI^7-4POr-egJEwkP}Gp>P)V^w;D0AnmzrFi9&fX&QCR0{b2O8A1qHP$ zxa_H2K^i;-9qrB30wa~aRVx)nS-gsDZF6)syI>rZrCZ1uoq(8dbKD=;iJ0lzv3$ zA`3M;I_tr!ZQqU%!WZJoD4>L@#DU6*%Ty;y9+SZdrKAIFFcO1MVwAR1m^$*nOj)K* z%e%$dji{j!B#*T2GMx zEWiwK8jM0OitD(D>yOjpwKlmstq!ZRt;5@Gy>9FEo2~BpUCsutXN9A))6wlQGnvU# z@RFT|j`iXXQ`%f!*KViKN~a%RW~D~t5robZ8jrk?$G@kz9Ib*wa(6foFYV2;0m;A( zTRWYOMj{#Q$DyrzT;3LR(?kE*;_SqLwbcW-o2+~hr@M_fxLsfSSAA};v(XBFV!qkx zx&;^JcI$PH-HxpdovsdVzTgukd92Ax;!4Fl}n0? z)ivGg1O#ffRAE+ zI|_I==An~-PVCk%O4GDA0oMTDgIhB<0e%mA#a)1}VUPSizzS?^4gscNH~a)(4&bMN zKLfl7H->%>copCY>#AeRF0FL5j`3b;^3CIIJ2v~ugs0B3m zI8wg0MN8?*O}TJhX4YUzW-j6J*pjvs{<)kOy*6pQkGN zr=Z{XY&5!zcJK`P-)1QKMbKOSYw0gVZ;G`~dz@{cuZoi|GURJP_x~mueGBRh{i(0B z0xM7ypEhhK{S45c>;AN~2e}K}2m0aU3s|$g2^NDV^#tpnJ`RI^H)8Vz#GpY>`*)*{ zW1!m*qqoM%3n!91ElYn0`p>}^lYhkUp%wI%xLY#^F&d+%q$wYjfqnsEy*y6-DnouJ z=vQKk-W5l0WV#h9`#|r<{e@ow8v4lxk8&5-2lTwtV%(HF3oHgtWo#ViKiINC|B;!V z`hCMkCqWN^US_8E#N^Y_x1WMePf8g2Q-5d3F9E#^=k2CAA8asuPyzgdIB%!3uMzaS zKyQ!pfy?kwKj^RHe5YM}qy4mEgZ?1sr?LCn5J%s^bUOErf?hT*&$IP8xp$>*%vp42 znk~l~O1I@K{Z>XrPT}oy^qe*R%ndnZyK>f)=MtU7xcE{OfbF_&?j`A&=Yy zJ=DzXG3$X@56pUC)&sL1nDxM{2WCAm>w#Gh%z9wf12cO-{lBpKKVh|&QV`EOiGv=% z!ZBX}E&VD{z%M}fQ2$$uA35=%_Ezw#89vni7xNk(7)Af^^QfB`valwkgSIB<;D3Sx zq{r&%D3o-*@r?Qr#$sPg!bK7;lu!XFrl~(zre!-F4+~)IKhbXy>A=JPe5{cTD}0wU zOxZmw`Q}Qf+W!-7iAxl-;$beX>rx(%>TzB97u#T5zf96UmUY8!sqFtXQ2#5R*zPJB z2bB`uC}ER?yCu9`!h0oDder|@Z@Bi_wbrHh$Mt+`X+d#8p`y?RMq|A&FU`rD^AC>i^8+`Ej;(m@%T9rY+K{lj6_Ub|%HEEEUs5=V!Y1 z`)CX!N_0{u!{cFZL}89L2G^Mn%14CH#Z$ZHW2wZeysK#ROV<=FW~a&%Rg9nNH?P#A z^0?B|$NW?MPY**Uv;QIHKVNH<{=wE7A3vA)mIVASfv0}$m;K^BbKs6j{09=xd*#5r zB=OC7N}LXP`Ow}*ne_Zf;(2czIC_$v@T=s8KktbHNAH^;yiHz6crP3H`4ZoAF)BFT z5Uycv z(}T2HlJm>KdZxyC11=D$boEP!w>{uL2mMtJX0_1#4aTe1V(`1u;2#0r8e=m`--kb~ zNzSk5SWk}Dzgn=W>+*j9p9}uP^KMM?uURShd9ND9eS}Y)nwQ3z-!Q`{(B`iU9Ro*& z3t?w6JpDL>{Ij}1u=74Yit8o*zzTuq{e2X-PNSz;^5-lO{BH`Nbxy*CM|8O)*rlEeWPVV1m&Cs>$BXYjLB=}(N$ zeUg72C2AaezX@j9l#O`ggH_*FIJb2GZqubux z>aKUR+8e#@PLJK;>(UzBZ5^#n+(j=~U9zSyITO8f#bxJP{dPQA)7gzzt>9rEd!w(d zts5eynw^Y^W2M{u9@s?C-r?|g{9Z`gGG`tnWo>nkg_+P2xZm9O7qBdz@YnFf!K-NSF6DJxU2pP`q|z$SXjO+0d@ zH_@<*@F0SC4nea!>2VI>IDT+}G~&HD2?`V5p%bI7l&{l?VaO^u4*b}M7$|`f!`tr0 zOLydpcaq5Q11zfRu~+ZJbMj#Fuz-`gAl|JbnsK#v_`G)XqS@O5a{Q}z?2R6`y~WYq zh}ZJ4o#H7OJ3Vy6b$-ahUc4G_>A4_*k=?7}xC z5iq$qs0*AeGHtXpLW!ygQ5lvjp~`5%(dKGE^KLI`hH-Rq6kr&%0wl3EBqo&*|1wDX z8n_f;&LxhAWkJEj6$J5`k4sRYy#yt%)~gE2%aS3YuDc4cDnVYYYZbIAMhO$;D}et9 zdkd<4wcnzkYF}io4RG`{d`e?pmwqNZ(Dya716n|p>|3S*D z@zcsAr-Zc>+@?d>tx!Khf!bH{iSI?Eb*cGCY@gQ4W_h(=qF{A`Kw|sPLLRF+K8L6s zwSH9ZOHAZfbp>htZ86EK{g(+jF;{$~n+{c1@J-+-_UIg@L+#V3_fd|?{;T*@a%vp! zgAB1Kd9|N2YA0=Y&QAd2TgfZK4E)^d5MW+=pd+Kj}h{#Yo{pa@&uq| q4=wdnzg7Mvva(%Bi0@&SfawVat9BJH*_TZIXq({3Ob|$@YX2J^7-6jd literal 0 HcmV?d00001 diff --git a/lib/jsmn/test/test_strict_links b/lib/jsmn/test/test_strict_links new file mode 100755 index 0000000000000000000000000000000000000000..0054670ef4b335263cdc53472c07c40ccf66041f GIT binary patch literal 30288 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 literal 0 HcmV?d00001 diff --git a/lib/jsmn/test/tests.c b/lib/jsmn/test/tests.c new file mode 100644 index 0000000..d8a4d92 --- /dev/null +++ b/lib/jsmn/test/tests.c @@ -0,0 +1,359 @@ +#include +#include +#include +#include + +#include "test.h" +#include "testutil.h" + +int test_empty(void) { + check(parse("{}", 1, 1, JSMN_OBJECT, 0, 2, 0)); + check(parse("[]", 1, 1, JSMN_ARRAY, 0, 2, 0)); + check(parse("[{},{}]", 3, 3, JSMN_ARRAY, 0, 7, 2, JSMN_OBJECT, 1, 3, 0, + JSMN_OBJECT, 4, 6, 0)); + return 0; +} + +int test_object(void) { + check(parse("{\"a\":0}", 3, 3, JSMN_OBJECT, 0, 7, 1, JSMN_STRING, "a", 1, + JSMN_PRIMITIVE, "0")); + check(parse("{\"a\":[]}", 3, 3, JSMN_OBJECT, 0, 8, 1, JSMN_STRING, "a", 1, + JSMN_ARRAY, 5, 7, 0)); + check(parse("{\"a\":{},\"b\":{}}", 5, 5, JSMN_OBJECT, -1, -1, 2, JSMN_STRING, + "a", 1, JSMN_OBJECT, -1, -1, 0, JSMN_STRING, "b", 1, JSMN_OBJECT, + -1, -1, 0)); + check(parse("{\n \"Day\": 26,\n \"Month\": 9,\n \"Year\": 12\n }", 7, 7, + JSMN_OBJECT, -1, -1, 3, JSMN_STRING, "Day", 1, JSMN_PRIMITIVE, + "26", JSMN_STRING, "Month", 1, JSMN_PRIMITIVE, "9", JSMN_STRING, + "Year", 1, JSMN_PRIMITIVE, "12")); + check(parse("{\"a\": 0, \"b\": \"c\"}", 5, 5, JSMN_OBJECT, -1, -1, 2, + JSMN_STRING, "a", 1, JSMN_PRIMITIVE, "0", JSMN_STRING, "b", 1, + JSMN_STRING, "c", 0)); + +#ifdef JSMN_STRICT + check(parse("{\"a\"\n0}", JSMN_ERROR_INVAL, 3)); + check(parse("{\"a\", 0}", JSMN_ERROR_INVAL, 3)); + check(parse("{\"a\": {2}}", JSMN_ERROR_INVAL, 3)); + check(parse("{\"a\": {2: 3}}", JSMN_ERROR_INVAL, 3)); + check(parse("{\"a\": {\"a\": 2 3}}", JSMN_ERROR_INVAL, 5)); +/* FIXME */ +/*check(parse("{\"a\"}", JSMN_ERROR_INVAL, 2));*/ +/*check(parse("{\"a\": 1, \"b\"}", JSMN_ERROR_INVAL, 4));*/ +/*check(parse("{\"a\",\"b\":1}", JSMN_ERROR_INVAL, 4));*/ +/*check(parse("{\"a\":1,}", JSMN_ERROR_INVAL, 4));*/ +/*check(parse("{\"a\":\"b\":\"c\"}", JSMN_ERROR_INVAL, 4));*/ +/*check(parse("{,}", JSMN_ERROR_INVAL, 4));*/ +#endif + return 0; +} + +int test_array(void) { + /* FIXME */ + /*check(parse("[10}", JSMN_ERROR_INVAL, 3));*/ + /*check(parse("[1,,3]", JSMN_ERROR_INVAL, 3)*/ + check(parse("[10]", 2, 2, JSMN_ARRAY, -1, -1, 1, JSMN_PRIMITIVE, "10")); + check(parse("{\"a\": 1]", JSMN_ERROR_INVAL, 3)); + /* FIXME */ + /*check(parse("[\"a\": 1]", JSMN_ERROR_INVAL, 3));*/ + return 0; +} + +int test_primitive(void) { + check(parse("{\"boolVar\" : true }", 3, 3, JSMN_OBJECT, -1, -1, 1, + JSMN_STRING, "boolVar", 1, JSMN_PRIMITIVE, "true")); + check(parse("{\"boolVar\" : false }", 3, 3, JSMN_OBJECT, -1, -1, 1, + JSMN_STRING, "boolVar", 1, JSMN_PRIMITIVE, "false")); + check(parse("{\"nullVar\" : null }", 3, 3, JSMN_OBJECT, -1, -1, 1, + JSMN_STRING, "nullVar", 1, JSMN_PRIMITIVE, "null")); + check(parse("{\"intVar\" : 12}", 3, 3, JSMN_OBJECT, -1, -1, 1, JSMN_STRING, + "intVar", 1, JSMN_PRIMITIVE, "12")); + check(parse("{\"floatVar\" : 12.345}", 3, 3, JSMN_OBJECT, -1, -1, 1, + JSMN_STRING, "floatVar", 1, JSMN_PRIMITIVE, "12.345")); + return 0; +} + +int test_string(void) { + check(parse("{\"strVar\" : \"hello world\"}", 3, 3, JSMN_OBJECT, -1, -1, 1, + JSMN_STRING, "strVar", 1, JSMN_STRING, "hello world", 0)); + check(parse("{\"strVar\" : \"escapes: \\/\\r\\n\\t\\b\\f\\\"\\\\\"}", 3, 3, + JSMN_OBJECT, -1, -1, 1, JSMN_STRING, "strVar", 1, JSMN_STRING, + "escapes: \\/\\r\\n\\t\\b\\f\\\"\\\\", 0)); + check(parse("{\"strVar\": \"\"}", 3, 3, JSMN_OBJECT, -1, -1, 1, JSMN_STRING, + "strVar", 1, JSMN_STRING, "", 0)); + check(parse("{\"a\":\"\\uAbcD\"}", 3, 3, JSMN_OBJECT, -1, -1, 1, JSMN_STRING, + "a", 1, JSMN_STRING, "\\uAbcD", 0)); + check(parse("{\"a\":\"str\\u0000\"}", 3, 3, JSMN_OBJECT, -1, -1, 1, + JSMN_STRING, "a", 1, JSMN_STRING, "str\\u0000", 0)); + check(parse("{\"a\":\"\\uFFFFstr\"}", 3, 3, JSMN_OBJECT, -1, -1, 1, + JSMN_STRING, "a", 1, JSMN_STRING, "\\uFFFFstr", 0)); + check(parse("{\"a\":[\"\\u0280\"]}", 4, 4, JSMN_OBJECT, -1, -1, 1, + JSMN_STRING, "a", 1, JSMN_ARRAY, -1, -1, 1, JSMN_STRING, + "\\u0280", 0)); + + check(parse("{\"a\":\"str\\uFFGFstr\"}", JSMN_ERROR_INVAL, 3)); + check(parse("{\"a\":\"str\\u@FfF\"}", JSMN_ERROR_INVAL, 3)); + check(parse("{{\"a\":[\"\\u028\"]}", JSMN_ERROR_INVAL, 4)); + return 0; +} + +int test_partial_string(void) { + int r; + unsigned long i; + jsmn_parser p; + jsmntok_t tok[5]; + const char *js = "{\"x\": \"va\\\\ue\", \"y\": \"value y\"}"; + + jsmn_init(&p); + for (i = 1; i <= strlen(js); i++) { + r = jsmn_parse(&p, js, i, tok, sizeof(tok) / sizeof(tok[0])); + if (i == strlen(js)) { + check(r == 5); + check(tokeq(js, tok, 5, JSMN_OBJECT, -1, -1, 2, JSMN_STRING, "x", 1, + JSMN_STRING, "va\\\\ue", 0, JSMN_STRING, "y", 1, JSMN_STRING, + "value y", 0)); + } else { + check(r == JSMN_ERROR_PART); + } + } + return 0; +} + +int test_partial_array(void) { +#ifdef JSMN_STRICT + int r; + unsigned long i; + jsmn_parser p; + jsmntok_t tok[10]; + const char *js = "[ 1, true, [123, \"hello\"]]"; + + jsmn_init(&p); + for (i = 1; i <= strlen(js); i++) { + r = jsmn_parse(&p, js, i, tok, sizeof(tok) / sizeof(tok[0])); + if (i == strlen(js)) { + check(r == 6); + check(tokeq(js, tok, 6, JSMN_ARRAY, -1, -1, 3, JSMN_PRIMITIVE, "1", + JSMN_PRIMITIVE, "true", JSMN_ARRAY, -1, -1, 2, JSMN_PRIMITIVE, + "123", JSMN_STRING, "hello", 0)); + } else { + check(r == JSMN_ERROR_PART); + } + } +#endif + return 0; +} + +int test_array_nomem(void) { + int i; + int r; + jsmn_parser p; + jsmntok_t toksmall[10], toklarge[10]; + const char *js; + + js = " [ 1, true, [123, \"hello\"]]"; + + for (i = 0; i < 6; i++) { + jsmn_init(&p); + memset(toksmall, 0, sizeof(toksmall)); + memset(toklarge, 0, sizeof(toklarge)); + r = jsmn_parse(&p, js, strlen(js), toksmall, i); + check(r == JSMN_ERROR_NOMEM); + + memcpy(toklarge, toksmall, sizeof(toksmall)); + + r = jsmn_parse(&p, js, strlen(js), toklarge, 10); + check(r >= 0); + check(tokeq(js, toklarge, 4, JSMN_ARRAY, -1, -1, 3, JSMN_PRIMITIVE, "1", + JSMN_PRIMITIVE, "true", JSMN_ARRAY, -1, -1, 2, JSMN_PRIMITIVE, + "123", JSMN_STRING, "hello", 0)); + } + return 0; +} + +int test_unquoted_keys(void) { +#ifndef JSMN_STRICT + int r; + jsmn_parser p; + jsmntok_t tok[10]; + const char *js; + + jsmn_init(&p); + js = "key1: \"value\"\nkey2 : 123"; + + r = jsmn_parse(&p, js, strlen(js), tok, 10); + check(r >= 0); + check(tokeq(js, tok, 4, JSMN_PRIMITIVE, "key1", JSMN_STRING, "value", 0, + JSMN_PRIMITIVE, "key2", JSMN_PRIMITIVE, "123")); +#endif + return 0; +} + +int test_issue_22(void) { + int r; + jsmn_parser p; + jsmntok_t tokens[128]; + const char *js; + + js = + "{ \"height\":10, \"layers\":[ { \"data\":[6,6], \"height\":10, " + "\"name\":\"Calque de Tile 1\", \"opacity\":1, \"type\":\"tilelayer\", " + "\"visible\":true, \"width\":10, \"x\":0, \"y\":0 }], " + "\"orientation\":\"orthogonal\", \"properties\": { }, \"tileheight\":32, " + "\"tilesets\":[ { \"firstgid\":1, \"image\":\"..\\/images\\/tiles.png\", " + "\"imageheight\":64, \"imagewidth\":160, \"margin\":0, " + "\"name\":\"Tiles\", " + "\"properties\":{}, \"spacing\":0, \"tileheight\":32, \"tilewidth\":32 " + "}], " + "\"tilewidth\":32, \"version\":1, \"width\":10 }"; + jsmn_init(&p); + r = jsmn_parse(&p, js, strlen(js), tokens, 128); + check(r >= 0); + return 0; +} + +int test_issue_27(void) { + const char *js = + "{ \"name\" : \"Jack\", \"age\" : 27 } { \"name\" : \"Anna\", "; + check(parse(js, JSMN_ERROR_PART, 8)); + return 0; +} + +int test_input_length(void) { + const char *js; + int r; + jsmn_parser p; + jsmntok_t tokens[10]; + + js = "{\"a\": 0}garbage"; + + jsmn_init(&p); + r = jsmn_parse(&p, js, 8, tokens, 10); + check(r == 3); + check(tokeq(js, tokens, 3, JSMN_OBJECT, -1, -1, 1, JSMN_STRING, "a", 1, + JSMN_PRIMITIVE, "0")); + return 0; +} + +int test_count(void) { + jsmn_parser p; + const char *js; + + js = "{}"; + jsmn_init(&p); + check(jsmn_parse(&p, js, strlen(js), NULL, 0) == 1); + + js = "[]"; + jsmn_init(&p); + check(jsmn_parse(&p, js, strlen(js), NULL, 0) == 1); + + js = "[[]]"; + jsmn_init(&p); + check(jsmn_parse(&p, js, strlen(js), NULL, 0) == 2); + + js = "[[], []]"; + jsmn_init(&p); + check(jsmn_parse(&p, js, strlen(js), NULL, 0) == 3); + + js = "[[], []]"; + jsmn_init(&p); + check(jsmn_parse(&p, js, strlen(js), NULL, 0) == 3); + + js = "[[], [[]], [[], []]]"; + jsmn_init(&p); + check(jsmn_parse(&p, js, strlen(js), NULL, 0) == 7); + + js = "[\"a\", [[], []]]"; + jsmn_init(&p); + check(jsmn_parse(&p, js, strlen(js), NULL, 0) == 5); + + js = "[[], \"[], [[]]\", [[]]]"; + jsmn_init(&p); + check(jsmn_parse(&p, js, strlen(js), NULL, 0) == 5); + + js = "[1, 2, 3]"; + jsmn_init(&p); + check(jsmn_parse(&p, js, strlen(js), NULL, 0) == 4); + + js = "[1, 2, [3, \"a\"], null]"; + jsmn_init(&p); + check(jsmn_parse(&p, js, strlen(js), NULL, 0) == 7); + + return 0; +} + +int test_nonstrict(void) { +#ifndef JSMN_STRICT + const char *js; + js = "a: 0garbage"; + check(parse(js, 2, 2, JSMN_PRIMITIVE, "a", JSMN_PRIMITIVE, "0garbage")); + + js = "Day : 26\nMonth : Sep\n\nYear: 12"; + check(parse(js, 6, 6, JSMN_PRIMITIVE, "Day", JSMN_PRIMITIVE, "26", + JSMN_PRIMITIVE, "Month", JSMN_PRIMITIVE, "Sep", JSMN_PRIMITIVE, + "Year", JSMN_PRIMITIVE, "12")); + + /* nested {s don't cause a parse error. */ + js = "\"key {1\": 1234"; + check(parse(js, 2, 2, JSMN_STRING, "key {1", 1, JSMN_PRIMITIVE, "1234")); + +#endif + return 0; +} + +int test_unmatched_brackets(void) { + const char *js; + js = "\"key 1\": 1234}"; + check(parse(js, JSMN_ERROR_INVAL, 2)); + js = "{\"key 1\": 1234"; + check(parse(js, JSMN_ERROR_PART, 3)); + js = "{\"key 1\": 1234}}"; + check(parse(js, JSMN_ERROR_INVAL, 3)); + js = "\"key 1\"}: 1234"; + check(parse(js, JSMN_ERROR_INVAL, 3)); + js = "{\"key {1\": 1234}"; + check(parse(js, 3, 3, JSMN_OBJECT, 0, 16, 1, JSMN_STRING, "key {1", 1, + JSMN_PRIMITIVE, "1234")); + js = "{\"key 1\":{\"key 2\": 1234}"; + check(parse(js, JSMN_ERROR_PART, 5)); + return 0; +} + +int test_object_key(void) { + const char *js; + + js = "{\"key\": 1}"; + check(parse(js, 3, 3, JSMN_OBJECT, 0, 10, 1, JSMN_STRING, "key", 1, + JSMN_PRIMITIVE, "1")); +#ifdef JSMN_STRICT + js = "{true: 1}"; + check(parse(js, JSMN_ERROR_INVAL, 3)); + js = "{1: 1}"; + check(parse(js, JSMN_ERROR_INVAL, 3)); + js = "{{\"key\": 1}: 2}"; + check(parse(js, JSMN_ERROR_INVAL, 5)); + js = "{[1,2]: 2}"; + check(parse(js, JSMN_ERROR_INVAL, 5)); +#endif + return 0; +} + +int main(void) { + test(test_empty, "test for a empty JSON objects/arrays"); + test(test_object, "test for a JSON objects"); + test(test_array, "test for a JSON arrays"); + test(test_primitive, "test primitive JSON data types"); + test(test_string, "test string JSON data types"); + + test(test_partial_string, "test partial JSON string parsing"); + test(test_partial_array, "test partial array reading"); + test(test_array_nomem, "test array reading with a smaller number of tokens"); + test(test_unquoted_keys, "test unquoted keys (like in JavaScript)"); + test(test_input_length, "test strings that are not null-terminated"); + test(test_issue_22, "test issue #22"); + test(test_issue_27, "test issue #27"); + test(test_count, "test tokens count estimation"); + test(test_nonstrict, "test for non-strict mode"); + test(test_unmatched_brackets, "test for unmatched brackets"); + test(test_object_key, "test for key type"); + printf("\nPASSED: %d\nFAILED: %d\n", test_passed, test_failed); + return (test_failed > 0); +} diff --git a/lib/jsmn/test/testutil.h b/lib/jsmn/test/testutil.h new file mode 100644 index 0000000..b4a51b5 --- /dev/null +++ b/lib/jsmn/test/testutil.h @@ -0,0 +1,96 @@ +#ifndef __TEST_UTIL_H__ +#define __TEST_UTIL_H__ + +#include "../jsmn.h" + +static int vtokeq(const char *s, jsmntok_t *t, unsigned long numtok, + va_list ap) { + if (numtok > 0) { + unsigned long i; + int start, end, size; + int type; + char *value; + + size = -1; + value = NULL; + for (i = 0; i < numtok; i++) { + type = va_arg(ap, int); + if (type == JSMN_STRING) { + value = va_arg(ap, char *); + size = va_arg(ap, int); + start = end = -1; + } else if (type == JSMN_PRIMITIVE) { + value = va_arg(ap, char *); + start = end = size = -1; + } else { + start = va_arg(ap, int); + end = va_arg(ap, int); + size = va_arg(ap, int); + value = NULL; + } + if (t[i].type != type) { + printf("token %lu type is %d, not %d\n", i, t[i].type, type); + return 0; + } + if (start != -1 && end != -1) { + if (t[i].start != start) { + printf("token %lu start is %d, not %d\n", i, t[i].start, start); + return 0; + } + if (t[i].end != end) { + printf("token %lu end is %d, not %d\n", i, t[i].end, end); + return 0; + } + } + if (size != -1 && t[i].size != size) { + printf("token %lu size is %d, not %d\n", i, t[i].size, size); + return 0; + } + + if (s != NULL && value != NULL) { + const char *p = s + t[i].start; + if (strlen(value) != (unsigned long)(t[i].end - t[i].start) || + strncmp(p, value, t[i].end - t[i].start) != 0) { + printf("token %lu value is %.*s, not %s\n", i, t[i].end - t[i].start, + s + t[i].start, value); + return 0; + } + } + } + } + return 1; +} + +static int tokeq(const char *s, jsmntok_t *tokens, int numtok, ...) { + int ok; + va_list args; + va_start(args, numtok); + ok = vtokeq(s, tokens, numtok, args); + va_end(args); + return ok; +} + +static int parse(const char *s, int status, int numtok, ...) { + int r; + int ok = 1; + va_list args; + jsmn_parser p; + jsmntok_t *t = malloc(numtok * sizeof(jsmntok_t)); + + jsmn_init(&p); + r = jsmn_parse(&p, s, strlen(s), t, numtok); + if (r != status) { + printf("status is %d, not %d\n", r, status); + return 0; + } + + if (status >= 0) { + va_start(args, numtok); + ok = vtokeq(s, t, numtok, args); + va_end(args); + } + free(t); + return ok; +} + +#endif /* __TEST_UTIL_H__ */ diff --git a/config.h b/src/config.h similarity index 100% rename from config.h rename to src/config.h diff --git a/fbuffer.c b/src/fbuffer.c similarity index 100% rename from fbuffer.c rename to src/fbuffer.c diff --git a/fbuffer.h b/src/fbuffer.h similarity index 100% rename from fbuffer.h rename to src/fbuffer.h diff --git a/fbuffer.o b/src/fbuffer.o similarity index 100% rename from fbuffer.o rename to src/fbuffer.o diff --git a/ste.c b/src/ste.c similarity index 95% rename from ste.c rename to src/ste.c index 2e271c9..7aa7c56 100644 --- a/ste.c +++ b/src/ste.c @@ -352,10 +352,10 @@ void cursorMove (int a) do { t.cur.x--; } while(!isStart(rows.rw[t.cur.y].chars[t.cur.x])); - } else + } else t.cur.x--; break; - + case (KEY_RIGHT): if (t.cur.x >= rows.rw[t.cur.y].size) { if (t.cur.y < rows.rownum - 1) { @@ -366,10 +366,10 @@ void cursorMove (int a) do { t.cur.x++; } while(isCont(rows.rw[t.cur.y].chars[t.cur.x])); - } else + } else t.cur.x++; break; - + case (KEY_UP): if (t.cur.y) { t.cur.y--; @@ -418,7 +418,7 @@ void curUpdateRender () right: x -> t.cur.off_x + (t.dim.x - 1) upper: y -> t.cur.off_y lower: y -> t.cur.off_y + (t.dim.y - 1) - The rows are drawn top to botom, starting + The rows are drawn top to botom, starting from the left most char of the render area until row end or when the characters hit the right bound. @@ -435,7 +435,7 @@ void curUpdateRender () if (t.cur.y == t.cur.off_y + t.dim.y) t.cur.off_y++; else t.cur.off_y += t.cur.y - (t.cur.off_y + t.dim.y) + 1; t.cur.r_y = t.dim.y - 1; - + } else if (t.cur.y < t.cur.off_y) { t.cur.off_y -= t.cur.off_y - t.cur.y; t.cur.r_y = 0; @@ -445,7 +445,7 @@ void curUpdateRender () static int i, c; for (c = i = 0, t.cur.r_x = 0; i < t.cur.x; i++) { c = rows.rw[t.cur.y].chars[i]; - + /* continue (skip increment) if you encounter a continuation char */ if (isCont(c)) continue; else if (isStart(c)) t.cur.r_x++; diff --git a/ste.o b/src/ste.o similarity index 100% rename from ste.o rename to src/ste.o