More bugfixing

This commit is contained in:
kevstone 2023-11-13 19:40:54 +00:00
parent f480c82035
commit a5052bcf3f
51 changed files with 328 additions and 239 deletions

View File

@ -24,7 +24,7 @@ grib_accessor_class_change_scanning_direction.cc
grib_accessor_class_check_internal_version.cc
grib_accessor_class_closest_date.cc
grib_accessor_class_codeflag.cc
grib_accessor_class_codetable.cc
#grib_accessor_class_codetable.cc
grib_accessor_class_codetable_title.cc
grib_accessor_class_codetable_units.cc
grib_accessor_class_concept.cc

View File

@ -6,5 +6,5 @@ class BitDataAccessorSpecific(AccessorSpecific):
super().__init__()
self._custom_arg_transforms = {
arg.Arg("unsigned char*","mdata") : arg.Arg("DataPointer","mdata"),
arg.Arg("unsigned char*","mdata") : arg.Arg("AccessorDataPointer","mdata"),
}

View File

@ -6,7 +6,7 @@ class BitsDataAccessorSpecific(AccessorSpecific):
super().__init__()
self._custom_arg_transforms = {
arg.Arg("unsigned char*","p") : arg.Arg("DataPointer","p"),
arg.Arg("unsigned char*","p") : arg.Arg("AccessorDataPointer","p"),
arg.Arg("int","type") : arg.Arg("GribType","type"),
}

View File

@ -6,6 +6,6 @@ class BytesDataAccessorSpecific(AccessorSpecific):
super().__init__()
self._custom_arg_transforms = {
arg.Arg("unsigned char*","p") : arg.Arg("DataPointer","p"),
arg.Arg("unsigned char*","p") : arg.Arg("AccessorDataPointer","p"),
}

View File

@ -0,0 +1,29 @@
from accessor_specific.default import AccessorSpecific
from converter_collection import Converter
import static_func_funcsig_conv
from funcsig import FuncSig
from arg_indexes import ArgIndexes
from arg import Arg
import arg
from funcsig_mapping import FuncSigMapping
class CodetableDataFuncSigConverter(static_func_funcsig_conv.StaticFunctionFuncSigConverter):
func_conversions = [
FuncSigMapping(FuncSig("int", "grib_inline_strcmp", [Arg("const char*", "a"), Arg("const char*", "b")]),
FuncSig(None, None, [None, None])),
FuncSigMapping(FuncSig("int", "str_eq", [Arg("const char*", "a"), Arg("const char*", "b")]),
FuncSig(None, None, [None, None])),
]
def __init__(self, cfuncsig):
super().__init__(cfuncsig)
self._conversions.extend(self.func_conversions)
class CodetableDataAccessorSpecific(AccessorSpecific):
def __init__(self) -> None:
super().__init__()
def update_converters(self, converters):
converters[Converter.STATIC_FUNC_FUNCSIG] = CodetableDataFuncSigConverter
return converters

View File

@ -6,6 +6,6 @@ class CountMissingDataAccessorSpecific(AccessorSpecific):
super().__init__()
self._custom_arg_transforms = {
arg.Arg("unsigned char*","p") : arg.Arg("DataPointer","p"),
arg.Arg("unsigned char*","p") : arg.Arg("AccessorDataPointer","p"),
}

View File

