json BUGFIX proper array parse and print

Includes the special [null] array and
any lists (array of objects) and
leaf-lists (array of values).

Refs cesnet/libnetconf2#331
diff --git a/src/parser_json.c b/src/parser_json.c
index 81d1842..e9cbfe9 100644
--- a/src/parser_json.c
+++ b/src/parser_json.c
@@ -962,17 +962,35 @@
     ret = lydjson_create_opaq(lydctx, name, name_len, prefix, prefix_len, parent, status_inner_p, node_p);
     LY_CHECK_RET(ret);
 
+    if ((*status_p == LYJSON_ARRAY) && (*status_inner_p == LYJSON_NULL)) {
+        /* special array null value */
+        ((struct lyd_node_opaq *)*node_p)->hints |= LYD_VALHINT_EMPTY;
+
+        /* must be the only item */
+        LY_CHECK_RET(lyjson_ctx_next(lydctx->jsonctx, status_inner_p));
+        if (*status_inner_p != LYJSON_ARRAY_CLOSED) {
+            LOGVAL(lydctx->jsonctx->ctx, LYVE_SYNTAX, "Array \"null\" member with another member.");
+            return LY_EVALID;
+        }
+
+        goto finish;
+    }
+
     while ((*status_p == LYJSON_ARRAY) || (*status_p == LYJSON_ARRAY_EMPTY)) {
         /* process another instance of the same node */
-        /* but first mark the node to be expected a list or a leaf-list */
-        ((struct lyd_node_opaq *)*node_p)->hints |= LYD_NODEHINT_LIST | LYD_NODEHINT_LEAFLIST;
 
         if ((*status_inner_p == LYJSON_OBJECT) || (*status_inner_p == LYJSON_OBJECT_EMPTY)) {
+            /* array with objects, list */
+            ((struct lyd_node_opaq *)*node_p)->hints |= LYD_NODEHINT_LIST;
+
             /* but first process children of the object in the array */
-            while (*status_inner_p != LYJSON_OBJECT_CLOSED && *status_inner_p != LYJSON_OBJECT_EMPTY) {
+            while ((*status_inner_p != LYJSON_OBJECT_CLOSED) && (*status_inner_p != LYJSON_OBJECT_EMPTY)) {
                 LY_CHECK_RET(lydjson_subtree_r(lydctx, *node_p, lyd_node_child_p(*node_p), NULL));
                 *status_inner_p = lyjson_ctx_status(lydctx->jsonctx, 0);
             }
+        } else {
+            /* array with values, leaf-list */
+            ((struct lyd_node_opaq *)*node_p)->hints |= LYD_NODEHINT_LEAFLIST;
         }
 
         LY_CHECK_RET(lyjson_ctx_next(lydctx->jsonctx, status_inner_p));
diff --git a/src/printer_json.c b/src/printer_json.c
index dea32d3..0682309 100644
--- a/src/printer_json.c
+++ b/src/printer_json.c
@@ -601,12 +601,13 @@
         has_content = 1;
     }
 
-    if (!node->schema || (node->schema->nodetype != LYS_LIST)) {
+    if ((node->schema && (node->schema->nodetype == LYS_LIST)) ||
+            (!node->schema && (((struct lyd_node_opaq *)node)->hints & LYD_NODEHINT_LIST))) {
+        ly_print_(ctx->out, "%s%*s{%s", (is_open_array(ctx, node) && ctx->level_printed >= ctx->level) ?
+                (DO_FORMAT ? ",\n" : ",") : "", INDENT, (DO_FORMAT && has_content) ? "\n" : "");
+    } else {
         ly_print_(ctx->out, "%s{%s", (is_open_array(ctx, node) && ctx->level_printed >= ctx->level) ? "," : "",
                 (DO_FORMAT && has_content) ? "\n" : "");
-    } else {
-        ly_print_(ctx->out, "%s%*s{%s", (is_open_array(ctx, node) && ctx->level_printed >= ctx->level) ? (DO_FORMAT ? ",\n" : ",") : "",
-                INDENT, (DO_FORMAT && has_content) ? "\n" : "");
     }
     LEVEL_INC;
 
@@ -772,10 +773,14 @@
 
         if (node->hints & (LYD_NODEHINT_LIST | LYD_NODEHINT_LEAFLIST)) {
             LY_CHECK_RET(json_print_array_open(ctx, &node->node));
-            LEVEL_INC;
         }
+        if (node->hints & LYD_NODEHINT_LEAFLIST) {
+            ly_print_(ctx->out, "%*s", INDENT);
+        }
+    } else if (node->hints & LYD_NODEHINT_LEAFLIST) {
+        ly_print_(ctx->out, ",%s%*s", DO_FORMAT ? "\n" : "", INDENT);
     }
-    if (node->child || (node->hints & (LYD_NODEHINT_LIST | LYD_NODEHINT_LEAFLIST))) {
+    if (node->child || (node->hints & LYD_NODEHINT_LIST)) {
         LY_CHECK_RET(json_print_inner(ctx, &node->node));
         LEVEL_PRINTED;
     } else {
@@ -795,7 +800,6 @@
     }
     if (last && (node->hints & (LYD_NODEHINT_LIST | LYD_NODEHINT_LEAFLIST))) {
         json_print_array_close(ctx);
-        LEVEL_DEC;
         LEVEL_PRINTED;
     }