Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Hyan1ce/issue254 #256

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions .vscode/c_cpp_properties.json
Original file line number Diff line number Diff line change
@@ -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
}
24 changes: 24 additions & 0 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
@@ -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
}
]
}
]
}
44 changes: 44 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -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"
}
}
29 changes: 29 additions & 0 deletions .vscode/tasks.json
Original file line number Diff line number Diff line change
@@ -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"
}
80 changes: 64 additions & 16 deletions tutorial01/leptjson.c
Original file line number Diff line number Diff line change
@@ -1,21 +1,29 @@
#include "leptjson.h"
#include <assert.h> /* assert() */
#include <stdlib.h> /* NULL */
#include <assert.h> /* assert() */
#include <stdlib.h> /* 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;
Expand All @@ -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;
}
23 changes: 17 additions & 6 deletions tutorial01/leptjson.h
Original file line number Diff line number Diff line change
@@ -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__ */
59 changes: 43 additions & 16 deletions tutorial01/test.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,32 +2,53 @@
#include <stdlib.h>
#include <string.h>
#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;
Expand All @@ -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"));
Expand All @@ -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;
Expand Down
Binary file added tutorial01/test.exe
Binary file not shown.
Loading