Date: Thu, 31 Jul 2014 16:20:42 GMT From: zkorchev@FreeBSD.org To: svn-soc-all@FreeBSD.org Subject: socsvn commit: r271646 - soc2014/zkorchev/freebsd_head/lib/libsol Message-ID: <201407311620.s6VGKgVu086277@socsvn.freebsd.org>
next in thread | raw e-mail | index | archive | help
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; };
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201407311620.s6VGKgVu086277>