Пример #1
0
    static const char *
match_hfdte_record(const char *p, struct tm *tm)
{
    int mday = 0, mon = 0, year = 0;
    p = match_literal(p, "HFDTE");
    if (!p) return 0;
    p = match_n_digits(p, 2, &mday);
    p = match_n_digits(p, 2, &mon);
    p = match_n_digits(p, 2, &year);
    p = match_literal(p, "\r\n");
    if (!p) return 0;
    tm->tm_year = year + 2000 - 1900;
    tm->tm_mon = mon - 1;
    tm->tm_mday = mday;
    return p;
}
Пример #2
0
	static void
flytec_pbrwps(flytec_t *flytec)
{
	flytec_puts_nmea(flytec, "PBRWPS,");
	flytec_expectc(flytec, XOFF);
	char line[128];
	while (flytec_gets_nmea(flytec, line, sizeof line)) {
		const char *p = line;
		p = match_literal(p, "PBRWPS,");
		int lat_deg = 0, lat_min = 0, lat_mmin = 0;
		p = match_n_digits(p, 2, &lat_deg);
		p = match_n_digits(p, 2, &lat_min);
		p = match_char(p, '.');
		p = match_n_digits(p, 3, &lat_mmin);
		p = match_char(p, ',');
		char lat_hemi = '\0';
		p = match_one_of(p, "NS", &lat_hemi);
		p = match_char(p, ',');
		int lon_deg = 0, lon_min = 0, lon_mmin = 0;
		p = match_n_digits(p, 3, &lon_deg);
		p = match_n_digits(p, 2, &lon_min);
		p = match_char(p, '.');
		p = match_n_digits(p, 3, &lon_mmin);
		p = match_char(p, ',');
		char lon_hemi = '\0';
		p = match_one_of(p, "EW", &lon_hemi);
		p = match_char(p, ',');
		char *name = 0;
		p = match_string_until(p, ',', 1, 0);
		p = match_string_until(p, ',', 1, &name);
		int ele = 0;
		p = match_unsigned(p, &ele);
		p = match_eos(p);
		if (p) {
			waypoint *w = waypt_new();
			w->latitude = lat_deg + lat_min / 60.0 + lat_mmin / 60000.0;
			if (lat_hemi == 'S')
				w->latitude = -w->latitude;
			w->longitude = lon_deg + lon_min / 60.0 + lon_mmin / 60000.0;
			if (lon_hemi == 'W')
				w->longitude = -w->longitude;
			w->altitude = ele;
			w->shortname = rstrip(name);
			waypt_add(w);
		} else {
			free(name);
		}
	}
	flytec_expectc(flytec, XON);
}
Пример #3
0
snp_t *snp_new(const char *p)
{
    snp_t *snp = alloc(sizeof(snp_t));
    p = match_literal(p, "PBRSNP,");
    p = match_string_until(p, ',', 1, &snp->instrument_id);
    p = match_string_until(p, ',', 1, &snp->pilot_name);
    p = match_unsigned(p, &snp->serial_number);
    p = match_char(p, ',');
    p = match_string_until(p, '\0', 0, &snp->software_version);
    p = match_eos(p);
    if (!p) {
	snp_delete(snp);
	return 0;
    }
    return snp;
}
Пример #4
0
	static void
flytec_pbrrts(flytec_t *flytec)
{
	flytec_puts_nmea(flytec, "PBRRTS,");
	flytec_expectc(flytec, XOFF);
	route_head *route = 0;
	char line[128];
	while (flytec_gets_nmea(flytec, line, sizeof line)) {
		const char *p = line;
		p = match_literal(p, "PBRRTS,");
		int index = 0, count = 0, routepoint_index = 0;
		p = match_unsigned(p, &index);
		p = match_char(p, ',');
		p = match_unsigned(p, &count);
		p = match_char(p, ',');
		p = match_unsigned(p, &routepoint_index);
		p = match_char(p, ',');
		if (!p)
			continue;
		if (routepoint_index == 0) {
			char *name = 0;
			p = match_string_until(p, '\0', 0, &name);
			p = match_eos(p);
			if (p) {
				route = route_head_alloc();
				route->rte_num = index + 1;
				route->rte_name = rstrip(name);
				route_add_head(route);
			} else {
				free(name);
			}
		} else {
			char *name = 0;
			p = match_string_until(p, ',', 1, 0);
			p = match_string_until(p, '\0', 0, &name);
			p = match_eos(p);
			if (p) {
				const waypoint *w = find_waypt_by_name(rstrip(name));
				if (w)
					route_add_wpt(route, waypt_dupe(w));
			}
			free(name);
		}
	}
	flytec_expectc(flytec, XON);
}
Пример #5
0
	static track_t *
