mirror of https://github.com/ecmwf/eccodes.git
bit and long accessors now build fully
This commit is contained in:
parent
6591891f15
commit
f863da9265
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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 ========================================
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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")])),
|
||||
|
||||
]
|
|
@ -23,6 +23,7 @@ common_includes = [
|
|||
"GribCpp/GribQuery.h",
|
||||
"GribCpp/GribUtils.h",
|
||||
"GribCpp/GribValue.h",
|
||||
"GribCpp/StringUtil.h",
|
||||
"GribCpp/GribAccessorFlag.h",
|
||||
"AccessorUtils/AccessorException.h"
|
||||
]
|
||||
|
|
|
@ -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")])),
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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():
|
||||
|
|
|
@ -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
|
||||
)
|
||||
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
|
@ -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);
|
||||
|
||||
}
|
Loading…
Reference in New Issue