Browse Source

vive: replace mjson with nxjson to get valid config values.

Lubosz Sarnecki 7 years ago
parent
commit
bf664f85f5
7 changed files with 41 additions and 966 deletions
  1. 1 1
      CMakeLists.txt
  2. 1 1
      meson.build
  3. 1 1
      src/Makefile.am
  4. 38 10
      src/drv_htc_vive/packet.c
  5. 0 33
      src/drv_htc_vive/vive_config.h
  6. 0 779
      src/ext_deps/mjson.c
  7. 0 141
      src/ext_deps/mjson.h

+ 1 - 1
CMakeLists.txt

@@ -97,7 +97,7 @@ if(OPENHMD_DRIVER_HTC_VIVE)
 	${CMAKE_CURRENT_LIST_DIR}/src/drv_htc_vive/vive.c
 	${CMAKE_CURRENT_LIST_DIR}/src/drv_htc_vive/packet.c
 	#${CMAKE_CURRENT_LIST_DIR}/src/ext_deps/miniz.c
-	${CMAKE_CURRENT_LIST_DIR}/src/ext_deps/mjson.c
+	${CMAKE_CURRENT_LIST_DIR}/src/ext_deps/nxjson.c
 	)
 	add_definitions(-DDRIVER_HTC_VIVE)
 

+ 1 - 1
meson.build

@@ -58,7 +58,7 @@ if _drivers.contains('vive')
 	sources += [
 		'src/drv_htc_vive/vive.c',
 		'src/drv_htc_vive/packet.c',
-		'src/ext_deps/mjson.c'
+		'src/ext_deps/nxjson.c'
 	]
 	c_args += '-DDRIVER_HTC_VIVE'
 	deps += dep_hidapi

+ 1 - 1
src/Makefile.am

@@ -31,7 +31,7 @@ if BUILD_DRIVER_HTC_VIVE
 libopenhmd_la_SOURCES += \
 	drv_htc_vive/vive.c \
 	drv_htc_vive/packet.c \
-	ext_deps/mjson.c
+	ext_deps/nxjson.c
 
 libopenhmd_la_CPPFLAGS += $(hidapi_CFLAGS) -DDRIVER_HTC_VIVE
 libopenhmd_la_LDFLAGS += $(hidapi_LIBS)

+ 38 - 10
src/drv_htc_vive/packet.c

@@ -1,5 +1,7 @@
 #include "vive.h"
+
 #include "vive_config.h"
+#include "../ext_deps/nxjson.h"
 
 #ifdef _MSC_VER
 #define inline __inline
@@ -70,6 +72,16 @@ void trim(const char* src, char* buff, const unsigned int sizeBuff)
     buff[i] = '\0';
 }
 
+void get_vec3f_from_json(const nx_json* json, const char* name, vec3f* result)
+{
+	const nx_json* acc_bias_arr = nx_json_get(json, name);
+
+	for (int i = 0; i < acc_bias_arr->length; i++) {
+		const nx_json* item = nx_json_item(acc_bias_arr, i);
+		result->arr[i] = (float) item->dbl_value;
+	}
+}
+
 bool vive_decode_config_packet(vive_config_packet* pkt,
                                const unsigned char* buffer,
                                uint16_t size)
