bit and long accessors now build fully

This commit is contained in:
kevstone 2023-11-05 20:09:29 +00:00
parent 6591891f15
commit f863da9265
15 changed files with 114 additions and 13 deletions

View File

@ -22,6 +22,13 @@ class Arg:
# Return the "raw" type, e.g. char for char* or int for const int&
@property
def underlying_type(self):
if self.type.startswith("std::string"):
return "char"
m = re.match(r"std::((vector)|(array))<(\w+)>", self.type)
if m:
return m.group(4)
m = re.match(r"(?:const)?\s*(\w+)\s*[\*&]?\*?\s*(const)?", self.type)
if m:
return m.group(1)

View File

@ -26,4 +26,4 @@ class ConstructorMethodConverter(MethodConverter):
if action == "size":
return "length" # Note - no () as it's a member!
return super().container_funcname_for(cpparg, action)
return super().container_func_call_for(cpparg, action)

View File

@ -732,10 +732,20 @@ class FunctionConverter:
elif m.group(1) == "{":
debug.line("transform_container_cppvariable_access", f"Ignoring {cppvariable.as_string()} braced initialiser [{post_match_string}]")
return cpp_container_arg.name + match_token.as_string() + post_match_string
elif m.group(1).isalnum():
debug.line("transform_container_cppvariable_access", f"Replaced {cppvariable.as_string()} = 0 with {{}}")
post_match_string = re.sub(m.group(1), f"{{{m.group(1)}}}", post_match_string)
return cpp_container_arg.name + match_token.as_string() + post_match_string
else:
container_underlying_type = cpp_container_arg.underlying_type
rhs_arg = self._transforms.cpparg_for_cppname(m.group(1))
rhs_arg_underling_type = rhs_arg.underlying_type if rhs_arg else None
if rhs_arg_underling_type and rhs_arg_underling_type != container_underlying_type:
debug.line("transform_container_cppvariable_access", f"rhs_arg_underling_type=[{rhs_arg_underling_type}] container_underlying_type=[{container_underlying_type}]")
debug.line("transform_container_cppvariable_access", f"Replaced {cppvariable.as_string()} = {m.group(1)} with static_cast<{container_underlying_type}>{{}}")
post_match_string = re.sub(m.group(1), f"{{static_cast<{container_underlying_type}>({rhs_arg.name})}}", post_match_string)
return cpp_container_arg.name + match_token.as_string() + post_match_string
elif m.group(1).isalnum():
debug.line("transform_container_cppvariable_access", f"Replaced {cppvariable.as_string()} = {m.group(1)} with {{}}")
post_match_string = re.sub(m.group(1), f"{{{m.group(1)}}}", post_match_string)
return cpp_container_arg.name + match_token.as_string() + post_match_string
elif match_token.is_comparison:
# Extract the assigned value
@ -943,8 +953,23 @@ class FunctionConverter:
return line
# Specific check for if(c) or if(!c) where c is a container
def process_container_if(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(m.group(2), f"{transformed_call}", line)
debug.line("process_container_if", 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_container_if(line)
return line
# ======================================== UPDATE FUNCTIONS ========================================

View File

@ -2,11 +2,13 @@
import funcsig_conversions.grib_common_funcsig_conv as grib_common_funcsig_conv
import funcsig_conversions.grib_query_funcsig_conv as grib_query_funcsig_conv
import funcsig_conversions.grib_value_funcsig_conv as grib_value_funcsig_conv
import funcsig_conversions.string_util_funcsig_conv as string_util_funcsig_conv
funcsig_conversions = [
grib_common_funcsig_conv.grib_common_funcsig_conversions,
grib_query_funcsig_conv.grib_query_funcsig_conversions,
grib_value_funcsig_conv.grib_value_funcsig_conversions
grib_value_funcsig_conv.grib_value_funcsig_conversions,
string_util_funcsig_conv.string_util_funcsig_conversions
]
# Return a list of all the funcsig conversions

View File

@ -0,0 +1,11 @@
from funcsig import FuncSig
from arg_indexes import ArgIndexes
from arg import Arg
from funcsig_mapping import FuncSigMapping
string_util_funcsig_conversions = [
FuncSigMapping( FuncSig("int", "string_to_long", [Arg("const char*", "input"), Arg("long*", "output"), Arg("int", "strict")]),
FuncSig("int", "stringToLong", [Arg("std::string", "input"), Arg("long&", "output"), Arg("int", "strict")])),
]

View File

@ -23,6 +23,7 @@ common_includes = [
"GribCpp/GribQuery.h",
"GribCpp/GribUtils.h",
"GribCpp/GribValue.h",
"GribCpp/StringUtil.h",
"GribCpp/GribAccessorFlag.h",
"AccessorUtils/AccessorException.h"
]

View File

@ -80,7 +80,7 @@ class InheritedMethodFuncSigConverter(MethodFuncSigConverter):
FuncSig("GribStatus", "pack", [None, Arg("grib_expression const&", "expression")])),
# static int value_count(grib_accessor*, long*);
FuncSigMapping(FuncSig("int", "value_count", [Arg("grib_accessor*", ""), Arg("long*", "")]),
FuncSig("long", "valueCount", [None, None])),
FuncSig("GribStatus", "valueCount", [None, Arg("long&", "count")])),
# static void update_size(grib_accessor*, size_t);
FuncSigMapping(FuncSig("int", "update_size", [Arg("grib_accessor*", ""), Arg("size_t", "")]),
FuncSig("void", "updateSize", [None, Arg("std::size_t", "s")])),