@ -6,6 +6,6 @@ class DataG1secondOrderConstantWidthPackingDataAccessorSpecific(AccessorSpecific
super().__init__()
self._custom_arg_transforms = {
arg.Arg("unsigned char*","buf") : arg.Arg("DataPointer","buf"),
arg.Arg("unsigned char*","buf") : arg.Arg("AccessorDataPointer","buf"),
}

View File

@ -25,7 +25,7 @@ class DataG1secondOrderGeneralPackingDataAccessorSpecific(AccessorSpecific):
super().__init__()
self._custom_arg_transforms = {
arg.Arg("unsigned char*","buf") : arg.Arg("DataPointer","buf"),
arg.Arg("unsigned char*","buf") : arg.Arg("AccessorDataPointer","buf"),
}
def update_converters(self, converters):

View File

@ -6,6 +6,6 @@ class DataRawPackingDataAccessorSpecific(AccessorSpecific):
super().__init__()
self._custom_arg_transforms = {
arg.Arg("unsigned char*","buf") : arg.Arg("DataPointer","buf"),
arg.Arg("unsigned char*","buf") : arg.Arg("AccessorDataPointer","buf"),
}

View File

@ -6,6 +6,6 @@ class DataRunLengthPackingDataAccessorSpecific(AccessorSpecific):
super().__init__()
self._custom_arg_transforms = {
arg.Arg("unsigned char*","buf") : arg.Arg("DataPointer","buf"),
arg.Arg("unsigned char*","buf") : arg.Arg("AccessorDataPointer","buf"),
}

View File

@ -6,6 +6,6 @@ class DataShPackedDataAccessorSpecific(AccessorSpecific):
super().__init__()
self._custom_arg_transforms = {
arg.Arg("unsigned char*","buf") : arg.Arg("DataPointer","buf"),
arg.Arg("unsigned char*","buf") : arg.Arg("AccessorDataPointer","buf"),
}

View File

@ -6,6 +6,6 @@ class DataShUnpackedDataAccessorSpecific(AccessorSpecific):
super().__init__()
self._custom_arg_transforms = {
arg.Arg("unsigned char*","buf") : arg.Arg("DataPointer","buf"),
arg.Arg("unsigned char*","buf") : arg.Arg("AccessorDataPointer","buf"),
}

View File

@ -25,7 +25,7 @@ class DataSimplePackingDataAccessorSpecific(AccessorSpecific):
super().__init__()
self._custom_arg_transforms = {
arg.Arg("unsigned char*","buf") : arg.Arg("DataPointer","buf"),
arg.Arg("unsigned char*","buf") : arg.Arg("AccessorDataPointer","buf"),
}
def update_converters(self, converters):

View File

@ -6,6 +6,6 @@ class G1HalfByteCodeflagDataAccessorSpecific(AccessorSpecific):
super().__init__()
self._custom_arg_transforms = {
arg.Arg("unsigned char*","dat") : arg.Arg("DataPointer","dat"),
arg.Arg("unsigned char*","dat") : arg.Arg("AccessorDataPointer","dat"),
}

View File

@ -6,6 +6,6 @@ class G1BitmapDataAccessorSpecific(AccessorSpecific):
super().__init__()
self._custom_arg_transforms = {
arg.Arg("unsigned char*","buf") : arg.Arg("DataPointer","buf"),
arg.Arg("unsigned char*","buf") : arg.Arg("AccessorDataPointer","buf"),
}

View File

@ -6,6 +6,6 @@ class Md5DataAccessorSpecific(AccessorSpecific):
super().__init__()
self._custom_arg_transforms = {
arg.Arg("unsigned char*","mess") : arg.Arg("DataPointer","mess"),
arg.Arg("unsigned char*","mess") : arg.Arg("AccessorDataPointer","mess"),
}

View File

@ -6,6 +6,6 @@ class MessageCopyDataAccessorSpecific(AccessorSpecific):
super().__init__()
self._custom_arg_transforms = {
arg.Arg("unsigned char*","v") : arg.Arg("DataPointer","v"),
arg.Arg("unsigned char*","v") : arg.Arg("AccessorDataPointer","v"),
}

View File

@ -6,6 +6,6 @@ class Uint64DataAccessorSpecific(AccessorSpecific):
super().__init__()
self._custom_arg_transforms = {
arg.Arg("unsigned char*","data") : arg.Arg("DataPointer","data"),
arg.Arg("unsigned char*","data") : arg.Arg("AccessorDataPointer","data"),
}

View File

@ -6,6 +6,6 @@ class Uint64LittleEndianDataAccessorSpecific(AccessorSpecific):
super().__init__()
self._custom_arg_transforms = {
arg.Arg("unsigned char*","data") : arg.Arg("DataPointer","data"),
arg.Arg("unsigned char*","data") : arg.Arg("AccessorDataPointer","data"),
}

View File

@ -6,6 +6,6 @@ class Uint8DataAccessorSpecific(AccessorSpecific):
super().__init__()
self._custom_arg_transforms = {
arg.Arg("unsigned char*","data") : arg.Arg("DataPointer","data"),
arg.Arg("unsigned char*","data") : arg.Arg("AccessorDataPointer","data"),
}

View File

@ -0,0 +1,48 @@
from accessor_specific.default import AccessorSpecific
from converter_collection import Converter
import static_func_funcsig_conv
import private_method_funcsig_conv
from funcsig import FuncSig
from arg_indexes import ArgIndexes
from arg import Arg
import arg
from funcsig_mapping import FuncSigMapping
class UnsignedDataFuncSigConverter(static_func_funcsig_conv.StaticFunctionFuncSigConverter):
func_conversions = [
FuncSigMapping(FuncSig("int", "value_is_missing", [Arg("long", "val")]),
FuncSig("int", "valueIsMissing", [Arg("long", "val")])),
]
def __init__(self, cfuncsig):
super().__init__(cfuncsig)
self._conversions.extend(self.func_conversions)
class UnsignedDataPrivateMethodFuncSigConverter(private_method_funcsig_conv.PrivateMethodFuncSigConverter):
func_conversions = [
FuncSigMapping(FuncSig("int", "pack_long_unsigned_helper", [Arg("grib_accessor*", "a"), Arg("const long*", "val"), Arg("size_t*", "len"), Arg("int", "check")]),
FuncSig("GribStatus", "packLongUnsignedHelper", [None, Arg("std::vector<long> const&", "longValues"), None, Arg("int", "check")]),
ArgIndexes(cbuffer=1, clength=2, cpp_container=1)),
]
def __init__(self, cfuncsig):
super().__init__(cfuncsig)
self._conversions.extend(self.func_conversions)
class UnsignedDataAccessorSpecific(AccessorSpecific):
def __init__(self) -> None:
super().__init__()
self._custom_arg_transforms = {
arg.Arg("unsigned char*","buf") : arg.Arg("AccessorDataBuffer","buf"),
}
self._custom_member_arg_transforms = {
arg.Arg("grib_arguments*","arg") : arg.Arg("AccessorInitData","arg"),
}
def update_converters(self, converters):
converters[Converter.STATIC_FUNC_FUNCSIG] = UnsignedDataFuncSigConverter
converters[Converter.PRIVATE_METHOD_FUNCSIG] = UnsignedDataPrivateMethodFuncSigConverter
return converters

View File

@ -96,6 +96,7 @@ container_types = [
"std::array",
"std::vector",
"std::map",
"AccessorDataBuffer",
]
# Return True if type is a container (std::vector etc)

View File

@ -12,38 +12,6 @@ class ConstructorMethodConverter(MethodConverter):
def create_cpp_function(self, cppfuncsig):
return constructor_method.ConstructorMethod(cppfuncsig, self._transforms.types["self"])
# overridden to short-circuit well-knwon transforms!
def convert_cfunction_calls(self, line):
# Transform the argument getters
m = re.search(r"((self->)?(\w+)\s+=\s+)?\bgrib_arguments_get_(\w+)\([^,]+, [^,]+, ([^\)]+)\)", line)
if m:
ctype = assignment_text = ""
if m.group(1):
assignment_text = m.group(1)
member_name = m.group(3)
for cmember, cppmember in self._transforms.members.items():
if cmember.name == member_name:
ctype = cppmember.type
break
get_what = m.group(4)
if get_what == "expression":
get_what = "GribExpressionPtr"
elif get_what in ["string", "name"]:
get_what = "std::string"
if not ctype:
ctype = "AccessorName"
if ctype == "AccessorName":
line = re.sub(m.re, f"{assignment_text}AccessorName(std::get<{get_what}>(initData.args[{m.group(5)}].second))", line)
else:
line = re.sub(m.re, f"{assignment_text}std::get<{get_what}>(initData.args[{m.group(5)}].second)", line)
debug.line("convert_cfunction_calls", f"Updated [bgrib_arguments_get_expression] line=[{line}]")
return super().convert_cfunction_calls(line)
# Overridden to get correct InitData "set size"
def container_func_call_for(self, cpparg, action, data=""):
if cpparg.underlying_type == "AccessorInitData":

View File

@ -41,8 +41,9 @@ env = Environment(
)
def parse_file(path):
in_definition = False
in_implementation = False
in_class_def_section = False
in_class_imp_section = False
in_main_code_section = False
in_function = False
includes = []
template = None
@ -104,31 +105,32 @@ def parse_file(path):
line = line.rstrip()
if stripped_line.startswith("START_CLASS_DEF"):
in_definition = True
in_class_def_section = True
continue
if stripped_line.startswith("END_CLASS_DEF"):
in_definition = False
in_class_def_section = False
continue
if stripped_line.startswith("/* START_CLASS_IMP */"):
in_implementation = True
in_class_imp_section = True
# Discard any global lines captured before here...
global_function.clear_lines()
continue
if stripped_line.startswith("/* END_CLASS_IMP */"):
in_implementation = False
in_class_imp_section = False
in_main_code_section = True
continue
if in_implementation:
if in_class_imp_section:
m = re.match(r"\s*\"(\w+)\",\s+/\* name \*/", stripped_line)
if m:
definitions["FACTORY"] = [m.group(1)]
continue
if in_definition:
if in_class_def_section:
if stripped_line.strip() == "":
continue
bits = [s.strip() for s in re.split(r"[=;]+", stripped_line)]
@ -141,6 +143,10 @@ def parse_file(path):
raise
continue
if not in_main_code_section:
debug.line("parse_file",f"[IGNORING] [{line}]")
continue
# Try and create a FuncSig from the line, if successful then it's a function definition!
cfuncsig = funcsig.FuncSig.from_string(line)
if cfuncsig:

View File

@ -9,3 +9,13 @@ class DestructorMethodConverter(MethodConverter):
def create_cpp_function(self, cppfuncsig):
return destructor_method.DestructorMethod(cppfuncsig, self._transforms.types["self"])
# Overridden to create an empty constructor if name is None
def create_cpp_body(self):
if self._cppfunction.name is None:
debug.line("create_cpp_body", f"\n============================== {self._cfunction.name} [IN] ==============================\n")
debug.line("create_cpp_body", f"Creating empty destructor body as no conversion defined (name is None)")
debug.line("create_cpp_body", f"\n============================== {self._cfunction.name} [OUT] ==============================\n")
return ["/* Destructor has been deleted */"]
return super().create_cpp_body()

View File

@ -894,22 +894,26 @@ class FunctionConverter:
# First, check for malloc
# Note: Group 2 (\()? and group 6 (\)) ensure we match the correct number of braces (grib_X()) vs grib_X()
# Note: Group 4 ([^,]+,)? is an optional match for the first param (usually c) which we discard, but may have already been removed!
m = re.search(r"\s*(\([^\)]+\))?(\()?grib_context_malloc(_\w+)?\(([^,]+,)?(.+)\)(\))[,;]", post_match_string)
m = re.search(r"\s*(\([^\)]+\))?(\()?grib_context_malloc(_\w+)?\(([^,]+,)?([^\)]*\)+)([,;])", post_match_string)
if m:
malloc_type = m.group(3) if m.group(3) else ""
match_string = m.group(5)
if not m.group(2):
match_string += m.group(6)
# Strip trailing ')' so parens match!
open_parens, close_parens = utils.count_parentheses(match_string)
extra_close_parens = close_parens-open_parens
if extra_close_parens > 0:
match_string = match_string[:len(match_string)-extra_close_parens]
# Check if we're creating (new arg) or resizing (existing arg)
if cpp_container_arg in self._new_cppargs_list:
transformed_line = f"{cpp_container_arg.name}({match_string});"
debug.line("transform_cpp_container_assignment", f"[CREATION] Replaced [{cpp_container_arg.name} = grib_context_malloc_X({match_string})] with [{transformed_line}]")
transformed_line = f"{cpp_container_arg.name}({match_string}{m.group(6)}"
debug.line("transform_cpp_container_assignment", f"[CREATION] Replaced [{cpp_container_arg.name} = grib_context_malloc{malloc_type}{m.group(3)}({match_string})] with [{transformed_line}]")
return transformed_line
else:
container_func_call = self.container_func_call_for(cpp_container_arg, "resize", match_string)
transformed_line = cpp_container_arg.name + "." + container_func_call + ";"
debug.line("transform_cpp_container_assignment", f"[EXISTING] Replaced {cpp_container_arg.name} = grib_context_malloc_X({match_string}) with [{transformed_line}]")
transformed_line = cpp_container_arg.name + "." + container_func_call + m.group(6)
debug.line("transform_cpp_container_assignment", f"[EXISTING] Replaced {cpp_container_arg.name} = grib_context_malloc_{malloc_type}({match_string}) with [{transformed_line}]")
return transformed_line
# Extract the assigned value
@ -1001,6 +1005,8 @@ class FunctionConverter:
debug.line("transform_cpp_container_non_assignment", f"INDEX OP: Replaced [{cpp_container_arg.name}{match_token.as_string()}{m.group(1)}] with post_match_string=[{cpp_container_arg.name}{post_match_string}]")
return cpp_container_arg.name + post_match_string
elif match_token.value in [",",")"]:
pass #assert False, f"FUNC ARG? [{arg.arg_string(cpp_container_arg)}]"
# TODO: Handle other comparisons?
@ -1220,24 +1226,13 @@ class FunctionConverter:
return line
# Specific check for if(c) or if(!c) where c is a container
def process_if_test(self, line):
m = re.search(r"\b(if\s*\(!?)(\w+)\)", line)
if m:
container_arg = self._transforms.cpparg_for_cppname(m.group(2))
if container_arg and arg.is_container(container_arg):
container_func_call = self.container_func_call_for(container_arg, "size")
transformed_call = f"{container_arg.name}.{container_func_call}"
line = re.sub(re.escape(m.group(2)), f"{transformed_call}", line)
debug.line("process_if_test", f"Replaced [{m.group(0)}] with [{transformed_call}] line:[{line}]")
# Specific check for TEST(arg) or TEST(!arg) where TEST is if, assert etc
# Supports special handling for container types
def process_boolean_test(self, line):
m = re.search(r"\b(\w+)(\s*\(!?)(\w+)\)", line)
return line
# Specific check for if(c) or if(!c) where c is a container (or other special types)
def process_assert_test(self, line):
m = re.search(r"\b(Assert\s*\(!?)(\w+)\)", line)
if m:
test_arg = self._transforms.cpparg_for_cppname(m.group(2))
if m and m.group(1) in ["if", "Assert"]:
test_arg = self._transforms.cpparg_for_cppname(m.group(3))
if test_arg:
transformed_call = None
@ -1248,15 +1243,14 @@ class FunctionConverter:
transformed_call = f"{test_arg.name}.get().size()"
if transformed_call:
line = re.sub(re.escape(m.group(2)), f"{transformed_call}", line)
line = re.sub(re.escape(m.group(3)), f"{transformed_call}", line)
debug.line("process_assert_test", f"Replaced [{m.group(0)}] with [{transformed_call}] line:[{line}]")
return line
# Override for any final updates...
def final_updates(self, line):
line = self.process_if_test(line)
line = self.process_assert_test(line)
line = self.process_boolean_test(line)
return line

View File

@ -6,15 +6,15 @@ from funcsig_mapping import FuncSigMapping
grib_bits_funcsig_conversions = [
FuncSigMapping( FuncSig("void", "grib_set_bit_on", [Arg("unsigned char*", "p"), Arg("long*", "bitp")]),
FuncSig("void", "gribSetBitOn", [Arg("DataPointer", "p"), Arg("long&", "bitp")])),
FuncSig("void", "gribSetBitOn", [Arg("AccessorDataPointer", "p"), Arg("long&", "bitp")])),
FuncSigMapping( FuncSig("void", "grib_set_bits_on", [Arg("unsigned char*", "p"), Arg("long*", "bitp"), Arg("long", "nbits")]),
FuncSig("void", "gribSetBitsOn", [Arg("DataPointer", "p"), Arg("long&", "bitp"), Arg("long", "nbits")])),
FuncSig("void", "gribSetBitsOn", [Arg("AccessorDataPointer", "p"), Arg("long&", "bitp"), Arg("long", "nbits")])),
FuncSigMapping( FuncSig("void", "grib_set_bit_off", [Arg("unsigned char*", "p"), Arg("long*", "bitp")]),
FuncSig("void", "gribSetBitOff", [Arg("DataPointer", "p"), Arg("long&", "bitp")])),
FuncSig("void", "gribSetBitOff", [Arg("AccessorDataPointer", "p"), Arg("long&", "bitp")])),
FuncSigMapping( FuncSig("void", "grib_set_bit", [Arg("unsigned char*", "p"), Arg("long", "bitp"), Arg("int", "val")]),
FuncSig("void", "gribSetBit", [Arg("DataPointer", "p"), Arg("long&", "bitp"), Arg("int", "val")])),
FuncSig("void", "gribSetBit", [Arg("AccessorDataPointer", "p"), Arg("long&", "bitp"), Arg("int", "val")])),
]

