Merge remote-tracking branch 'origin/master' into reference-tlv

Conflicts:
	openflow_input/bsn_tlv
diff --git a/.build/push-artifacts.sh b/.build/push-artifacts.sh
index 8c7b60b..ec81d62 100755
--- a/.build/push-artifacts.sh
+++ b/.build/push-artifacts.sh
@@ -9,9 +9,11 @@
     exit 1
 fi
 
+ARTIFACT_REPO_BRANCH=${2-master}
+
 ARTIFACT_REPO=$(mktemp -d --tmpdir "push-artifacts-repo.XXXXXXX")
 
-git clone ${ARTIFACT_REPO_URL} ${ARTIFACT_REPO}
+git clone ${ARTIFACT_REPO_URL} ${ARTIFACT_REPO} -b ${ARTIFACT_REPO_BRANCH}
 find ${ARTIFACT_REPO} -mindepth 1 -maxdepth 1 -type d \! -name '.*' -print0 | xargs -0 rm -r
 make LOXI_OUTPUT_DIR=${ARTIFACT_REPO} clean all
 
@@ -55,7 +57,7 @@
 
     git tag -a -f "loxi/${loxi_head}" -m "Tag Loxigen Revision ${loxi_head}"
     git push --tags
-    git push
+    git push origin HEAD
 )
 
 rm -rf ${ARTIFACT_REPO}
diff --git a/c_gen/c_test_gen.py b/c_gen/c_test_gen.py
index 109ab9b..5342a42 100644
--- a/c_gen/c_test_gen.py
+++ b/c_gen/c_test_gen.py
@@ -393,24 +393,6 @@
     %(cls)s_t *obj, int value);
 """ % dict(cls=cls, v_name=loxi_utils.version_to_name(version)))
 
-    out.write("""
-/*
- * Declarations for list population and check primitives
- */
-""")
-
-    for version in of_g.of_version_range:
-        for cls in of_g.ordered_list_objects:
-            if version in of_g.unified[cls]:
-               out.write("""
-extern int
-    list_setup_%(cls)s_%(v_name)s(
-    %(cls)s_t *list, int value);
-extern int
-    list_check_%(cls)s_%(v_name)s(
-    %(cls)s_t *list, int value);
-""" % dict(cls=cls, v_name=loxi_utils.version_to_name(version)))
-
     out.write("\n#endif /* _TEST_COMMON_H_ */\n")
 
 def gen_common_test(out, name):
@@ -485,7 +467,6 @@
 
     gen_fill_string(out)
     gen_scalar_set_check_funs(out)
-    gen_list_set_check_funs(out)
     gen_unified_accessor_funs(out)
 
     gen_ident_tests(out)
@@ -757,115 +738,6 @@
     TEST_OK(%(cls)s_next(list, &elt));
 """ % dict(cls=cls))
 