track_new(const char *p)
{
	track_t *track = xmalloc(sizeof(track_t));
	memset(track, 0, sizeof *track);
	p = match_literal(p, "PBRTL,");
	p = match_unsigned(p, &track->count);
	p = match_char(p, ',');
	p = match_unsigned(p, &track->index);
	p = match_char(p, ',');
	struct tm tm;
	memset(&tm, 0, sizeof tm);
	p = match_unsigned(p, &tm.tm_mday);
	p = match_char(p, '.');
	p = match_unsigned(p, &tm.tm_mon);
	p = match_char(p, '.');
	p = match_unsigned(p, &tm.tm_year);
	p = match_char(p, ',');
	p = match_unsigned(p, &tm.tm_hour);
	p = match_char(p, ':');
	p = match_unsigned(p, &tm.tm_min);
	p = match_char(p, ':');
	p = match_unsigned(p, &tm.tm_sec);
	p = match_char(p, ',');
	int duration_hour = 0, duration_min = 0, duration_sec = 0;
	p = match_unsigned(p, &duration_hour);
	p = match_char(p, ':');
	p = match_unsigned(p, &duration_min);
	p = match_char(p, ':');
	p = match_unsigned(p, &duration_sec);
	p = match_eos(p);
	if (!p) {
		track_delete(track);
		return 0;
	}
	tm.tm_mon -= 1;
	tm.tm_year += 2000 - 1900;
	track->date = DATE_NEW(tm);
	track->time = mktime(&tm);
	if (track->time == (time_t) -1)
		DIE("mktime", errno);
	track->duration = 3600 * duration_hour + 60 * duration_min + duration_sec;
	return track;
}
Пример #6
0
ssize_t
spdk_json_parse(void *json, size_t size, struct spdk_json_val *values, size_t num_values,
		void **end, uint32_t flags)
{
	uint8_t *json_end = json + size;
	enum spdk_json_val_type containers[SPDK_JSON_MAX_NESTING_DEPTH];
	size_t con_value[SPDK_JSON_MAX_NESTING_DEPTH];
	enum spdk_json_val_type con_type = SPDK_JSON_VAL_INVALID;
	bool trailing_comma = false;
	size_t depth = 0; /* index into containers */
	size_t cur_value = 0; /* index into values */
	size_t con_start_value;
	uint8_t *data = json;
	uint8_t *new_data;
	int rc;
	const struct json_literal *lit;
	enum {
		STATE_VALUE, /* initial state */
		STATE_VALUE_SEPARATOR, /* value separator (comma) */
		STATE_NAME, /* "name": value */
		STATE_NAME_SEPARATOR, /* colon */
		STATE_END, /* parsed the complete value, so only whitespace is valid */
	} state = STATE_VALUE;

#define ADD_VALUE(t, val_start_ptr, val_end_ptr) \
	if (values && cur_value < num_values) { \
		values[cur_value].type = t; \
		values[cur_value].start = val_start_ptr; \
		values[cur_value].len = val_end_ptr - val_start_ptr; \
	} \
	cur_value++

	while (data < json_end) {
		uint8_t c = *data;

		switch (c) {
		case ' ':
		case '\t':
		case '\r':
		case '\n':
			/* Whitespace is allowed between any tokens. */
			data++;
			break;

		case 't':
		case 'f':
		case 'n':
			/* true, false, or null */
			if (state != STATE_VALUE) return SPDK_JSON_PARSE_INVALID;
			lit = &g_json_literals[(c >> 3) & 3]; /* See comment above g_json_literals[] */
			assert(lit->str[0] == c);
			rc = match_literal(data, json_end, lit->str, lit->len);
			if (rc < 0) return rc;
			ADD_VALUE(lit->type, data, data + rc);
			data += rc;
			state = depth ? STATE_VALUE_SEPARATOR : STATE_END;
			trailing_comma = false;
			break;

		case '"':
			if (state != STATE_VALUE && state != STATE_NAME) return SPDK_JSON_PARSE_INVALID;
			rc = json_decode_string(data, json_end, &new_data, flags);
			if (rc < 0) return rc;
			/*
			 * Start is data + 1 to skip initial quote.
			 * Length is data + rc - 1 to skip both quotes.
			 */
			ADD_VALUE(state == STATE_VALUE ? SPDK_JSON_VAL_STRING : SPDK_JSON_VAL_NAME,
				  data + 1, data + rc - 1);
			data = new_data;
			if (state == STATE_NAME) {
				state = STATE_NAME_SEPARATOR;
			} else {
				state = depth ? STATE_VALUE_SEPARATOR : STATE_END;
			}
			trailing_comma = false;
			break;

		case '-':
		case '0':
		case '1':
		case '2':
		case '3':
		case '4':
		case '5':
		case '6':
		case '7':
		case '8':
		case '9':
			if (state != STATE_VALUE) return SPDK_JSON_PARSE_INVALID;
			rc = json_valid_number(data, json_end);
			if (rc < 0) return rc;
			ADD_VALUE(SPDK_JSON_VAL_NUMBER, data, data + rc);
			data += rc;
			state = depth ? STATE_VALUE_SEPARATOR : STATE_END;
			trailing_comma = false;
			break;

		case '{':
		case '[':
			if (state != STATE_VALUE) return SPDK_JSON_PARSE_INVALID;
			if (depth == SPDK_JSON_MAX_NESTING_DEPTH) {
				return SPDK_JSON_PARSE_MAX_DEPTH_EXCEEDED;
			}
			if (c == '{') {
				con_type = SPDK_JSON_VAL_OBJECT_BEGIN;
				state = STATE_NAME;
			} else {
				con_type = SPDK_JSON_VAL_ARRAY_BEGIN;
				state = STATE_VALUE;
			}
			con_value[depth] = cur_value;
			containers[depth++] = con_type;
			ADD_VALUE(con_type, data, data + 1);
			data++;
			trailing_comma = false;
			break;

		case '}':
		case ']':
			if (trailing_comma) return SPDK_JSON_PARSE_INVALID;
			if (depth == 0) return SPDK_JSON_PARSE_INVALID;
			con_type = containers[--depth];
			con_start_value = con_value[depth];
			if (values && con_start_value < num_values) {
				values[con_start_value].len = cur_value - con_start_value - 1;
			}
			if (c == '}') {
				if (state != STATE_NAME && state != STATE_VALUE_SEPARATOR) {
					return SPDK_JSON_PARSE_INVALID;
				}
				if (con_type != SPDK_JSON_VAL_OBJECT_BEGIN) {
					return SPDK_JSON_PARSE_INVALID;
				}
				ADD_VALUE(SPDK_JSON_VAL_OBJECT_END, data, data + 1);
			} else {
				if (state != STATE_VALUE && state != STATE_VALUE_SEPARATOR) {
					return SPDK_JSON_PARSE_INVALID;
				}
				if (con_type != SPDK_JSON_VAL_ARRAY_BEGIN) {
					return SPDK_JSON_PARSE_INVALID;
				}
				ADD_VALUE(SPDK_JSON_VAL_ARRAY_END, data, data + 1);
			}
			con_type = depth == 0 ? SPDK_JSON_VAL_INVALID : containers[depth - 1];
			data++;
			state = depth ? STATE_VALUE_SEPARATOR : STATE_END;
			trailing_comma = false;
			break;

		case ',':
			if (state != STATE_VALUE_SEPARATOR) return SPDK_JSON_PARSE_INVALID;
			data++;
			assert(con_type == SPDK_JSON_VAL_ARRAY_BEGIN ||
			       con_type == SPDK_JSON_VAL_OBJECT_BEGIN);
			state = con_type == SPDK_JSON_VAL_ARRAY_BEGIN ? STATE_VALUE : STATE_NAME;
			trailing_comma = true;
			break;

		case ':':
			if (state != STATE_NAME_SEPARATOR) return SPDK_JSON_PARSE_INVALID;
			data++;
			state = STATE_VALUE;
			break;

		case '/':
			if (!(flags & SPDK_JSON_PARSE_FLAG_ALLOW_COMMENTS)) {
				return SPDK_JSON_PARSE_INVALID;
			}
			rc = json_valid_comment(data, json_end);
			if (rc < 0) return rc;
			/* Skip over comment */
			data += rc;
			break;

		default:
			return SPDK_JSON_PARSE_INVALID;
		}

		if (state == STATE_END) {
			break;
		}
	}

	if (state == STATE_END) {
		/* Skip trailing whitespace */
		while (data < json_end) {
			uint8_t c = *data;

			if (c == ' ' || c == '\t' || c == '\r' || c == '\n') {
				data++;
			} else {
				break;
			}
		}

		/*
		 * These asserts are just for sanity checking - they are guaranteed by the allowed
		 *  state transitions.
		 */
		assert(depth == 0);
		assert(trailing_comma == false);
		assert(data <= json_end);
		if (end) {
			*end = data;
		}
		return cur_value;
	}

	/* Invalid end state - ran out of data */
	if (end) {
		*end = data;
	}
	return SPDK_JSON_PARSE_INCOMPLETE;
}
Пример #7
0
static match_result match_null(const char* begin, const char* end, token_kind& kind, std::size_t& length)
{
    kind = token_kind::null;
    return match_literal(begin, end, "null", length);
}
Пример #8
0
static match_result match_false(const char* begin, const char* end, token_kind& kind, std::size_t& length)
{
    kind = token_kind::boolean;
    return match_literal(begin, end, "false", length);
}