View File

@ -2,7 +2,6 @@
import funcsig_conversions.grib_stub_funcsig_conversions.grib_accessor_class_stub_funcsig_conv as grib_accessor_class_stub_funcsig_conv
import funcsig_conversions.grib_stub_funcsig_conversions.grib_accessor_stub_funcsig_conv as grib_accessor_stub_funcsig_conv
import funcsig_conversions.grib_stub_funcsig_conversions.grib_bits_any_endian_stub_funcsig_conv as grib_bits_any_endian_stub_funcsig_conv
import funcsig_conversions.grib_stub_funcsig_conversions.grib_bits_fast_big_endian_stub_funcsig_conv as grib_bits_fast_big_endian_stub_funcsig_conv
import funcsig_conversions.grib_stub_funcsig_conversions.grib_buffer_stub_funcsig_conv as grib_buffer_stub_funcsig_conv
import funcsig_conversions.grib_stub_funcsig_conversions.grib_date_stub_funcsig_conv as grib_date_stub_funcsig_conv
import funcsig_conversions.grib_stub_funcsig_conversions.grib_util_stub_funcsig_conv as grib_util_stub_funcsig_conv
@ -14,7 +13,6 @@ grib_stub_funcsig_conversions = [
grib_accessor_class_stub_funcsig_conv.grib_accessor_class_stub_funcsig_conversions,
grib_accessor_stub_funcsig_conv.grib_accessor_stub_funcsig_conversions,
grib_bits_any_endian_stub_funcsig_conv.grib_bits_any_endian_stub_funcsig_conversions,
grib_bits_fast_big_endian_stub_funcsig_conv.grib_bits_fast_big_endian_stub_funcsig_conversions,
grib_buffer_stub_funcsig_conv.grib_buffer_stub_funcsig_conversions,
grib_date_stub_funcsig_conv.grib_date_stub_funcsig_conversions,
grib_util_stub_funcsig_conv.grib_util_stub_funcsig_conversions,

View File

@ -6,5 +6,11 @@ from funcsig_mapping import FuncSigMapping
grib_bits_any_endian_stub_funcsig_conversions = [
FuncSigMapping( FuncSig("unsigned long", "grib_decode_unsigned_long", [Arg("const unsigned char*", "p"), Arg("long*", "p"), Arg("long", "nbits")]),
FuncSig("unsigned long", "gribDecodeUnsignedLong", [Arg("AccessorDataBuffer::const_pointer", "input"), Arg("long&", "bitPos"), Arg("long", "numBits")])),
FuncSig("unsigned long", "gribDecodeUnsignedLong", [Arg("const AccessorDataPointer", "input"), Arg("long&", "bitPos"), Arg("long", "numBits")])),
FuncSigMapping( FuncSig("int", "grib_encode_unsigned_long", [Arg("unsigned char*", "p"), Arg("unsigned long", "val"), Arg("long*", "bitp"), Arg("long", "nbits")]),
FuncSig("GribStatus", "gribEncodeUnsignedLong", [Arg("AccessorDataPointer", "input"), Arg("unsigned long", "val"), Arg("long&", "bitPos"), Arg("long", "numBits")])),
FuncSigMapping( FuncSig("int", "grib_encode_unsigned_longb", [Arg("unsigned char*", "p"), Arg("unsigned long", "val"), Arg("long*", "bitp"), Arg("long", "nbits")]),
FuncSig("GribStatus", "gribEncodeUnsignedLongb", [Arg("AccessorDataPointer", "input"), Arg("unsigned long", "val"), Arg("long&", "bitPos"), Arg("long", "numBits")])),
]

