11#include "leptjson.h"
22#include <assert.h> /* assert() */
33#include <stdlib.h> /* NULL, strtod() */
4+ #include <errno.h> /* errno, ERANGE */
5+ #include <math.h> /* HUGE_VAL */
46
57#define EXPECT (c , ch ) do { assert(*c->json == (ch)); c->json++; } while(0)
68
9+ #define ISDIGIT (ch ) ((ch) >= '0' && (ch) <= '9')
10+ #define ISDIGIT1TO9 (ch ) ((ch) >= '1' && (ch) <= '9')
11+
712typedef struct {
813 const char * json ;
914}lept_context ;
@@ -15,49 +20,50 @@ static void lept_parse_whitespace(lept_context* c) {
1520 c -> json = p ;
1621}
1722
18- static int lept_parse_true (lept_context * c , lept_value * v ) {
19- EXPECT (c , 't' );
20- if (c -> json [0 ] != 'r' || c -> json [1 ] != 'u' || c -> json [2 ] != 'e' )
21- return LEPT_PARSE_INVALID_VALUE ;
22- c -> json += 3 ;
23- v -> type = LEPT_TRUE ;
24- return LEPT_PARSE_OK ;
25- }
26-
27- static int lept_parse_false (lept_context * c , lept_value * v ) {
28- EXPECT (c , 'f' );
29- if (c -> json [0 ] != 'a' || c -> json [1 ] != 'l' || c -> json [2 ] != 's' || c -> json [3 ] != 'e' )
30- return LEPT_PARSE_INVALID_VALUE ;
31- c -> json += 4 ;
32- v -> type = LEPT_FALSE ;
33- return LEPT_PARSE_OK ;
34- }
35-
36- static int lept_parse_null (lept_context * c , lept_value * v ) {
37- EXPECT (c , 'n' );
38- if (c -> json [0 ] != 'u' || c -> json [1 ] != 'l' || c -> json [2 ] != 'l' )
39- return LEPT_PARSE_INVALID_VALUE ;
40- c -> json += 3 ;
41- v -> type = LEPT_NULL ;
23+ static int lept_parse_literal (lept_context * c , lept_value * v , const char * literal , lept_type type ) {
24+ size_t i ;
25+ EXPECT (c , literal [0 ]);
26+ for (i = 0 ; i < literal [i + 1 ]; i ++ )
27+ if (c -> json [i ] != literal [i + 1 ])
28+ return LEPT_PARSE_INVALID_VALUE ;
29+ c -> json += i ;
30+ v -> type = type ;
4231 return LEPT_PARSE_OK ;
4332}
4433
4534static int lept_parse_number (lept_context * c , lept_value * v ) {
46- char * end ;
47- /* \TODO validate number */
48- v -> n = strtod (c -> json , & end );
49- if (c -> json == end )
50- return LEPT_PARSE_INVALID_VALUE ;
51- c -> json = end ;
35+ const char * p = c -> json ;
36+ if (* p == '-' ) p ++ ;
37+ if (* p == '0' ) p ++ ;
38+ else {
39+ if (!ISDIGIT1TO9 (* p )) return LEPT_PARSE_INVALID_VALUE ;
40+ for (p ++ ; ISDIGIT (* p ); p ++ );
41+ }
42+ if (* p == '.' ) {
43+ p ++ ;
44+ if (!ISDIGIT (* p )) return LEPT_PARSE_INVALID_VALUE ;
45+ for (p ++ ; ISDIGIT (* p ); p ++ );
46+ }
47+ if (* p == 'e' || * p == 'E' ) {
48+ p ++ ;
49+ if (* p == '-' || * p == '+' ) p ++ ;
50+ if (!ISDIGIT (* p )) return LEPT_PARSE_INVALID_VALUE ;
51+ for (p ++ ; ISDIGIT (* p ); p ++ );
52+ }
53+ errno = 0 ;
54+ v -> n = strtod (c -> json , NULL );
55+ if (errno == ERANGE && (v -> n == HUGE_VAL || v -> n == - HUGE_VAL ))
56+ return LEPT_PARSE_NUMBER_TOO_BIG ;
5257 v -> type = LEPT_NUMBER ;
58+ c -> json = p ;
5359 return LEPT_PARSE_OK ;
5460}
5561
5662static int lept_parse_value (lept_context * c , lept_value * v ) {
5763 switch (* c -> json ) {
58- case 't' : return lept_parse_true (c , v );
59- case 'f' : return lept_parse_false (c , v );
60- case 'n' : return lept_parse_null (c , v );
64+ case 't' : return lept_parse_literal (c , v , "true" , LEPT_TRUE );
65+ case 'f' : return lept_parse_literal (c , v , "false" , LEPT_FALSE );
66+ case 'n' : return lept_parse_literal (c , v , "null" , LEPT_NULL );
6167 default : return lept_parse_number (c , v );
6268 case '\0' : return LEPT_PARSE_EXPECT_VALUE ;
6369 }
0 commit comments