/* number = [ '-' ] digit+ [ '.' digit+ ] [ ['e'|'E'] ['+'|'-'] digit+ ] */ static int parse_number(struct frozen *f) { int ch = cur(f); SET_STATE(f, f->cur, "", 0); if (ch == '-') f->cur++; EXPECT(f->cur < f->end, JSON_STRING_INCOMPLETE); EXPECT(is_digit(f->cur[0]), JSON_STRING_INVALID); while (f->cur < f->end && is_digit(f->cur[0])) f->cur++; if (f->cur < f->end && f->cur[0] == '.') { f->cur++; EXPECT(f->cur < f->end, JSON_STRING_INCOMPLETE); EXPECT(is_digit(f->cur[0]), JSON_STRING_INVALID); while (f->cur < f->end && is_digit(f->cur[0])) f->cur++; } if (f->cur < f->end && (f->cur[0] == 'e' || f->cur[0] == 'E')) { f->cur++; EXPECT(f->cur < f->end, JSON_STRING_INCOMPLETE); if ((f->cur[0] == '+' || f->cur[0] == '-')) f->cur++; EXPECT(f->cur < f->end, JSON_STRING_INCOMPLETE); EXPECT(is_digit(f->cur[0]), JSON_STRING_INVALID); while (f->cur < f->end && is_digit(f->cur[0])) f->cur++; } truncate_path(f, fstate.path_len); CALL_BACK(f, JSON_TYPE_NUMBER, fstate.ptr, f->cur - fstate.ptr); return 0; }
void do_stop() { can_interrupt = true; car_set_left_speed(0); car_set_right_speed(0); CALL_BACK(STOP,FINISH); delayMs(100); }
void do_turn_back() { car_set_left_speed(0); car_set_left_speed(0); delayMs(100); car_change_direction(); CALL_BACK(TURN_BACK,FINISH); }
/* object = '{' pair { ',' pair } '}' */ static int parse_object(struct frozen *f) { TRY(test_and_skip(f, '{')); { CALL_BACK(f, JSON_TYPE_OBJECT_START, NULL, 0); { SET_STATE(f, f->cur - 1, ".", 1); while (cur(f) != '}') { TRY(parse_pair(f)); if (cur(f) == ',') f->cur++; } TRY(test_and_skip(f, '}')); truncate_path(f, fstate.path_len); CALL_BACK(f, JSON_TYPE_OBJECT_END, fstate.ptr, f->cur - fstate.ptr); } } return 0; }
/* identifier = letter { letter | digit | '_' } */ static int parse_identifier(struct frozen *f) { EXPECT(is_alpha(cur(f)), JSON_STRING_INVALID); { SET_STATE(f, f->cur, JSON_TYPE_STRING, "", 0); while (f->cur < f->end && (*f->cur == '_' || is_alpha(*f->cur) || is_digit(*f->cur))) { f->cur++; } CALL_BACK(f); } return 0; }
/* object = '{' pair { ',' pair } '}' */ static int parse_object(struct frozen *f) { TRY(test_and_skip(f, '{')); { SET_STATE(f, f->cur - 1, JSON_TYPE_OBJECT, ".", 1); while (cur(f) != '}') { TRY(parse_pair(f)); if (cur(f) == ',') f->cur++; } TRY(test_and_skip(f, '}')); CALL_BACK(f); } return 0; }
static int expect(struct frozen *f, const char *s, int len, enum json_type t) { int i, n = left(f); SET_STATE(f, f->cur, t, "", 0); for (i = 0; i < len; i++) { if (i >= n) return JSON_STRING_INCOMPLETE; if (f->cur[i] != s[i]) return JSON_STRING_INVALID; } f->cur += len; CALL_BACK(f); return 0; }
static int expect(struct frozen *f, const char *s, int len, enum json_token_type tok_type) { int i, n = left(f); SET_STATE(f, f->cur, "", 0); for (i = 0; i < len; i++) { if (i >= n) return JSON_STRING_INCOMPLETE; if (f->cur[i] != s[i]) return JSON_STRING_INVALID; } f->cur += len; truncate_path(f, fstate.path_len); CALL_BACK(f, tok_type, fstate.ptr, f->cur - fstate.ptr); return 0; }
/* array = '[' [ value { ',' value } ] ']' */ static int parse_array(struct frozen *f) { int i = 0, current_path_len; char buf[20]; TRY(test_and_skip(f, '[')); { SET_STATE(f, f->cur - 1, JSON_TYPE_ARRAY, "", 0); while (cur(f) != ']') { snprintf(buf, sizeof(buf), "[%d]", i); i++; current_path_len = append_to_path(f, buf, strlen(buf)); TRY(parse_value(f)); truncate_path(f, current_path_len); if (cur(f) == ',') f->cur++; } TRY(test_and_skip(f, ']')); CALL_BACK(f); } return 0; }
/* string = '"' { quoted_printable_chars } '"' */ static int parse_string(struct frozen *f) { int n, ch = 0, len = 0; TRY(test_and_skip(f, '"')); { SET_STATE(f, f->cur, JSON_TYPE_STRING, "", 0); for (; f->cur < f->end; f->cur += len) { ch = *(unsigned char *) f->cur; len = get_utf8_char_len((unsigned char) ch); EXPECT(ch >= 32 && len > 0, JSON_STRING_INVALID); /* No control chars */ EXPECT(len < left(f), JSON_STRING_INCOMPLETE); if (ch == '\\') { EXPECT((n = get_escape_len(f->cur + 1, left(f))) > 0, n); len += n; } else if (ch == '"') { CALL_BACK(f); f->cur++; break; }; } } return ch == '"' ? 0 : JSON_STRING_INCOMPLETE; }