View File

@ -1,10 +0,0 @@
from funcsig import FuncSig
from arg_indexes import ArgIndexes
from arg import Arg
from funcsig_mapping import FuncSigMapping
grib_bits_fast_big_endian_stub_funcsig_conversions = [
FuncSigMapping( FuncSig("int", "grib_encode_unsigned_longb", [Arg("const unsigned char*", "p"), Arg("unsigned long", "val"), Arg("long*", "bitp"), Arg("long", "nbits")]),
FuncSig("GribStatus", "gribEncodeUnsignedLongb", [Arg("AccessorDataBuffer::const_pointer", "input"), Arg("unsigned long", "val"), Arg("long&", "bitPos"), Arg("long", "numBits")])),
]

View File

@ -6,13 +6,13 @@ from funcsig_mapping import FuncSigMapping
grib_buffer_stub_funcsig_conversions = [
FuncSigMapping( FuncSig("void", "grib_buffer_delete", [Arg("const grib_context*", "c"), Arg("grib_buffer*", "b")]),
FuncSig("void", "griBufferDelete", [None, Arg("AccessorDataBuffer", "b")])),
FuncSig("void", "griBufferDelete", [None, Arg("AccessorDataBuffer&", "b")])),
FuncSigMapping( FuncSig("void", "grib_buffer_replace", [Arg("grib_accessor*", "a"), Arg("const unsigned char*", "data"), Arg("size_t", "newsize"), Arg("int", "update_lengths"), Arg("int", "update_paddings")]),
FuncSig("void", "gribBufferReplace", [Arg("AccessorPtr", "ptr"), Arg("AccessorDataBuffer", "data"), Arg("size_t", "newsize"), Arg("int", "updateLengths"), Arg("int", "updatePaddings")])),
FuncSig("void", "gribBufferReplace", [None, Arg("AccessorDataBuffer&", "data"), Arg("size_t", "newsize"), Arg("int", "updateLengths"), Arg("int", "updatePaddings")])),
FuncSigMapping( FuncSig("void", "grib_buffer_set_ulength_bits", [Arg("const grib_context*", "c"), Arg("grib_buffer*", "b"), Arg("size_t", "length_bits")]),
FuncSig("void", "gribBufferSetUlengthBits", [None, Arg("AccessorDataBuffer", "b"), Arg("size_t", "lengthBits")])),
FuncSig("void", "gribBufferSetUlengthBits", [None, Arg("AccessorDataBuffer&", "b"), Arg("size_t", "lengthBits")])),
FuncSigMapping( FuncSig("grib_buffer*", "grib_create_growable_buffer", [Arg("const grib_context*", "c")]),
FuncSig("AccessorDataBuffer", "gribCreateGrowableBuffer", [None])),

