Initial import

LoxiGen is the work of several developers, not just myself.
diff --git a/c_gen/c_show_gen.py b/c_gen/c_show_gen.py
new file mode 100644
index 0000000..5dab038
--- /dev/null
+++ b/c_gen/c_show_gen.py
@@ -0,0 +1,268 @@
+# Copyright 2013, Big Switch Networks, Inc.
+#
+# LoxiGen is licensed under the Eclipse Public License, version 1.0 (EPL), with
+# the following special exception:
+#
+# LOXI Exception
+#
+# As a special exception to the terms of the EPL, you may distribute libraries
+# generated by LoxiGen (LoxiGen Libraries) under the terms of your choice, provided
+# that copyright and licensing notices generated by LoxiGen are not altered or removed
+# from the LoxiGen Libraries and the notice provided below is (i) included in
+# the LoxiGen Libraries, if distributed in source code form and (ii) included in any
+# documentation for the LoxiGen Libraries, if distributed in binary form.
+#
+# Notice: "Copyright 2013, Big Switch Networks, Inc. This library was generated by the LoxiGen Compiler."
+#
+# You may not use this file except in compliance with the EPL or LOXI Exception. You may obtain
+# a copy of the EPL at:
+#
+# http://www.eclipse.org/legal/epl-v10.html
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# EPL for the specific language governing permissions and limitations
+# under the EPL.
+
+"""
+@brief Show function generation
+
+Generates show function files.
+
+"""
+
+import sys
+import of_g
+import loxi_front_end.match as match
+import loxi_front_end.flags as flags
+from generic_utils import *
+import loxi_front_end.type_maps as type_maps
+import loxi_utils.loxi_utils as loxi_utils
+import loxi_front_end.identifiers as identifiers
+from c_test_gen import var_name_map
+
+def gen_obj_show_h(out, name):
+    loxi_utils.gen_c_copy_license(out)
+    out.write("""
+/**
+ *
+ * AUTOMATICALLY GENERATED FILE.  Edits will be lost on regen.
+ *
+ * Header file for object showing. 
+ */
+
+/**
+ * Show  object declarations
+ *
+ * Routines that emit a human-readable dump of each object.
+ *
+ */
+
+#if !defined(_LOCI_OBJ_SHOW_H_)
+#define _LOCI_OBJ_SHOW_H_
+
+#include <loci/loci.h>
+#include <stdio.h>
+
+/* g++ requires this to pick up PRI, etc.
+ * See  http://gcc.gnu.org/ml/gcc-help/2006-10/msg00223.html
+ */
+#if !defined(__STDC_FORMAT_MACROS)
+#define __STDC_FORMAT_MACROS
+#endif
+#include <inttypes.h>
+
+
+/**
+ * Show any OF object. 
+ */
+int of_object_show(loci_writer_f writer, void* cookie, of_object_t* obj); 
+
+
+
+
+
+
+""")
+
+    type_to_emitter = dict(
+
+        )
+    for version in of_g.of_version_range:
+        for cls in of_g.standard_class_order:
+            if not loxi_utils.class_in_version(cls, version):
+                continue
+            if cls in type_maps.inheritance_map:
+                continue
+            out.write("""\
+int %(cls)s_%(ver_name)s_show(loci_writer_f writer, void* cookie, %(cls)s_t *obj);
+""" % dict(cls=cls, ver_name=loxi_utils.version_to_name(version)))
+
+    out.write("""
+#endif /* _LOCI_OBJ_SHOW_H_ */
+""")
+
+def gen_obj_show_c(out, name):
+    loxi_utils.gen_c_copy_license(out)
+    out.write("""
+/**
+ *
+ * AUTOMATICALLY GENERATED FILE.  Edits will be lost on regen.
+ *
+ * Source file for object showing. 
+ * 
+ */
+
+#define DISABLE_WARN_UNUSED_RESULT
+#include <loci/loci.h>
+#include <loci/loci_show.h>
+#include <loci/loci_obj_show.h>
+
+static int
+unknown_show(loci_writer_f writer, void* cookie, of_object_t *obj)
+{
+    return writer(cookie, "Unable to print object of type %d, version %d\\n", 
+                         obj->object_id, obj->version);
+}    
+""")
+
+    for version in of_g.of_version_range:
+        ver_name = loxi_utils.version_to_name(version)
+        for cls in of_g.standard_class_order:
+            if not loxi_utils.class_in_version(cls, version):
+                continue
+            if cls in type_maps.inheritance_map:
+                continue
+            out.write("""
+int
+%(cls)s_%(ver_name)s_show(loci_writer_f writer, void* cookie, %(cls)s_t *obj)
+{
+    int out = 0;
+""" % dict(cls=cls, ver_name=ver_name))
+
+            members, member_types = loxi_utils.all_member_types_get(cls, version)
+            for m_type in member_types:
+                if loxi_utils.type_is_scalar(m_type) or m_type in \
+                        ["of_match_t", "of_octets_t"]:
+                    # Declare instance of these
+                    out.write("    %s %s;\n" % (m_type, var_name_map(m_type)))
+                else:
+                    out.write("""
+    %(m_type)s %(v_name)s;
+"""  % dict(m_type=m_type, v_name=var_name_map(m_type)))
+                    if loxi_utils.class_is_list(m_type):
+                        base_type = loxi_utils.list_to_entry_type(m_type)
+                        out.write("    %s elt;\n    int rv;\n" % base_type)
+            for member in members:
+                m_type = member["m_type"]
+                m_name = member["name"]
+                #emitter = "LOCI_SHOW_" + loxi_utils.type_to_short_name(m_type)
+                emitter = "LOCI_SHOW_" + loxi_utils.type_to_short_name(m_type) + "_" + m_name; 
+                if loxi_utils.skip_member_name(m_name):
+                    continue
+                if (loxi_utils.type_is_scalar(m_type) or
+                    m_type in ["of_match_t", "of_octets_t"]):
+                    out.write("""
+    %(cls)s_%(m_name)s_get(obj, &%(v_name)s);
+    out += writer(cookie, "%(m_name)s=");
+    out += %(emitter)s(writer, cookie, %(v_name)s);
+    out += writer(cookie, " "); 
+""" % dict(cls=cls, m_name=m_name, m_type=m_type,
+           v_name=var_name_map(m_type), emitter=emitter))
+                elif loxi_utils.class_is_list(m_type):
+                    sub_cls = m_type[:-2] # Trim _t
+                    elt_type = loxi_utils.list_to_entry_type(m_type)
+                    out.write("""
+    out += writer(cookie, "%(elt_type)s={ ");
+    %(cls)s_%(m_name)s_bind(obj, &%(v_name)s);
+    %(u_type)s_ITER(&%(v_name)s, &elt, rv) {
+        of_object_show(writer, cookie, (of_object_t *)&elt);
+    }
+    out += writer(cookie, "} "); 
+""" % dict(sub_cls=sub_cls, u_type=sub_cls.upper(), v_name=var_name_map(m_type),
+           elt_type=elt_type, cls=cls, m_name=m_name, m_type=m_type))
+                else:
+                    sub_cls = m_type[:-2] # Trim _t
+                    out.write("""
+    %(cls)s_%(m_name)s_bind(obj, &%(v_name)s);
+    out += %(sub_cls)s_%(ver_name)s_show(writer, cookie, &%(v_name)s);
+""" % dict(cls=cls, sub_cls=sub_cls, m_name=m_name, 
+           v_name=var_name_map(m_type), ver_name=ver_name))
+
+            out.write("""
+    return out;
+}
+""")
+    out.write("""
+/**
+ * Log a match entry
+ */
+int
+loci_show_match(loci_writer_f writer, void* cookie, of_match_t *match)
+{
+    int out = 0;
+""")
+
+    for key, entry in match.of_match_members.items():
+        m_type = entry["m_type"]
+        #emitter = "LOCI_SHOW_" + loxi_utils.type_to_short_name(m_type)
+        emitter = "LOCI_SHOW_" + loxi_utils.type_to_short_name(m_type) + "_" + key; 
+        out.write("""
+    if (OF_MATCH_MASK_%(ku)s_ACTIVE_TEST(match)) {
+        out += writer(cookie, "%(key)s active="); 
+        out += %(emitter)s(writer, cookie, match->fields.%(key)s);
+        out += writer(cookie, "/"); 
+        out += %(emitter)s(writer, cookie, match->masks.%(key)s);
+        out += writer(cookie, " ");
+    }
+""" % dict(key=key, ku=key.upper(), emitter=emitter, m_type=m_type))
+
+    out.write("""
+    return out;
+}
+""")
+
+    # Generate big table indexed by version and object
+    for version in of_g.of_version_range:
+        out.write("""
+static loci_obj_show_f show_funs_v%(version)s[OF_OBJECT_COUNT] = {
+""" % dict(version=version))
+        out.write("    unknown_show, /* of_object, not a valid specific type */\n")
+        for j, cls in enumerate(of_g.all_class_order):
+            comma = ""
+            if j < len(of_g.all_class_order) - 1: # Avoid ultimate comma
+                comma = ","
+
+            if (not loxi_utils.class_in_version(cls, version) or 
+                    cls in type_maps.inheritance_map):
+                out.write("    unknown_show%s\n" % comma);
+            else:
+                out.write("    %s_%s_show%s\n" % 
+                          (cls, loxi_utils.version_to_name(version), comma))
+        out.write("};\n\n")
+
+    out.write("""
+static loci_obj_show_f *show_funs[5] = {
+    NULL,
+    show_funs_v1,
+    show_funs_v2,
+    show_funs_v3,
+    show_funs_v4
+};
+
+int
+of_object_show(loci_writer_f writer, void* cookie, of_object_t *obj)
+{
+    if ((obj->object_id > 0) && (obj->object_id < OF_OBJECT_COUNT)) {
+        if (((obj)->version > 0) && ((obj)->version <= OF_VERSION_1_2)) {
+            /* @fixme VERSION */
+            return show_funs[obj->version][obj->object_id](writer, cookie, (of_object_t *)obj);
+        } else {
+            return writer(cookie, "Bad version %d\\n", obj->version);
+        }
+    }
+    return writer(cookie, "Bad object id %d\\n", obj->object_id);
+}
+""")
+