Merge into master from pull request #316:
pyloxi: reduce boilerplate code required for each module (https://github.com/floodlight/loxigen/pull/316)
diff --git a/lang_python.py b/lang_python.py
index 019b62d..18fca27 100644
--- a/lang_python.py
+++ b/lang_python.py
@@ -28,12 +28,6 @@
"""
Python backend for LOXI
-This language specific file defines a dictionary 'targets' that
-defines the generated files and the functions used to generate them.
-
-For each generated file there is a generate_* function in py_gen.codegen
-and a Tenjin template under py_gen/templates.
-
Target directory structure:
pyloxi:
loxi:
@@ -64,51 +58,9 @@
"""
import os
-from loxi_globals import OFVersions
-import loxi_globals
-import loxi_utils.loxi_utils as loxi_utils
-import py_gen
-import py_gen.util
import py_gen.codegen
-import template_utils
-versions = {
- 1: "of10",
- 2: "of11",
- 3: "of12",
- 4: "of13",
-}
-
-prefix = 'pyloxi/loxi'
-
-modules = {
- 1: ["action", "common", "const", "message", "util"],
- 2: ["action", "common", "const", "instruction", "message", "util"],
- 3: ["action", "common", "const", "instruction", "message", "oxm", "util"],
- 4: ["action", "action_id", "common", "const", "instruction", "instruction_id", "message", "meter_band", "oxm", "bsn_tlv", "util"],
-}
-
-def make_gen(name, version):
- fn = getattr(py_gen.codegen, "generate_" + name)
- return lambda out, name: fn(out, name, version)
-
-def static(template_name):
- return lambda out, name: py_gen.util.render_template(out, template_name)
-
-targets = {
- prefix+'/__init__.py': static('toplevel_init.py'),
- prefix+'/pp.py': static('pp.py'),
- prefix+'/generic_util.py': static('generic_util.py'),
-}
-
-for version, subdir in versions.items():
- targets['%s/%s/__init__.py' % (prefix, subdir)] = make_gen('init', version)
- for module in modules[version]:
- filename = '%s/%s/%s.py' % (prefix, subdir, module)
- targets[filename] = make_gen(module, OFVersions.from_wire(version))
+PREFIX = 'pyloxi/loxi'
def generate(install_dir):
- py_gen.codegen.init()
- for (name, fn) in targets.items():
- with template_utils.open_output(install_dir, name) as outfile:
- fn(outfile, os.path.basename(name))
+ py_gen.codegen.codegen(os.path.join(install_dir, PREFIX))
diff --git a/py_gen/codegen.py b/py_gen/codegen.py
index 9c32e7f..3b0988e 100644
--- a/py_gen/codegen.py
+++ b/py_gen/codegen.py
@@ -26,16 +26,13 @@
# under the EPL.
from collections import defaultdict
+import os
import loxi_globals
-import struct
import template_utils
import loxi_utils.loxi_utils as utils
import util
-import oftype
from loxi_ir import *
-modules_by_version = {}
-
# Map from inheritance root to module name
roots = {
'of_header': 'message',
@@ -69,63 +66,36 @@
modules[module_name].append(ofclass)
return modules
-def generate_init(out, name, version):
- util.render_template(out, 'init.py', version=version)
+def codegen(install_dir):
+ def render(name, template_name=None, **ctx):
+ if template_name is None:
+ template_name = os.path.basename(name)
+ with template_utils.open_output(install_dir, name) as out:
+ util.render_template(out, template_name, **ctx)
-def generate_action(out, name, version):
- util.render_template(out, 'module.py',
- ofclasses=modules_by_version[version]['action'],
- version=version)
+ render('__init__.py', template_name='toplevel_init.py')
+ render('pp.py')
+ render('generic_util.py')
-def generate_action_id(out, name, version):
- util.render_template(out, 'module.py',
- ofclasses=modules_by_version[version]['action_id'],
- version=version)
+ for version in loxi_globals.OFVersions.all_supported:
+ subdir = 'of' + version.version.replace('.', '')
+ modules = build_ofclasses(version)
-def generate_oxm(out, name, version):
- util.render_template(out, 'module.py',
- ofclasses=modules_by_version[version]['oxm'],
- version=version)
+ render(os.path.join(subdir, '__init__.py'), template_name='init.py',
+ version=version, modules=modules.keys())
-def generate_common(out, name, version):
- util.render_template(out, 'module.py',
- ofclasses=modules_by_version[version]['common'],
- version=version,
- extra_template='_common_extra.py')
+ render(os.path.join(subdir, 'util.py'), version=version)
-def generate_const(out, name, version):
- util.render_template(out, 'const.py', version=version,
- enums=loxi_globals.ir[version].enums)
+ render(os.path.join(subdir, 'const.py'), version=version,
+ enums=loxi_globals.ir[version].enums)
-def generate_instruction(out, name, version):
- util.render_template(out, 'module.py',
- ofclasses=modules_by_version[version]['instruction'],
- version=version)
+ args_by_module = {
+ 'common': { 'extra_template' : '_common_extra.py' },
+ 'message': { 'extra_template' : '_message_extra.py' },
+ }
-def generate_instruction_id(out, name, version):
- util.render_template(out, 'module.py',
- ofclasses=modules_by_version[version]['instruction_id'],
- version=version)
-
-def generate_message(out, name, version):
- util.render_template(out, 'module.py',
- ofclasses=modules_by_version[version]['message'],
- version=version,
- extra_template='_message_extra.py')
-
-def generate_meter_band(out, name, version):
- util.render_template(out, 'module.py',
- ofclasses=modules_by_version[version]['meter_band'],
- version=version)
-
-def generate_util(out, name, version):
- util.render_template(out, 'util.py', version=version)
-
-def generate_bsn_tlv(out, name, version):
- util.render_template(out, 'module.py',
- ofclasses=modules_by_version[version]['bsn_tlv'],
- version=version)
-
-def init():
- for version in loxi_globals.OFVersions.target_versions:
- modules_by_version[version] = build_ofclasses(version)
+ for name, ofclasses in modules.items():
+ args = args_by_module.get(name, {})
+ render(os.path.join(subdir, name + '.py'), template_name='module.py',
+ version=version, ofclasses=ofclasses, modules=modules.keys(),
+ **args)
diff --git a/py_gen/templates/init.py b/py_gen/templates/init.py
index 3b73baa..aa968b6 100644
--- a/py_gen/templates/init.py
+++ b/py_gen/templates/init.py
@@ -29,17 +29,10 @@
:: include('_autogen.py')
-import action, common, const, message
-:: if version >= 2:
-import instruction
-:: #endif
-:: if version >= 3:
-import oxm
-:: #endif
-:: if version >= 4:
-import meter_band
-import bsn_tlv
-:: #endif
+import const
+:: for module in modules:
+import ${module}
+:: #endfor
from const import *
from common import *
from loxi import ProtocolError
diff --git a/py_gen/templates/module.py b/py_gen/templates/module.py
index dfe23e8..331044d 100644
--- a/py_gen/templates/module.py
+++ b/py_gen/templates/module.py
@@ -34,20 +34,9 @@
import struct
import loxi
import const
-import common
-import action
-:: if version >= OFVersions.VERSION_1_1:
-import instruction
-:: #endif
-:: if version >= OFVersions.VERSION_1_2:
-import oxm
-:: #endif
-:: if version >= OFVersions.VERSION_1_3:
-import action_id
-import instruction_id
-import meter_band
-import bsn_tlv
-:: #endif
+:: for module in modules:
+import ${module}
+:: #endfor
import util
import loxi.generic_util