View File

@ -60,7 +60,7 @@ base_members_map = {
arg.Arg("long","offset") : arg.Arg("long","offset_"),
arg.Arg("unsigned long","flags") : arg.Arg("unsigned long","flags_"),
arg.Arg("int","dirty") : arg.Arg("int","dirty_"),
arg.Arg("grib_virtual_value*","vvalue") : arg.Arg("std::unique_ptr<grib_virtual_value>","vvalue_"),
arg.Arg("grib_virtual_value*","vvalue") : arg.Arg("GribVirtualValuePtr","vvalue_"),
arg.Arg("const char*","set") : arg.Arg("std::string","set_")
}
@ -259,20 +259,12 @@ class GribAccessorConverter:
self._transforms.add_to_members(cmember, cppmember)
def add_constructor_method(self):
# Create a default constructor if none exists
if self._grib_accessor.constructor:
constructor_method_converter = self._converters[Converter.CONSTRUCTOR_METHOD]()
self._accessor_data._constructor = constructor_method_converter.to_cpp_function(self._grib_accessor.constructor, self._transforms)
else:
self._accessor_data._constructor = self._converters[Converter.CONSTRUCTOR_METHOD]()
constructor_method_converter = self._converters[Converter.CONSTRUCTOR_METHOD]()
self._accessor_data._constructor = constructor_method_converter.to_cpp_function(self._grib_accessor.constructor, self._transforms)
def add_destructor_method(self):
# Create a default destructor if none exists
if self._grib_accessor.destructor:
destructor_method_converter = self._converters[Converter.DESTRUCTOR_METHOD]()
self._accessor_data._destructor = destructor_method_converter.to_cpp_function(self._grib_accessor.destructor, self._transforms)
else:
self._accessor_data._destructor = self._converters[Converter.DESTRUCTOR_METHOD]()
destructor_method_converter = self._converters[Converter.DESTRUCTOR_METHOD]()
self._accessor_data._destructor = destructor_method_converter.to_cpp_function(self._grib_accessor.destructor, self._transforms)
def add_inherited_methods(self):
for cfunc in self._grib_accessor.inherited_methods:

View File