View File

@ -117,7 +117,7 @@ class MethodConverter(FunctionConverter):
cppstruct_arg = None
# If AccessorPtr, keep access as "->"
cpparg = self._transforms.cpparg_for(cstruct_arg.name)
cpparg = self._transforms.cpparg_for_cname(cstruct_arg.name)
if cpparg and cpparg.type == "AccessorPtr":
if cstruct_arg.member.name == "name":
# Special handling: Replace name member with a string literal (it's only used in logging)

View File

@ -71,13 +71,21 @@ class Transforms:
return None
# Helper to return the cpparg for the supplied cname, or None
def cpparg_for(self, cname):
def cpparg_for_cname(self, cname):
for carg, cpparg in self.all_args.items():
if carg.name == cname:
return cpparg
return None
# Helper to return the cpparg for the supplied cppname, or None
def cpparg_for_cppname(self, cppname):
for cpparg in self.all_args.values():
if cpparg and cpparg.name == cppname:
return cpparg
return None
# Helper to return the cpptype for the supplied cppname, or None
def cpptype_of(self, cppname):
for cpparg in self.all_args.values():

View File

@ -60,6 +60,8 @@ set(accessor_grib_cpp_src_files
${accessor_grib_cpp_dir}/GribUtils.h
${accessor_grib_cpp_dir}/GribValue.cc
${accessor_grib_cpp_dir}/GribValue.h
${accessor_grib_cpp_dir}/StringUtil.cc
${accessor_grib_cpp_dir}/StringUtil.h
)

View File

@ -27,7 +27,9 @@ std::size_t Accessor::stringLength() const
long Accessor::valueCount() const
{
return data_->valueCount();
long count{};
data_->valueCount(count);
return count;
}
GribType Accessor::nativeType() const

View File

@ -36,9 +36,10 @@ std::size_t AccessorData::stringLength() const
return 1024;
}
long AccessorData::valueCount() const
GribStatus AccessorData::valueCount(long& count) const
{
return 1;
count = 1;
return GribStatus::NOT_IMPLEMENTED;
}
long AccessorData::byteCount() const

View File

@ -27,7 +27,8 @@ public:
virtual void dump() const;
virtual std::size_t stringLength() const;
virtual long valueCount() const;
//virtual long valueCount() const;
virtual GribStatus valueCount(long& count) const;
virtual long byteCount() const;
virtual long byteOffset() const;
virtual GribType nativeType() const;

View File

@ -0,0 +1,29 @@
#include "StringUtil.h"
#include <charconv>
namespace eccodes::accessor {
GribStatus stringToLong(std::string input, long& output, int strict)
{
const int base = 10;
long val{0};
auto [endptr, ec] = std::from_chars(input.data(), input.data() + input.size(), val, base);
if (ec == std::errc::invalid_argument ||
ec == std::errc::result_out_of_range ||
ec != std::errc())
{
return GribStatus::INVALID_ARGUMENT;
}
if (strict && endptr != input.data() + input.size())
{
// Left over characters - strict has failed!
return GribStatus::INVALID_ARGUMENT;
}
output = val;
return GribStatus::SUCCESS;
}
}

View File

@ -0,0 +1,12 @@
#pragma once
// C++ implementation of the existing string_util.cc
#include "GribCpp/GribStatus.h"
#include <string>
namespace eccodes::accessor {
GribStatus stringToLong(std::string input, long& output, int strict);
}