mirror of
https://github.com/YosysHQ/yosys
synced 2025-09-30 21:19:30 +00:00
hotfix: fix new log functions being incompatible with pyosys
Modify python wrapper generator script with corner-case handlers such that functions that start with `log_formatted` have the format string coerced to `"%s"` and also have an alias without the `_formatted` part.
This commit is contained in:
parent
6b3a7e2440
commit
9fa27dae3c
1 changed files with 33 additions and 5 deletions
|
@ -71,7 +71,7 @@ keyword_aliases = {
|
||||||
|
|
||||||
#These can be used without any explicit conversion
|
#These can be used without any explicit conversion
|
||||||
primitive_types = ["void", "bool", "int", "double", "size_t", "std::string",
|
primitive_types = ["void", "bool", "int", "double", "size_t", "std::string",
|
||||||
"string", "State", "char_p", "std::source_location", "source_location"]
|
"string", "string_view", "std::string_view", "State", "char_p", "std::source_location", "source_location"]
|
||||||
|
|
||||||
from enum import Enum
|
from enum import Enum
|
||||||
|
|
||||||
|
@ -557,6 +557,7 @@ class Attribute:
|
||||||
default_value = None
|
default_value = None
|
||||||
pos = None
|
pos = None
|
||||||
pos_counter = 0
|
pos_counter = 0
|
||||||
|
coerce_arg = None
|
||||||
|
|
||||||
def __init__(self, wtype, varname, is_const = False, default_value = None):
|
def __init__(self, wtype, varname, is_const = False, default_value = None):
|
||||||
self.wtype = wtype
|
self.wtype = wtype
|
||||||
|
@ -566,7 +567,7 @@ class Attribute:
|
||||||
self.container = None
|
self.container = None
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def from_string(str_def, containing_file, line_number):
|
def from_string(str_def, containing_file, line_number, *, owner_fn_name=""):
|
||||||
if len(str_def) < 3:
|
if len(str_def) < 3:
|
||||||
return None
|
return None
|
||||||
orig = str_def
|
orig = str_def
|
||||||
|
@ -630,6 +631,14 @@ class Attribute:
|
||||||
else:
|
else:
|
||||||
arg.wtype.attr_type = attr_types.amp
|
arg.wtype.attr_type = attr_types.amp
|
||||||
arg.varname = arg.varname[1:]
|
arg.varname = arg.varname[1:]
|
||||||
|
|
||||||
|
# special exception: format strings
|
||||||
|
if arg.wtype.name in ["std::string_view", "string_view"]:
|
||||||
|
if arg.varname == "format":
|
||||||
|
arg.coerce_arg = '"%s"'
|
||||||
|
elif arg.varname == "prefix" and "warning" in owner_fn_name:
|
||||||
|
arg.coerce_arg = '"Warning: "'
|
||||||
|
|
||||||
return arg
|
return arg
|
||||||
|
|
||||||
#Generates the varname. If the attribute has no name in the header file,
|
#Generates the varname. If the attribute has no name in the header file,
|
||||||
|
@ -1391,7 +1400,7 @@ class WFunction:
|
||||||
for i, arg in enumerate(args):
|
for i, arg in enumerate(args):
|
||||||
if arg.strip() == "...":
|
if arg.strip() == "...":
|
||||||
continue
|
continue
|
||||||
parsed = Attribute.from_string(arg.strip(), containing_file, line_number)
|
parsed = Attribute.from_string(arg.strip(), containing_file, line_number, owner_fn_name=func.name)
|
||||||
if parsed == None:
|
if parsed == None:
|
||||||
return None
|
return None
|
||||||
# Only allow std::source_location as defaulted last argument, and
|
# Only allow std::source_location as defaulted last argument, and
|
||||||
|
@ -1431,6 +1440,8 @@ class WFunction:
|
||||||
text += "static "
|
text += "static "
|
||||||
text += self.ret_type.gen_text() + " " + self.alias + "("
|
text += self.ret_type.gen_text() + " " + self.alias + "("
|
||||||
for arg in self.args:
|
for arg in self.args:
|
||||||
|
if arg.coerce_arg:
|
||||||
|
continue
|
||||||
text += arg.gen_listitem()
|
text += arg.gen_listitem()
|
||||||
text += ", "
|
text += ", "
|
||||||
if len(self.args) > 0:
|
if len(self.args) > 0:
|
||||||
|
@ -1497,6 +1508,8 @@ class WFunction:
|
||||||
text += self.member_of.name + "::"
|
text += self.member_of.name + "::"
|
||||||
text += self.alias + "("
|
text += self.alias + "("
|
||||||
for arg in self.args:
|
for arg in self.args:
|
||||||
|
if arg.coerce_arg:
|
||||||
|
continue
|
||||||
text += arg.gen_listitem()
|
text += arg.gen_listitem()
|
||||||
text += ", "
|
text += ", "
|
||||||
if len(self.args) > 0:
|
if len(self.args) > 0:
|
||||||
|
@ -1516,13 +1529,14 @@ class WFunction:
|
||||||
if self.ret_type.name in classnames:
|
if self.ret_type.name in classnames:
|
||||||
text += self.ret_type.name + "::get_py_obj("
|
text += self.ret_type.name + "::get_py_obj("
|
||||||
if self.member_of == None:
|
if self.member_of == None:
|
||||||
text += "::" + self.namespace + "::" + self.alias + "("
|
text += "::" + self.namespace + "::" + self.name + "("
|
||||||
elif self.is_static:
|
elif self.is_static:
|
||||||
text += self.member_of.namespace + "::" + self.member_of.name + "::" + self.name + "("
|
text += self.member_of.namespace + "::" + self.member_of.name + "::" + self.name + "("
|
||||||
else:
|
else:
|
||||||
text += "this->get_cpp_obj()->" + self.name + "("
|
text += "this->get_cpp_obj()->" + self.name + "("
|
||||||
for arg in self.args:
|
for arg in self.args:
|
||||||
text += arg.gen_call() + ", "
|
text += arg.coerce_arg or arg.gen_call()
|
||||||
|
text += ", "
|
||||||
if len(self.args) > 0:
|
if len(self.args) > 0:
|
||||||
text = text[:-2]
|
text = text[:-2]
|
||||||
if self.ret_type.name in classnames:
|
if self.ret_type.name in classnames:
|
||||||
|
@ -1639,6 +1653,8 @@ class WFunction:
|
||||||
else:
|
else:
|
||||||
text += "(" + self.member_of.name + "::*)("
|
text += "(" + self.member_of.name + "::*)("
|
||||||
for a in self.args:
|
for a in self.args:
|
||||||
|
if a.coerce_arg:
|
||||||
|
continue
|
||||||
text += a.gen_listitem_hash() + ", "
|
text += a.gen_listitem_hash() + ", "
|
||||||
if len(self.args) > 0:
|
if len(self.args) > 0:
|
||||||
text = text[0:-2] + f"){self.gen_post_qualifiers(True)}>"
|
text = text[0:-2] + f"){self.gen_post_qualifiers(True)}>"
|
||||||
|
@ -2122,6 +2138,16 @@ def parse_header(source):
|
||||||
if class_ == None:
|
if class_ == None:
|
||||||
debug("\tFound unowned function \"" + candidate.name + "\" in namespace " + concat_namespace(namespaces),2)
|
debug("\tFound unowned function \"" + candidate.name + "\" in namespace " + concat_namespace(namespaces),2)
|
||||||
unowned_functions.append(candidate)
|
unowned_functions.append(candidate)
|
||||||
|
|
||||||
|
# generate log aliases
|
||||||
|
if candidate.name.startswith("log_formatted"):
|
||||||
|
alias = candidate.name.replace("log_formatted", "log")
|
||||||
|
if alias == "log_string":
|
||||||
|
alias = "log"
|
||||||
|
copied_candidate = copy.copy(candidate)
|
||||||
|
copied_candidate.alias = alias
|
||||||
|
unowned_functions.append(copied_candidate)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
debug("\t\tFound function \"" + candidate.name + "\" of class \"" + class_[0].name + "\" in namespace " + concat_namespace(namespaces),2)
|
debug("\t\tFound function \"" + candidate.name + "\" of class \"" + class_[0].name + "\" in namespace " + concat_namespace(namespaces),2)
|
||||||
class_[0].found_funs.append(candidate)
|
class_[0].found_funs.append(candidate)
|
||||||
|
@ -2359,6 +2385,8 @@ def gen_wrappers(filename, debug_level_ = 0):
|
||||||
#include <boost/iostreams/stream.hpp>
|
#include <boost/iostreams/stream.hpp>
|
||||||
USING_YOSYS_NAMESPACE
|
USING_YOSYS_NAMESPACE
|
||||||
|
|
||||||
|
using std::string_view;
|
||||||
|
|
||||||
namespace YOSYS_PYTHON {
|
namespace YOSYS_PYTHON {
|
||||||
|
|
||||||
[[noreturn]] static void log_python_exception_as_error() {
|
[[noreturn]] static void log_python_exception_as_error() {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue