diff --git a/.vscode/c_cpp_properties.json b/.vscode/c_cpp_properties.json new file mode 100644 index 00000000..b1880ec9 --- /dev/null +++ b/.vscode/c_cpp_properties.json @@ -0,0 +1,18 @@ +{ + "configurations": [ + { + "name": "windows-gcc-x64", + "includePath": [ + "${workspaceFolder}/**" + ], + "compilerPath": "D:/mingw64/bin/gcc.exe", + "cStandard": "${default}", + "cppStandard": "${default}", + "intelliSenseMode": "windows-gcc-x64", + "compilerArgs": [ + "" + ] + } + ], + "version": 4 +} \ No newline at end of file diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 00000000..a37c1ac5 --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,24 @@ +{ + "version": "0.2.0", + "configurations": [ + { + "name": "C/C++ Runner: Debug Session", + "type": "cppdbg", + "request": "launch", + "args": [], + "stopAtEntry": false, + "externalConsole": true, + "cwd": "d:/GitRepo/Hyan1ce-json-tutorial", + "program": "d:/GitRepo/Hyan1ce-json-tutorial/build/Debug/outDebug", + "MIMode": "gdb", + "miDebuggerPath": "gdb", + "setupCommands": [ + { + "description": "Enable pretty-printing for gdb", + "text": "-enable-pretty-printing", + "ignoreFailures": true + } + ] + } + ] +} \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 00000000..30577de5 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,44 @@ +{ + "C_Cpp_Runner.cCompilerPath": "gcc", + "C_Cpp_Runner.cppCompilerPath": "g++", + "C_Cpp_Runner.debuggerPath": "gdb", + "C_Cpp_Runner.cStandard": "", + "C_Cpp_Runner.cppStandard": "", + "C_Cpp_Runner.msvcBatchPath": "", + "C_Cpp_Runner.useMsvc": false, + "C_Cpp_Runner.warnings": [ + "-Wall", + "-Wextra", + "-Wpedantic", + "-Wshadow", + "-Wformat=2", + "-Wconversion", + "-Wnull-dereference", + "-Wsign-conversion" + ], + "C_Cpp_Runner.enableWarnings": true, + "C_Cpp_Runner.warningsAsError": false, + "C_Cpp_Runner.compilerArgs": [], + "C_Cpp_Runner.linkerArgs": [], + "C_Cpp_Runner.includePaths": [], + "C_Cpp_Runner.includeSearch": [ + "*", + "**/*" + ], + "C_Cpp_Runner.excludeSearch": [ + "**/build", + "**/build/**", + "**/.*", + "**/.*/**", + "**/.vscode", + "**/.vscode/**" + ], + "C_Cpp_Runner.useAddressSanitizer": false, + "files.associations": { + "cmath": "c", + "type_traits": "c", + "limits": "c", + "typeinfo": "c", + "cstdlib": "c" + } +} \ No newline at end of file diff --git a/.vscode/tasks.json b/.vscode/tasks.json new file mode 100644 index 00000000..454f27a3 --- /dev/null +++ b/.vscode/tasks.json @@ -0,0 +1,29 @@ +{ + "tasks": [ + { + "type": "cppbuild", + "label": "C/C++: gcc.exe 生成活动文件", + "command": "D:/mingw64/bin/gcc.exe", + "args": [ + "-fdiagnostics-color=always", + "-g", + "${file}", + "-o", + "${fileDirname}\\${fileBasenameNoExtension}.exe", + "" + ], + "options": { + "cwd": "D:/mingw64/bin" + }, + "problemMatcher": [ + "$gcc" + ], + "group": { + "kind": "build", + "isDefault": true + }, + "detail": "调试器生成的任务。" + } + ], + "version": "2.0.0" +} \ No newline at end of file diff --git a/tutorial01/leptjson.c b/tutorial01/leptjson.c index 5299fe1d..877c53b0 100644 --- a/tutorial01/leptjson.c +++ b/tutorial01/leptjson.c @@ -1,21 +1,29 @@ #include "leptjson.h" -#include /* assert() */ -#include /* NULL */ +#include /* assert() */ +#include /* NULL */ -#define EXPECT(c, ch) do { assert(*c->json == (ch)); c->json++; } while(0) +#define EXPECT(c, ch) \ + do \ + { \ + assert(*c->json == (ch)); \ + c->json++; \ + } while (0) -typedef struct { - const char* json; -}lept_context; +typedef struct +{ + const char *json; +} lept_context; -static void lept_parse_whitespace(lept_context* c) { +static void lept_parse_whitespace(lept_context *c) +{ const char *p = c->json; while (*p == ' ' || *p == '\t' || *p == '\n' || *p == '\r') p++; c->json = p; } -static int lept_parse_null(lept_context* c, lept_value* v) { +static int lept_parse_null(lept_context *c, lept_value *v) +{ EXPECT(c, 'n'); if (c->json[0] != 'u' || c->json[1] != 'l' || c->json[2] != 'l') return LEPT_PARSE_INVALID_VALUE; @@ -24,24 +32,64 @@ static int lept_parse_null(lept_context* c, lept_value* v) { return LEPT_PARSE_OK; } -static int lept_parse_value(lept_context* c, lept_value* v) { - switch (*c->json) { - case 'n': return lept_parse_null(c, v); - case '\0': return LEPT_PARSE_EXPECT_VALUE; - default: return LEPT_PARSE_INVALID_VALUE; +static int lept_parse_true(lept_context *c, lept_value *v) +{ + EXPECT(c, 't'); + if (c->json[0] != 'r' || c->json[1] != 'u' || c->json[2] != 'e') + return LEPT_PARSE_INVALID_VALUE; + c->json += 3; + v->type = LEPT_TRUE; + return LEPT_PARSE_OK; +} + +static int lept_parse_false(lept_context *c, lept_value *v) +{ + EXPECT(c, 'f'); + if (c->json[0] != 'a' || c->json[1] != 'l' || c->json[2] != 's' || c->json[3] != 'e') + return LEPT_PARSE_INVALID_VALUE; + c->json += 4; + v->type = LEPT_FALSE; + return LEPT_PARSE_OK; +} + +static int lept_parse_value(lept_context *c, lept_value *v) +{ + switch (*c->json) + { + case 'n': // null + return lept_parse_null(c, v); + case '\0': // whitespace + return LEPT_PARSE_EXPECT_VALUE; + case 't': + return lept_parse_true(c, v); + case 'f': + return lept_parse_false(c, v); + default: + return LEPT_PARSE_INVALID_VALUE; } } -int lept_parse(lept_value* v, const char* json) { +int lept_parse(lept_value *v, const char *json) +{ lept_context c; + int ret; assert(v != NULL); c.json = json; v->type = LEPT_NULL; lept_parse_whitespace(&c); - return lept_parse_value(&c, v); + if ((ret = lept_parse_value(&c, v)) == LEPT_PARSE_OK) + { + lept_parse_whitespace(&c); + if (*c.json != '\0') + { + ret = LEPT_PARSE_ROOT_NOT_SINGULAR; + } + } + return ret; } -lept_type lept_get_type(const lept_value* v) { +lept_type lept_get_type(const lept_value *v) +{ assert(v != NULL); return v->type; } diff --git a/tutorial01/leptjson.h b/tutorial01/leptjson.h index 9b65d22a..7b9f53d4 100644 --- a/tutorial01/leptjson.h +++ b/tutorial01/leptjson.h @@ -1,21 +1,32 @@ #ifndef LEPTJSON_H__ #define LEPTJSON_H__ -typedef enum { LEPT_NULL, LEPT_FALSE, LEPT_TRUE, LEPT_NUMBER, LEPT_STRING, LEPT_ARRAY, LEPT_OBJECT } lept_type; +typedef enum +{ + LEPT_NULL, + LEPT_FALSE, + LEPT_TRUE, + LEPT_NUMBER, + LEPT_STRING, + LEPT_ARRAY, + LEPT_OBJECT +} lept_type; -typedef struct { +typedef struct +{ lept_type type; -}lept_value; +} lept_value; -enum { +enum +{ LEPT_PARSE_OK = 0, LEPT_PARSE_EXPECT_VALUE, LEPT_PARSE_INVALID_VALUE, LEPT_PARSE_ROOT_NOT_SINGULAR }; -int lept_parse(lept_value* v, const char* json); +int lept_parse(lept_value *v, const char *json); -lept_type lept_get_type(const lept_value* v); +lept_type lept_get_type(const lept_value *v); #endif /* LEPTJSON_H__ */ diff --git a/tutorial01/test.c b/tutorial01/test.c index e7672181..10a080c3 100644 --- a/tutorial01/test.c +++ b/tutorial01/test.c @@ -2,32 +2,53 @@ #include #include #include "leptjson.h" +#include "leptjson.c" static int main_ret = 0; static int test_count = 0; static int test_pass = 0; -#define EXPECT_EQ_BASE(equality, expect, actual, format) \ - do {\ - test_count++;\ - if (equality)\ - test_pass++;\ - else {\ - fprintf(stderr, "%s:%d: expect: " format " actual: " format "\n", __FILE__, __LINE__, expect, actual);\ - main_ret = 1;\ - }\ - } while(0) +#define EXPECT_EQ_BASE(equality, expect, actual, format) \ + do \ + { \ + test_count++; \ + if (equality) \ + test_pass++; \ + else \ + { \ + fprintf(stderr, "%s:%d: expect: " format " actual: " format "\n", __FILE__, __LINE__, expect, actual); \ + main_ret = 1; \ + } \ + } while (0) #define EXPECT_EQ_INT(expect, actual) EXPECT_EQ_BASE((expect) == (actual), expect, actual, "%d") -static void test_parse_null() { +static void test_parse_null() +{ lept_value v; v.type = LEPT_FALSE; EXPECT_EQ_INT(LEPT_PARSE_OK, lept_parse(&v, "null")); EXPECT_EQ_INT(LEPT_NULL, lept_get_type(&v)); } -static void test_parse_expect_value() { +static void test_parse_true() +{ + lept_value v; + v.type = LEPT_FALSE; + EXPECT_EQ_INT(LEPT_PARSE_OK, lept_parse(&v, "true")); + EXPECT_EQ_INT(LEPT_TRUE, lept_get_type(&v)); +} + +static void test_parse_false() +{ + lept_value v; + v.type = LEPT_FALSE; + EXPECT_EQ_INT(LEPT_PARSE_OK, lept_parse(&v, "false")); + EXPECT_EQ_INT(LEPT_FALSE, lept_get_type(&v)); +} + +static void test_parse_expect_value() +{ lept_value v; v.type = LEPT_FALSE; @@ -39,7 +60,8 @@ static void test_parse_expect_value() { EXPECT_EQ_INT(LEPT_NULL, lept_get_type(&v)); } -static void test_parse_invalid_value() { +static void test_parse_invalid_value() +{ lept_value v; v.type = LEPT_FALSE; EXPECT_EQ_INT(LEPT_PARSE_INVALID_VALUE, lept_parse(&v, "nul")); @@ -50,21 +72,26 @@ static void test_parse_invalid_value() { EXPECT_EQ_INT(LEPT_NULL, lept_get_type(&v)); } -static void test_parse_root_not_singular() { +static void test_parse_root_not_singular() +{ lept_value v; v.type = LEPT_FALSE; EXPECT_EQ_INT(LEPT_PARSE_ROOT_NOT_SINGULAR, lept_parse(&v, "null x")); EXPECT_EQ_INT(LEPT_NULL, lept_get_type(&v)); } -static void test_parse() { +static void test_parse() +{ test_parse_null(); + test_parse_true(); + test_parse_false(); test_parse_expect_value(); test_parse_invalid_value(); test_parse_root_not_singular(); } -int main() { +int main() +{ test_parse(); printf("%d/%d (%3.2f%%) passed\n", test_pass, test_count, test_pass * 100.0 / test_count); return main_ret; diff --git a/tutorial01/test.exe b/tutorial01/test.exe new file mode 100644 index 00000000..0bd57ba2 Binary files /dev/null and b/tutorial01/test.exe differ diff --git a/tutorial02/leptjson.c b/tutorial02/leptjson.c index 7693e43b..53940099 100644 --- a/tutorial02/leptjson.c +++ b/tutorial02/leptjson.c @@ -1,21 +1,34 @@ #include "leptjson.h" -#include /* assert() */ -#include /* NULL, strtod() */ +#include /* assert() */ +#include /* NULL, strtod() */ +#include /* errno, ERANGE */ +#include /* HUGE_VAL */ -#define EXPECT(c, ch) do { assert(*c->json == (ch)); c->json++; } while(0) +#define EXPECT(c, ch) \ + do \ + { \ + assert(*c->json == (ch)); \ + c->json++; \ + } while (0) -typedef struct { - const char* json; -}lept_context; +#define ISDIGIT(ch) ((ch) >= '0' && (ch) <= '9') +#define ISDIGIT1TO9(ch) ((ch) >= '1' && (ch) <= '9') -static void lept_parse_whitespace(lept_context* c) { +typedef struct +{ + const char *json; +} lept_context; + +static void lept_parse_whitespace(lept_context *c) +{ const char *p = c->json; while (*p == ' ' || *p == '\t' || *p == '\n' || *p == '\r') p++; c->json = p; } -static int lept_parse_true(lept_context* c, lept_value* v) { +static int lept_parse_true(lept_context *c, lept_value *v) +{ EXPECT(c, 't'); if (c->json[0] != 'r' || c->json[1] != 'u' || c->json[2] != 'e') return LEPT_PARSE_INVALID_VALUE; @@ -24,7 +37,8 @@ static int lept_parse_true(lept_context* c, lept_value* v) { return LEPT_PARSE_OK; } -static int lept_parse_false(lept_context* c, lept_value* v) { +static int lept_parse_false(lept_context *c, lept_value *v) +{ EXPECT(c, 'f'); if (c->json[0] != 'a' || c->json[1] != 'l' || c->json[2] != 's' || c->json[3] != 'e') return LEPT_PARSE_INVALID_VALUE; @@ -33,7 +47,8 @@ static int lept_parse_false(lept_context* c, lept_value* v) { return LEPT_PARSE_OK; } -static int lept_parse_null(lept_context* c, lept_value* v) { +static int lept_parse_null(lept_context *c, lept_value *v) +{ EXPECT(c, 'n'); if (c->json[0] != 'u' || c->json[1] != 'l' || c->json[2] != 'l') return LEPT_PARSE_INVALID_VALUE; @@ -42,37 +57,118 @@ static int lept_parse_null(lept_context* c, lept_value* v) { return LEPT_PARSE_OK; } -static int lept_parse_number(lept_context* c, lept_value* v) { - char* end; - /* \TODO validate number */ - v->n = strtod(c->json, &end); - if (c->json == end) +static int lept_parse_literal(lept_context *c, lept_value *v) +{ + switch (*c->json) + { + case 'n': + { + if (c->json[0] != 'u' || c->json[1] != 'l' || c->json[2] != 'l') + return LEPT_PARSE_INVALID_VALUE; + c->json += 3; + v->type = LEPT_NULL; + } + case 't': + { + if (c->json[0] != 'r' || c->json[1] != 'u' || c->json[2] != 'e') + return LEPT_PARSE_INVALID_VALUE; + c->json += 3; + v->type = LEPT_TRUE; + } + case 'f': + { + if (c->json[0] != 'a' || c->json[1] != 'l' || c->json[2] != 's' || c->json[3] != 'e') + return LEPT_PARSE_INVALID_VALUE; + c->json += 4; + v->type = LEPT_FALSE; + } + default: return LEPT_PARSE_INVALID_VALUE; - c->json = end; + return LEPT_PARSE_OK; + } +} + +static int lept_parse_number(lept_context *c, lept_value *v) +{ + const char *p = c->json; + // 加减号 + if (*p == '-') + p++; + // 数字0 + if (*p == '0') + { + p++; + } + else + { + if (!ISDIGIT1TO9(*p)) + return LEPT_PARSE_INVALID_VALUE; + p++; + while (ISDIGIT(*p)) + p++; + } + // 判断小数点 + if (*p == '.') + { + p++; + if (!ISDIGIT(*p)) + return LEPT_PARSE_INVALID_VALUE; + p++; + while (ISDIGIT(*p)) + p++; + } + // 判断e,E + if (*p == 'e' || *p == 'E') + { + p++; + if (*p == '-' || *p == '+') + p++; + if (!(ISDIGIT(*p))) + return LEPT_PARSE_INVALID_VALUE; + p++; + while (ISDIGIT(*p)) + p++; + } + + errno = 0; + v->n = strtod(c->json, NULL); + if (errno == ERANGE && (v->n == HUGE_VAL || v->n == -HUGE_VAL)) + return LEPT_PARSE_NUMBER_TOO_BIG; v->type = LEPT_NUMBER; + c->json = p; return LEPT_PARSE_OK; } -static int lept_parse_value(lept_context* c, lept_value* v) { - switch (*c->json) { - case 't': return lept_parse_true(c, v); - case 'f': return lept_parse_false(c, v); - case 'n': return lept_parse_null(c, v); - default: return lept_parse_number(c, v); - case '\0': return LEPT_PARSE_EXPECT_VALUE; +static int lept_parse_value(lept_context *c, lept_value *v) +{ + switch (*c->json) + { + case 't': + return lept_parse_true(c, v); + case 'f': + return lept_parse_false(c, v); + case 'n': + return lept_parse_null(c, v); + default: + return lept_parse_number(c, v); + case '\0': + return LEPT_PARSE_EXPECT_VALUE; } } -int lept_parse(lept_value* v, const char* json) { +int lept_parse(lept_value *v, const char *json) +{ lept_context c; int ret; assert(v != NULL); c.json = json; v->type = LEPT_NULL; lept_parse_whitespace(&c); - if ((ret = lept_parse_value(&c, v)) == LEPT_PARSE_OK) { + if ((ret = lept_parse_value(&c, v)) == LEPT_PARSE_OK) + { lept_parse_whitespace(&c); - if (*c.json != '\0') { + if (*c.json != '\0') + { v->type = LEPT_NULL; ret = LEPT_PARSE_ROOT_NOT_SINGULAR; } @@ -80,12 +176,14 @@ int lept_parse(lept_value* v, const char* json) { return ret; } -lept_type lept_get_type(const lept_value* v) { +lept_type lept_get_type(const lept_value *v) +{ assert(v != NULL); return v->type; } -double lept_get_number(const lept_value* v) { +double lept_get_number(const lept_value *v) +{ assert(v != NULL && v->type == LEPT_NUMBER); return v->n; } diff --git a/tutorial02/test.c b/tutorial02/test.c index eaa5db69..e3200aad 100644 --- a/tutorial02/test.c +++ b/tutorial02/test.c @@ -2,55 +2,63 @@ #include #include #include "leptjson.h" +#include "leptjson.c" static int main_ret = 0; static int test_count = 0; static int test_pass = 0; -#define EXPECT_EQ_BASE(equality, expect, actual, format) \ - do {\ - test_count++;\ - if (equality)\ - test_pass++;\ - else {\ - fprintf(stderr, "%s:%d: expect: " format " actual: " format "\n", __FILE__, __LINE__, expect, actual);\ - main_ret = 1;\ - }\ - } while(0) +#define EXPECT_EQ_BASE(equality, expect, actual, format) \ + do \ + { \ + test_count++; \ + if (equality) \ + test_pass++; \ + else \ + { \ + fprintf(stderr, "%s:%d: expect: " format " actual: " format "\n", __FILE__, __LINE__, expect, actual); \ + main_ret = 1; \ + } \ + } while (0) #define EXPECT_EQ_INT(expect, actual) EXPECT_EQ_BASE((expect) == (actual), expect, actual, "%d") #define EXPECT_EQ_DOUBLE(expect, actual) EXPECT_EQ_BASE((expect) == (actual), expect, actual, "%.17g") -static void test_parse_null() { +static void test_parse_null() +{ lept_value v; v.type = LEPT_FALSE; EXPECT_EQ_INT(LEPT_PARSE_OK, lept_parse(&v, "null")); EXPECT_EQ_INT(LEPT_NULL, lept_get_type(&v)); } -static void test_parse_true() { +static void test_parse_true() +{ lept_value v; v.type = LEPT_FALSE; EXPECT_EQ_INT(LEPT_PARSE_OK, lept_parse(&v, "true")); EXPECT_EQ_INT(LEPT_TRUE, lept_get_type(&v)); } -static void test_parse_false() { +static void test_parse_false() +{ lept_value v; v.type = LEPT_TRUE; EXPECT_EQ_INT(LEPT_PARSE_OK, lept_parse(&v, "false")); EXPECT_EQ_INT(LEPT_FALSE, lept_get_type(&v)); } -#define TEST_NUMBER(expect, json)\ - do {\ - lept_value v;\ - EXPECT_EQ_INT(LEPT_PARSE_OK, lept_parse(&v, json));\ - EXPECT_EQ_INT(LEPT_NUMBER, lept_get_type(&v));\ - EXPECT_EQ_DOUBLE(expect, lept_get_number(&v));\ - } while(0) - -static void test_parse_number() { +#define TEST_NUMBER(expect, json) \ + do \ + { \ + lept_value v; \ + EXPECT_EQ_INT(LEPT_PARSE_OK, lept_parse(&v, json)); \ + EXPECT_EQ_INT(LEPT_NUMBER, lept_get_type(&v)); \ + EXPECT_EQ_DOUBLE(expect, lept_get_number(&v)); \ + } while (0) + +static void test_parse_number() +{ TEST_NUMBER(0.0, "0"); TEST_NUMBER(0.0, "-0"); TEST_NUMBER(0.0, "-0.0"); @@ -70,26 +78,30 @@ static void test_parse_number() { TEST_NUMBER(1.234E+10, "1.234E+10"); TEST_NUMBER(1.234E-10, "1.234E-10"); TEST_NUMBER(0.0, "1e-10000"); /* must underflow */ + TEST_NUMBER(1.0000000000000002, "1.0000000000000002"); /* the smallest number > 1 */ + TEST_NUMBER(4.9406564584124654e-324, "4.9406564584124654e-324"); /* minimum denormal */ } -#define TEST_ERROR(error, json)\ - do {\ - lept_value v;\ - v.type = LEPT_FALSE;\ - EXPECT_EQ_INT(error, lept_parse(&v, json));\ - EXPECT_EQ_INT(LEPT_NULL, lept_get_type(&v));\ - } while(0) - -static void test_parse_expect_value() { +#define TEST_ERROR(error, json) \ + do \ + { \ + lept_value v; \ + v.type = LEPT_FALSE; \ + EXPECT_EQ_INT(error, lept_parse(&v, json)); \ + EXPECT_EQ_INT(LEPT_NULL, lept_get_type(&v)); \ + } while (0) + +static void test_parse_expect_value() +{ TEST_ERROR(LEPT_PARSE_EXPECT_VALUE, ""); TEST_ERROR(LEPT_PARSE_EXPECT_VALUE, " "); } -static void test_parse_invalid_value() { +static void test_parse_invalid_value() +{ TEST_ERROR(LEPT_PARSE_INVALID_VALUE, "nul"); TEST_ERROR(LEPT_PARSE_INVALID_VALUE, "?"); -#if 0 /* invalid number */ TEST_ERROR(LEPT_PARSE_INVALID_VALUE, "+0"); TEST_ERROR(LEPT_PARSE_INVALID_VALUE, "+1"); @@ -99,28 +111,26 @@ static void test_parse_invalid_value() { TEST_ERROR(LEPT_PARSE_INVALID_VALUE, "inf"); TEST_ERROR(LEPT_PARSE_INVALID_VALUE, "NAN"); TEST_ERROR(LEPT_PARSE_INVALID_VALUE, "nan"); -#endif } -static void test_parse_root_not_singular() { +static void test_parse_root_not_singular() +{ TEST_ERROR(LEPT_PARSE_ROOT_NOT_SINGULAR, "null x"); -#if 0 /* invalid number */ TEST_ERROR(LEPT_PARSE_ROOT_NOT_SINGULAR, "0123"); /* after zero should be '.' , 'E' , 'e' or nothing */ TEST_ERROR(LEPT_PARSE_ROOT_NOT_SINGULAR, "0x0"); TEST_ERROR(LEPT_PARSE_ROOT_NOT_SINGULAR, "0x123"); -#endif } -static void test_parse_number_too_big() { -#if 0 +static void test_parse_number_too_big() +{ TEST_ERROR(LEPT_PARSE_NUMBER_TOO_BIG, "1e309"); TEST_ERROR(LEPT_PARSE_NUMBER_TOO_BIG, "-1e309"); -#endif } -static void test_parse() { +static void test_parse() +{ test_parse_null(); test_parse_true(); test_parse_false(); @@ -131,7 +141,8 @@ static void test_parse() { test_parse_number_too_big(); } -int main() { +int main() +{ test_parse(); printf("%d/%d (%3.2f%%) passed\n", test_pass, test_count, test_pass * 100.0 / test_count); return main_ret; diff --git a/tutorial02/test.exe b/tutorial02/test.exe new file mode 100644 index 00000000..8094a1b5 Binary files /dev/null and b/tutorial02/test.exe differ diff --git a/tutorial02_answer/test.c b/tutorial02_answer/test.c index ac0186d1..0fbd29a2 100644 --- a/tutorial02_answer/test.c +++ b/tutorial02_answer/test.c @@ -1,6 +1,7 @@ #include #include #include +#include "leptjson.c" #include "leptjson.h" static int main_ret = 0; diff --git a/tutorial02_answer/test.exe b/tutorial02_answer/test.exe new file mode 100644 index 00000000..42342d73 Binary files /dev/null and b/tutorial02_answer/test.exe differ