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

Main #203

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open

Main #203

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Binary file not shown.
Binary file not shown.
Binary file not shown.
106 changes: 73 additions & 33 deletions tutorial01/leptjson.c
Original file line number Diff line number Diff line change
@@ -1,47 +1,87 @@
#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;

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;
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_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;
c->json += 3;
v->type = LEPT_NULL;
return LEPT_PARSE_OK;
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;
c->json += 3;
v->type = LEPT_NULL;
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;
}

int lept_parse(lept_value* v, const char* json) {
lept_context c;
assert(v != NULL);
c.json = json;
v->type = LEPT_NULL;
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;
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) {
lept_context c;
int res;
assert(v != NULL);
c.json = json;
v->type = LEPT_NULL;
lept_parse_whitespace(&c);
res = lept_parse_value(&c, v);
if (res == LEPT_PARSE_OK) {
lept_parse_whitespace(&c);
return lept_parse_value(&c, v);
if (c.json[0] != '\0') {
res = LEPT_PARSE_ROOT_NOT_SINGULAR;
}
}
return res;
}

lept_type lept_get_type(const lept_value* v) {
assert(v != NULL);
return v->type;
lept_type lept_get_type(const lept_value *v) {
assert(v != NULL);
return v->type;
}
17 changes: 17 additions & 0 deletions tutorial01/test.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,21 @@ static void test_parse_null() {
EXPECT_EQ_INT(LEPT_NULL, lept_get_type(&v));
}

static void test_parse_true() {
lept_value v;
v.type = LEPT_NULL;
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_NULL;
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;

Expand Down Expand Up @@ -59,6 +74,8 @@ static void test_parse_root_not_singular() {

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();
Expand Down
Binary file not shown.
Binary file not shown.
Binary file not shown.
57 changes: 56 additions & 1 deletion tutorial02/leptjson.c
Original file line number Diff line number Diff line change
@@ -1,8 +1,15 @@
#include "leptjson.h"
#include <assert.h> /* assert() */
#include <stdio.h>
#include <stdlib.h> /* NULL, strtod() */
#include <string.h>
/* #include <ctype.h> */
#include <errno.h>
#include <math.h>

#define EXPECT(c, ch) do { assert(*c->json == (ch)); c->json++; } while(0)
#define ISDIGIT(ch) ((ch) >= '0' && (ch) <= '9')
#define ISDIGIT1TO9(ch) ((ch) >= '1' && (ch) <= '9')

typedef struct {
const char* json;
Expand All @@ -15,7 +22,7 @@ static void lept_parse_whitespace(lept_context* c) {
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;
Expand All @@ -40,12 +47,55 @@ static int lept_parse_null(lept_context* c, lept_value* v) {
c->json += 3;
v->type = LEPT_NULL;
return LEPT_PARSE_OK;
}*/

static int lept_parse_literal(lept_context* c, lept_value* v, const char* target, int type) {
int len = strlen(target);
int i;
/* assert(strlen(c->json) == len); */
for (i = 0; i < len; ++i) {
if (c->json[i] != target[i]) {
return LEPT_PARSE_INVALID_VALUE;
}
}
c->json += len;
v->type = type;
return LEPT_PARSE_OK;
}

static int lept_parse_number(lept_context* c, lept_value* v) {
char* end;
/* \TODO validate number */
/* 1. start with 0-9 or - */
int len = strlen(c->json);
if (c->json[0] != '-' && !ISDIGIT(c->json[0])) {
return LEPT_PARSE_INVALID_VALUE;
}
/* 2. 0 must be single 0, can't be like 0.0 */
if (c->json[0] == '0' && len > 1) {
if (c->json[1] != '.') {
return LEPT_PARSE_ROOT_NOT_SINGULAR;
}
}
/* 3. there must be some numbers after . */
if (len > 1) {
int i = 0;
for (i = 0; i < len; ++i) {
if (c->json[i] == '.') {
if (i == len - 1) {
return LEPT_PARSE_INVALID_VALUE;
} else {
break;
}
}
}
}
errno = 0;
v->n = strtod(c->json, &end);
if (errno == ERANGE && (v->n == HUGE_VAL || v->n == -HUGE_VAL)) {
v->type = LEPT_NULL;
return LEPT_PARSE_NUMBER_TOO_BIG;
}
if (c->json == end)
return LEPT_PARSE_INVALID_VALUE;
c->json = end;
Expand All @@ -55,9 +105,14 @@ static int lept_parse_number(lept_context* c, lept_value* v) {

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);
*/
case 't': return lept_parse_literal(c, v, "true", LEPT_TRUE);
case 'f': return lept_parse_literal(c, v, "false", LEPT_FALSE);
case 'n': return lept_parse_literal(c, v, "null", LEPT_NULL);
default: return lept_parse_number(c, v);
case '\0': return LEPT_PARSE_EXPECT_VALUE;
}
Expand Down
13 changes: 6 additions & 7 deletions tutorial02/test.c
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,12 @@ 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");
TEST_NUMBER(4.9406564584124654e-324, "4.9406564584124654e-324");
TEST_NUMBER(2.2250738585072009e-308, "2.2250738585072009e-308");
TEST_NUMBER(2.2250738585072014e-308, "2.2250738585072014e-308");
TEST_NUMBER(1.7976931348623157e+308, "1.7976931348623157e+308");
}

#define TEST_ERROR(error, json)\
Expand All @@ -89,7 +95,6 @@ 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");
Expand All @@ -99,25 +104,19 @@ 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() {
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
TEST_ERROR(LEPT_PARSE_NUMBER_TOO_BIG, "1e309");
TEST_ERROR(LEPT_PARSE_NUMBER_TOO_BIG, "-1e309");
#endif
}

static void test_parse() {
Expand Down