3
0
Fork 0
mirror of https://github.com/YosysHQ/yosys synced 2025-09-09 19:21:26 +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());
}
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,
DynamicIntCount num_dynamic_ints, const void *arg)
{

View file

@ -8,6 +8,10 @@
YOSYS_NAMESPACE_BEGIN
namespace RTLIL {
struct IdString;
}
inline std::string vstringf(const char *fmt, va_list ap)
{
// 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:
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_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 *");
}
*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,
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'.
void format_emit_void_ptr(std::string &result, std::string_view spec, int *dynamic_ints,
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);
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;
case CONVSPEC_VOID_PTR:
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... 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...);
}

View file

@ -1,6 +1,7 @@
#include <gtest/gtest.h>
#include "kernel/io.h"
#include "kernel/rtlil.h"
YOSYS_NAMESPACE_BEGIN
@ -44,6 +45,12 @@ TEST(KernelStringfTest, stringViewParam)
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)
{
EXPECT_EQ(stringf("%%"), "%");