@@ -106,16 +118,32 @@ bool vive_decode_config_packet(vive_config_packet* pkt,
 	FILE* dfp;
 	dfp = fopen("jsondebug.json","w");
 	json_enable_debug(3, dfp);*/
-	int status = json_read_object((char*)output, sensor_offsets, NULL);
-	LOGI("\n--- Converted Vive JSON Data ---\n\n");
-	LOGI("acc_bias = %f %f %f\n", acc_bias[0], acc_bias[1], acc_bias[2]);
-	LOGI("acc_scale = %f %f %f\n", acc_scale[0], acc_scale[1], acc_scale[2]);
-	LOGI("gyro_bias = %f %f %f\n", gyro_bias[0], gyro_bias[1], gyro_bias[2]);
-	LOGI("gyro_scale = %f %f %f\n", gyro_scale[0], gyro_scale[1], gyro_scale[2]);
-	LOGI("\n--- End of Vive JSON Data ---\n\n");
-
-	if (status != 0)
-		puts(json_error_string(status));
+	const nx_json* json = nx_json_parse((char*)output, 0);
+
+	vec3f acc_bias;
+	vec3f acc_scale;
+	vec3f gyro_bias;
+	vec3f gyro_scale;
+
+	if (json) {
+		get_vec3f_from_json(json, "acc_bias", &acc_bias);
+		get_vec3f_from_json(json, "acc_scale", &acc_scale);
+		get_vec3f_from_json(json, "gyro_bias", &gyro_bias);
+		get_vec3f_from_json(json, "gyro_scale", &gyro_scale);
+
+		nx_json_free(json);
+
+		LOGI("\n--- Converted Vive JSON Data ---\n\n");
+		LOGI("acc_bias = %f %f %f\n", acc_bias.x, acc_bias.y, acc_bias.z);
+		LOGI("acc_scale = %f %f %f\n", acc_scale.x, acc_scale.y, acc_scale.z);
+		LOGI("gyro_bias = %f %f %f\n", gyro_bias.x, gyro_bias.y, gyro_bias.z);
+		LOGI("gyro_scale = %f %f %f\n", gyro_scale.x, gyro_scale.y, gyro_scale.z);
+		LOGI("\n--- End of Vive JSON Data ---\n\n");
+	} else {
+		LOGE("Could not parse JSON data.\n");
+		return false;
+	}
+
 	/** END OF DEBUG JSON PARSER CODE **/
 
 //	free(pCmp);

+ 0 - 33
src/drv_htc_vive/vive_config.h

@@ -7,37 +7,4 @@
 #pragma GCC diagnostic ignored "-Wimplicit-function-declaration"
 #pragma GCC diagnostic ignored "-Wmisleading-indentation"
 #include "../ext_deps/miniz.c"
-#include "../ext_deps/mjson.h"
 #pragma GCC diagnostic pop
-
-//Temporary, will get 'structed up'
-static double acc_bias[3];
-static double acc_scale[3];
-static double gyro_bias[3];
-static double gyro_scale[3];
-//end of temporary
-
-//Vive config packet
-const struct json_attr_t sensor_offsets[] = {
-    {"acc_bias", t_array,   .addr.array.element_type = t_real,
-                            .addr.array.arr.reals.store = acc_bias,
-                            .addr.array.maxlen = 3},
-    {"acc_scale", t_array,  .addr.array.element_type = t_real,
-                            .addr.array.arr.reals.store = acc_scale,
-                            .addr.array.maxlen = 3},
-    {"device", t_object},
-    {"device_class", t_ignore},
-    {"device_pid", t_ignore},
-    {"device_serial_number", t_ignore},
-    {"device_vid", t_ignore},
-    {"display_edid", t_ignore},
-    {"display_gc", t_ignore},
-    {"display_mc", t_ignore},
-    {"gyro_bias", t_array,  .addr.array.element_type = t_real,
-                            .addr.array.arr.reals.store = gyro_bias,
-                            .addr.array.maxlen = 3},
-    {"gyro_scale", t_array, .addr.array.element_type = t_real,
-                            .addr.array.arr.reals.store = gyro_scale,
-                            .addr.array.maxlen = 3},
-    {NULL},
-};

+ 0 - 779
src/ext_deps/mjson.c

@@ -1,779 +0,0 @@
-/****************************************************************************
-
-NAME
-   mjson.c - parse JSON into fixed-extent data structures
-
-DESCRIPTION
-   This module parses a large subset of JSON (JavaScript Object
-Notation).  Unlike more general JSON parsers, it doesn't use malloc(3)
-and doesn't support polymorphism; you need to give it a set of
-template structures describing the expected shape of the incoming
-JSON, and it will error out if that shape is not matched.  When the
-parse succeeds, attribute values will be extracted into static
-locations specified in the template structures.
-
-   The "shape" of a JSON object in the type signature of its
-attributes (and attribute values, and so on recursively down through
-all nestings of objects and arrays).  This parser is indifferent to
-the order of attributes at any level, but you have to tell it in
-advance what the type of each attribute value will be and where the
-parsed value will be stored. The template structures may supply
-default values to be used when an expected attribute is omitted.
-
-   The preceding paragraph told one fib.  A single attribute may
-actually have a span of multiple specifications with different
-syntactically distinguishable types (e.g. string vs. real vs. integer
-vs. boolean, but not signed integer vs. unsigned integer).  The parser
-will match the right spec against the actual data.
-
-   The dialect this parses has some limitations.  First, it cannot
-recognize the JSON "null" value. Second, all elements of an array must
-be of the same type. Third, characters may not be array elements (this
-restriction could be lifted)
-
-   There are separate entry points for beginning a parse of either
-JSON object or a JSON array. JSON "float" quantities are actually
-stored as doubles.
-
-   This parser processes object arrays in one of two different ways,
-defending on whether the array subtype is declared as object or
-structobject.
-
-   Object arrays take one base address per object subfield, and are
-mapped into parallel C arrays (one per subfield).  Strings are not
-supported in this kind of array, as they don't have a "natural" size
-to use as an offset multiplier.
-
-   Structobjects arrays are a way to parse a list of objects to a set
-of modifications to a corresponding array of C structs.  The trick is
-that the array object initialization has to specify both the C struct
-array's base address and the stride length (the size of the C struct).
-If you initialize the offset fields with the correct offsetof calls,
-everything will work. Strings are supported but all string storage
-has to be inline in the struct.
-
-PERMISSIONS
-   This file is Copyright (c) 2014 by Eric S. Raymond
-   BSD terms apply: see the file COPYING in the distribution root for details.
-
-***************************************************************************/
-/* The strptime prototype is not provided unless explicitly requested.
- * We also need to set the value high enough to signal inclusion of
- * newer features (like clock_gettime).  See the POSIX spec for more info:
- * http://pubs.opengroup.org/onlinepubs/9699919799/functions/V2_chap02.html#tag_15_02_01_02 */
-#define _XOPEN_SOURCE 600
-
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <stdbool.h>
-#include <stdarg.h>
-#include <ctype.h>
-#include <errno.h>
-#include <time.h>
-#include <math.h>	/* for HUGE_VAL */
-
-#include "mjson.h"
-
-#define DEBUG_ENABLE 1
-#ifdef DEBUG_ENABLE
-static int debuglevel = 0;
-static FILE *debugfp;
-
-void json_enable_debug(int level, FILE * fp)
-/* control the level and destination of debug trace messages */
-{
-    debuglevel = level;
-    debugfp = fp;
-}
-
-static void json_trace(int errlevel, const char *fmt, ...)
-/* assemble command in printf(3) style */
-{
-    if (errlevel <= debuglevel) {
-	char buf[BUFSIZ];
-	va_list ap;
-
-	(void)strncpy(buf, "json: ", BUFSIZ-1);
-	buf[BUFSIZ-1] = '\0';
-	va_start(ap, fmt);
-	(void)vsnprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), fmt,
-			ap);
-	va_end(ap);
-
-	(void)fputs(buf, debugfp);
-    }
-}
-
-# define json_debug_trace(args) (void) json_trace args
-#else
-# define json_debug_trace(args) /*@i1@*/do { } while (0)
-#endif /* DEBUG_ENABLE */
-
-/*@-immediatetrans -dependenttrans -usereleased -compdef@*/
-static /*@null@*/ char *json_target_address(const struct json_attr_t *cursor,
-					     /*@null@*/
-					     const struct json_array_t
-					     *parent, int offset)
-{
-    char *targetaddr = NULL;
-    if (parent == NULL || parent->element_type != t_structobject) {
-	/* ordinary case - use the address in the cursor structure */
-	switch (cursor->type) {
-	case t_ignore:
-	    targetaddr = NULL;
-	    break;
-	case t_integer:
-	    targetaddr = (char *)&cursor->addr.integer[offset];
-	    break;
-	case t_uinteger:
-	    targetaddr = (char *)&cursor->addr.uinteger[offset];
-	    break;
-	case t_time:
-	case t_real:
-	    targetaddr = (char *)&cursor->addr.real[offset];
-	    break;
-	case t_string:
-	    targetaddr = cursor->addr.string;
-	    break;
-	case t_boolean:
-	    targetaddr = (char *)&cursor->addr.boolean[offset];
-	    break;
-	case t_character:
-	    targetaddr = (char *)&cursor->addr.character[offset];
-	    break;
-	default:
-	    targetaddr = NULL;
-	    break;
-	}
-    } else
-	/* tricky case - hacking a member in an array of structures */
-	targetaddr =
-	    parent->arr.objects.base + (offset * parent->arr.objects.stride) +
-	    cursor->addr.offset;
-    json_debug_trace((1, "Target address for %s (offset %d) is %p\n",
-		      cursor->attribute, offset, targetaddr));
-    return targetaddr;
-}
-
-#ifdef TIME_ENABLE
-static double iso8601_to_unix( /*@in@*/ char *isotime)
-/* ISO8601 UTC to Unix UTC */
-{
-    char *dp = NULL;
-    double usec;
-    struct tm tm;
-
-   /*@i1@*/ dp = strptime(isotime, "%Y-%m-%dT%H:%M:%S", &tm);
-    if (dp == NULL)
-	return (double)HUGE_VAL;
-    if (*dp == '.')
-	usec = strtod(dp, NULL);
-    else
-	usec = 0;
-    return (double)timegm(&tm) + usec;
-}
-#endif /* TIME_ENABLE */
-
-/*@-immediatetrans -dependenttrans +usereleased +compdef@*/
-
-static int json_internal_read_object(const char *cp,
-				     const struct json_attr_t *attrs,
-				     /*@null@*/
-				     const struct json_array_t *parent,
-				     int offset,
-				     /*@null@*/ const char **end)
-{
-    /*@ -nullstate -nullderef -mustfreefresh -nullpass -usedef @*/
-    enum
-    { init, await_attr, in_attr, await_value, in_val_string,
-	in_escape, in_val_token, post_val, post_array
-    } state = 0;
-#ifdef DEBUG_ENABLE
-    char *statenames[] = {
-	"init", "await_attr", "in_attr", "await_value", "in_val_string",
-	"in_escape", "in_val_token", "post_val", "post_array",
-    };
-#endif /* DEBUG_ENABLE */
-    char attrbuf[JSON_ATTR_MAX + 1], *pattr = NULL;
-    char valbuf[JSON_VAL_MAX + 1], *pval = NULL;
-    bool value_quoted = false;
-    char uescape[5];		/* enough space for 4 hex digits and a NUL */
-    const struct json_attr_t *cursor;
-    int substatus, n, maxlen = 0;
-    unsigned int u;
-    const struct json_enum_t *mp;
-    char *lptr;
-
-#ifdef S_SPLINT_S
-    /* prevents gripes about buffers not being completely defined */
-    memset(valbuf, '\0', sizeof(valbuf));
-    memset(attrbuf, '\0', sizeof(attrbuf));
-#endif /* S_SPLINT_S */
-
-    if (end != NULL)
-	*end = NULL;		/* give it a well-defined value on parse failure */
-
-    /* stuff fields with defaults in case they're omitted in the JSON input */
-    for (cursor = attrs; cursor->attribute != NULL; cursor++)
-	if (!cursor->nodefault) {
-	    lptr = json_target_address(cursor, parent, offset);
-	    if (lptr != NULL)
-		switch (cursor->type) {
-		case t_integer:
-		    memcpy(lptr, &cursor->dflt.integer, sizeof(int));
-		    break;
-		case t_uinteger:
-		    memcpy(lptr, &cursor->dflt.uinteger, sizeof(unsigned int));
-		    break;
-		case t_time:
-		case t_real:
-		    memcpy(lptr, &cursor->dflt.real, sizeof(double));
-		    break;
-		case t_string:
-		    if (parent != NULL
-			&& parent->element_type != t_structobject
-			&& offset > 0)
-			return JSON_ERR_NOPARSTR;
-		    lptr[0] = '\0';
-		    break;
-		case t_boolean:
-		    memcpy(lptr, &cursor->dflt.boolean, sizeof(bool));
-		    break;
-		case t_character:
-		    lptr[0] = cursor->dflt.character;
-		    break;
-		case t_object:	/* silences a compiler warning */
-		case t_structobject:
-		case t_array:
-		case t_check:
-		case t_ignore:
-		    break;
-		}
-	}
-
-    json_debug_trace((1, "JSON parse of '%s' begins.\n", cp));
-
-    /* parse input JSON */
-    for (; *cp != '\0'; cp++) {
-	json_debug_trace((2, "State %-14s, looking at '%c' (%p)\n",
-			  statenames[state], *cp, cp));
-	switch (state) {
-	case init:
-	    if (isspace((unsigned char) *cp))
-		continue;
-	    else if (*cp == '{')
-		state = await_attr;
-	    else {
-		json_debug_trace((1,
-				  "Non-WS when expecting object start.\n"));
-		if (end != NULL)
-		    *end = cp;
-		return JSON_ERR_OBSTART;
-	    }
-	    break;
-	case await_attr:
-	    if (isspace((unsigned char) *cp))
-		continue;
-	    else if (*cp == '"') {
-		state = in_attr;
-		pattr = attrbuf;
-		if (end != NULL)
-		    *end = cp;
-	    } else if (*cp == '}')
-		break;
-	    else {
-		json_debug_trace((1, "Non-WS when expecting attribute.\n"));
-		if (end != NULL)
-		    *end = cp;
-		return JSON_ERR_ATTRSTART;
-	    }
-	    break;
-	case in_attr:
-	    if (pattr == NULL)
-		/* don't update end here, leave at attribute start */
-		return JSON_ERR_NULLPTR;
-	    if (*cp == '"') {
-		*pattr++ = '\0';
-		json_debug_trace((1, "Collected attribute name %s\n",
-				  attrbuf));
-		for (cursor = attrs; cursor->attribute != NULL; cursor++) {
-		    json_debug_trace((2, "Checking against %s\n",
-				      cursor->attribute));
-		    if (strcmp(cursor->attribute, attrbuf) == 0)
-			break;
-		}
-		if (cursor->attribute == NULL) {
-		    json_debug_trace((1,
-				      "Unknown attribute name '%s' (attributes begin with '%s').\n",
-				      attrbuf, attrs->attribute));
-		    /* don't update end here, leave at attribute start */
-		    return JSON_ERR_BADATTR;
-		}
-		state = await_value;
-		if (cursor->type == t_string)
-		    maxlen = (int)cursor->len - 1;
-		else if (cursor->type == t_check)
-		    maxlen = (int)strlen(cursor->dflt.check);
-		else if (cursor->type == t_time || cursor->type == t_ignore)
-		    maxlen = JSON_VAL_MAX;
-		else if (cursor->map != NULL)
-		    maxlen = (int)sizeof(valbuf) - 1;
-		pval = valbuf;
-	    } else if (pattr >= attrbuf + JSON_ATTR_MAX - 1) {
-		json_debug_trace((1, "Attribute name too long.\n"));
-		/* don't update end here, leave at attribute start */
-		return JSON_ERR_ATTRLEN;
-	    } else
-		*pattr++ = *cp;
-	    break;
-	case await_value:
-	    if (isspace((unsigned char) *cp) || *cp == ':')
-		continue;
-	    else if (*cp == '[') {
-		if (cursor->type != t_array) {
-		    json_debug_trace((1,
-				      "Saw [ when not expecting array.\n"));
-		    if (end != NULL)
-			*end = cp;
-		    return JSON_ERR_NOARRAY;
-		}
-		substatus = json_read_array(cp, &cursor->addr.array, &cp);
-		if (substatus != 0)
-		    return substatus;
-		state = post_array;
-	    } else if (cursor->type == t_array) {
-		json_debug_trace((1,
-				  "Array element was specified, but no [.\n"));
-		if (end != NULL)
-		    *end = cp;
-		return JSON_ERR_NOBRAK;
-	    } else if (*cp == '"') {
-		value_quoted = true;
-		state = in_val_string;
-		pval = valbuf;
-	    } else {
-		value_quoted = false;
-		state = in_val_token;
-		pval = valbuf;
-		*pval++ = *cp;
-	    }
-	    break;
-	case in_val_string:
-	    if (pval == NULL)
-		/* don't update end here, leave at value start */
-		return JSON_ERR_NULLPTR;
-	    if (*cp == '\\')
-		state = in_escape;
-	    else if (*cp == '"') {
-		*pval++ = '\0';
-		json_debug_trace((1, "Collected string value %s\n", valbuf));
-		state = post_val;
-	    } else if (pval > valbuf + JSON_VAL_MAX - 1
-		       || pval > valbuf + maxlen) {
-		json_debug_trace((1, "String value too long.\n"));
-		/* don't update end here, leave at value start */
-		return JSON_ERR_STRLONG;	/*  */
-	    } else
-		*pval++ = *cp;
-	    break;
-	case in_escape:
-	    if (pval == NULL)
-		/* don't update end here, leave at value start */
-		return JSON_ERR_NULLPTR;
-	    switch (*cp) {
-	    case 'b':
-		*pval++ = '\b';
-		break;
-	    case 'f':
-		*pval++ = '\f';
-		break;
-	    case 'n':
-		*pval++ = '\n';
-		break;
-	    case 'r':
-		*pval++ = '\r';
-		break;
-	    case 't':
-		*pval++ = '\t';
-		break;
-	    case 'u':
-		for (n = 0; n < 4 && cp[n] != '\0'; n++)
-		    uescape[n] = *cp++;
-		--cp;
-		(void)sscanf(uescape, "%04x", &u);
-		*pval++ = (char)u;	/* will truncate values above 0xff */
-		break;
-	    default:		/* handles double quote and solidus */
-		*pval++ = *cp;
-		break;
-	    }
-	    state = in_val_string;
-	    break;
-	case in_val_token:
-	    if (pval == NULL)
-		/* don't update end here, leave at value start */
-		return JSON_ERR_NULLPTR;
-	    if (isspace((unsigned char) *cp) || *cp == ',' || *cp == '}') {
-		*pval = '\0';
-		json_debug_trace((1, "Collected token value %s.\n", valbuf));
-		state = post_val;
-		if (*cp == '}' || *cp == ',')
-		    --cp;
-	    } else if (pval > valbuf + JSON_VAL_MAX - 1) {
-		json_debug_trace((1, "Token value too long.\n"));
-		/* don't update end here, leave at value start */
-		return JSON_ERR_TOKLONG;
-	    } else
-		*pval++ = *cp;
-	    break;
-	case post_val:
-	    /*
-	     * We know that cursor points at the first spec matching
-	     * the current attribute.  We don't know that it's *the*
-	     * correct spec; our dialect allows there to be any number
-	     * of adjacent ones with the same attrname but different
-	     * types.  Here's where we try to seek forward for a
-	     * matching type/attr pair if we're not looking at one.
-	     */
-	    for (;;) {
-		int seeking = cursor->type;
-		if (value_quoted && (cursor->type == t_string || cursor->type == t_time))
-		    break;
-		if ((strcmp(valbuf, "true")==0 || strcmp(valbuf, "false")==0)
-			&& seeking == t_boolean)
-		    break;
-		if (isdigit((unsigned char) valbuf[0])) {
-		    bool decimal = strchr(valbuf, '.') != NULL;
-		    if (decimal && seeking == t_real)
-			break;
-		    if (!decimal && (seeking == t_integer || seeking == t_uinteger))
-			break;
-		}
-		if (cursor[1].attribute==NULL)	/* out of possiblities */
-		    break;
-		if (strcmp(cursor[1].attribute, attrbuf)!=0)
-		    break;
-		++cursor;
-	    }
-	    if (value_quoted
-		&& (cursor->type != t_string && cursor->type != t_character
-		    && cursor->type != t_check && cursor->type != t_time
-		    && cursor->type != t_ignore && cursor->map == 0)) {
-		json_debug_trace((1,
-				  "Saw quoted value when expecting non-string.\n"));
-		return JSON_ERR_QNONSTRING;
-	    }
-	    if (!value_quoted
-		&& (cursor->type == t_string || cursor->type == t_check
-		    || cursor->type == t_time || cursor->map != 0)) {
-		json_debug_trace((1,
-				  "Didn't see quoted value when expecting string.\n"));
-		return JSON_ERR_NONQSTRING;
-	    }
-	    if (cursor->map != 0) {
-		for (mp = cursor->map; mp->name != NULL; mp++)
-		    if (strcmp(mp->name, valbuf) == 0) {
-			goto foundit;
-		    }
-		json_debug_trace((1, "Invalid enumerated value string %s.\n",
-				  valbuf));
-		return JSON_ERR_BADENUM;
-	      foundit:
-		(void)snprintf(valbuf, sizeof(valbuf), "%d", mp->value);
-	    }
-	    lptr = json_target_address(cursor, parent, offset);
-	    if (lptr != NULL)
-		switch (cursor->type) {
-		case t_integer:
-		    {
-			int tmp = atoi(valbuf);
-			memcpy(lptr, &tmp, sizeof(int));
-		    }
-		    break;
-		case t_uinteger:
-		    {
-			unsigned int tmp = (unsigned int)atoi(valbuf);
-			memcpy(lptr, &tmp, sizeof(unsigned int));
-		    }
-		    break;
-		case t_time:
-#ifdef TIME_ENABLE
-		    {
-			double tmp = iso8601_to_unix(valbuf);
-			memcpy(lptr, &tmp, sizeof(double));
-		    }
-#endif /* TIME_ENABLE */
-		    break;
-		case t_real:
-		    {
-			double tmp = atof(valbuf);
-			memcpy(lptr, &tmp, sizeof(double));
-		    }
-		    break;
-		case t_string:
-		    if (parent != NULL
-			&& parent->element_type != t_structobject
-			&& offset > 0)
-			return JSON_ERR_NOPARSTR;
-		    (void)strncpy(lptr, valbuf, cursor->len);
-		    valbuf[sizeof(valbuf)-1] = '\0';
-		    break;
-		case t_boolean:
-		    {
-			bool tmp = (strcmp(valbuf, "true") == 0);
-			memcpy(lptr, &tmp, sizeof(bool));
-		    }
-		    break;
-		case t_character:
-		    if (strlen(valbuf) > 1)
-			/* don't update end here, leave at value start */
-			return JSON_ERR_STRLONG;
-		    else
-			lptr[0] = valbuf[0];
-		    break;
-		case t_ignore:	/* silences a compiler warning */
-		case t_object:	/* silences a compiler warning */
-		case t_structobject:
-		case t_array:
-		    break;
-		case t_check:
-		    if (strcmp(cursor->dflt.check, valbuf) != 0) {
-			json_debug_trace((1,
-					  "Required attribute value %s not present.\n",
-					  cursor->dflt.check));
-			/* don't update end here, leave at start of attribute */
-			return JSON_ERR_CHECKFAIL;
-		    }
-		    break;
-		}
-	    /*@fallthrough@*/
-	case post_array:
-	    if (isspace((unsigned char) *cp))
-		continue;
-	    else if (*cp == ',')
-		state = await_attr;
-	    else if (*cp == '}') {
-		++cp;
-		goto good_parse;
-	    } else {
-		json_debug_trace((1, "Garbage while expecting comma or }\n"));
-		if (end != NULL)
-		    *end = cp;
-		return JSON_ERR_BADTRAIL;
-	    }
-	    break;
-	}
-    }
-
-  good_parse:
-    /* in case there's another object following, consume trailing WS */
-    while (isspace((unsigned char) *cp))
-	++cp;
-    if (end != NULL)
-	*end = cp;
-    json_debug_trace((1, "JSON parse ends.\n"));
-    return 0;
-    /*@ +nullstate +nullderef +mustfreefresh +nullpass +usedef @*/
-}
-
-int json_read_array(const char *cp, const struct json_array_t *arr,
-		    const char **end)
-{
-    /*@-nullstate -onlytrans@*/
-    int substatus, offset, arrcount;
-    char *tp;
-
-    if (end != NULL)
-	*end = NULL;		/* give it a well-defined value on parse failure */
-
-    json_debug_trace((1, "Entered json_read_array()\n"));
-
-    while (isspace((unsigned char) *cp))
-	cp++;
-    if (*cp != '[') {
-	json_debug_trace((1, "Didn't find expected array start\n"));
-	return JSON_ERR_ARRAYSTART;
-    } else
-	cp++;
-
-    tp = arr->arr.strings.store;
-    arrcount = 0;
-
-    /* Check for empty array */
-    while (isspace((unsigned char) *cp))
-	cp++;
-    if (*cp == ']')
-	goto breakout;
-
-    for (offset = 0; offset < arr->maxlen; offset++) {
-	char *ep = NULL;
-	json_debug_trace((1, "Looking at %s\n", cp));
-	switch (arr->element_type) {
-	case t_string:
-	    if (isspace((unsigned char) *cp))
-		cp++;
-	    if (*cp != '"')
-		return JSON_ERR_BADSTRING;
-	    else
-		++cp;
-	    arr->arr.strings.ptrs[offset] = tp;
-	    for (; tp - arr->arr.strings.store < arr->arr.strings.storelen;
-		 tp++)
-		if (*cp == '"') {
-		    ++cp;
-		    *tp++ = '\0';
-		    goto stringend;
-		} else if (*cp == '\0') {
-		    json_debug_trace((1,
-				      "Bad string syntax in string list.\n"));
-		    return JSON_ERR_BADSTRING;
-		} else {
-		    *tp = *cp++;
-		}
-	    json_debug_trace((1, "Bad string syntax in string list.\n"));
-	    return JSON_ERR_BADSTRING;
-	  stringend:
-	    break;
-	case t_object:
-	case t_structobject:
-	    substatus =
-		json_internal_read_object(cp, arr->arr.objects.subtype, arr,
-					  offset, &cp);
-	    if (substatus != 0) {
-		if (end != NULL)
-		    end = &cp;
-		return substatus;
-	    }
-	    break;
-	case t_integer:
-	    arr->arr.integers.store[offset] = (int)strtol(cp, &ep, 0);
-	    if (ep == cp)
-		return JSON_ERR_BADNUM;
-	    else
-		cp = ep;
-	    break;
-	case t_uinteger:
-	    arr->arr.uintegers.store[offset] = (unsigned int)strtoul(cp, &ep, 0);
-	    if (ep == cp)
-		return JSON_ERR_BADNUM;
-	    else
-		cp = ep;
-	    break;
-#ifdef TIME_ENABLE
-	case t_time:
-	    if (*cp != '"')
-		return JSON_ERR_BADSTRING;
-	    else
-		++cp;
-	    arr->arr.reals.store[offset] = iso8601_to_unix((char *)cp);
-	    if (arr->arr.reals.store[offset] >= HUGE_VAL)
-		return JSON_ERR_BADNUM;
-	    while (*cp && *cp != '"')
-		cp++;
-	    if (*cp != '"')
-		return JSON_ERR_BADSTRING;
-	    else
-		++cp; 
-	    break;
-#endif /* TIME_ENABLE */
-	case t_real:
-	    arr->arr.reals.store[offset] = strtod(cp, &ep);
-	    if (ep == cp)
-		return JSON_ERR_BADNUM;
-	    else
-		cp = ep;
-	    break;
-	case t_boolean:
-	    if (strncmp(cp, "true", 4) == 0) {
-		arr->arr.booleans.store[offset] = true;
-		cp += 4;
-	    }
-	    else if (strncmp(cp, "false", 5) == 0) {
-		arr->arr.booleans.store[offset] = false;
-		cp += 5;
-	    }
-	    break;
-	case t_character:
-	case t_array:
-	case t_check:
-	case t_ignore:
-	    json_debug_trace((1, "Invalid array subtype.\n"));
-	    return JSON_ERR_SUBTYPE;
-	}
-	arrcount++;
-	if (isspace((unsigned char) *cp))
-	    cp++;
-	if (*cp == ']') {
-	    json_debug_trace((1, "End of array found.\n"));
-	    goto breakout;
-	} else if (*cp == ',')
-	    cp++;
-	else {
-	    json_debug_trace((1, "Bad trailing syntax on array.\n"));
-	    return JSON_ERR_BADSUBTRAIL;
-	}
-    }
-    json_debug_trace((1, "Too many elements in array.\n"));
-    if (end != NULL)
-	*end = cp;
-    return JSON_ERR_SUBTOOLONG;
-  breakout:
-    if (arr->count != NULL)
-	*(arr->count) = arrcount;
-    if (end != NULL)
-	*end = cp;
-    /*@ -nullderef @*/
-    json_debug_trace((1, "leaving json_read_array() with %d elements\n",
-		      arrcount));
-    /*@ +nullderef @*/
-    return 0;
-    /*@+nullstate +onlytrans@*/
-}
-
-int json_read_object(const char *cp, const struct json_attr_t *attrs,
-		     /*@null@*/ const char **end)
-{
-    int st;
-
-    json_debug_trace((1, "json_read_object() sees '%s'\n", cp));
-    st = json_internal_read_object(cp, attrs, NULL, 0, end);
-    return st;
-}
-
-const /*@observer@*/ char *json_error_string(int err)
-{
-    const char *errors[] = {
-	"unknown error while parsing JSON",
-	"non-whitespace when expecting object start",
-	"non-whitespace when expecting attribute start",
-	"unknown attribute name",
-	"attribute name too long",
-	"saw [ when not expecting array",
-	"array element specified, but no [",
-	"string value too long",
-	"token value too long",
-	"garbage while expecting comma or } or ]",
-	"didn't find expected array start",
-	"error while parsing object array",
-	"too many array elements",
-	"garbage while expecting array comma",
-	"unsupported array element type",
-	"error while string parsing",
-	"check attribute not matched",
-	"can't support strings in parallel arrays",
-	"invalid enumerated value",
-	"saw quoted value when expecting nonstring",
-	"didn't see quoted value when expecting string",
-	"other data conversion error",
-	"unexpected null value or attribute pointer",
-    };
-
-    if (err <= 0 || err >= (int)(sizeof(errors) / sizeof(errors[0])))
-	return errors[0];
-    else
-	return errors[err];
-}
-
-/* end */
-

