11#include "leptjson.h"
22#include <assert.h> /* assert() */
33#include <stdlib.h> /* NULL, strtod() */
4-
4+ #include <math.h> /* HUGE_VAL*/
5+ #include <errno.h>
6+ #include <stdio.h>
57#define EXPECT (c , ch ) do { assert(*c->json == (ch)); c->json++; } while(0)
68
79typedef struct {
@@ -15,49 +17,84 @@ static void lept_parse_whitespace(lept_context* c) {
1517 c -> json = p ;
1618}
1719
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 ;
20+ static int lept_parse_literal (lept_context * c ,lept_value * v , lept_type m ){
21+ int i ,len ;
22+ const char * str ;
23+ assert (m == LEPT_TRUE || m == LEPT_FALSE || m == LEPT_NULL );
24+ switch (m ){
25+ case LEPT_TRUE : len = 3 ; str = "true" ; break ;
26+ case LEPT_FALSE : len = 4 ; str = "false" ; break ;
27+ case LEPT_NULL : len = 3 ; str = "null" ; break ;
28+ }
29+ EXPECT (c ,str [0 ]);
30+ for (i = 0 ;i < len ;i ++ )
31+ if (c -> json [i ] != str [i + 1 ])
32+ return LEPT_PARSE_INVALID_VALUE ;
33+ c -> json += len ;
34+ v -> type = m ;
2435 return LEPT_PARSE_OK ;
2536}
2637
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 ;
42- return LEPT_PARSE_OK ;
43- }
38+ #define ISDIGIT (ch ) ((ch) >= '0' && (ch) <= '9')
39+ #define ISDIGIT1TO9 (ch ) ((ch) >= '1' && (ch) <= '9')
4440
4541static int lept_parse_number (lept_context * c , lept_value * v ) {
46- char * end ;
47- /* \TODO validate number */
42+ char * end ;
43+ const char * cur = c -> json ;
44+ if (cur [0 ] == 'N' && cur [1 ] == 'A' && cur [2 ] == 'N'
45+ || cur [0 ] == 'n' && cur [1 ] == 'a' && cur [2 ] == 'n'
46+ || cur [0 ] == 'I' && cur [1 ] == 'N' && cur [2 ] == 'F'
47+ || cur [0 ] == 'i' && cur [1 ] == 'n' && cur [2 ] == 'f' )
48+ return LEPT_PARSE_INVALID_VALUE ;
49+ if (* cur == '+' )
50+ return LEPT_PARSE_INVALID_VALUE ;
51+ if (* cur == '-' )
52+ cur ++ ;
53+
54+ if (* cur == '.' )
55+ return LEPT_PARSE_INVALID_VALUE ;
56+ if (* cur == '0' ) {
57+ cur ++ ;
58+ if (ISDIGIT (* cur ) || * cur == 'x' || * cur == 'X' )
59+ return LEPT_PARSE_ROOT_NOT_SINGULAR ;
60+ }
61+ else if (ISDIGIT1TO9 (* cur )) {
62+ for (cur ++ ; ISDIGIT (* cur ); cur ++ );
63+ }
64+
65+ if (* cur == '.' ) {
66+ cur ++ ;
67+ if (!ISDIGIT (* cur ))
68+ return LEPT_PARSE_INVALID_VALUE ;
69+ else
70+ while (ISDIGIT (* ++ cur ));
71+ }
72+
73+ if (* cur == 'e' || * cur == 'E' ) {
74+ cur ++ ;
75+ if (* cur == '+' || * cur == '-' )
76+ cur ++ ;
77+ if (!ISDIGIT (* cur ))
78+ return LEPT_PARSE_INVALID_VALUE ;
79+ else
80+ for (cur ++ ; ISDIGIT (* cur ); cur ++ );
81+ }
82+
83+ errno = 0 ;
4884 v -> n = strtod (c -> json , & end );
49- if (c -> json == end )
50- return LEPT_PARSE_INVALID_VALUE ;
51- c -> json = end ;
85+ if (c -> json == end ) return LEPT_PARSE_INVALID_VALUE ;
86+ if ((v -> n == HUGE_VAL || v -> n == - HUGE_VAL ) && errno == ERANGE )
87+ return LEPT_PARSE_NUMBER_TOO_BIG ;
88+ c -> json = cur ;
5289 v -> type = LEPT_NUMBER ;
5390 return LEPT_PARSE_OK ;
5491}
5592
5693static int lept_parse_value (lept_context * c , lept_value * v ) {
5794 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 );
95+ case 't' : return lept_parse_literal (c , v , LEPT_TRUE );
96+ case 'f' : return lept_parse_literal (c , v , LEPT_FALSE );
97+ case 'n' : return lept_parse_literal (c , v , LEPT_NULL );
6198 default : return lept_parse_number (c , v );
6299 case '\0' : return LEPT_PARSE_EXPECT_VALUE ;
63100 }
0 commit comments