Skip to content

Commit

Permalink
Pulled module paths up (i.e. module/enum and module/struct instead of…
Browse files Browse the repository at this point in the history
… struct/module) and applied them to all tags. Codegen adds __init__.py file to this path where the module attributes are set.
  • Loading branch information
Candoran2 committed Sep 18, 2021
1 parent 2aec99c commit 774d7aa
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 11 deletions.
30 changes: 20 additions & 10 deletions codegen.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
from codegen.Enum import Enum
from codegen.Bitfield import Bitfield
from codegen.Versions import Versions
from codegen.Module import Module
from codegen.naming_conventions import clean_comment_str

logging.basicConfig(level=logging.DEBUG)
Expand Down Expand Up @@ -47,14 +48,21 @@ def generate_module_paths(self, root):
"""preprocessing - generate module paths for imports relative to the output dir"""
for child in root:
# only check stuff that has a name - ignore version tags
if child.tag not in ("version", "module", "token"):
class_name = convention.name_class(child.attrib["name"])
out_segments = ["formats", self.format_name,]
if child.attrib.get("module"):
out_segments.append(child.attrib["module"])
out_segments.extend([child.tag, class_name, ])
if child.tag not in ("version", "token"):
base_segments = os.path.join("formats", self.format_name)
if child.tag == "module":
# for modules, set the path to base/module_name
class_name = convention.name_module(child.attrib["name"])
class_segments = [class_name]
else:
# for classes, set the path to module_path/tag/class_name or
# base/tag/class_name if it's not part of a module
class_name = convention.name_class(child.attrib["name"])
if child.attrib.get("module"):
base_segments = self.path_dict[convention.name_module(child.attrib["module"])]
class_segments = [child.tag, class_name, ]
# store the final relative module path for this class
self.path_dict[class_name] = os.path.join(*out_segments)
self.path_dict[class_name] = os.path.join(base_segments, *class_segments)
self.tag_dict[class_name.lower()] = child.tag

self.path_dict["Array"] = "array"
Expand All @@ -76,7 +84,7 @@ def load_xml(self, xml_file):

for child in root:
self.replace_tokens(child)
if child.tag != 'version':
if child.tag not in ('version', 'module'):
self.apply_conventions(child)
try:
if child.tag in self.struct_types:
Expand All @@ -87,8 +95,8 @@ def load_xml(self, xml_file):
# self.write_basic(child)
elif child.tag == "enum":
Enum(self, child)
# elif child.tag == "module":
# self.read_module(child)
elif child.tag == "module":
Module(self, child)
elif child.tag == "version":
versions.read(child)
elif child.tag == "token":
Expand Down Expand Up @@ -122,6 +130,8 @@ def apply_conventions(self, struct):
self.apply_convention(field, convention.name_class, ("type",))
self.apply_convention(field, convention.name_class, ("onlyT",))
self.apply_convention(field, convention.name_class, ("excludeT",))
for default in field:
self.apply_convention(field, convention.name_class, ("onlyT",))

# filter comment str
struct.text = clean_comment_str(struct.text, indent="\t", class_comment='"""')
Expand Down
24 changes: 24 additions & 0 deletions codegen/Module.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import os
from codegen.naming_conventions import clean_comment_str, name_module

class Module:

def __init__(self, parser, element):
self.parser = parser
self.element = element
self.read(element)
self.write(parser.path_dict[name_module(element.attrib["name"])])

def read(self, element):
self.comment_str = clean_comment_str(element.text, indent="", class_comment='"""')[2:]
self.priority = int(element.attrib.get("priority",""))
self.depends = [name_module(module) for module in element.attrib.get("depends","").split(" ")]
self.custom = bool(eval(element.attrib.get("custom","true").replace("true","True").replace("false","False"),{}))

def write(self, rel_path):
file = open(os.path.join(os.getcwd(), "generated", rel_path, "__init__.py"), "w", encoding=self.parser.encoding)
file.write(self.comment_str)
file.write(f'\n\n__priority__ = {repr(self.priority)}')
file.write(f'\n__depends__ = {repr(self.depends)}')
file.write(f'\n__custom__ = {repr(self.custom)}')
file.write(f'\n')
13 changes: 12 additions & 1 deletion codegen/naming_conventions.py
Original file line number Diff line number Diff line change
Expand Up @@ -123,4 +123,15 @@ def clean_comment_str(comment_str="", indent="", class_comment=""):
lines = [f"\n{indent}{class_comment}",] + [f"\n{indent}{line.strip()}" for line in comment_str.strip().split("\n")] + [f"\n{indent}{class_comment}",]
else:
lines = [f"\n{indent}# {line.strip()}" for line in comment_str.strip().split("\n")]
return "\n" + "".join(lines)
return "\n" + "".join(lines)


def name_module(name):
"""Converts a module name into a name suitable for a python module
:param name: the module name
:type name: str
:return: Reformatted module name
>>> name_module('BSHavok')
'bshavok'
"""
return name.lower()

0 comments on commit 774d7aa

Please sign in to comment.