11#include "leptjson.h"
22#include <assert.h> /* assert() */
3+ #include <errno.h> /* errno, ERANGE */
4+ #include <math.h> /* HUGE_VAL */
35#include <stdlib.h> /* NULL, strtod() */
46
57#define EXPECT (c , ch ) do { assert(*c->json == (ch)); c->json++; } while(0)
8+ #define ISDIGIT (ch ) ((ch) >= '0' && (ch) <= '9')
9+ #define ISDIGIT1TO9 (ch ) ((ch) >= '1' && (ch) <= '9')
610
711typedef struct {
812 const char * json ;
@@ -15,49 +19,57 @@ static void lept_parse_whitespace(lept_context* c) {
1519 c -> json = p ;
1620}
1721
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 ;
22+ static int lept_parse_literal (lept_context * c , lept_value * v , const char * literal , lept_type type )
23+ {
24+ size_t i ;
25+ EXPECT (c , literal [0 ]);
26+ for (i = 0 ; literal [i + 1 ] != '\0' ; i ++ )
27+ if (c -> json [i ] != literal [i + 1 ])
28+ return LEPT_PARSE_INVALID_VALUE ;
29+ c -> json += i ;
30+ v -> type = type ;
31+ return LEPT_PARSE_OK ;
2532}
2633
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- }
34+ static int lept_parse_number (lept_context * c , lept_value * v ) {
35+
36+ const char * p = c -> json ;
37+ if (* p == '-' ) p ++ ;
38+ if (* p == '0' ) p ++ ;
39+ else
40+ {
41+ if (!ISDIGIT1TO9 (* p )) return LEPT_PARSE_INVALID_VALUE ;
42+ for (p ++ ; ISDIGIT (* p ); p ++ );
43+ }
44+ if (* p == '.' )
45+ {
46+ p ++ ;
47+ if (!ISDIGIT (* p )) return LEPT_PARSE_INVALID_VALUE ;
48+ for (p ++ ; ISDIGIT (* p );p ++ );
49+ }
50+ if (* p == 'E' || * p == 'e' )
51+ {
52+ p ++ ;
53+ if (* p == '-' || * p == '+' ) p ++ ;
54+ if (!ISDIGIT (* p )) return LEPT_PARSE_INVALID_VALUE ;
55+ for (p ++ ; ISDIGIT (* p ); p ++ );
56+ }
3557
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 ;
42- return LEPT_PARSE_OK ;
43- }
58+ errno = 0 ;
59+ v -> n = strtod (c -> json , NULL );
60+ if (errno == ERANGE && (v -> n == HUGE_VAL || v -> n == - HUGE_VAL ))
61+ return LEPT_PARSE_NUMBER_TOO_BIG ;
62+ v -> type = LEPT_NUMBER ;
63+ c -> json = p ;
64+ return LEPT_PARSE_OK ;
4465
45- static 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 ;
52- v -> type = LEPT_NUMBER ;
53- return LEPT_PARSE_OK ;
5466}
5567
5668static int lept_parse_value (lept_context * c , lept_value * v ) {
5769 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 );
70+ case 't' : return lept_parse_literal (c ,v , "true" , LEPT_TRUE );
71+ case 'f' : return lept_parse_literal (c , v , "false" , LEPT_FALSE );
72+ case 'n' : return lept_parse_literal (c , v , "null" , LEPT_NULL );
6173 default : return lept_parse_number (c , v );
6274 case '\0' : return LEPT_PARSE_EXPECT_VALUE ;
6375 }
0 commit comments