return Iterator(Class, lib.eolian_all_classes_get(self._obj))
@property
+ def all_namespaces(self):
+ # TODO find a better way to find namespaces (maybe inside eolian?)
+ nspaces = []
+ for cls in self.all_classes:
+ ns = Namespace(self, cls.namespace)
+ if not ns in nspaces:
+ nspaces.append(ns)
+ nspaces.sort()
+ return nspaces
+
+ def namespace_get_by_name(self, name):
+ return Namespace(self, name)
+
+ @property
def typedecl_all_enums(self):
return Iterator(Typedecl, lib.eolian_typedecl_all_enums_get(self._obj))
return bool(lib.eolian_all_eot_files_parse(self._obj))
+### Namespace Utility Class #################################################
+
+class Namespace(object):
+ def __init__(self, unit, namespace_name):
+ self._name = namespace_name
+ self._unit = unit
+
+ def __repr__(self):
+ return "<eolian.Namespace '{0._name}'>".format(self)
+
+ def __eq__(self, other):
+ return self.name == other.name
+
+ def __lt__(self, other):
+ return self.name < other.name
+
+ def __gt__(self, other):
+ return self.name > other.name
+
+ @property
+ def name(self):
+ return self._name
+
+ @property
+ def namespaces(self):
+ return self._name.split('.')
+
+ @property
+ def classes(self):
+ return [ c for c in self._unit.all_classes
+ if c.namespace == self._name ]
+
+ @property
+ def regulars(self):
+ return [ c for c in self._unit.all_classes
+ if c.type == Eolian_Class_Type.REGULAR and
+ c.namespace == self._name]
+
+ @property
+ def mixins(self):
+ return [ c for c in self._unit.all_classes
+ if c.type == Eolian_Class_Type.MIXIN and
+ c.namespace == self._name]
+
+ @property
+ def interfaces(self):
+ return [ c for c in self._unit.all_classes
+ if c.type == Eolian_Class_Type.INTERFACE and
+ c.namespace == self._name]
+
+ @property
+ def aliases(self):
+ return [ td for td in self._unit.typedecl_all_aliases
+ if td.namespace == self._name]
+
+ @property
+ def structs(self):
+ return [ td for td in self._unit.typedecl_all_structs
+ if td.namespace == self._name]
+
+ @property
+ def enums(self):
+ return [ td for td in self._unit.typedecl_all_enums
+ if td.namespace == self._name]
+
+
### Eolian Classes ##########################################################
class Class(EolianBaseObject):
("text", c_char_p),
("text_end", c_char_p)]
+
class Documentation(EolianBaseObject):
# def __repr__(self):
# return "<eolian.Documentation '{0.name}'>".format(self)
atexit.register(lambda: lib.eolian_shutdown())
-
### API coverage statistics #################################################
if __name__ == '__main__':
Args:
filename: Template file to load. (REQUIRED)
- data: User provided context for the template.
+ context: User provided context for the template (dict).
"""
- def __init__(self, filename, encoding='utf-8', data=None, escape=None,
+ def __init__(self, filename, encoding='utf-8', context=None, escape=None,
loader_class=pyratemp.LoaderFile,
parser_class=pyratemp.Parser,
renderer_class=pyratemp.Renderer,
# Build the global context for the template
global_ctx = {}
# user provided context (low pri)
- if data:
- global_ctx.update(data)
+ if context:
+ global_ctx.update(context)
# standard names (not overwritables)
global_ctx.update({
# Template info
ctx.update(kargs)
if cls:
ctx['cls'] = eolian_db.class_get_by_name(cls)
+ if ns:
+ ctx['namespace'] = eolian_db.namespace_get_by_name(ns)
if struct:
ctx['struct'] = eolian_db.typedecl_struct_get_by_name(struct)
if enum:
ctx['enum'] = eolian_db.typedecl_enum_get_by_name(enum)
if alias:
ctx['alias'] = eolian_db.typedecl_alias_get_by_name(alias)
- if ns:
- ctx['namespace'] = ns
- ctx['namespaces'] = ns.split('.')
- ctx['classes'] = [ c for c in eolian_db.all_classes
- if c.full_name.startswith(ns + '.') ]
- ctx['aliases'] = [ a for a in eolian_db.typedecl_all_aliases
- if a.full_name.startswith(ns + '.') ]
- ctx['structs'] = [ s for s in eolian_db.typedecl_all_structs
- if s.full_name.startswith(ns + '.') ]
- ctx['enums'] = [ e for e in eolian_db.typedecl_all_enums
- if e.full_name.startswith(ns + '.') ]
if verbose and filename:
print('generating "{}" from template "{}"'.format(
if __name__ == '__main__':
import argparse
- parser = argparse.ArgumentParser(description='Pyolian generator.')
+ parser = argparse.ArgumentParser(description='Pyolian template based generator.')
parser.add_argument('template',
help='The template file to use. (REQUIRED)')
parser.add_argument('--output', '-o', metavar='FILE', default=None,
self.assertNotEqual(enum1, 0)
self.assertNotEqual(cls1, enum1)
-
class TestEolianUnit(unittest.TestCase):
self.assertGreater(all_count, 400)
+class TestEolianNamespace(unittest.TestCase):
+ def test_all_namespace(self):
+ count = 0
+ for ns in state.all_namespaces:
+ self.assertIsInstance(ns, eolian.Namespace)
+ count += 1
+ self.assertGreater(count, 100)
+
+ def test_namespace_equality(self):
+ ns1 = eolian.Namespace(state, 'Efl.Io')
+ ns2 = eolian.Namespace(state, 'Efl.Net')
+ self.assertIsInstance(ns1, eolian.Namespace)
+ self.assertIsInstance(ns2, eolian.Namespace)
+ self.assertNotEqual(ns1, ns2)
+ self.assertEqual(ns1, eolian.Namespace(state, 'Efl.Io'))
+ self.assertEqual(ns2, eolian.Namespace(state, 'Efl.Net'))
+
+ def test_namespace_sorting(self):
+ nspaces = state.all_namespaces
+ nspaces.sort(reverse=True)
+ self.assertGreater(nspaces[0], nspaces[-1])
+ self.assertLess(nspaces[1], nspaces[0])
+
+ def test_namespace_by_name(self):
+ ns = eolian.Namespace(state, 'Efl.Net')
+ self.assertIsInstance(ns, eolian.Namespace)
+ self.assertEqual(ns.name, 'Efl.Net')
+ self.assertEqual(ns.namespaces, ['Efl', 'Net'])
+
+ ns = state.namespace_get_by_name('Efl')
+ self.assertIsInstance(ns, eolian.Namespace)
+ self.assertEqual(ns.name, 'Efl')
+
+ self.assertGreater(len(ns.classes), 30)
+ for cls in ns.classes:
+ self.assertIsInstance(cls, eolian.Class)
+ self.assertGreater(len(ns.regulars), 4)
+ for cls in ns.regulars:
+ self.assertIsInstance(cls, eolian.Class)
+ self.assertEqual(cls.type, eolian.Eolian_Class_Type.REGULAR)
+ self.assertGreater(len(ns.mixins), 0)
+ for cls in ns.mixins:
+ self.assertIsInstance(cls, eolian.Class)
+ self.assertEqual(cls.type, eolian.Eolian_Class_Type.MIXIN)
+ self.assertGreater(len(ns.interfaces), 15)
+ for cls in ns.interfaces:
+ self.assertIsInstance(cls, eolian.Class)
+ self.assertEqual(cls.type, eolian.Eolian_Class_Type.INTERFACE)
+
+ self.assertGreater(len(ns.enums), 1)
+ for td in ns.enums:
+ self.assertIsInstance(td, eolian.Typedecl)
+ self.assertEqual(td.type, eolian.Eolian_Typedecl_Type.ENUM)
+ self.assertGreater(len(ns.aliases), 0)
+ for td in ns.aliases:
+ self.assertIsInstance(td, eolian.Typedecl)
+ # TODO eolian_typedecl_all_aliases_get also return FUNCTION_POINTER
+ # is this correct? or an eolian bug ?
+ # self.assertEqual(td.type, eolian.Eolian_Typedecl_Type.ALIAS)
+ self.assertGreater(len(ns.structs), 2)
+ for td in ns.structs:
+ self.assertIsInstance(td, eolian.Typedecl)
+ self.assertEqual(td.type, eolian.Eolian_Typedecl_Type.STRUCT)
+
+
class TestEolianClass(unittest.TestCase):
def test_class(self):
cls = state.class_get_by_file('efl_loop_timer.eo')
================================================================================
-Namespace: ${namespace}$ ${namespaces}$
+Namespace: ${namespace.name}$ ${namespace.namespaces}$
================================================================================
-Classes:
-========
-<!--(for cls in classes)-->
- * ${cls.full_name}$ (${cls.type}$)
+Regular Classes:
+================
+<!--(for cls in namespace.regulars)-->
+ * ${cls.full_name}$ (${cls.type.name.lower()}$)
+<!--(else)-->
+ no classes available
+<!--(end)-->
+
+Interfaces:
+===========
+<!--(for cls in namespace.interfaces)-->
+ * ${cls.full_name}$ (${cls.type.name.lower()}$)
+<!--(else)-->
+ no classes available
+<!--(end)-->
+
+Mixins:
+=======
+<!--(for cls in namespace.mixins)-->
+ * ${cls.full_name}$ (${cls.type.name.lower()}$)
<!--(else)-->
no classes available
<!--(end)-->
Aliases:
========
-<!--(for typedecl in aliases)-->
+<!--(for typedecl in namespace.aliases)-->
* ${typedecl.full_name}$
<!--(else)-->
no alias available
Structs:
========
-<!--(for typedecl in structs)-->
+<!--(for typedecl in namespace.structs)-->
* ${typedecl.full_name}$
<!--(for field in typedecl.struct_fields)-->
- ${field}$
+ ${field.type.name}$ ${field.name}$
<!--(end)-->
<!--(else)-->
no structs available
Enums:
======
-<!--(for typedecl in enums)-->
+<!--(for typedecl in namespace.enums)-->
* ${typedecl.full_name}$
<!--(for field in typedecl.enum_fields)-->
- ${field}$
+ ${field.c_name}$ = ${field.value.serialize}$
<!--(end)-->
<!--(else)-->
no enums available