]> granicus.if.org Git - jq/commitdiff
JV_KIND_INVALID values to represent failed lookups, etc + various tests.
authorStephen Dolan <mu@netsoc.tcd.ie>
Mon, 3 Sep 2012 15:16:14 +0000 (16:16 +0100)
committerStephen Dolan <mu@netsoc.tcd.ie>
Mon, 3 Sep 2012 15:16:14 +0000 (16:16 +0100)
c/execute.c
c/jv.c
c/jv.h
c/main.c
c/testdata

index 0c31e072a56232763808934a6bcc42f376a52c0f..d98872b306efbd3e0be4c93962f310d31e04f444 100644 (file)
@@ -321,8 +321,7 @@ jv jq_next() {
     do_backtrack:
     case BACKTRACK: {
       if (!stack_restore()) {
-        // FIXME: invalid jv value
-        return jv_null();
+        return jv_invalid();
       }
       pc = *frame_current_retaddr(&frame_stk);
       frame_pop(&frame_stk);
@@ -443,7 +442,7 @@ void run_program(struct bytecode* bc) {
   fgets(buf, sizeof(buf), stdin);
   jq_init(bc, jv_parse(buf));
   jv result;
-  while (jv_get_kind(result = jq_next()) != JV_KIND_NULL) {
+  while (jv_is_valid(result = jq_next())) {
     jv_dump(result);
     printf("\n");
   }
diff --git a/c/jv.c b/c/jv.c
index 198bfeda1f8f983f0e4a527ccc863783b0a9dead..4484dc9fdce42850b92c49957970a467c66596ad 100644 (file)
--- a/c/jv.c
+++ b/c/jv.c
@@ -37,10 +37,15 @@ jv_kind jv_get_kind(jv x) {
   return x.kind;
 }
 
+static const jv JV_INVALID = {JV_KIND_INVALID, {0}};
 static const jv JV_NULL = {JV_KIND_NULL, {0}};
 static const jv JV_FALSE = {JV_KIND_FALSE, {0}};
 static const jv JV_TRUE = {JV_KIND_TRUE, {0}};
 
+jv jv_invalid() {
+  return JV_INVALID;
+}
+
 jv jv_true() {
   return JV_TRUE;
 }
@@ -671,7 +676,13 @@ jv jv_object() {
 jv jv_object_get(jv object, jv key) {
   assert(jv_get_kind(object) == JV_KIND_OBJECT);
   assert(jv_get_kind(key) == JV_KIND_STRING);
-  jv val = jv_copy(*jvp_object_read(&object.val.complex, jvp_string_ptr(&key.val.complex)));
+  jv* slot = jvp_object_read(&object.val.complex, jvp_string_ptr(&key.val.complex));
+  jv val;
+  if (slot) {
+    val = jv_copy(*slot);
+  } else {
+    val = jv_invalid();
+  }
   jv_free(object);
   jv_free(key);
   return val;
diff --git a/c/jv.h b/c/jv.h
index 754f0316555dcce97feafb24be3ebf1c43451fc0..b251329cb57133ab042b3265cf5ec975898fde4b 100644 (file)
--- a/c/jv.h
+++ b/c/jv.h
@@ -8,6 +8,7 @@
 
 
 typedef enum {
+  JV_KIND_INVALID,
   JV_KIND_NULL,
   JV_KIND_FALSE,
   JV_KIND_TRUE,
@@ -40,12 +41,14 @@ typedef struct {
  */
 
 jv_kind jv_get_kind(jv);
+static int jv_is_valid(jv x) { return jv_get_kind(x) != JV_KIND_INVALID; }
 
 jv jv_copy(jv);
 void jv_free(jv);
 
 int jv_equal(jv, jv);
 
+jv jv_invalid();
 jv jv_null();
 jv jv_true();
 jv jv_false();
@@ -95,6 +98,9 @@ static jv jv_lookup(jv t, jv k) {
   jv v;
   if (jv_get_kind(t) == JV_KIND_OBJECT && jv_get_kind(k) == JV_KIND_STRING) {
     v = jv_object_get(t, k);
+    if (!jv_is_valid(v)) {
+      v = jv_null();
+    }
   } else if (jv_get_kind(t) == JV_KIND_ARRAY && jv_get_kind(k) == JV_KIND_NUMBER) {
     // FIXME: don't do lookup for noninteger index
     v = jv_array_get(t, (int)jv_number_value(k));
index 5cdc7d62661f6a7cb862ae017cfc64ffb9e9975a..5879d031a07f7ed7d0d7a5f3e5d6340d84aae2f9 100644 (file)
--- a/c/main.c
+++ b/c/main.c
@@ -46,7 +46,7 @@ void run_tests() {
       if (skipline(buf)) break;
       jv expected = jv_parse(buf);
       jv actual = jq_next();
-      if (!1) {
+      if (!jv_is_valid(actual)) {
         printf("Insufficient results\n");
         pass = 0;
         break;
@@ -59,14 +59,14 @@ void run_tests() {
         pass = 0;
       }
     }
-    if (pass && 0) { /*
+    if (pass) {
       jv extra = jq_next();
-      if (extra) {
+      if (jv_is_valid(extra)) {
         printf("Superfluous result: ");
-        json_dumpf(extra, stdout, JSON_ENCODE_ANY);
+        jv_dump(extra);
         printf("\n");
         pass = 0;
-        }*/
+      }
     }
     jq_teardown();
     bytecode_free(bc);
index 2cdaaa5f8c21015ba7e0f84123cf203634cc2a10..c6388d67980a3aa2130a3dbc7dc093813d4aff9b 100644 (file)
@@ -59,11 +59,9 @@ null
 {"foo": {"bar": 42}, "bar": "badvalue"}
 42
 
-
-# FIXME strings
-# .["foo"].bar
-# {"foo": {"bar": 42}, "bar": "badvalue"}
-# 42
+.["foo"].bar
+{"foo": {"bar": 42}, "bar": "badvalue"}
+42
 
 
 #
@@ -172,6 +170,12 @@ true
 [1]
 true
 
+null,1,null
+"hello"
+null
+1
+null
+
 [1,2,3]
 [5,6]
 [1,2,3]
@@ -193,3 +197,18 @@ def id(x):x; 2000 as $x | def f(x):1 as $x | id([$x, x, x]); def g(x): 100 as $x
 [[20,10][1,0] as $x | def f: (100,200) as $y | def g: [$x + $y, .]; . + $x | g; f[0] | [f][0][1] | f]
 "woo, testing!"
 [[110.0, 130.0], [210.0, 130.0], [110.0, 230.0], [210.0, 230.0], [120.0, 160.0], [220.0, 160.0], [120.0, 260.0], [220.0, 260.0]]
+
+#
+# Assignment
+#
+.message = "goodbye"
+{"message": "hello"}
+{"message": "goodbye"}
+
+.foo = .bar
+{"bar":42}
+{"foo":42, "bar":42}
+
+def inc(x): x |= .+1; inc(.[].a)
+[{"a":1,"b":2},{"a":2,"b":4},{"a":7,"b":8}]
+[{"a":2,"b":2},{"a":3,"b":4},{"a":8,"b":8}]