-def setup_list_fn(out, version, cls):
-    """
-    Generate a helper function that populates a list with two
-    of each type of subclass it supports
-    """
-    out.write("""
-/**
- * Set up a list of type %(cls)s with two of each type of subclass
- */
-int
-list_setup_%(cls)s_%(v_name)s(
-    %(cls)s_t *list, int value)
-{
-""" % dict(cls=cls, v_name=loxi_utils.version_to_name(version)))
-    base_type = loxi_utils.list_to_entry_type(cls)
-    out.write("""
-    of_object_t elt;
-    int cur_len = 0;
-    (void) elt;
-    (void) cur_len;
-""" % dict(cls=cls, base_type=base_type))
-
-    sub_classes =  type_maps.sub_class_map(base_type, version)
-    sub_classes = [(instance, subcls) for (instance, subcls) in sub_classes if not type_maps.class_is_virtual(subcls)]
-    v_name = loxi_utils.version_to_name(version)
-
-    if not type_maps.class_is_virtual(base_type):
-        out.write("    /* No subclasses for %s */\n"% base_type)
-        out.write("    %s_t *elt_p;\n" % base_type)
-        out.write("\n    elt_p = &elt;\n")
-    else:
-        out.write("    /* Declare pointers for each subclass */\n")
-        for instance, subcls in sub_classes:
-            out.write("    %s_t *%s;\n" % (subcls, instance))
-        out.write("\n    /* Instantiate pointers for each subclass */\n")
-        for instance, subcls in sub_classes:
-            out.write("    %s = &elt;\n" % (instance))
-
-    if not type_maps.class_is_virtual(base_type): # No inheritance case
-        setup_instance(out, cls, base_type, "elt_p", v_name, version)
-    else:
-        for instance, subcls in sub_classes:
-            setup_instance(out, cls, subcls, instance, v_name, version)
-    out.write("""
-
-    return value;
-}
-""")
-
-def check_list_fn(out, version, cls):
-    """
-    Generate a helper function that checks a list populated by above fn
-    """
-    out.write("""
-/**
- * Check a list of type %(cls)s generated by
- * list_setup_%(cls)s_%(v_name)s
- */
-int
-list_check_%(cls)s_%(v_name)s(
-    %(cls)s_t *list, int value)
-{
-""" % dict(cls=cls, v_name=loxi_utils.version_to_name(version)))
-    base_type = loxi_utils.list_to_entry_type(cls)
-    out.write("""
-    of_object_t elt;
-    (void) elt;
-""" % dict(cls=cls, base_type=base_type))
-
-    sub_classes =  type_maps.sub_class_map(base_type, version)
-    sub_classes = [(instance, subcls) for (instance, subcls) in sub_classes if not type_maps.class_is_virtual(subcls)]
-    v_name = loxi_utils.version_to_name(version)
-
-    if not type_maps.class_is_virtual(base_type):
-        out.write("    /* No subclasses for %s */\n"% base_type)
-        out.write("    %s_t *elt_p;\n" % base_type)
-        out.write("\n    elt_p = &elt;\n")
-    else:
-        out.write("    /* Declare pointers for each subclass */\n")
-        for instance, subcls in sub_classes:
-            out.write("    %s_t *%s;\n" % (subcls, instance))
-        out.write("\n    /* Instantiate pointers for each subclass */\n")
-        for instance, subcls in sub_classes:
-            out.write("    %s = &elt;\n" % (instance))
-
-    if not type_maps.class_is_virtual(base_type) or sub_classes:
-        out.write("    TEST_OK(%(cls)s_first(list, &elt));\n" % dict(cls=cls))
-
-    if not type_maps.class_is_virtual(base_type): # No inheritance case
-        check_instance(out, cls, base_type, "elt_p", v_name, version, True)
-    else:
-        count = 0
-        for instance, subcls in sub_classes:
-            count += 1
-            check_instance(out, cls, subcls, instance, v_name,
-                           version, count==len(sub_classes))
-
-    out.write("""
-    return value;
-}
-""" % dict(base_type=base_type))
-
-def gen_list_set_check_funs(out):
-    for version in of_g.of_version_range:
-        for cls in of_g.ordered_list_objects:
-            if version in of_g.unified[cls]:
-                setup_list_fn(out, version, cls)
-                check_list_fn(out, version, cls)
-
 # Maybe: Get a map from list class to parent, mem_name of container
 
 def list_test(out, version, cls):
@@ -888,7 +760,7 @@
     TEST_ASSERT(list->parent == NULL);
     TEST_ASSERT(list->object_id == %(enum_cls)s);
 
-    value = list_setup_%(cls)s_%(v_name)s(list, value);
+    value = %(cls)s_%(v_name)s_populate(list, value);
     TEST_ASSERT(value != 0);
 """ % dict(cls=cls, base_type=base_type, v_name=loxi_utils.version_to_name(version),
            enum_cls=loxi_utils.enum_name(cls)))
@@ -896,7 +768,7 @@
     out.write("""
     /* Now check values */
     value = 1;
-    value = list_check_%(cls)s_%(v_name)s(list, value);
+    value = %(cls)s_%(v_name)s_check(list, value);
     TEST_ASSERT(value != 0);
 """ % dict(cls=cls, v_name=loxi_utils.version_to_name(version)))
 
@@ -1184,8 +1056,15 @@
     out.write("""
     of_object_t elt;
     int cur_len = 0;
+    static int recursion;
     (void) elt;
     (void) cur_len;
+
+    if (recursion > 0) {
+        return value;
+    }
+
+    recursion++;
 """ % dict(cls=cls, base_type=base_type))
 
     sub_classes =  type_maps.sub_class_map(base_type, version)
@@ -1210,6 +1089,7 @@
         for instance, subcls in sub_classes:
             setup_instance(out, cls, subcls, instance, v_name, version)
     out.write("""
+    recursion--;
     return value;
 }
 """)
@@ -1231,6 +1111,13 @@
     of_object_t elt;
     int count = 0;
     int rv;
+    static int recursion;
+
+    if (recursion > 0) {
+        return value;
+    }
+
+    recursion++;
 """ % dict(cls=cls, base_type=base_type))
 
 
@@ -1299,6 +1186,7 @@
         of_object_delete((of_object_t *)dup);
     }
 
+    recursion--;
     return value;
 }
 """ % dict(cls=cls, u_cls=cls.upper(), entry_count=entry_count))
diff --git a/openflow_input/bsn_tlv b/openflow_input/bsn_tlv
index 21325ae..59fa53a 100644
--- a/openflow_input/bsn_tlv
+++ b/openflow_input/bsn_tlv
@@ -395,6 +395,14 @@
     uint32_t value; /* Milliseconds */
 };
 
+/* A reference to an entry in another gentable */
+struct of_bsn_tlv_reference : of_bsn_tlv {
+    uint16_t type == 59;
+    uint16_t length;
+    uint16_t table_id;
+    list(of_bsn_tlv_t) key;
+};
+
 struct of_bsn_tlv_ipv4_netmask : of_bsn_tlv {
     uint16_t type == 60;
     uint16_t length;