socsvn commit: r271646 - soc2014/zkorchev/freebsd_head/lib/libsol

zkorchev at FreeBSD.org zkorchev at FreeBSD.org
Thu Jul 31 16:20:43 UTC 2014


Author: zkorchev
Date: Thu Jul 31 16:20:42 2014
New Revision: 271646
URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=271646

Log:
  draft for human-readable format for libsol

Modified:
  soc2014/zkorchev/freebsd_head/lib/libsol/sol.c
  soc2014/zkorchev/freebsd_head/lib/libsol/sol.h

Modified: soc2014/zkorchev/freebsd_head/lib/libsol/sol.c
==============================================================================
--- soc2014/zkorchev/freebsd_head/lib/libsol/sol.c	Thu Jul 31 15:40:03 2014	(r271645)
+++ soc2014/zkorchev/freebsd_head/lib/libsol/sol.c	Thu Jul 31 16:20:42 2014	(r271646)
@@ -34,21 +34,42 @@
 
 // TODO track whether a key or a value is expected and generate error when appropriate?
 
-// TODO unsigned type support (used for fstat pipes)
+static void padding(const struct sol_stream *restrict stream)
+{
+#define T4 "\t\t\t\t"
+	static const char buf[] = "\n" T4 T4 T4 T4 T4 T4 T4 T4;
+	printf("%.*s", 1 + stream->ctx.c.depth - stream->ctx.c.stack[0], buf);
+#undef T4
+}
+
+static void separator(struct sol_stream *restrict stream)
+{
+	if (!stream->ctx.c.depth) return;
+	if (stream->ctx.c.stack[stream->ctx.c.depth - 1]) return;
+
+	if (stream->ctx.c.first)
+		stream->ctx.c.first = 0;
+	else
+		printf(",");
+}
 
 int sol_init(struct sol_stream *restrict stream)
 {
 	char *format = getenv("SOL_FORMAT");
 
-	if (!format)
-		return 0;
+	if (!format) return 0;
 	if (!strcmp(format, "json"))
+	{
 		stream->f = SOL_JSON;
-	else
-		return 0;
-
-	//stream->f = format;
-	stream->ctx.g = yajl_gen_alloc(0);
+		stream->ctx.g = yajl_gen_alloc(0);
+	}
+	else if (!strcmp(format, "configuration"))
+	{
+		stream->f = SOL_CONF;
+		stream->ctx.c.depth = 0;
+		stream->ctx.c.first = 0;
+	}
+	else return 0;
 
 	return stream->f;
 }
@@ -57,6 +78,7 @@
 {
 	const char *buffer;
 	size_t length;
+
 	switch (stream->f)
 	{
 	case SOL_JSON:
@@ -64,19 +86,45 @@
 		write(1, buffer, length);
 		yajl_gen_clear(stream->ctx.g);
 		break;
+
+	case SOL_CONF:
+		fflush(stdout);
+		break;
 	}
 }
 
 void sol_term(struct sol_stream *restrict stream)
 {
 	flush(stream);
-	write(1, "\n", 1); // TODO change this
-	yajl_gen_free(stream->ctx.g);
+	switch (stream->f)
+	{
+	case SOL_JSON:
+		write(1, "\n", 1); // TODO change this
+		yajl_gen_free(stream->ctx.g);
+		break;
+
+	case SOL_CONF:
+		write(1, "\n", 1); // TODO change this
+		break;
+	}
 }
 
 int sol_array_start(struct sol_stream *restrict stream)
 {
-	yajl_gen_array_open(stream->ctx.g);
+	switch (stream->f)
+	{
+	case SOL_JSON:
+		yajl_gen_array_open(stream->ctx.g);
+		break;
+
+	case SOL_CONF:
+		separator(stream);
+		padding(stream);
+		printf("[");
+		stream->ctx.c.stack[stream->ctx.c.depth++] = 0;
+		stream->ctx.c.first = 1;
+		break;
+	}
 
 	return 0;
 }
@@ -84,14 +132,41 @@
 int sol_array_end(struct sol_stream *restrict stream)
 {
 	flush(stream);
-	yajl_gen_array_close(stream->ctx.g);
+	switch (stream->f)
+	{
+	case SOL_JSON:
+		yajl_gen_array_close(stream->ctx.g);
+		break;
+
+	case SOL_CONF:
+		stream->ctx.c.depth -= 1;
+		stream->ctx.c.first = 0;
+		padding(stream);
+		printf("]");
+		break;
+	}
 
 	return 0;
 }
 
 int sol_map_start(struct sol_stream *restrict stream)
 {
-	yajl_gen_map_open(stream->ctx.g);
+	switch (stream->f)
+	{
+	case SOL_JSON:
+		yajl_gen_map_open(stream->ctx.g);
+		break;
+
+	case SOL_CONF:
+		if (stream->ctx.c.depth)
+		{
+			separator(stream);
+			padding(stream);
+			printf("{");
+		}
+		stream->ctx.c.stack[stream->ctx.c.depth++] = 1;
+		break;
+	}
 
 	return 0;
 }