+ 0 - 141
src/ext_deps/mjson.h

@@ -1,141 +0,0 @@
-/* Structures for JSON parsing using only fixed-extent memory
- *
- * This file is Copyright (c) 2014 by Eric S. Raymond.
- * BSD terms apply: see the file COPYING in the distribution root for details.
- */
-
-#include <stdbool.h>
-#include <ctype.h>
-#include <stdio.h>
-#include <sys/types.h>
-
-#define NITEMS(x) (int)(sizeof(x)/sizeof(x[0]))
-
-typedef enum {t_integer, t_uinteger, t_real,
-	      t_string, t_boolean, t_character,
-	      t_time,
-	      t_object, t_structobject, t_array,
-	      t_check, t_ignore} 
-    json_type;
-
-struct json_enum_t {
-    char	*name;
-    int		value;
-};
-
-struct json_array_t {
-    json_type element_type;
-    union {
-	struct {
-	    const struct json_attr_t *subtype;
-	    char *base;
-	    size_t stride;
-	} objects;
-	struct {
-	    char **ptrs;
-	    char *store;
-	    int storelen;
-	} strings;
-	struct {
-	    int *store;
-	} integers;
-	struct {
-	    unsigned int *store;
-	} uintegers;
-	struct {
-	    double *store;
-	} reals;
-	struct {
-	    bool *store;
-	} booleans;
-    } arr;
-    int *count, maxlen;
-};
-
-struct json_attr_t {
-    char *attribute;
-    json_type type;
-    union {
-	int *integer;
-	unsigned int *uinteger;
-	double *real;
-	char *string;
-	bool *boolean;
-	char *character;
-	struct json_array_t array;
-	size_t offset;
-    } addr;
-    union {
-	int integer;
-	unsigned int uinteger;
-	double real;
-	bool boolean;
-	char character;
-	char *check;
-    } dflt;
-    size_t len;
-    const struct json_enum_t *map;
-    bool nodefault;
-};
-
-#define JSON_ATTR_MAX	31	/* max chars in JSON attribute name */
-#define JSON_VAL_MAX	512	/* max chars in JSON value part */
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-int json_read_object(const char *, const struct json_attr_t *,
-		     /*@null@*/const char **);
-int json_read_array(const char *, const struct json_array_t *,
-		    /*@null@*/const char **);
-const /*@observer@*/char *json_error_string(int);
-
-void json_enable_debug(int, FILE *);
-#ifdef __cplusplus
-}
-#endif
-
-#define JSON_ERR_OBSTART	1	/* non-WS when expecting object start */
-#define JSON_ERR_ATTRSTART	2	/* non-WS when expecting attrib start */
-#define JSON_ERR_BADATTR	3	/* unknown attribute name */
-#define JSON_ERR_ATTRLEN	4	/* attribute name too long */
-#define JSON_ERR_NOARRAY	5	/* saw [ when not expecting array */
-#define JSON_ERR_NOBRAK 	6	/* array element specified, but no [ */
-#define JSON_ERR_STRLONG	7	/* string value too long */
-#define JSON_ERR_TOKLONG	8	/* token value too long */
-#define JSON_ERR_BADTRAIL	9	/* garbage while expecting comma or } or ] */
-#define JSON_ERR_ARRAYSTART	10	/* didn't find expected array start */
-#define JSON_ERR_OBJARR 	11	/* error while parsing object array */
-#define JSON_ERR_SUBTOOLONG	12	/* too many array elements */
-#define JSON_ERR_BADSUBTRAIL	13	/* garbage while expecting array comma */
-#define JSON_ERR_SUBTYPE	14	/* unsupported array element type */
-#define JSON_ERR_BADSTRING	15	/* error while string parsing */
-#define JSON_ERR_CHECKFAIL	16	/* check attribute not matched */
-#define JSON_ERR_NOPARSTR	17	/* can't support strings in parallel arrays */
-#define JSON_ERR_BADENUM	18	/* invalid enumerated value */
-#define JSON_ERR_QNONSTRING	19	/* saw quoted value when expecting nonstring */
-#define JSON_ERR_NONQSTRING	19	/* didn't see quoted value when expecting string */
-#define JSON_ERR_MISC		20	/* other data conversion error */
-#define JSON_ERR_BADNUM		21	/* error while parsing a numerical argument */
-#define JSON_ERR_NULLPTR	22	/* unexpected null value or attribute pointer */
-
-/*
- * Use the following macros to declare template initializers for structobject
- * arrays.  Writing the equivalents out by hand is error-prone.
- *
- * STRUCTOBJECT takes a structure name s, and a fieldname f in s.
- *
- * STRUCTARRAY takes the name of a structure array, a pointer to a an
- * initializer defining the subobject type, and the address of an integer to
- * store the length in.
- */
-#define STRUCTOBJECT(s, f)	.addr.offset = offsetof(s, f)
-#define STRUCTARRAY(a, e, n) \
-	.addr.array.element_type = t_structobject, \
-	.addr.array.arr.objects.subtype = e, \
-	.addr.array.arr.objects.base = (char*)a, \
-	.addr.array.arr.objects.stride = sizeof(a[0]), \
-	.addr.array.count = n, \
-	.addr.array.maxlen = (int)(sizeof(a)/sizeof(a[0]))
-
-/* json.h ends here */