class EscdfFortranModule(object): def __init__(self, group, yaml_doc, template=None): # Init self.group = group self.specs = EscdfSpecs(self.group, yaml_doc) if template: self.template = EscdfTemplate(template) else: self.template = EscdfTemplate(f03_mod_default) # Build Fortran interfaces f03_interfaces = [] for elem in self.specs.get_elements(): spec = self.specs.get_spec(elem) for action in ["read", "write"]: spec["action"] = action f03_interfaces.append("%s" % EscdfFortranInterface(spec)) # Substitute patterns self.patterns = {} self.patterns["group"] = self.group self.patterns["interfaces"] = "\n".join(f03_interfaces) self.f03_module = self.template.substitute(self.patterns) def __str__(self): return self.f03_module
def test_substitute_default(self): tpl_text = "This is a @%template%@ test\n @%test_block%@" tpl = EscdfTemplate(tpl_text) pat = {"template": "TEMPLATE", "test_block": "BLOCK"} txt = tpl.substitute(pat) assert txt == "This is a TEMPLATE test\n BLOCK"
def test_substitute_custom(self): tpl_text = "This is a ##template@ test\n ##test_block@" tpl = EscdfTemplate(tpl_text, start_tag="##", end_tag="@") pat = {"template": "TEMPLATE", "test_block": "BLOCK"} txt = tpl.substitute(pat) assert txt == "This is a TEMPLATE test\n BLOCK"
class EscdfFortranInterface(object): def __init__(self, specs, template=None): """Generate a Fortran interface for a variable from a dictionary""" # Init self.specs = specs if ( template ): self.template = EscdfTemplate(template) else: self.template = EscdfTemplate(f03_interface_default) # Hard-coded specs -> Fortran type conversion (for now) self.f03_type = { "bool":"logical", "char":"character(len=*)", "double":"double precision", "float":"real", "int":"integer", "long_int":"integer", "short_int":"integer", "unsigned_long":"integer", "unsigned_int":"integer", "unsigned_short":"integer"} # Hard-coded argument intents (for now) self.f03_intent = {"read":"inout", "write":"in"} # Check consistency of specs required_fields = ["action", "group", "name", "object", "type"] errs = [item for item in required_fields if item not in specs] if ( len(errs) > 0 ): raise KeyError("missing required fields: %s" % errs) # Generate Fortran source code f03_specs = { "name":specs["name"], "group":specs["group"], "action":specs["action"]} params_list = [self.specs["group"], self.specs["name"]] f03_specs["params_list"] = ", ".join(params_list) f03_specs["params_desc"] = "type(c_ptr), intent(%s) :: %s\n" % \ (self.f03_intent[specs["action"]], specs["group"]) if ( specs["object"] == "scalar" ): param_intent = "intent(%s)" % self.f03_intent[specs["action"]] else: param_intent = "pointer" f03_specs["params_desc"] += "%s, %s :: %s" % \ (self.f03_type[specs["type"]], param_intent, specs["name"]) f03_text = self.template.substitute(f03_specs) self.f03_text = self.template.wrap_fortran(f03_text) def __str__(self): return self.f03_text
class EscdfFortranWrapper(object): def __init__(self, specs, template=None): # Init self.specs = specs if ( template ): self.template = EscdfTemplate(template) else: self.template = EscdfTemplate(f03_wrapper_default) # Hard-coded specs -> C type conversion (for now) self.wrap_type = { "bool":"bool", "char":"char", "double":"double", "float":"float", "int":"int", "long_int":"long", "short_int":"short", "unsigned_long":"unsigned long", "unsigned_int":"unsigned int", "unsigned_short":"unsigned short"} # Check consistency of specs required_fields = ["action", "group", "name", "object", "type"] errs = [item for item in required_fields if item not in specs] if ( len(errs) > 0 ): raise KeyError("missing required fields: %s" % errs) # Generate wrapper code wrap_specs = { "name":specs["name"], "group":specs["group"], "action":specs["action"]} params = "escdf_%s_t *%s, %s *%s" % \ (specs["group"], specs["group"], self.wrap_type[specs["type"]], specs["name"]) wrap_specs["params"] = params glue_ptr = "" if ( specs["object"] == "scalar" ): glue_ptr = "*" if ( specs["action"] == "read" ): if ( specs["spec_type"] == "metadata" ): glue_code = "*%s = %s.%s;" % \ (specs["name"], specs["group"], specs["name"]) else: glue_code = "%s%s = escdf_%s_%s_%s();" % \ (glue_ptr, specs["name"], specs["group"], specs["action"], specs["name"]) elif ( specs["action"] == "write" ): glue_code = "escdf_%s_%s_%s(%s%s);" % \ (specs["group"], specs["action"], specs["name"], glue_ptr, specs["name"]) else: raise NotImplementedError("unknown action '%s'" % specs["action"]) wrap_specs["glue_code"] = glue_code self.wrapper_text = self.template.substitute(wrap_specs) def __str__(self): return self.wrapper_text