@ -12,6 +12,43 @@ class MethodConverter(FunctionConverter):
def create_cpp_function(self, cppfuncsig):
return method.Method(cppfuncsig, self._transforms.types["self"])
# overridden to short-circuit well-knwon transforms!
def convert_cfunction_calls(self, line):
# Transform the argument getters
m = re.search(r"((self->)?(\w+)\s+=\s+)?\bgrib_arguments_get_(\w+)\([^,]+, ([^,]+), ([^\)]+)\)", line)
if m:
ctype = assignment_text = ""
if m.group(1):
assignment_text = m.group(1)
member_name = m.group(3)
for cmember, cppmember in self._transforms.members.items():
if cmember.name == member_name:
ctype = cppmember.type
break
get_what = m.group(4)
if get_what == "expression":
get_what = "GribExpressionPtr"
elif get_what in ["string", "name"]:
get_what = "std::string"
if not ctype:
ctype = "AccessorName"
if m.group(5).startswith("self->"):
grib_arguments_arg_name = m.group(5)
else:
grib_arguments_arg_name = "initData"
if ctype == "AccessorName":
line = re.sub(m.re, f"{assignment_text}AccessorName(std::get<{get_what}>({grib_arguments_arg_name}.args[{m.group(6)}].second))", line)
else:
line = re.sub(m.re, f"{assignment_text}std::get<{get_what}>({grib_arguments_arg_name}.args[{m.group(6)}].second)", line)
debug.line("convert_cfunction_calls", f"Updated [bgrib_arguments_get_expression] line=[{line}]")
return super().convert_cfunction_calls(line)
# WARNING: CAN CAUSE CONFLICTS WITH e.g. "self->owner" member and "owner" local variable
# The former is detected via self-> struct access instead
# We only validate vars that end in "_" are indeed members, or return None
@ -53,10 +90,17 @@ class MethodConverter(FunctionConverter):
if not cppstruct_member:
cppstruct_member = struct_arg.StructArg("", cppmember.name, cstruct_member.index)
if cstruct_member.member:
# TODO: Additonal members here means that we've not processed something correctly - need to fix!
cppstruct_member_member = self.apply_default_cstruct_arg_transform(cstruct_member.member)
cppstruct_member.member = cppstruct_member_member
debug.line("transform_cstruct_arg_member", f"WARNING: Unexpected member, so not processed correctly: {cstruct_member.member.as_string()}")
if cstruct_member.name == "vvalue":
# This is a direct mapping
cppstruct_member.member = cstruct_member.member
elif cppmember and cppmember.type == "AccessorInitData":
# This is a direct mapping
cppstruct_member.member = cstruct_member.member
else:
# TODO: Additonal members here means that we've not processed something correctly - need to fix!
cppstruct_member_member = self.apply_default_cstruct_arg_transform(cstruct_member.member)
cppstruct_member.member = cppstruct_member_member
debug.line("transform_cstruct_arg_member", f"WARNING: Unexpected member, so not processed correctly: {cstruct_member.member.as_string()}")
break
# If super-> then replace with the correct AccessorName:: call, else remove top-level (self->, a-> etc)
@ -95,7 +139,7 @@ class MethodConverter(FunctionConverter):
return cppstruct_arg
# transform and a->foo where foo is a non-member
# transform any a->foo where foo is a non-member
def transform_cstruct_arg_a_nonmember(self, cstruct_arg):
cppstruct_arg = None
@ -250,23 +294,26 @@ class MethodConverter(FunctionConverter):
# Overridden to handle member types e.g. AccessorName x = NULL
def custom_transform_cppvariable_access(self, cppvariable, original_var, match_token, post_match_string):
accessor_arg = None
access_arg = None
for cpparg in self._transforms.all_args.values():
if cpparg and cpparg.name == cppvariable.name and cpparg.type == "AccessorPtr":
accessor_arg = cpparg
for cpparg_list in [self._transforms.all_args.values(),
self._transforms.members.values()]:
for cpparg in cpparg_list:
if cpparg and cpparg.name == cppvariable.name:
access_arg = cpparg
break
if not accessor_arg:
return None
if not access_arg:
return super().custom_transform_cppvariable_access(cppvariable, original_var, match_token, post_match_string)
if match_token.is_assignment:
m = re.match(r"\s*(NULL)", post_match_string)
if m:
post_match_string = re.sub(m.re, "nullptr", post_match_string)
return cppvariable.as_string() + match_token.as_string() + post_match_string
if access_arg.type == "AccessorPtr":
m = re.match(r"\s*(NULL)", post_match_string)
if m:
post_match_string = re.sub(m.re, "nullptr", post_match_string)
return cppvariable.as_string() + match_token.as_string() + post_match_string
return None
return super().custom_transform_cppvariable_access(cppvariable, original_var, match_token, post_match_string)
# Find any overloaded virtual function calls that are not implemented in this class, and add to the
# "using" list so we can add a "using base::func" directive in the header
@ -366,30 +413,11 @@ class MethodConverter(FunctionConverter):
return super().transform_container_cppvariable_access(cppvariable, original_var, match_token, post_match_string)
# Overridden for member checks
def process_if_test(self, line):
m = re.search(r"\b(if\s*\(!?)(\w+)\)", line)
if m:
arg_name = m.group(2)
container_arg = None
for cppmember in self._transforms.members.values():
if cppmember.name == arg_name and arg.is_container(cppmember):
container_arg = cppmember
break
def process_boolean_test(self, line):
m = re.search(r"\b(\w+)(\s*\(!?)(\w+)\)", line)
if container_arg:
container_func_call = self.container_func_call_for(container_arg, "size")
transformed_call = f"{container_arg.name}.{container_func_call}"
line = re.sub(re.escape(m.group(2)), f"{transformed_call}", line)
debug.line("process_if_test", f"Replaced [{m.group(0)}] with [{transformed_call}] line:[{line}]")
return line
return super().process_if_test(line)
# Overridden for member checks
def process_assert_test(self, line):
m = re.search(r"\b(Assert\s*\(!?)(\w+)\)", line)
if m:
arg_name = m.group(2)
if m and m.group(1) in ["if", "Assert"]:
arg_name = m.group(3)
test_arg = None
for cppmember in self._transforms.members.values():
if cppmember.name == arg_name:
@ -403,13 +431,15 @@ class MethodConverter(FunctionConverter):
transformed_call = f"{test_arg.name}.{container_func_call}"
elif test_arg.type == "AccessorName":
transformed_call = f"{test_arg.name}.get()"
elif test_arg.type == "AccessorInitData":
transformed_call = f"{test_arg.name}.args.size()"
if transformed_call:
line = re.sub(re.escape(m.group(2)), f"{transformed_call}", line)
line = re.sub(re.escape(m.group(3)), f"{transformed_call}", line)
debug.line("process_assert_test", f"Replaced [{m.group(0)}] with [{transformed_call}] line:[{line}]")
return line
return super().process_assert_test(line)
return super().process_boolean_test(line)
# Return a list of all pre-defined conversions
def method_conversions_list(self):

View File

@ -76,8 +76,6 @@ set(accessor_grib_stub_src_files
${accessor_grib_stub_dir}/GribActionStub.h
${accessor_grib_stub_dir}/GribBitsAnyEndianStub.cc
${accessor_grib_stub_dir}/GribBitsAnyEndianStub.h
${accessor_grib_stub_dir}/GribBitsFastBigEndianStub.cc
${accessor_grib_stub_dir}/GribBitsFastBigEndianStub.h
${accessor_grib_stub_dir}/GribBufferStub.cc
${accessor_grib_stub_dir}/GribBufferStub.h
${accessor_grib_stub_dir}/GribContextStub.cc
@ -90,6 +88,7 @@ set(accessor_grib_stub_src_files
${accessor_grib_stub_dir}/GribUtilStub.h
${accessor_grib_stub_dir}/GribParseUtilsStub.cc
${accessor_grib_stub_dir}/GribParseUtilsStub.h
${accessor_grib_stub_dir}/GribVirtualValueStub.h
)
# Variables to be used in the parent CMakeLists.txt

View File

@ -52,12 +52,12 @@ int Accessor::isMissing() const
return data_->isMissing();
}
bool Accessor::newBuffer(AccessorDataBuffer const& accBuffer)
bool Accessor::newBuffer(AccessorDataView const& accBuffer)
{
return data_->newBuffer(accBuffer);
}
AccessorDataBuffer Accessor::currentBuffer() const
AccessorDataView Accessor::currentBuffer() const
{
return data_->currentBuffer();
}

