blob: 14709abf063f2a07b3a46b7175ef4eaf7766eb52 [file] [log] [blame]
Rich Lanea06d0c32013-03-25 08:52:03 -07001# Copyright 2013, Big Switch Networks, Inc.
2#
3# LoxiGen is licensed under the Eclipse Public License, version 1.0 (EPL), with
4# the following special exception:
5#
6# LOXI Exception
7#
8# As a special exception to the terms of the EPL, you may distribute libraries
9# generated by LoxiGen (LoxiGen Libraries) under the terms of your choice, provided
10# that copyright and licensing notices generated by LoxiGen are not altered or removed
11# from the LoxiGen Libraries and the notice provided below is (i) included in
12# the LoxiGen Libraries, if distributed in source code form and (ii) included in any
13# documentation for the LoxiGen Libraries, if distributed in binary form.
14#
15# Notice: "Copyright 2013, Big Switch Networks, Inc. This library was generated by the LoxiGen Compiler."
16#
17# You may not use this file except in compliance with the EPL or LOXI Exception. You may obtain
18# a copy of the EPL at:
19#
20# http://www.eclipse.org/legal/epl-v10.html
21#
22# Unless required by applicable law or agreed to in writing, software
23# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
24# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
25# EPL for the specific language governing permissions and limitations
26# under the EPL.
27
28"""
29@brief Show function generation
30
31Generates show function files.
32
33"""
34
35import sys
36import of_g
37import loxi_front_end.match as match
38import loxi_front_end.flags as flags
39from generic_utils import *
40import loxi_front_end.type_maps as type_maps
41import loxi_utils.loxi_utils as loxi_utils
42import loxi_front_end.identifiers as identifiers
43from c_test_gen import var_name_map
44
45def gen_obj_show_h(out, name):
46 loxi_utils.gen_c_copy_license(out)
47 out.write("""
48/**
49 *
50 * AUTOMATICALLY GENERATED FILE. Edits will be lost on regen.
51 *
52 * Header file for object showing.
53 */
54
55/**
56 * Show object declarations
57 *
58 * Routines that emit a human-readable dump of each object.
59 *
60 */
61
62#if !defined(_LOCI_OBJ_SHOW_H_)
63#define _LOCI_OBJ_SHOW_H_
64
65#include <loci/loci.h>
66#include <stdio.h>
67
68/* g++ requires this to pick up PRI, etc.
69 * See http://gcc.gnu.org/ml/gcc-help/2006-10/msg00223.html
70 */
71#if !defined(__STDC_FORMAT_MACROS)
72#define __STDC_FORMAT_MACROS
73#endif
74#include <inttypes.h>
75
76
77/**
78 * Show any OF object.
79 */
80int of_object_show(loci_writer_f writer, void* cookie, of_object_t* obj);
81
82
83
84
85
86
87""")
88
89 type_to_emitter = dict(
90
91 )
92 for version in of_g.of_version_range:
93 for cls in of_g.standard_class_order:
94 if not loxi_utils.class_in_version(cls, version):
95 continue
96 if cls in type_maps.inheritance_map:
97 continue
98 out.write("""\
99int %(cls)s_%(ver_name)s_show(loci_writer_f writer, void* cookie, %(cls)s_t *obj);
100""" % dict(cls=cls, ver_name=loxi_utils.version_to_name(version)))
101
102 out.write("""
103#endif /* _LOCI_OBJ_SHOW_H_ */
104""")
105
106def gen_obj_show_c(out, name):
107 loxi_utils.gen_c_copy_license(out)
108 out.write("""
109/**
110 *
111 * AUTOMATICALLY GENERATED FILE. Edits will be lost on regen.
112 *
113 * Source file for object showing.
114 *
115 */
116
117#define DISABLE_WARN_UNUSED_RESULT
118#include <loci/loci.h>
119#include <loci/loci_show.h>
120#include <loci/loci_obj_show.h>
121
122static int
123unknown_show(loci_writer_f writer, void* cookie, of_object_t *obj)
124{
125 return writer(cookie, "Unable to print object of type %d, version %d\\n",
126 obj->object_id, obj->version);
127}
128""")
129
130 for version in of_g.of_version_range:
131 ver_name = loxi_utils.version_to_name(version)
132 for cls in of_g.standard_class_order:
133 if not loxi_utils.class_in_version(cls, version):
134 continue
135 if cls in type_maps.inheritance_map:
136 continue
137 out.write("""
138int
139%(cls)s_%(ver_name)s_show(loci_writer_f writer, void* cookie, %(cls)s_t *obj)
140{
141 int out = 0;
142""" % dict(cls=cls, ver_name=ver_name))
143
144 members, member_types = loxi_utils.all_member_types_get(cls, version)
145 for m_type in member_types:
146 if loxi_utils.type_is_scalar(m_type) or m_type in \
147 ["of_match_t", "of_octets_t"]:
148 # Declare instance of these
149 out.write(" %s %s;\n" % (m_type, var_name_map(m_type)))
150 else:
151 out.write("""
152 %(m_type)s %(v_name)s;
153""" % dict(m_type=m_type, v_name=var_name_map(m_type)))
154 if loxi_utils.class_is_list(m_type):
155 base_type = loxi_utils.list_to_entry_type(m_type)
156 out.write(" %s elt;\n int rv;\n" % base_type)
157 for member in members:
158 m_type = member["m_type"]
159 m_name = member["name"]
160 #emitter = "LOCI_SHOW_" + loxi_utils.type_to_short_name(m_type)
161 emitter = "LOCI_SHOW_" + loxi_utils.type_to_short_name(m_type) + "_" + m_name;
162 if loxi_utils.skip_member_name(m_name):
163 continue
164 if (loxi_utils.type_is_scalar(m_type) or
165 m_type in ["of_match_t", "of_octets_t"]):
166 out.write("""
167 %(cls)s_%(m_name)s_get(obj, &%(v_name)s);
168 out += writer(cookie, "%(m_name)s=");
169 out += %(emitter)s(writer, cookie, %(v_name)s);
170 out += writer(cookie, " ");
171""" % dict(cls=cls, m_name=m_name, m_type=m_type,
172 v_name=var_name_map(m_type), emitter=emitter))
173 elif loxi_utils.class_is_list(m_type):
174 sub_cls = m_type[:-2] # Trim _t
175 elt_type = loxi_utils.list_to_entry_type(m_type)
176 out.write("""
177 out += writer(cookie, "%(elt_type)s={ ");
178 %(cls)s_%(m_name)s_bind(obj, &%(v_name)s);
179 %(u_type)s_ITER(&%(v_name)s, &elt, rv) {
180 of_object_show(writer, cookie, (of_object_t *)&elt);
181 }
182 out += writer(cookie, "} ");
183""" % dict(sub_cls=sub_cls, u_type=sub_cls.upper(), v_name=var_name_map(m_type),
184 elt_type=elt_type, cls=cls, m_name=m_name, m_type=m_type))
185 else:
186 sub_cls = m_type[:-2] # Trim _t
187 out.write("""
188 %(cls)s_%(m_name)s_bind(obj, &%(v_name)s);
189 out += %(sub_cls)s_%(ver_name)s_show(writer, cookie, &%(v_name)s);
190""" % dict(cls=cls, sub_cls=sub_cls, m_name=m_name,
191 v_name=var_name_map(m_type), ver_name=ver_name))
192
193 out.write("""
194 return out;
195}
196""")
197 out.write("""
198/**
199 * Log a match entry
200 */
201int
202loci_show_match(loci_writer_f writer, void* cookie, of_match_t *match)
203{
204 int out = 0;
205""")
206
207 for key, entry in match.of_match_members.items():
208 m_type = entry["m_type"]
209 #emitter = "LOCI_SHOW_" + loxi_utils.type_to_short_name(m_type)
210 emitter = "LOCI_SHOW_" + loxi_utils.type_to_short_name(m_type) + "_" + key;
211 out.write("""
212 if (OF_MATCH_MASK_%(ku)s_ACTIVE_TEST(match)) {
213 out += writer(cookie, "%(key)s active=");
214 out += %(emitter)s(writer, cookie, match->fields.%(key)s);
215 out += writer(cookie, "/");
216 out += %(emitter)s(writer, cookie, match->masks.%(key)s);
217 out += writer(cookie, " ");
218 }
219""" % dict(key=key, ku=key.upper(), emitter=emitter, m_type=m_type))
220
221 out.write("""
222 return out;
223}
224""")
225
226 # Generate big table indexed by version and object
227 for version in of_g.of_version_range:
228 out.write("""
Rich Laneb157b0f2013-03-27 13:55:28 -0700229static const loci_obj_show_f show_funs_v%(version)s[OF_OBJECT_COUNT] = {
Rich Lanea06d0c32013-03-25 08:52:03 -0700230""" % dict(version=version))
231 out.write(" unknown_show, /* of_object, not a valid specific type */\n")
232 for j, cls in enumerate(of_g.all_class_order):
233 comma = ""
234 if j < len(of_g.all_class_order) - 1: # Avoid ultimate comma
235 comma = ","
236
237 if (not loxi_utils.class_in_version(cls, version) or
238 cls in type_maps.inheritance_map):
239 out.write(" unknown_show%s\n" % comma);
240 else:
241 out.write(" %s_%s_show%s\n" %
242 (cls, loxi_utils.version_to_name(version), comma))
243 out.write("};\n\n")
244
245 out.write("""
Rich Laneb157b0f2013-03-27 13:55:28 -0700246static const loci_obj_show_f *const show_funs[5] = {
Rich Lanea06d0c32013-03-25 08:52:03 -0700247 NULL,
248 show_funs_v1,
249 show_funs_v2,
250 show_funs_v3,
251 show_funs_v4
252};
253
254int
255of_object_show(loci_writer_f writer, void* cookie, of_object_t *obj)
256{
257 if ((obj->object_id > 0) && (obj->object_id < OF_OBJECT_COUNT)) {
258 if (((obj)->version > 0) && ((obj)->version <= OF_VERSION_1_2)) {
259 /* @fixme VERSION */
260 return show_funs[obj->version][obj->object_id](writer, cookie, (of_object_t *)obj);
261 } else {
262 return writer(cookie, "Bad version %d\\n", obj->version);
263 }
264 }
265 return writer(cookie, "Bad object id %d\\n", obj->object_id);
266}
267""")
268