3
0
Fork 0
mirror of https://github.com/YosysHQ/yosys synced 2025-09-11 12:11:27 +00:00

Support IdString parameters in stringf

This commit is contained in:
Robert O'Callahan 2025-08-19 22:21:08 +00:00
parent 41452e43b2
commit c41ba912d8
3 changed files with 34 additions and 2 deletions

View file

@ -575,6 +575,17 @@ void format_emit_string_view(std::string &result, std::string_view spec, int *dy
format_emit_stringf(result, spec, dynamic_ints, num_dynamic_ints, std::string(arg).c_str()); format_emit_stringf(result, spec, dynamic_ints, num_dynamic_ints, std::string(arg).c_str());
} }
void format_emit_idstring(std::string &result, std::string_view spec, int *dynamic_ints,
DynamicIntCount num_dynamic_ints, const IdString &arg)
{
if (spec == "%s") {
// Format checking will have guaranteed num_dynamic_ints == 0.
result += arg.c_str();
return;
}
format_emit_stringf(result, spec, dynamic_ints, num_dynamic_ints, arg.c_str());
}
void format_emit_void_ptr(std::string &result, std::string_view spec, int *dynamic_ints, void format_emit_void_ptr(std::string &result, std::string_view spec, int *dynamic_ints,
DynamicIntCount num_dynamic_ints, const void *arg) DynamicIntCount num_dynamic_ints, const void *arg)
{ {

View file

@ -8,6 +8,10 @@
YOSYS_NAMESPACE_BEGIN YOSYS_NAMESPACE_BEGIN
namespace RTLIL {
struct IdString;
}
inline std::string vstringf(const char *fmt, va_list ap) inline std::string vstringf(const char *fmt, va_list ap)
{ {
// For the common case of strings shorter than 128, save a heap // For the common case of strings shorter than 128, save a heap
@ -240,7 +244,8 @@ constexpr void check_format(std::string_view fmt, int fmt_start, bool *has_escap
case CONVSPEC_CHAR_PTR: case CONVSPEC_CHAR_PTR:
if constexpr (!std::is_convertible_v<Arg, const char *> && if constexpr (!std::is_convertible_v<Arg, const char *> &&
!std::is_convertible_v<Arg, const std::string &> && !std::is_convertible_v<Arg, const std::string &> &&
!std::is_convertible_v<Arg, const std::string_view &>) { !std::is_convertible_v<Arg, const std::string_view &> &&
!std::is_convertible_v<Arg, const RTLIL::IdString &>) {
YOSYS_ABORT("Expected type convertible to char *"); YOSYS_ABORT("Expected type convertible to char *");
} }
*specs = found; *specs = found;
@ -279,6 +284,10 @@ void format_emit_string(std::string &result, std::string_view spec, int *dynamic
void format_emit_string_view(std::string &result, std::string_view spec, int *dynamic_ints, void format_emit_string_view(std::string &result, std::string_view spec, int *dynamic_ints,
DynamicIntCount num_dynamic_ints, std::string_view arg); DynamicIntCount num_dynamic_ints, std::string_view arg);
// Emit the string representation of `arg` that has been converted to a `RTLIL::IdString'.
void format_emit_idstring(std::string &result, std::string_view spec, int *dynamic_ints,
DynamicIntCount num_dynamic_ints, const RTLIL::IdString &arg);
// Emit the string representation of `arg` that has been converted to a `double'. // Emit the string representation of `arg` that has been converted to a `double'.
void format_emit_void_ptr(std::string &result, std::string_view spec, int *dynamic_ints, void format_emit_void_ptr(std::string &result, std::string_view spec, int *dynamic_ints,
DynamicIntCount num_dynamic_ints, const void *arg); DynamicIntCount num_dynamic_ints, const void *arg);
@ -329,6 +338,11 @@ inline void format_emit_one(std::string &result, std::string_view fmt, const Fou
format_emit_string_view(result, spec, dynamic_ints, num_dynamic_ints, s); format_emit_string_view(result, spec, dynamic_ints, num_dynamic_ints, s);
return; return;
} }
if constexpr (std::is_convertible_v<Arg, const RTLIL::IdString &>) {
const RTLIL::IdString &s = arg;
format_emit_idstring(result, spec, dynamic_ints, num_dynamic_ints, s);
return;
}
break; break;
case CONVSPEC_VOID_PTR: case CONVSPEC_VOID_PTR:
if constexpr (std::is_convertible_v<Arg, const void *>) { if constexpr (std::is_convertible_v<Arg, const void *>) {
@ -433,7 +447,7 @@ template <typename T> struct WrapType { using type = T; };
template <typename T> using TypeIdentity = typename WrapType<T>::type; template <typename T> using TypeIdentity = typename WrapType<T>::type;
template <typename... Args> template <typename... Args>
inline std::string stringf(FmtString<TypeIdentity<Args>...> fmt, Args... args) inline std::string stringf(FmtString<TypeIdentity<Args>...> fmt, const Args &... args)
{ {
return fmt.format(args...); return fmt.format(args...);
} }

View file

@ -1,6 +1,7 @@
#include <gtest/gtest.h> #include <gtest/gtest.h>
#include "kernel/io.h" #include "kernel/io.h"
#include "kernel/rtlil.h"
YOSYS_NAMESPACE_BEGIN YOSYS_NAMESPACE_BEGIN
@ -44,6 +45,12 @@ TEST(KernelStringfTest, stringViewParam)
EXPECT_EQ(stringf("%s", std::string_view("hello")), "hello"); EXPECT_EQ(stringf("%s", std::string_view("hello")), "hello");
} }
TEST(KernelStringfTest, idStringParam)
{
RTLIL::IdString id("$hello");
EXPECT_EQ(stringf("%s", id), "$hello");
}
TEST(KernelStringfTest, escapePercent) TEST(KernelStringfTest, escapePercent)
{ {
EXPECT_EQ(stringf("%%"), "%"); EXPECT_EQ(stringf("%%"), "%");