View File

@ -27,8 +27,8 @@ public:
int compare(AccessorPtr const rhs) const;
int isMissing() const;
bool newBuffer(AccessorDataBuffer const& accBuffer);
AccessorDataBuffer currentBuffer() const;
bool newBuffer(AccessorDataView const& accBuffer);
AccessorDataView currentBuffer() const;
// Required to support C -> C++ Conversion - Start
long byteCount() const;

View File

@ -5,7 +5,7 @@
#include <vector>
#include <cstddef>
// Provides a non-owning view to a contiguous block of memory, accessed as std::byte
// Provides a non-owning view to a contiguous block of memory, accessed as unsigned char
//
// Required because we have to use C++17, so don't have access to std::span
//
@ -15,23 +15,19 @@
namespace eccodes::accessor {
template<typename T>
class AccessorBuffer {
class AccessorDataView {
public:
using value_type = T;
using value_type = unsigned char;
using pointer = value_type*;
using const_pointer = value_type const*;
using reference = value_type&;
using const_reference = value_type const&;
using size_type = size_t;
using difference_type = ptrdiff_t;
constexpr AccessorBuffer() noexcept : data_{ nullptr }, size_{ 0 } {};
constexpr AccessorDataView() noexcept : data_{ nullptr }, size_{ 0 } {};
constexpr AccessorBuffer(AccessorBuffer const&) noexcept = default;
constexpr AccessorBuffer& operator=(AccessorBuffer const&) noexcept = default;
constexpr AccessorDataView(AccessorDataView const&) noexcept = default;
constexpr AccessorDataView& operator=(AccessorDataView const&) noexcept = default;
constexpr AccessorBuffer(value_type *const buffer, const size_type num_elements) noexcept
constexpr AccessorDataView(value_type *const buffer, const size_type num_elements) noexcept
: data_(reinterpret_cast<pointer>(buffer)), size_(sizeof(value_type) * num_elements) {}
[[nodiscard]] constexpr size_type size_bytes() const noexcept {
@ -51,7 +47,8 @@ private:
size_type size_;
};
using AccessorDataBuffer = AccessorBuffer<unsigned char>;
using DataPointer = unsigned char*;
using AccessorDataPointer = unsigned char*;
using AccessorDataBuffer = std::vector<unsigned char>;
}

View File

@ -15,13 +15,13 @@ AccessorData::AccessorData(AccessorInitData const& initData)
AccessorData::~AccessorData() = default;
bool AccessorData::newBuffer(AccessorDataBuffer const& accBuffer)
bool AccessorData::newBuffer(AccessorDataView const& accBuffer)
{
buffer_ = accBuffer;
return true;
}
AccessorDataBuffer AccessorData::currentBuffer() const
AccessorDataView AccessorData::currentBuffer() const
{
return buffer_;
}

View File

@ -6,6 +6,7 @@
#include "AccessorTraits.h"
#include "GribCpp/GribType.h"
#include "GribCpp/GribStatus.h"
#include "GribStub/GribVirtualValueStub.h"
#include <string>
#include <memory>
@ -22,8 +23,8 @@ public:
AccessorData(AccessorInitData const& initData);
virtual ~AccessorData() = 0;
bool newBuffer(AccessorDataBuffer const& accBuffer);
AccessorDataBuffer currentBuffer() const;
bool newBuffer(AccessorDataView const& accBuffer);
AccessorDataView currentBuffer() const;
virtual void dump() const;
virtual std::size_t stringLength() const;
@ -80,12 +81,12 @@ public:
// Ideally these would be private, but that makes the conversion much harder so they are protected instead
// This will be revisited later...
protected:
AccessorDataBuffer buffer_{};
AccessorDataView buffer_{};
long length_{};
long offset_{};
unsigned long flags_{};
int dirty_{};
std::unique_ptr<grib_virtual_value> vvalue_{};
GribVirtualValuePtr vvalue_{};
std::string set_{};
};

View File

@ -5,14 +5,14 @@
namespace eccodes::accessor {
void gribSetBitOn(DataPointer p, long& bitp)
void gribSetBitOn(AccessorDataPointer p, long& bitp)
{
p += bitp / 8;
*p |= (1u << (7 - (bitp % 8)));
bitp++;
}
void gribSetBitsOn(DataPointer p, long& bitp, long nbits)
void gribSetBitsOn(AccessorDataPointer p, long& bitp, long nbits)
{
int i;
for (i = 0; i < nbits; i++) {
@ -20,14 +20,14 @@ void gribSetBitsOn(DataPointer p, long& bitp, long nbits)
}
}
void gribSetBitOff(DataPointer p, long& bitp)
void gribSetBitOff(AccessorDataPointer p, long& bitp)
{
p += bitp / 8;
*p &= ~(1u << (7 - (bitp % 8)));
bitp++;
}
void gribSetBit(DataPointer p, long bitp, int val)
void gribSetBit(AccessorDataPointer p, long bitp, int val)
{
if (val == 0)
gribSetBitOff(p, bitp);

View File

@ -7,10 +7,10 @@
namespace eccodes::accessor {
void gribSetBitOn(DataPointer p, long& bitp);
void gribSetBitsOn(DataPointer p, long& bitp, long nbits);
void gribSetBitOff(DataPointer p, long& bitp);
void gribSetBit(DataPointer p, long bitp, int val);
void gribSetBitOn(AccessorDataPointer p, long& bitp);
void gribSetBitsOn(AccessorDataPointer p, long& bitp, long nbits);
void gribSetBitOff(AccessorDataPointer p, long& bitp);
void gribSetBit(AccessorDataPointer p, long bitp, int val);
}

View File

@ -5,17 +5,34 @@
namespace eccodes::accessor {
// A mask with x least-significant bits set, possibly 0 or >=32 */
// -1UL is 1111111... in every bit in binary representation
#define BIT_MASK(x) \
(((x) == max_nbits) ? (unsigned long)-1UL : (1UL << (x)) - 1)
// decode a value consisting of nbits from an octet-bitstream to long-representation
unsigned long gribDecodeUnsignedLong(DataPointer input, long& bitPos, long numBits)
unsigned long gribDecodeUnsignedLong(const AccessorDataPointer input, long& bitPos, long numBits)
{
assert(false); // TODO
return 0;
}
unsigned long gribDecodeUnsignedLong(const AccessorDataBuffer& input, long& bitPos, long numBits)
{
assert(false); // TODO
return 0;
}
GribStatus gribEncodeUnsignedLong(AccessorDataPointer p, unsigned long val, long& bitPos, long numBits)
{
assert(false); // TODO
return GribStatus::NOT_IMPLEMENTED;
}
GribStatus gribEncodeUnsignedLong(AccessorDataBuffer& p, unsigned long val, long& bitPos, long numBits)
{
assert(false); // TODO
return GribStatus::NOT_IMPLEMENTED;
}
GribStatus gribEncodeUnsignedLongb(AccessorDataPointer p, unsigned long val, long& bitPos, long nnumBitsb)
{
assert(false); // TODO
return GribStatus::NOT_IMPLEMENTED;
}
}

View File

@ -3,9 +3,19 @@
// C++ implementation of the existing grib_bits_any_endian.cc
#include "AccessorBuffer.h"
#include "GribCpp/GribStatus.h"
namespace eccodes::accessor {
unsigned long gribDecodeUnsignedLong(DataPointer input, long& bitPos, long numBits);
// AccessorDataBuffer& overload added to support conversion from C to C++
unsigned long gribDecodeUnsignedLong(const AccessorDataPointer input, long& bitPos, long numBits);
unsigned long gribDecodeUnsignedLong(const AccessorDataBuffer& input, long& bitPos, long numBits);
// AccessorDataBuffer& overload added to support conversion from C to C++
GribStatus gribEncodeUnsignedLong(AccessorDataPointer p, unsigned long val, long& bitp, long nbits);
GribStatus gribEncodeUnsignedLong(AccessorDataBuffer& p, unsigned long val, long& bitPos, long numBits);
//int grib_encode_unsigned_longb(unsigned char* p, unsigned long val, long* bitp, long nb);
GribStatus gribEncodeUnsignedLongb(AccessorDataPointer p, unsigned long val, long& bitPos, long numBits);
}

View File

@ -1,14 +0,0 @@
#include "GribBitsFastBigEndianStub.h"
#include <cassert>
namespace eccodes::accessor {
GribStatus gribEncodeUnsignedLongb(DataPointer p, unsigned long val, long& bitp, long nbits)
{
assert(false); // TODO
return GribStatus::NOT_IMPLEMENTED;
}
}

View File

@ -1,12 +0,0 @@
#pragma once
// C++ implementation of the existing grib_bits_fast_big_endian.cc
#include "AccessorBuffer.h"
#include "GribCpp/GribStatus.h"
namespace eccodes::accessor {
GribStatus gribEncodeUnsignedLongb(DataPointer p, unsigned long val, long& bitp, long nbits);
}

View File

@ -5,18 +5,17 @@
namespace eccodes::accessor {
void griBufferDelete(AccessorDataBuffer b)
void griBufferDelete(AccessorDataBuffer& b)
{
assert(false);
}
void gribBufferReplace(AccessorPtr ptr, AccessorDataBuffer data,
size_t newsize, int update_lengths, int update_paddings)
void gribBufferReplace(AccessorDataBuffer& data, size_t newsize, int update_lengths, int update_paddings)
{
assert(false);
}
void gribBufferSetUlengthBits(AccessorDataBuffer b, size_t length_bits)
void gribBufferSetUlengthBits(AccessorDataBuffer& b, size_t length_bits)
{
assert(false);
}

View File

@ -7,10 +7,9 @@
namespace eccodes::accessor {
void griBufferDelete(AccessorDataBuffer b);
void gribBufferReplace(AccessorPtr ptr, AccessorDataBuffer data,
size_t newsize, int updateLengths, int updatePaddings);
void gribBufferSetUlengthBits(AccessorDataBuffer b, size_t lengthBits);
void griBufferDelete(AccessorDataBuffer& b);
void gribBufferReplace(AccessorDataBuffer& data, size_t newsize, int updateLengths, int updatePaddings);
void gribBufferSetUlengthBits(AccessorDataBuffer& b, size_t lengthBits);
AccessorDataBuffer gribCreateGrowableBuffer();
}

View File

@ -6,10 +6,10 @@
#include "GribActionStub.h"
#include "GribAccessorStub.h"
#include "GribBitsAnyEndianStub.h"
#include "GribBitsFastBigEndianStub.h"
#include "GribBufferStub.h"
#include "GribContextStub.h"
#include "GribDateStub.h"
#include "GribExpressionStub.h"
#include "GribUtilStub.h"
#include "GribParseUtilsStub.h"
#include "GribVirtualValueStub.h"

View File

@ -0,0 +1,21 @@
#pragma once
#include "GribCpp/GribType.h"
#include <string>
#include <memory>
namespace eccodes::accessor {
struct GribVirtualValue
{
long lval;
double dval;
std::string cval;
int missing;
int length;
GribType type;
};
using GribVirtualValuePtr = std::shared_ptr<GribVirtualValue>;
}

View File

@ -45,7 +45,7 @@ void createAccessors(LayoutEntries const& entries, GribBuffer& buffer)
{
auto accessor = AccessorFactory::instance().build(AccessorType(entry.type_), AccessorName(entry.name_), AccessorNameSpace(""), AccessorInitData{});
AccessorDataBuffer accBuffer{buffer.data() + offset, static_cast<std::size_t>(entry.byteCount_)};
AccessorDataView accBuffer{buffer.data() + offset, static_cast<std::size_t>(entry.byteCount_)};
offset += entry.byteCount_;
accessor->newBuffer(accBuffer);

View File

@ -118,7 +118,7 @@ grib_accessor_class* grib_accessor_class_unsigned = &_grib_accessor_class_unsign
static void init(grib_accessor* a, const long len, grib_arguments* arg)
{
grib_accessor_unsigned* self = (grib_accessor_unsigned*)a;
self->arg = NULL;
//self->arg = NULL;
self->arg = arg;
self->nbytes = len;