mirror of https://github.com/ecmwf/eccodes.git
Identify and remove (or comment out as appropriate) invalid types
This commit is contained in:
parent
58f88b4b0e
commit
64b24dee6c
|
@ -12,8 +12,11 @@ class Arg(code_interface.CodeInterface):
|
|||
def __init__(self, decl_spec, name="", is_func_arg=False) -> None:
|
||||
if isinstance(decl_spec, DeclSpec):
|
||||
self._decl_spec = DeclSpec.from_instance(decl_spec)
|
||||
else:
|
||||
elif isinstance(decl_spec, str):
|
||||
self._decl_spec = DeclSpec.from_decl_specifier_seq(decl_spec)
|
||||
else:
|
||||
assert False, f"Unexpected decl_spec=[{decl_spec}]"
|
||||
|
||||
self._name = name
|
||||
self._is_func_arg = is_func_arg # Support for processing function sig args differently to other args
|
||||
|
||||
|
|
|
@ -16,9 +16,34 @@ class DeclSpec(code_interface.CodeInterface):
|
|||
self._type = type
|
||||
self._pointer = pointer
|
||||
|
||||
# ---------- Support for NoneDeclSpec: Begin ----------
|
||||
|
||||
# NoneDeclSpec is used when a C DeclSpec doesn't have a C++ equivalent (i.e. we don't want to convert it!)
|
||||
class _NoneDeclSpec:
|
||||
def __repr__(self):
|
||||
return "<NoneDeclSpec>"
|
||||
|
||||
def __eq__(self, other):
|
||||
# This version is required for testing DeclSpec.NONE = <VAR>
|
||||
# As the DeclSpec.__eq__ version won't be called when self=DeclSpec.NONE !!!
|
||||
return isinstance(other, DeclSpec._NoneDeclSpec)
|
||||
|
||||
def __ne__(self, other):
|
||||
return not self.__eq__(other)
|
||||
|
||||
NONE = _NoneDeclSpec() # The singleton instance to represent "None"
|
||||
|
||||
# ---------- Support for NoneDeclSpec: End ----------
|
||||
|
||||
# Create a DeclSpec from a string representing the sequence, e.g. "const char*"
|
||||
# Pass None (or empty string) to return DeclSpec.NONE
|
||||
@classmethod
|
||||
def from_decl_specifier_seq(cls, decl_specifier_seq):
|
||||
assert decl_specifier_seq, f"Unexpected decl_specifier_seq=[{decl_specifier_seq}]"
|
||||
if not decl_specifier_seq:
|
||||
return DeclSpec.NONE
|
||||
|
||||
assert isinstance(decl_specifier_seq, str), f"Expected str, got [{decl_specifier_seq}]"
|
||||
|
||||
decl_specifier_seq = decl_specifier_seq.strip()
|
||||
storage_class = ""
|
||||
const_qualifier = ""
|
||||
|
@ -97,15 +122,19 @@ class DeclSpec(code_interface.CodeInterface):
|
|||
def is_array_type(self):
|
||||
return self.pointer == "[]"
|
||||
|
||||
# Support for DeclSpec as a dict key
|
||||
# ---------- Support for DeclSpec as a dict key: Begin ----------
|
||||
def __hash__(self):
|
||||
return hash((self._storage_class, self._const_qualifier, self.type, self._pointer))
|
||||
|
||||
# Support for DeclSpec as a dict key
|
||||
def __eq__(self, other):
|
||||
if isinstance(other, DeclSpec):
|
||||
return self.storage_class == other.storage_class and self.const_qualifier == other.const_qualifier and self.pointer == other.pointer and self.type == other.type
|
||||
return False
|
||||
if self is DeclSpec.NONE or other is DeclSpec.NONE:
|
||||
return self is other
|
||||
return self.storage_class == other.storage_class and self.const_qualifier == other.const_qualifier and self.pointer == other.pointer and self.type == other.type
|
||||
|
||||
def __ne__(self, other):
|
||||
return not self.__eq__(other)
|
||||
# ---------- Support for DeclSpec as a dict key: End ----------
|
||||
|
||||
# Return the full decl-specifier-seq as a (parsed) string (i.e. consistent spacing etc, not just what was passed in!)
|
||||
def as_lines(self):
|
||||
|
|
|
@ -13,7 +13,8 @@ class VariableDeclaration(code_interface.CodeInterface):
|
|||
self._variable = variable
|
||||
self._value = value
|
||||
|
||||
assert isinstance(self._variable, arg.Arg), f"Variable must be an Arg class"
|
||||
assert self._variable != arg.Arg.NONE, f"Variable can't be NoneArg!"
|
||||
assert isinstance(self._variable, arg.Arg), f"Variable must be an Arg class, not=[{variable}]"
|
||||
assert isinstance(self._value, code_interface.CodeInterface), f"Value must be a CodeInterface class (or a string)"
|
||||
|
||||
@property
|
||||
|
|
|
@ -28,10 +28,13 @@ class ArgConverter(code_interface_converter.CodeInterfaceConverter):
|
|||
conversion_data.add_type_mapping(carg.decl_spec, cpp_decl_spec)
|
||||
debug.line("create_cpp_code_object", f"Arg conversion type mapping: carg.decl_spec=[{debug.as_debug_string(carg.decl_spec)}] cpp_decl_spec=[{debug.as_debug_string(cpp_decl_spec)}]")
|
||||
|
||||
cpp_name = standard_transforms.transform_variable_name(carg.name)
|
||||
cpp_is_func_arg = carg.is_func_arg
|
||||
if cpp_decl_spec == declaration_specifier.DeclSpec.NONE:
|
||||
cpp_arg = arg.Arg.NONE
|
||||
else:
|
||||
cpp_name = standard_transforms.transform_variable_name(carg.name)
|
||||
cpp_is_func_arg = carg.is_func_arg
|
||||
|
||||
cpp_arg = arg.Arg(cpp_decl_spec, cpp_name, cpp_is_func_arg)
|
||||
cpp_arg = arg.Arg(cpp_decl_spec, cpp_name, cpp_is_func_arg)
|
||||
|
||||
conversion_data.add_arg_mapping(carg, cpp_arg)
|
||||
debug.line("create_cpp_code_object", f"Arg conversion arg mapping: [{debug.as_debug_string(carg)}] -> [{debug.as_debug_string(cpp_arg)}]")
|
||||
|
|
|
@ -102,15 +102,9 @@ CodeInterfaceConverterClasses = {
|
|||
virtual_member_function.VirtualMemberFunction : virtual_member_function_converter.VirtualMemberFunctionConverter,
|
||||
}
|
||||
|
||||
def get_debug_string(code_obj):
|
||||
if code_obj:
|
||||
return f"{code_obj if type(code_obj) is str else code_obj.as_string()}"
|
||||
else:
|
||||
return "None"
|
||||
|
||||
# Convert a code_object into a C++ code_object
|
||||
def convert_ccode_object(ccode_object, conversion_data):
|
||||
debug.line("convert_ccode_object", f"[IN] [{type(ccode_object).__name__}] {get_debug_string(ccode_object)}")
|
||||
debug.line("convert_ccode_object", f"[IN] [{type(ccode_object).__name__}] {debug.as_debug_string(ccode_object)}")
|
||||
|
||||
if ccode_object is None:
|
||||
cpp_obj = None
|
||||
|
@ -121,6 +115,14 @@ def convert_ccode_object(ccode_object, conversion_data):
|
|||
converter = converter_class(ccode_object)
|
||||
cpp_obj = converter.to_cpp_code_object(conversion_data)
|
||||
|
||||
debug.line("convert_ccode_object", f"[OUT][{type(cpp_obj).__name__}] {get_debug_string(cpp_obj)}")
|
||||
debug.line("convert_ccode_object", f"[OUT][{type(cpp_obj).__name__}] {debug.as_debug_string(cpp_obj)}")
|
||||
|
||||
return cpp_obj
|
||||
|
||||
def as_commented_out_code(ccode_object, prefix=""):
|
||||
comment_string = "// "
|
||||
if prefix:
|
||||
comment_string += f"[{prefix}] "
|
||||
comment_string += debug.as_debug_string(ccode_object)
|
||||
|
||||
return literal.Literal(comment_string)
|
|
@ -43,10 +43,10 @@ class ConversionData:
|
|||
|
||||
def add_type_mapping(self, cdecl_spec, cppdecl_spec):
|
||||
if cdecl_spec in self.active_map.type_mappings:
|
||||
assert self.active_map.type_mappings[cdecl_spec] == cppdecl_spec, f"Updating an existing arg: [{cdecl_spec.as_string()}] -> [{cppdecl_spec.as_string()}] Previous arg=[{self.active_map.type_mappings[cdecl_spec]}]"
|
||||
assert self.active_map.type_mappings[cdecl_spec] == cppdecl_spec, f"Updating an existing arg: [{debug.as_debug_string(cdecl_spec)}] -> [{debug.as_debug_string(cppdecl_spec)}] Previous arg=[{self.active_map.type_mappings[cdecl_spec]}]"
|
||||
else:
|
||||
self.active_map.type_mappings[cdecl_spec] = cppdecl_spec
|
||||
debug.line("add_type_mapping", f"Adding decl_spec: [{cdecl_spec.as_string()}] -> [{cppdecl_spec.as_string()}]")
|
||||
debug.line("add_type_mapping", f"Adding decl_spec: [{debug.as_debug_string(cdecl_spec)}] -> [{debug.as_debug_string(cppdecl_spec)}]")
|
||||
|
||||
def add_arg_mapping(self, carg, cpparg):
|
||||
if not carg.name:
|
||||
|
@ -54,17 +54,17 @@ class ConversionData:
|
|||
return
|
||||
|
||||
if carg in self.active_map.arg_mappings:
|
||||
assert self.active_map.arg_mappings[carg] == cpparg, f"Updating an existing arg: [{carg.as_string()}] -> [{cpparg.as_string()}] Previous arg=[{self.active_map.arg_mappings[carg]}]"
|
||||
assert self.active_map.arg_mappings[carg] == cpparg, f"Updating an existing arg: [{debug.as_debug_string(carg)}] -> [{debug.as_debug_string(cpparg)}] Previous arg=[{self.active_map.arg_mappings[carg]}]"
|
||||
else:
|
||||
self.active_map.arg_mappings[carg] = cpparg
|
||||
debug.line("add_arg_mapping", f"Adding arg: [{carg.as_string()}] -> [{cpparg.as_string()}]")
|
||||
debug.line("add_arg_mapping", f"Adding arg: [{debug.as_debug_string(carg)}] -> [{debug.as_debug_string(cpparg)}]")
|
||||
|
||||
def add_function_arg_mapping(self, carg, cpparg):
|
||||
if carg in self.active_map.function_arg_mappings:
|
||||
assert self.active_map.function_arg_mappings[carg] == cpparg, f"Updating an existing function arg: [{carg.as_string()}] -> [{cpparg.as_string()}] Previous function arg=[{self.active_map.function_arg_mappings[carg]}]"
|
||||
assert self.active_map.function_arg_mappings[carg] == cpparg, f"Updating an existing function arg: [{debug.as_debug_string(carg)}] -> [{debug.as_debug_string(cpparg)}] Previous function arg=[{self.active_map.function_arg_mappings[carg]}]"
|
||||
else:
|
||||
self.active_map.function_arg_mappings[carg] = cpparg
|
||||
debug.line("add_function_arg_mappings", f"Adding function arg: [{carg.as_string()}] -> [{cpparg.as_string()}]")
|
||||
debug.line("add_function_arg_mappings", f"Adding function arg: [{debug.as_debug_string(carg)}] -> [{debug.as_debug_string(cpparg)}]")
|
||||
|
||||
def add_funcsig_mapping(self, mapping):
|
||||
assert isinstance(mapping, funcsig_mapping.FuncSigMapping), f"Expected FuncSigMapping, got type=[{type(mapping).__name__}]"
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
|
||||
import utils.debug as debug
|
||||
import code_object.value_declaration_reference as value_declaration_reference
|
||||
import code_object.arg as arg
|
||||
import code_object_converter.code_interface_converter as code_interface_converter
|
||||
import code_object_converter.conversion_funcs as conversion_funcs
|
||||
|
||||
|
@ -19,7 +20,7 @@ class ValueDeclarationReferenceConverter(code_interface_converter.CodeInterfaceC
|
|||
|
||||
# 2. Check if it is an arg
|
||||
cpparg = conversion_data.cpparg_for_carg_name(cdecl_ref_expr_value)
|
||||
if cpparg:
|
||||
if cpparg and cpparg != arg.Arg.NONE:
|
||||
return value_declaration_reference.ValueDeclarationReference(cpparg.name)
|
||||
|
||||
# 3. Perform a default conversion
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
|
||||
import utils.debug as debug
|
||||
import code_object.variable_declaration as variable_declaration
|
||||
import code_object.arg as arg
|
||||
import code_object_converter.code_interface_converter as code_interface_converter
|
||||
import code_object_converter.conversion_funcs as conversion_funcs
|
||||
|
||||
|
@ -10,10 +11,16 @@ class VariableDeclarationConverter(code_interface_converter.CodeInterfaceConvert
|
|||
assert isinstance(ccode_object, variable_declaration.VariableDeclaration), f"Expected VariableDeclaration, got type=[{type(ccode_object)}]"
|
||||
|
||||
def create_cpp_code_object(self, conversion_data):
|
||||
|
||||
cpp_variable = conversion_funcs.convert_ccode_object(self._ccode_object.variable, conversion_data)
|
||||
|
||||
if cpp_variable == arg.Arg.NONE:
|
||||
return conversion_funcs.as_commented_out_code(self._ccode_object, f"Removed invalid variable")
|
||||
|
||||
cpp_value = conversion_funcs.convert_ccode_object(self._ccode_object.value, conversion_data)
|
||||
|
||||
cpp_variable_declaration = variable_declaration.VariableDeclaration(cpp_variable, cpp_value)
|
||||
|
||||
return cpp_variable_declaration
|
||||
|
||||
|
||||
|
|
|
@ -9,6 +9,7 @@ from grib_accessor.supporting.member_functions import grib_accessor_member_funcs
|
|||
import grib_accessor.supporting.member_functions as member_functions
|
||||
import grib_accessor.supporting.virtual_member_functions as virtual_member_functions
|
||||
import grib_accessor.supporting.includes as includes
|
||||
import grib_accessor.supporting.grib_types as grib_types
|
||||
|
||||
prefix = "grib_accessor_class_"
|
||||
rename = {
|
||||
|
@ -52,6 +53,8 @@ class GribAccessorCCodeConverter(default_ccode_converter.DefaultCCodeConverter):
|
|||
for mapping in grib_accessor_virtual_member_funcsig_mapping:
|
||||
self._conversion_data.add_virtual_member_funcsig_mapping(mapping)
|
||||
|
||||
grib_types.add_grib_types_to_conversion_data(self._conversion_data)
|
||||
|
||||
def set_function_specific_conversion_data(self, function_name):
|
||||
pass
|
||||
|
||||
|
|
|
@ -0,0 +1,37 @@
|
|||
|
||||
from code_object.arg import Arg
|
||||
from code_object.declaration_specifier import DeclSpec
|
||||
import code_object_converter.supporting.conversion_data as conversion_data
|
||||
|
||||
common_grib_type_transforms = {
|
||||
"grib_accessor*" : "AccessorPtr",
|
||||
"grib_handle*" : None,
|
||||
"grib_context*" : None,
|
||||
}
|
||||
|
||||
grib_array_type_transforms = {
|
||||
"grib_darray*" : "std::vector<double>",
|
||||
"grib_iarray*" : "std::vector<long>",
|
||||
"grib_sarray*" : "std::string",
|
||||
"grib_vdarray*" : "std::vector<std::vector<double>>",
|
||||
"grib_viarray*" : "std::vector<std::vector<long>>",
|
||||
"grib_vsarray*" : "std::vector<std::string>",
|
||||
}
|
||||
|
||||
grib_array_function_transforms = {
|
||||
"grib_darray" : "std::vector<double>",
|
||||
"grib_iarray" : "std::vector<long>",
|
||||
"grib_sarray" : "std::string",
|
||||
"grib_vdarray" : "std::vector<std::vector<double>>",
|
||||
"grib_viarray" : "std::vector<std::vector<long>>",
|
||||
"grib_vsarray" : "std::vector<std::string>",
|
||||
}
|
||||
|
||||
def add_grib_types_to_conversion_data(conversion_data):
|
||||
for type_transforms in [common_grib_type_transforms, grib_array_type_transforms]:
|
||||
for key, value in type_transforms.items():
|
||||
cdecl_spec = DeclSpec.from_decl_specifier_seq(key)
|
||||
cppdecl_spec = DeclSpec.from_decl_specifier_seq(value)
|
||||
conversion_data.add_type_mapping(cdecl_spec, cppdecl_spec)
|
||||
|
||||
# TODO - Add Function Transforms...
|
|
@ -1,5 +1,6 @@
|
|||
|
||||
from datetime import datetime
|
||||
from code_object.code_interface import CodeInterface
|
||||
|
||||
func_pad = 40
|
||||
debug_enabled = True
|
||||
|
@ -57,13 +58,15 @@ def line(func, text):
|
|||
else:
|
||||
print(f"{func:{func_pad}}:{elapsed_time_str} {text}")
|
||||
|
||||
# Safe way to print a CodeInterface object even if it is None - useful for
|
||||
# debug output
|
||||
def as_debug_string(code_interface_inst):
|
||||
if code_interface_inst is not None:
|
||||
if isinstance(code_interface_inst, str):
|
||||
return code_interface_inst
|
||||
# Safe way to print a value even if it is None - useful for
|
||||
# CodeInstance classes etc
|
||||
def as_debug_string(value):
|
||||
if value is not None:
|
||||
if isinstance(value, str):
|
||||
return value
|
||||
elif isinstance(value, CodeInterface):
|
||||
return value.as_string()
|
||||
else:
|
||||
return code_interface_inst.as_string()
|
||||
return f"[{value}]"
|
||||
else:
|
||||
return "None"
|
||||
|
|
Loading…
Reference in New Issue