@@ -99,14 +174,39 @@
 int sol_map_end(struct sol_stream *restrict stream)
 {
 	flush(stream);
-	yajl_gen_map_close(stream->ctx.g);
+	switch (stream->f)
+	{
+	case SOL_JSON:
+		yajl_gen_map_close(stream->ctx.g);
+		break;
+
+	case SOL_CONF:
+		stream->ctx.c.depth -= 1;
+		if (stream->ctx.c.depth)
+		{
+			padding(stream);
+			printf("}");
+		}
+		stream->ctx.c.first = 0;
+		break;
+	}
 
 	return 0;
 }
 
 int sol_map_key(struct sol_stream *restrict stream, const char *key, size_t length)
 {
-	yajl_gen_string(stream->ctx.g, (const unsigned char *)key, length);
+	switch (stream->f)
+	{
+	case SOL_JSON:
+		yajl_gen_string(stream->ctx.g, (const unsigned char *)key, length);
+		break;
+
+	case SOL_CONF:
+		padding(stream);
+		printf("%s", key);
+		break;
+	}
 
 	return 0;
 }
@@ -117,40 +217,101 @@
 	size_t len;
 
 	len = sprintf(buffer, "%" PRIi64, number);
-	yajl_gen_string(stream->ctx.g, (const unsigned char *)buffer, len);
-
-	return 0;
+	return sol_map_key(stream, buffer, len);
 }
 
 int sol_string(struct sol_stream *restrict stream, const char *data, size_t length)
 {
-	yajl_gen_string(stream->ctx.g, (const unsigned char *)data, length);
+	switch (stream->f)
+	{
+	case SOL_JSON:
+		yajl_gen_string(stream->ctx.g, (const unsigned char *)data, length);
+		break;
+
+	case SOL_CONF:
+		if (stream->ctx.c.stack[stream->ctx.c.depth - 1])
+			printf(" = \"%s\";", data);
+		else
+		{
+			separator(stream);
+			padding(stream);
+			printf("\"%s\"", data);
+		}
+		break;
+	}
 
 	return 0;
 }
 
 int sol_boolean(struct sol_stream *restrict stream, unsigned char value)
 {
-	yajl_gen_bool(stream->ctx.g, value);
+	switch (stream->f)
+	{
+	case SOL_JSON:
+		yajl_gen_bool(stream->ctx.g, value);
+		break;
+
+	case SOL_CONF:
+		if (stream->ctx.c.stack[stream->ctx.c.depth - 1])
+			printf(" = %s;", (value ? "true" : "false"));
+		else
+		{
+			separator(stream);
+			padding(stream);
+			printf("%s", (value ? "true" : "false"));
+		}
+		break;
+	}
 
 	return 0;
 }
 
 int sol_integer(struct sol_stream *restrict stream, int64_t value)
 {
-	yajl_gen_integer(stream->ctx.g, value);
+	switch (stream->f)
+	{
+	case SOL_JSON:
+		yajl_gen_integer(stream->ctx.g, value);
+		break;
+
+	case SOL_CONF:
+		if (stream->ctx.c.stack[stream->ctx.c.depth - 1])
+			printf(" = %" PRId64 ";", value);
+		else
+		{
+			separator(stream);
+			padding(stream);
+			printf("%" PRId64, value);
+		}
+		break;
+	}
 
 	return 0;
 }
 
-int sol_uinteger(struct sol_stream *restrict stream, uint64_t value) // TODO better name for this?
+int sol_uinteger(struct sol_stream *restrict stream, uint64_t value)
 {
 	char buffer[20 + 1]; // UINT64_MAX fits in 20 bytes
 	size_t len;
 
-	// TODO use hex when supported
-	len = sprintf(buffer, "%" PRIu64, value);
-	yajl_gen_number(stream->ctx.g, buffer, len);
+	switch (stream->f)
+	{
+	case SOL_JSON:
+		len = sprintf(buffer, "%" PRIu64, value);
+		yajl_gen_number(stream->ctx.g, buffer, len);
+		break;
+
+	case SOL_CONF:
+		if (stream->ctx.c.stack[stream->ctx.c.depth - 1])
+			printf(" = %" PRIx64 ";", value);
+		else
+		{
+			separator(stream);
+			padding(stream);
+			printf("%" PRIx64, value);
+		}
+		break;
+	}
 
 	return 0;
 }
@@ -158,7 +319,23 @@
 int sol_float(struct sol_stream *restrict stream, double value)
 {
 	// todo round mantissa?
-	yajl_gen_double(stream->ctx.g, value);
+	switch (stream->f)
+	{
+	case SOL_JSON:
+		yajl_gen_double(stream->ctx.g, value);
+		break;
+
+	case SOL_CONF:
+		if (stream->ctx.c.stack[stream->ctx.c.depth - 1])
+			printf(" = %f;", value);
+		else
+		{
+			separator(stream);
+			padding(stream);
+			printf("%f", value);
+		}
+		break;
+	}
 
 	return 0;
 }

Modified: soc2014/zkorchev/freebsd_head/lib/libsol/sol.h
==============================================================================
--- soc2014/zkorchev/freebsd_head/lib/libsol/sol.h	Thu Jul 31 15:40:03 2014	(r271645)
+++ soc2014/zkorchev/freebsd_head/lib/libsol/sol.h	Thu Jul 31 16:20:42 2014	(r271646)
@@ -29,12 +29,20 @@
 
 #define SOL_MAP_KEYL(stream, key) sol_map_key(stream, key, sizeof(key) - 1)
 
+#define SOL_DEPTH_MAX 32
+
 struct sol_stream
 {
-	enum {SOL_JSON = 1} f;
+	enum {SOL_JSON = 1, SOL_CONF} f;
 	union
 	{
 		yajl_gen g;
+		struct
+		{
+			unsigned char stack[SOL_DEPTH_MAX];
+			unsigned depth;
+			int first;
+		} c;
 	} ctx;
 };
 


More information about the svn-soc-all mailing list