Merge remote-tracking branch 'origin/secure-bump-opensta-0321' into secure-sta-test-by-opus

Signed-off-by: Jaehyun Kim <jhkim@precisioninno.com>
This commit is contained in:
Jaehyun Kim 2026-03-21 18:54:41 +09:00
commit 9547beead3
9 changed files with 448 additions and 475 deletions

View File

@ -1,5 +1,7 @@
#include <gtest/gtest.h>
#include "DelayFloat.hh"
#include "Delay.hh"
#include "DelayScalar.hh"
#include "StaState.hh"
#include "MinMax.hh"
#include "Graph.hh"
#include "Transition.hh"
@ -9,38 +11,55 @@
namespace sta {
// Minimal StaState subclass that provides a DelayOps for unit tests.
class TestStaState : public StaState
{
public:
TestStaState() { delay_ops_ = new DelayOpsScalar(); }
~TestStaState() override { delete delay_ops_; delay_ops_ = nullptr; }
};
class DelayFloatTest : public ::testing::Test {
protected:
void SetUp() override {
initDelayConstants();
sta_state_ = new TestStaState();
}
void TearDown() override {
delete sta_state_;
sta_state_ = nullptr;
}
// Convenience accessor for delay comparison functions.
const StaState *sta() const { return sta_state_; }
TestStaState *sta_state_;
};
TEST_F(DelayFloatTest, DelayZero) {
EXPECT_TRUE(delayZero(0.0f));
EXPECT_TRUE(delayZero(delay_zero));
EXPECT_FALSE(delayZero(1.0f));
EXPECT_FALSE(delayZero(-1.0f));
EXPECT_TRUE(delayZero(Delay(0.0f), sta()));
EXPECT_TRUE(delayZero(delay_zero, sta()));
EXPECT_FALSE(delayZero(Delay(1.0f), sta()));
EXPECT_FALSE(delayZero(Delay(-1.0f), sta()));
}
TEST_F(DelayFloatTest, DelayEqual) {
EXPECT_TRUE(delayEqual(1.0f, 1.0f));
EXPECT_TRUE(delayEqual(0.0f, 0.0f));
EXPECT_FALSE(delayEqual(1.0f, 2.0f));
EXPECT_TRUE(delayEqual(Delay(1.0f), Delay(1.0f), sta()));
EXPECT_TRUE(delayEqual(Delay(0.0f), Delay(0.0f), sta()));
EXPECT_FALSE(delayEqual(Delay(1.0f), Delay(2.0f), sta()));
}
TEST_F(DelayFloatTest, DelayInf) {
// delayInf checks against STA's INF constant, not IEEE infinity
EXPECT_TRUE(delayInf(INF));
EXPECT_TRUE(delayInf(-INF));
EXPECT_FALSE(delayInf(0.0f));
EXPECT_FALSE(delayInf(1e10f));
EXPECT_TRUE(delayInf(Delay(INF), sta()));
EXPECT_TRUE(delayInf(Delay(-INF), sta()));
EXPECT_FALSE(delayInf(Delay(0.0f), sta()));
EXPECT_FALSE(delayInf(Delay(1e10f), sta()));
}
TEST_F(DelayFloatTest, DelayLess) {
EXPECT_TRUE(delayLess(1.0f, 2.0f, nullptr));
EXPECT_FALSE(delayLess(2.0f, 1.0f, nullptr));
EXPECT_FALSE(delayLess(1.0f, 1.0f, nullptr));
EXPECT_TRUE(delayLess(Delay(1.0f), Delay(2.0f), sta()));
EXPECT_FALSE(delayLess(Delay(2.0f), Delay(1.0f), sta()));
EXPECT_FALSE(delayLess(Delay(1.0f), Delay(1.0f), sta()));
}
TEST_F(DelayFloatTest, DelayRemove) {
@ -50,11 +69,6 @@ TEST_F(DelayFloatTest, DelayRemove) {
EXPECT_FLOAT_EQ(result, 2.0f);
}
TEST_F(DelayFloatTest, DelayRatio) {
EXPECT_FLOAT_EQ(delayRatio(6.0f, 3.0f), 2.0f);
EXPECT_FLOAT_EQ(delayRatio(0.0f, 1.0f), 0.0f);
}
TEST_F(DelayFloatTest, DelayInitValueMin) {
const Delay &init = delayInitValue(MinMax::min());
// Min init value should be a large positive number
@ -68,8 +82,8 @@ TEST_F(DelayFloatTest, DelayInitValueMax) {
}
TEST_F(DelayFloatTest, MakeDelay) {
Delay d = makeDelay(1.5f, 0.0f, 0.0f);
EXPECT_FLOAT_EQ(d, 1.5f);
Delay d = makeDelay(1.5f, 0.0f);
EXPECT_FLOAT_EQ(delayAsFloat(d), 1.5f);
}
TEST_F(DelayFloatTest, DelayAsFloat) {
@ -79,33 +93,33 @@ TEST_F(DelayFloatTest, DelayAsFloat) {
// Additional delay tests for improved coverage
TEST_F(DelayFloatTest, DelayGreater) {
EXPECT_TRUE(delayGreater(2.0f, 1.0f, nullptr));
EXPECT_FALSE(delayGreater(1.0f, 2.0f, nullptr));
EXPECT_FALSE(delayGreater(1.0f, 1.0f, nullptr));
EXPECT_TRUE(delayGreater(Delay(2.0f), Delay(1.0f), sta()));
EXPECT_FALSE(delayGreater(Delay(1.0f), Delay(2.0f), sta()));
EXPECT_FALSE(delayGreater(Delay(1.0f), Delay(1.0f), sta()));
}
TEST_F(DelayFloatTest, DelayLessEqual) {
EXPECT_TRUE(delayLessEqual(1.0f, 2.0f, nullptr));
EXPECT_TRUE(delayLessEqual(1.0f, 1.0f, nullptr));
EXPECT_FALSE(delayLessEqual(2.0f, 1.0f, nullptr));
EXPECT_TRUE(delayLessEqual(Delay(1.0f), Delay(2.0f), sta()));
EXPECT_TRUE(delayLessEqual(Delay(1.0f), Delay(1.0f), sta()));
EXPECT_FALSE(delayLessEqual(Delay(2.0f), Delay(1.0f), sta()));
}
TEST_F(DelayFloatTest, DelayGreaterEqual) {
EXPECT_TRUE(delayGreaterEqual(2.0f, 1.0f, nullptr));
EXPECT_TRUE(delayGreaterEqual(1.0f, 1.0f, nullptr));
EXPECT_FALSE(delayGreaterEqual(1.0f, 2.0f, nullptr));
EXPECT_TRUE(delayGreaterEqual(Delay(2.0f), Delay(1.0f), sta()));
EXPECT_TRUE(delayGreaterEqual(Delay(1.0f), Delay(1.0f), sta()));
EXPECT_FALSE(delayGreaterEqual(Delay(1.0f), Delay(2.0f), sta()));
}
TEST_F(DelayFloatTest, MakeDelayWithSigma) {
// In float mode, sigma is ignored
Delay d = makeDelay(2.5f, 0.1f, 0.2f);
EXPECT_FLOAT_EQ(d, 2.5f);
// makeDelay(mean, std_dev) - sigma stored in Delay class
Delay d = makeDelay(2.5f, 0.1f);
EXPECT_FLOAT_EQ(delayAsFloat(d), 2.5f);
}
TEST_F(DelayFloatTest, DelayNegative) {
Delay d = -5.0f;
EXPECT_FLOAT_EQ(delayAsFloat(d), -5.0f);
EXPECT_FALSE(delayZero(d));
EXPECT_FALSE(delayZero(d, sta()));
}
////////////////////////////////////////////////////////////////
@ -274,11 +288,12 @@ TEST(VertexStandaloneTest, Paths)
EXPECT_EQ(v.paths(), nullptr);
}
// Test Vertex slews
TEST(VertexStandaloneTest, Slews)
// Test Vertex pin default
TEST(VertexStandaloneTest, PinDefault)
{
Vertex v;
EXPECT_EQ(v.slews(), nullptr);
// slews() is protected; verify public pin() accessor instead
EXPECT_EQ(v.pin(), nullptr);
}
////////////////////////////////////////////////////////////////
@ -360,10 +375,10 @@ TEST(EdgeStandaloneTest, RemoveDelayAnnotated)
TEST(EdgeStandaloneTest, SetArcDelays)
{
Edge e;
// Set and clear arc delays
ArcDelay *delays = new ArcDelay[4];
// Set and clear arc delays (setArcDelays takes float*)
float *delays = new float[4];
for (int i = 0; i < 4; i++)
delays[i] = 0.0;
delays[i] = 0.0f;
e.setArcDelays(delays);
EXPECT_NE(e.arcDelays(), nullptr);
e.setArcDelays(nullptr);
@ -385,14 +400,14 @@ TEST_F(DelayFloatTest, DelayLessEqualMinMax)
{
// 4-arg delayLessEqual with MinMax
// With max: same as fuzzyLessEqual
EXPECT_TRUE(delayLessEqual(1.0f, 2.0f, MinMax::max(), nullptr));
EXPECT_TRUE(delayLessEqual(1.0f, 1.0f, MinMax::max(), nullptr));
EXPECT_FALSE(delayLessEqual(2.0f, 1.0f, MinMax::max(), nullptr));
EXPECT_TRUE(delayLessEqual(Delay(1.0f), Delay(2.0f), MinMax::max(), sta()));
EXPECT_TRUE(delayLessEqual(Delay(1.0f), Delay(1.0f), MinMax::max(), sta()));
EXPECT_FALSE(delayLessEqual(Delay(2.0f), Delay(1.0f), MinMax::max(), sta()));
// With min: same as fuzzyGreaterEqual (reversed)
EXPECT_TRUE(delayLessEqual(2.0f, 1.0f, MinMax::min(), nullptr));
EXPECT_TRUE(delayLessEqual(1.0f, 1.0f, MinMax::min(), nullptr));
EXPECT_FALSE(delayLessEqual(1.0f, 2.0f, MinMax::min(), nullptr));
EXPECT_TRUE(delayLessEqual(Delay(2.0f), Delay(1.0f), MinMax::min(), sta()));
EXPECT_TRUE(delayLessEqual(Delay(1.0f), Delay(1.0f), MinMax::min(), sta()));
EXPECT_FALSE(delayLessEqual(Delay(1.0f), Delay(2.0f), MinMax::min(), sta()));
}
////////////////////////////////////////////////////////////////
@ -413,7 +428,8 @@ TEST(EdgeStandaloneTest, DefaultState)
TEST(VertexStandaloneTest, SlewsDefault)
{
Vertex v;
EXPECT_EQ(v.slews(), nullptr);
// slews() is protected; verify public paths() accessor instead
EXPECT_EQ(v.paths(), nullptr);
}
// Test Edge::arcDelayAnnotateBit - static method
@ -440,22 +456,14 @@ TEST(EdgeStandaloneTest, EdgeInitViaTimingArcSet)
EXPECT_EQ(e.timingArcSet(), nullptr);
}
// Test Vertex setSlews
// Covers: Vertex::setSlews
// Test Vertex initial state via public accessors
// Covers: Vertex default state
TEST(VertexStandaloneTest, SetSlews)
{
Vertex v;
EXPECT_EQ(v.slews(), nullptr);
// Allocate some slews
Slew *slews = new Slew[4];
for (int i = 0; i < 4; i++)
slews[i] = static_cast<float>(i) * 1e-9f;
// setSlews is protected, but we test via the public slews() accessor
// We can't directly call setSlews, but we verify initial state
EXPECT_EQ(v.slews(), nullptr);
delete[] slews;
// slews() and setSlews() are protected; verify public accessors instead
EXPECT_EQ(v.pin(), nullptr);
EXPECT_EQ(v.paths(), nullptr);
}
// Test Vertex setPaths
@ -541,14 +549,12 @@ TEST(EdgeStandaloneTest, SetTimingArcSetNull)
EXPECT_EQ(e.timingArcSet(), nullptr);
}
// Test Vertex setSlews indirectly - slews_ is protected
// Covers: Vertex::setSlews path
// Test Vertex public accessors for initial state
// Covers: Vertex::paths, Vertex::setPaths
TEST(VertexStandaloneTest, VertexSlewsProtected)
{
Vertex v;
// Initially slews_ is nullptr
EXPECT_EQ(v.slews(), nullptr);
// setPaths is public - at least verify paths
// slews() is protected; verify public setPaths/paths instead
v.setPaths(nullptr);
EXPECT_EQ(v.paths(), nullptr);
}
@ -673,7 +679,8 @@ TEST(EdgeStandaloneTest, ArcDelaysSetAndAccess)
{
Edge e;
EXPECT_EQ(e.arcDelays(), nullptr);
ArcDelay *delays = new ArcDelay[8];
// setArcDelays takes float*
float *delays = new float[8];
for (int i = 0; i < 8; i++)
delays[i] = static_cast<float>(i) * 1e-12f;
e.setArcDelays(delays);
@ -773,14 +780,14 @@ TEST(EdgeStandaloneTest, MultipleFlagCombinations)
TEST_F(DelayFloatTest, DelayLessEqualMinMaxVariant)
{
// With max: standard less-equal
EXPECT_TRUE(delayLessEqual(1.0f, 2.0f, MinMax::max(), nullptr));
EXPECT_TRUE(delayLessEqual(2.0f, 2.0f, MinMax::max(), nullptr));
EXPECT_FALSE(delayLessEqual(3.0f, 2.0f, MinMax::max(), nullptr));
EXPECT_TRUE(delayLessEqual(Delay(1.0f), Delay(2.0f), MinMax::max(), sta()));
EXPECT_TRUE(delayLessEqual(Delay(2.0f), Delay(2.0f), MinMax::max(), sta()));
EXPECT_FALSE(delayLessEqual(Delay(3.0f), Delay(2.0f), MinMax::max(), sta()));
// With min: reversed (greater-equal)
EXPECT_TRUE(delayLessEqual(3.0f, 2.0f, MinMax::min(), nullptr));
EXPECT_TRUE(delayLessEqual(2.0f, 2.0f, MinMax::min(), nullptr));
EXPECT_FALSE(delayLessEqual(1.0f, 2.0f, MinMax::min(), nullptr));
EXPECT_TRUE(delayLessEqual(Delay(3.0f), Delay(2.0f), MinMax::min(), sta()));
EXPECT_TRUE(delayLessEqual(Delay(2.0f), Delay(2.0f), MinMax::min(), sta()));
EXPECT_FALSE(delayLessEqual(Delay(1.0f), Delay(2.0f), MinMax::min(), sta()));
}
////////////////////////////////////////////////////////////////

View File

@ -60,8 +60,8 @@ TEST_F(UnitTest, UserToSta) {
TEST_F(UnitTest, AsString) {
Unit unit(1e-9f, "s", 3);
const char *str = unit.asString(1e-9f);
EXPECT_NE(str, nullptr);
std::string str = unit.asString(1e-9f);
EXPECT_FALSE(str.empty());
// Should produce something like "1.000"
}
@ -1268,8 +1268,8 @@ TEST(InternalPowerTest, DirectConstruction) {
InternalPower pwr(nullptr, nullptr, nullptr, when_expr, models);
EXPECT_EQ(pwr.when(), when_expr.get());
EXPECT_EQ(pwr.relatedPgPin(), nullptr);
EXPECT_EQ(pwr.model(RiseFall::rise()), nullptr);
EXPECT_EQ(pwr.model(RiseFall::fall()), nullptr);
EXPECT_EQ(pwr.model(RiseFall::rise()).model(), nullptr);
EXPECT_EQ(pwr.model(RiseFall::fall()).model(), nullptr);
}
////////////////////////////////////////////////////////////////
@ -1450,26 +1450,27 @@ TEST_F(LinearModelTest, GateLinearModelConstruct) {
TEST_F(LinearModelTest, GateLinearModelGateDelay) {
GateLinearModel model(cell_, 1.0f, 2.0f);
ArcDelay gate_delay;
Slew drvr_slew;
float gate_delay;
float drvr_slew;
// delay = intrinsic + resistance * load_cap = 1.0 + 2.0 * 3.0 = 7.0
model.gateDelay(nullptr, 0.0f, 3.0f, false, gate_delay, drvr_slew);
EXPECT_FLOAT_EQ(delayAsFloat(gate_delay), 7.0f);
EXPECT_FLOAT_EQ(delayAsFloat(drvr_slew), 0.0f);
model.gateDelay(nullptr, 0.0f, 3.0f, gate_delay, drvr_slew);
EXPECT_FLOAT_EQ(gate_delay, 7.0f);
EXPECT_FLOAT_EQ(drvr_slew, 0.0f);
}
TEST_F(LinearModelTest, GateLinearModelZeroLoad) {
GateLinearModel model(cell_, 2.5f, 1.0f);
ArcDelay gate_delay;
Slew drvr_slew;
float gate_delay;
float drvr_slew;
// delay = 2.5 + 1.0 * 0.0 = 2.5
model.gateDelay(nullptr, 0.0f, 0.0f, false, gate_delay, drvr_slew);
EXPECT_FLOAT_EQ(delayAsFloat(gate_delay), 2.5f);
model.gateDelay(nullptr, 0.0f, 0.0f, gate_delay, drvr_slew);
EXPECT_FLOAT_EQ(gate_delay, 2.5f);
}
TEST_F(LinearModelTest, GateLinearModelReportGateDelay) {
GateLinearModel model(cell_, 1.0f, 2.0f);
std::string report = model.reportGateDelay(nullptr, 0.0f, 0.5f, false, 3);
std::string report = model.reportGateDelay(nullptr, 0.0f, 0.5f,
nullptr, PocvMode::scalar, 3);
EXPECT_FALSE(report.empty());
// Report should contain "Delay ="
EXPECT_NE(report.find("Delay"), std::string::npos);
@ -1477,23 +1478,27 @@ TEST_F(LinearModelTest, GateLinearModelReportGateDelay) {
TEST_F(LinearModelTest, CheckLinearModelConstruct) {
CheckLinearModel model(cell_, 3.0f);
ArcDelay delay = model.checkDelay(nullptr, 0.0f, 0.0f, 0.0f, false);
ArcDelay delay = model.checkDelay(nullptr, 0.0f, 0.0f, 0.0f,
nullptr, PocvMode::scalar);
EXPECT_FLOAT_EQ(delayAsFloat(delay), 3.0f);
}
TEST_F(LinearModelTest, CheckLinearModelCheckDelay) {
CheckLinearModel model(cell_, 5.5f);
// checkDelay always returns intrinsic_ regardless of other params
ArcDelay delay1 = model.checkDelay(nullptr, 1.0f, 2.0f, 3.0f, true);
ArcDelay delay1 = model.checkDelay(nullptr, 1.0f, 2.0f, 3.0f,
nullptr, PocvMode::scalar);
EXPECT_FLOAT_EQ(delayAsFloat(delay1), 5.5f);
ArcDelay delay2 = model.checkDelay(nullptr, 0.0f, 0.0f, 0.0f, false);
ArcDelay delay2 = model.checkDelay(nullptr, 0.0f, 0.0f, 0.0f,
nullptr, PocvMode::scalar);
EXPECT_FLOAT_EQ(delayAsFloat(delay2), 5.5f);
}
TEST_F(LinearModelTest, CheckLinearModelReportCheckDelay) {
CheckLinearModel model(cell_, 2.0f);
std::string report = model.reportCheckDelay(nullptr, 0.0f, nullptr,
0.0f, 0.0f, false, 3);
0.0f, 0.0f,
nullptr, PocvMode::scalar, 3);
EXPECT_FALSE(report.empty());
EXPECT_NE(report.find("Check"), std::string::npos);
}
@ -1505,24 +1510,24 @@ TEST_F(LinearModelTest, CheckLinearModelReportCheckDelay) {
TEST(InternalPowerTest, ModelAccess) {
InternalPowerModels models{};
InternalPower pwr(nullptr, nullptr, nullptr, nullptr, models);
// Initially models should be nullptr
EXPECT_EQ(pwr.model(RiseFall::rise()), nullptr);
EXPECT_EQ(pwr.model(RiseFall::fall()), nullptr);
// Initially models should have null inner TableModel
EXPECT_EQ(pwr.model(RiseFall::rise()).model(), nullptr);
EXPECT_EQ(pwr.model(RiseFall::fall()).model(), nullptr);
}
TEST(InternalPowerTest, WithModel) {
// Create a minimal model: Table -> TableModel -> InternalPowerModel
TablePtr tbl = std::make_shared<Table>(1.0f);
TableModel *table_model = new TableModel(tbl, nullptr,
ScaleFactorType::internal_power,
RiseFall::rise());
auto power_model = std::make_shared<InternalPowerModel>(table_model);
auto table_model = std::make_shared<TableModel>(tbl, nullptr,
ScaleFactorType::internal_power,
RiseFall::rise());
InternalPowerModel power_model(table_model);
InternalPowerModels models{};
models[RiseFall::riseIndex()] = power_model;
InternalPower pwr(nullptr, nullptr, nullptr, nullptr, models);
EXPECT_EQ(pwr.model(RiseFall::rise()), power_model.get());
EXPECT_EQ(pwr.model(RiseFall::fall()), nullptr);
EXPECT_NE(pwr.model(RiseFall::rise()).model(), nullptr);
EXPECT_EQ(pwr.model(RiseFall::fall()).model(), nullptr);
}
////////////////////////////////////////////////////////////////
@ -3473,9 +3478,9 @@ TEST(LibertyUtilTest, PortLibertyToStaWithBrackets) {
TEST(InternalPowerModelTest, PowerLookupOrder0) {
TablePtr tbl = std::make_shared<Table>(5.0f);
TableModel *table_model = new TableModel(tbl, nullptr,
ScaleFactorType::internal_power,
RiseFall::rise());
auto table_model = std::make_shared<TableModel>(tbl, nullptr,
ScaleFactorType::internal_power,
RiseFall::rise());
InternalPowerModel model(table_model);
LibertyLibrary lib("test_lib", "test.lib");
TestCell cell(&lib, "INV", "test.lib");
@ -3485,9 +3490,9 @@ TEST(InternalPowerModelTest, PowerLookupOrder0) {
TEST(InternalPowerModelTest, ReportPowerOrder0) {
TablePtr tbl = std::make_shared<Table>(3.0f);
TableModel *table_model = new TableModel(tbl, nullptr,
ScaleFactorType::internal_power,
RiseFall::rise());
auto table_model = std::make_shared<TableModel>(tbl, nullptr,
ScaleFactorType::internal_power,
RiseFall::rise());
InternalPowerModel model(table_model);
LibertyLibrary lib("test_lib", "test.lib");
TestCell cell(&lib, "INV", "test.lib");
@ -3505,9 +3510,9 @@ TEST(InternalPowerModelTest, PowerLookupOrder1) {
values.push_back(1.0f);
values.push_back(3.0f);
TablePtr tbl = std::make_shared<Table>(std::move(values), axis);
TableModel *table_model = new TableModel(tbl, nullptr,
ScaleFactorType::internal_power,
RiseFall::rise());
auto table_model = std::make_shared<TableModel>(tbl, nullptr,
ScaleFactorType::internal_power,
RiseFall::rise());
InternalPowerModel model(table_model);
LibertyLibrary lib("test_lib", "test.lib");
TestCell cell(&lib, "INV", "test.lib");
@ -3529,9 +3534,9 @@ TEST(InternalPowerModelTest, PowerLookupOrder2) {
FloatSeq row1; row1.push_back(3.0f); row1.push_back(4.0f);
values.push_back(std::move(row0)); values.push_back(std::move(row1));
TablePtr tbl = std::make_shared<Table>(std::move(values), axis1, axis2);
TableModel *table_model = new TableModel(tbl, nullptr,
ScaleFactorType::internal_power,
RiseFall::rise());
auto table_model = std::make_shared<TableModel>(tbl, nullptr,
ScaleFactorType::internal_power,
RiseFall::rise());
InternalPowerModel model(table_model);
LibertyLibrary lib("test_lib", "test.lib");
TestCell cell(&lib, "INV", "test.lib");

View File

@ -61,20 +61,20 @@ TEST_F(VerilogNamespaceTest, PortBusName) {
// Test Verilog-to-STA conversion
TEST_F(VerilogNamespaceTest, ModuleVerilogToSta) {
std::string verilog_name = "top_module";
std::string result = moduleVerilogToSta(&verilog_name);
std::string result = moduleVerilogToSta(verilog_name);
EXPECT_EQ(result, "top_module");
}
TEST_F(VerilogNamespaceTest, InstanceVerilogToSta) {
std::string verilog_name = "u1";
std::string result = instanceVerilogToSta(&verilog_name);
std::string result = instanceVerilogToSta(verilog_name);
EXPECT_EQ(result, "u1");
}
// Test escaped name round-trip
TEST_F(VerilogNamespaceTest, EscapedNameRoundTrip) {
std::string verilog_name = "\\esc_name ";
std::string sta = instanceVerilogToSta(&verilog_name);
std::string sta = instanceVerilogToSta(verilog_name);
EXPECT_FALSE(sta.empty());
}

View File

@ -886,7 +886,7 @@ TEST_F(VariablesTest, SetUseDefaultArrivalClock) {
TEST_F(VariablesTest, SetPocvEnabled) {
Variables vars;
vars.setPocvEnabled(true);
vars.setPocvMode(PocvMode::normal);
EXPECT_TRUE(vars.pocvEnabled());
}
@ -2170,7 +2170,7 @@ TEST_F(SdcInitTest, GroupPathClone) {
ExceptionPath *cloned = gp.clone(nullptr, nullptr, nullptr, true);
EXPECT_NE(cloned, nullptr);
EXPECT_TRUE(cloned->isGroupPath());
EXPECT_STREQ(cloned->name(), "grp");
EXPECT_EQ(cloned->name(), "grp");
delete cloned;
}
@ -2184,22 +2184,22 @@ TEST_F(SdcInitTest, FilterPathClone) {
TEST_F(SdcInitTest, FalsePathAsString) {
FalsePath fp(nullptr, nullptr, nullptr, MinMaxAll::all(), true, nullptr);
const char *str = fp.asString(sta_->cmdNetwork());
EXPECT_NE(str, nullptr);
std::string str = fp.to_string(sta_->cmdNetwork());
EXPECT_FALSE(str.empty());
}
TEST_F(SdcInitTest, PathDelayAsString) {
PathDelay pd(nullptr, nullptr, nullptr, MinMax::max(), false, false,
1.0e-9f, true, nullptr);
const char *str = pd.asString(sta_->cmdNetwork());
EXPECT_NE(str, nullptr);
std::string str = pd.to_string(sta_->cmdNetwork());
EXPECT_FALSE(str.empty());
}
TEST_F(SdcInitTest, MultiCyclePathAsString) {
MultiCyclePath mcp(nullptr, nullptr, nullptr, MinMaxAll::all(),
true, 2, true, nullptr);
const char *str = mcp.asString(sta_->cmdNetwork());
EXPECT_NE(str, nullptr);
std::string str = mcp.to_string(sta_->cmdNetwork());
EXPECT_FALSE(str.empty());
}
// ExceptionPath type predicates
@ -2320,7 +2320,7 @@ TEST_F(SdcInitTest, ExceptionPathDefaultHandlers) {
EXPECT_FALSE(fp.useEndClk());
EXPECT_EQ(fp.pathMultiplier(), 0);
EXPECT_FLOAT_EQ(fp.delay(), 0.0f);
EXPECT_EQ(fp.name(), nullptr);
EXPECT_TRUE(fp.name().empty());
EXPECT_FALSE(fp.isDefault());
EXPECT_FALSE(fp.ignoreClkLatency());
EXPECT_FALSE(fp.breakPath());
@ -2641,8 +2641,8 @@ TEST_F(SdcInitTest, ClockEdgeDetails) {
EXPECT_EQ(fall->transition(), RiseFall::fall());
EXPECT_EQ(rise->opposite(), fall);
EXPECT_EQ(fall->opposite(), rise);
EXPECT_NE(rise->name(), nullptr);
EXPECT_NE(fall->name(), nullptr);
EXPECT_FALSE(rise->name().empty());
EXPECT_FALSE(fall->name().empty());
EXPECT_GE(rise->index(), 0);
EXPECT_GE(fall->index(), 0);
EXPECT_NE(rise->index(), fall->index());
@ -2878,8 +2878,8 @@ TEST_F(SdcInitTest, SdcMakePathDelay) {
TEST_F(SdcInitTest, SdcRemoveClockGroupsOther) {
ASSERT_NO_THROW(( [&](){
Sdc *sdc = sta_->cmdSdc();
sdc->removeClockGroupsPhysicallyExclusive(nullptr);
sdc->removeClockGroupsAsynchronous(nullptr);
sdc->removeClockGroupsPhysicallyExclusive();
sdc->removeClockGroupsAsynchronous();
}() ));
}
@ -3813,7 +3813,7 @@ TEST_F(SdcInitTest, VariablesSetUseDefaultArrivalClock) {
TEST_F(SdcInitTest, VariablesSetPocvEnabled) {
Variables vars;
vars.setPocvEnabled(true);
vars.setPocvMode(PocvMode::normal);
EXPECT_TRUE(vars.pocvEnabled());
}
@ -4565,7 +4565,7 @@ TEST_F(SdcExceptionPathTest, GroupPathIsGroupPath) {
GroupPath gp("grp", false, nullptr, nullptr, nullptr, true, nullptr);
EXPECT_TRUE(gp.isGroupPath());
EXPECT_FALSE(gp.isFalse());
EXPECT_STREQ(gp.name(), "grp");
EXPECT_EQ(gp.name(), "grp");
EXPECT_FALSE(gp.isDefault());
EXPECT_EQ(gp.type(), ExceptionPathType::group_path);
}

View File

@ -84,18 +84,18 @@ set_propagated_clock [get_clocks clk1]
# set_clock_groups
############################################################
set_clock_groups -logically_exclusive -group [get_clocks clk1] -group [get_clocks clk2]
set_clock_groups -name le_grp -logically_exclusive -group [get_clocks clk1] -group [get_clocks clk2]
# Remove and re-add as physically exclusive
unset_clock_groups -logically_exclusive -all
unset_clock_groups -logically_exclusive -name le_grp
set_clock_groups -physically_exclusive -group [get_clocks clk1] -group [get_clocks clk2]
set_clock_groups -name pe_grp -physically_exclusive -group [get_clocks clk1] -group [get_clocks clk2]
unset_clock_groups -physically_exclusive -all
unset_clock_groups -physically_exclusive -name pe_grp
set_clock_groups -asynchronous -group [get_clocks clk1] -group [get_clocks clk2]
set_clock_groups -name async_grp -asynchronous -group [get_clocks clk1] -group [get_clocks clk2]
unset_clock_groups -asynchronous -all
unset_clock_groups -asynchronous -name async_grp
############################################################
# set_clock_sense

View File

@ -1233,14 +1233,14 @@ TEST_F(ExceptionPathTest, GroupPathBasic) {
EXPECT_FALSE(gp.isFalse());
EXPECT_FALSE(gp.isPathDelay());
EXPECT_EQ(gp.type(), ExceptionPathType::group_path);
EXPECT_STREQ(gp.name(), "group1");
EXPECT_EQ(gp.name(), "group1");
EXPECT_FALSE(gp.isDefault());
}
TEST_F(ExceptionPathTest, GroupPathDefault) {
GroupPath gp("default_group", true, nullptr, nullptr, nullptr, true, nullptr);
EXPECT_TRUE(gp.isDefault());
EXPECT_STREQ(gp.name(), "default_group");
EXPECT_EQ(gp.name(), "default_group");
}
TEST_F(ExceptionPathTest, GroupPathTypePriority) {
@ -1258,7 +1258,7 @@ TEST_F(ExceptionPathTest, GroupPathClone) {
GroupPath gp("gp_clone", true, nullptr, nullptr, nullptr, true, "comment");
ExceptionPath *clone = gp.clone(nullptr, nullptr, nullptr, true);
EXPECT_TRUE(clone->isGroupPath());
EXPECT_STREQ(clone->name(), "gp_clone");
EXPECT_EQ(clone->name(), "gp_clone");
EXPECT_TRUE(clone->isDefault());
delete clone;
}
@ -1377,7 +1377,7 @@ TEST_F(ExceptionPathTest, DefaultValues) {
EXPECT_FALSE(fp.useEndClk());
EXPECT_EQ(fp.pathMultiplier(), 0);
EXPECT_FLOAT_EQ(fp.delay(), 0.0f);
EXPECT_EQ(fp.name(), nullptr);
EXPECT_EQ(fp.name(), "");
EXPECT_FALSE(fp.isDefault());
EXPECT_FALSE(fp.ignoreClkLatency());
EXPECT_FALSE(fp.breakPath());

View File

@ -44,7 +44,7 @@ TEST_F(SpiceSmokeTest, TransitionNames) {
EXPECT_EQ(Transition::fall()->to_string(), "v");
}
// Tests for streamPrint (free function in WriteSpice.cc)
// Tests for print (Format.hh - formerly print)
class StreamPrintTest : public ::testing::Test {
protected:
void SetUp() override {
@ -63,7 +63,7 @@ protected:
TEST_F(StreamPrintTest, BasicString) {
std::ofstream out(tmpfile_);
ASSERT_TRUE(out.is_open());
streamPrint(out, "hello world\n");
sta::print(out, "hello world\n");
out.close();
std::ifstream in(tmpfile_);
@ -75,7 +75,7 @@ TEST_F(StreamPrintTest, BasicString) {
TEST_F(StreamPrintTest, FormattedOutput) {
std::ofstream out(tmpfile_);
ASSERT_TRUE(out.is_open());
streamPrint(out, "v%d %s 0 %.3f\n", 1, "node1", 1.800);
sta::print(out, "v{} {} 0 {:.3f}\n", 1, "node1", 1.800);
out.close();
std::ifstream in(tmpfile_);
@ -87,7 +87,7 @@ TEST_F(StreamPrintTest, FormattedOutput) {
TEST_F(StreamPrintTest, ScientificNotation) {
std::ofstream out(tmpfile_);
ASSERT_TRUE(out.is_open());
streamPrint(out, "C%d %s 0 %.3e\n", 1, "net1", 1.5e-12);
sta::print(out, "C{} {} 0 {:.3e}\n", 1, "net1", 1.5e-12);
out.close();
std::ifstream in(tmpfile_);
@ -99,9 +99,9 @@ TEST_F(StreamPrintTest, ScientificNotation) {
TEST_F(StreamPrintTest, MultipleWrites) {
std::ofstream out(tmpfile_);
ASSERT_TRUE(out.is_open());
streamPrint(out, "* Header\n");
streamPrint(out, ".tran %.3g %.3g\n", 1e-13, 1e-9);
streamPrint(out, ".end\n");
sta::print(out, "* Header\n");
sta::print(out, ".tran {:.3g} {:.3g}\n", 1e-13, 1e-9);
sta::print(out, ".end\n");
out.close();
std::ifstream in(tmpfile_);
@ -182,11 +182,11 @@ TEST_F(XyceCsvTest, FileNotReadableThrows) {
);
}
// Additional streamPrint tests for format coverage
// Additional print tests for format coverage
TEST_F(StreamPrintTest, EmptyString) {
std::ofstream out(tmpfile_);
ASSERT_TRUE(out.is_open());
streamPrint(out, "%s", "");
sta::print(out, "{}", "");
out.close();
std::ifstream in(tmpfile_);
@ -200,7 +200,7 @@ TEST_F(StreamPrintTest, LongString) {
ASSERT_TRUE(out.is_open());
// Build a long subcircuit line
std::string long_name(200, 'x');
streamPrint(out, ".subckt %s\n", long_name.c_str());
sta::print(out, ".subckt {}\n", long_name.c_str());
out.close();
std::ifstream in(tmpfile_);
@ -213,7 +213,7 @@ TEST_F(StreamPrintTest, LongString) {
TEST_F(StreamPrintTest, SpiceResistor) {
std::ofstream out(tmpfile_);
ASSERT_TRUE(out.is_open());
streamPrint(out, "R%d %s %s %.4e\n", 1, "n1", "n2", 1.0e3);
sta::print(out, "R{} {} {} {:.4e}\n", 1, "n1", "n2", 1.0e3);
out.close();
std::ifstream in(tmpfile_);
@ -227,7 +227,7 @@ TEST_F(StreamPrintTest, SpiceResistor) {
TEST_F(StreamPrintTest, SpiceComment) {
std::ofstream out(tmpfile_);
ASSERT_TRUE(out.is_open());
streamPrint(out, "* %s\n", "This is a SPICE comment");
sta::print(out, "* {}\n", "This is a SPICE comment");
out.close();
std::ifstream in(tmpfile_);
@ -240,7 +240,7 @@ TEST_F(StreamPrintTest, SpiceComment) {
TEST_F(StreamPrintTest, SpiceSubcktInstantiation) {
std::ofstream out(tmpfile_);
ASSERT_TRUE(out.is_open());
streamPrint(out, "x%s %s %s %s %s %s\n",
sta::print(out, "x{} {} {} {} {} {}\n",
"inst1", "vdd", "vss", "in", "out", "INV");
out.close();
@ -254,7 +254,7 @@ TEST_F(StreamPrintTest, SpiceSubcktInstantiation) {
TEST_F(StreamPrintTest, SpiceMeasure) {
std::ofstream out(tmpfile_);
ASSERT_TRUE(out.is_open());
streamPrint(out, ".measure tran %s trig v(%s) val=%.1f %s=%.3e\n",
sta::print(out, ".measure tran {} trig v({}) val={:.1f} {}={:.3e}\n",
"delay", "in", 0.9, "targ", 1e-9);
out.close();
@ -346,11 +346,11 @@ TEST_F(SpiceSmokeTest, TransitionInitFinalString) {
// Additional SPICE tests for function coverage
////////////////////////////////////////////////////////////////
// streamPrint with integers
// print with integers
TEST_F(StreamPrintTest, IntegerFormats) {
std::ofstream out(tmpfile_);
ASSERT_TRUE(out.is_open());
streamPrint(out, "R%d %d %d %d\n", 1, 100, 200, 50000);
sta::print(out, "R{} {} {} {}\n", 1, 100, 200, 50000);
out.close();
std::ifstream in(tmpfile_);
@ -359,11 +359,11 @@ TEST_F(StreamPrintTest, IntegerFormats) {
EXPECT_EQ(line, "R1 100 200 50000");
}
// streamPrint with mixed types
// print with mixed types
TEST_F(StreamPrintTest, MixedTypes) {
std::ofstream out(tmpfile_);
ASSERT_TRUE(out.is_open());
streamPrint(out, ".param %s=%g\n", "vdd", 1.8);
sta::print(out, ".param {}={:g}\n", "vdd", 1.8);
out.close();
std::ifstream in(tmpfile_);
@ -374,11 +374,11 @@ TEST_F(StreamPrintTest, MixedTypes) {
EXPECT_NE(line.find("1.8"), std::string::npos);
}
// streamPrint with percent
// print with percent
TEST_F(StreamPrintTest, PercentLiteral) {
std::ofstream out(tmpfile_);
ASSERT_TRUE(out.is_open());
streamPrint(out, "value = 100%%\n");
sta::print(out, "value = 100%\n");
out.close();
std::ifstream in(tmpfile_);
@ -387,12 +387,12 @@ TEST_F(StreamPrintTest, PercentLiteral) {
EXPECT_NE(line.find("100%"), std::string::npos);
}
// streamPrint with very long format
// print with very long format
TEST_F(StreamPrintTest, VeryLongFormat) {
std::ofstream out(tmpfile_);
ASSERT_TRUE(out.is_open());
std::string long_name(500, 'n');
streamPrint(out, ".subckt %s port1 port2 port3\n", long_name.c_str());
sta::print(out, ".subckt {} port1 port2 port3\n", long_name.c_str());
out.close();
std::ifstream in(tmpfile_);
@ -502,11 +502,11 @@ TEST_F(SpiceSmokeTest, TransitionFind) {
EXPECT_EQ(Transition::find("v"), Transition::fall());
}
// Test streamPrint with empty format
// Test print with empty format
TEST_F(StreamPrintTest, EmptyFormat) {
std::ofstream out(tmpfile_);
ASSERT_TRUE(out.is_open());
streamPrint(out, "%s", "");
sta::print(out, "{}", "");
out.close();
std::ifstream in(tmpfile_);
@ -515,11 +515,11 @@ TEST_F(StreamPrintTest, EmptyFormat) {
EXPECT_EQ(content, "");
}
// Test streamPrint with integer formatting
// Test print with integer formatting
TEST_F(StreamPrintTest, IntegerFormatting) {
std::ofstream out(tmpfile_);
ASSERT_TRUE(out.is_open());
streamPrint(out, "R%d %d %d %.2f\n", 1, 10, 20, 100.5);
sta::print(out, "R{} {} {} {:.2f}\n", 1, 10, 20, 100.5);
out.close();
std::ifstream in(tmpfile_);
@ -528,13 +528,13 @@ TEST_F(StreamPrintTest, IntegerFormatting) {
EXPECT_EQ(line, "R1 10 20 100.50");
}
// Test streamPrint with multiple lines
// Test print with multiple lines
TEST_F(StreamPrintTest, MultipleLines) {
std::ofstream out(tmpfile_);
ASSERT_TRUE(out.is_open());
streamPrint(out, "line1\n");
streamPrint(out, "line2\n");
streamPrint(out, "line3\n");
sta::print(out, "line1\n");
sta::print(out, "line2\n");
sta::print(out, "line3\n");
out.close();
std::ifstream in(tmpfile_);
@ -547,11 +547,11 @@ TEST_F(StreamPrintTest, MultipleLines) {
EXPECT_EQ(line, "line3");
}
// Test streamPrint with special characters
// Test print with special characters
TEST_F(StreamPrintTest, SpecialChars) {
std::ofstream out(tmpfile_);
ASSERT_TRUE(out.is_open());
streamPrint(out, "* SPICE deck for %s\n", "test_design");
sta::print(out, "* SPICE deck for {}\n", "test_design");
out.close();
std::ifstream in(tmpfile_);
@ -609,12 +609,12 @@ TEST_F(SpiceSmokeTest, MinMaxOpposite) {
// R6_ tests for Spice function coverage
////////////////////////////////////////////////////////////////
// Test streamPrint with wide variety of format specifiers
// Covers: streamPrint with many format types
// Test print with wide variety of format specifiers
// Covers: print with many format types
TEST_F(StreamPrintTest, FormatSpecifiers) {
std::ofstream out(tmpfile_);
ASSERT_TRUE(out.is_open());
streamPrint(out, "%c %s %d %f %e %g\n", 'A', "test", 42, 3.14, 1.5e-12, 1.8);
sta::print(out, "{:c} {} {} {} {:e} {:g}\n", 'A', "test", 42, 3.14, 1.5e-12, 1.8);
out.close();
std::ifstream in(tmpfile_);
@ -625,12 +625,12 @@ TEST_F(StreamPrintTest, FormatSpecifiers) {
EXPECT_NE(line.find("42"), std::string::npos);
}
// Test streamPrint with SPICE node naming
// Covers: streamPrint for SPICE net naming patterns
// Test print with SPICE node naming
// Covers: print for SPICE net naming patterns
TEST_F(StreamPrintTest, SpiceNodeNaming) {
std::ofstream out(tmpfile_);
ASSERT_TRUE(out.is_open());
streamPrint(out, "C%d %s %s %.4e\n", 1, "n_top/sub/net:1", "0", 1.5e-15);
sta::print(out, "C{} {} {} {:.4e}\n", 1, "n_top/sub/net:1", "0", 1.5e-15);
out.close();
std::ifstream in(tmpfile_);
@ -640,12 +640,12 @@ TEST_F(StreamPrintTest, SpiceNodeNaming) {
EXPECT_NE(line.find("n_top/sub/net:1"), std::string::npos);
}
// Test streamPrint with SPICE .include directive
// Covers: streamPrint for SPICE directives
// Test print with SPICE .include directive
// Covers: print for SPICE directives
TEST_F(StreamPrintTest, SpiceIncludeDirective) {
std::ofstream out(tmpfile_);
ASSERT_TRUE(out.is_open());
streamPrint(out, ".include \"%s\"\n", "/path/to/models.spice");
sta::print(out, ".include \"{}\"\n", "/path/to/models.spice");
out.close();
std::ifstream in(tmpfile_);
@ -655,12 +655,12 @@ TEST_F(StreamPrintTest, SpiceIncludeDirective) {
EXPECT_NE(line.find("/path/to/models.spice"), std::string::npos);
}
// Test streamPrint SPICE voltage source
// Covers: streamPrint for voltage sources
// Test print SPICE voltage source
// Covers: print for voltage sources
TEST_F(StreamPrintTest, SpiceVoltageSource) {
std::ofstream out(tmpfile_);
ASSERT_TRUE(out.is_open());
streamPrint(out, "v%s %s 0 %.3f\n", "dd", "vdd", 1.800);
sta::print(out, "v{} {} 0 {:.3f}\n", "dd", "vdd", 1.800);
out.close();
std::ifstream in(tmpfile_);
@ -669,12 +669,12 @@ TEST_F(StreamPrintTest, SpiceVoltageSource) {
EXPECT_EQ(line, "vdd vdd 0 1.800");
}
// Test streamPrint SPICE .tran with detailed parameters
// Covers: streamPrint for transient analysis
// Test print SPICE .tran with detailed parameters
// Covers: print for transient analysis
TEST_F(StreamPrintTest, SpiceTransAnalysis) {
std::ofstream out(tmpfile_);
ASSERT_TRUE(out.is_open());
streamPrint(out, ".tran %g %g %g %g\n", 1e-13, 5e-9, 0.0, 1e-12);
sta::print(out, ".tran {:g} {:g} {:g} {:g}\n", 1e-13, 5e-9, 0.0, 1e-12);
out.close();
std::ifstream in(tmpfile_);
@ -683,15 +683,15 @@ TEST_F(StreamPrintTest, SpiceTransAnalysis) {
EXPECT_NE(line.find(".tran"), std::string::npos);
}
// Test streamPrint SPICE PWL source
// Covers: streamPrint with PWL voltage source
// Test print SPICE PWL source
// Covers: print with PWL voltage source
TEST_F(StreamPrintTest, SpicePWLSource) {
std::ofstream out(tmpfile_);
ASSERT_TRUE(out.is_open());
streamPrint(out, "v_in in 0 PWL(\n");
streamPrint(out, "+%.3e %.3f\n", 0.0, 0.0);
streamPrint(out, "+%.3e %.3f\n", 1e-10, 1.8);
streamPrint(out, "+%.3e %.3f)\n", 2e-10, 1.8);
sta::print(out, "v_in in 0 PWL(\n");
sta::print(out, "+{:.3e} {:.3f}\n", 0.0, 0.0);
sta::print(out, "+{:.3e} {:.3f}\n", 1e-10, 1.8);
sta::print(out, "+{:.3e} {:.3f})\n", 2e-10, 1.8);
out.close();
std::ifstream in(tmpfile_);
@ -812,12 +812,12 @@ TEST_F(SpiceSmokeTest, RiseFallShortName) {
// R8_ tests for SPICE module coverage improvement
////////////////////////////////////////////////////////////////
// Test streamPrint with SPICE transistor format (used in writeParasiticNetwork)
// Covers: streamPrint paths used by WriteSpice
// Test print with SPICE transistor format (used in writeParasiticNetwork)
// Covers: print paths used by WriteSpice
TEST_F(StreamPrintTest, SpiceTransistorFormat) {
std::ofstream out(tmpfile_);
ASSERT_TRUE(out.is_open());
streamPrint(out, "M%d %s %s %s %s %s W=%.3e L=%.3e\n",
sta::print(out, "M{} {} {} {} {} {} W={:.3e} L={:.3e}\n",
1, "drain", "gate", "source", "bulk", "NMOS",
1.0e-6, 45.0e-9);
out.close();
@ -830,13 +830,13 @@ TEST_F(StreamPrintTest, SpiceTransistorFormat) {
EXPECT_NE(line.find("NMOS"), std::string::npos);
}
// Test streamPrint with SPICE capacitor format (used in writeParasiticNetwork)
// Covers: streamPrint paths used by WriteSpice::writeParasiticNetwork
// Test print with SPICE capacitor format (used in writeParasiticNetwork)
// Covers: print paths used by WriteSpice::writeParasiticNetwork
TEST_F(StreamPrintTest, SpiceCapacitorFormat) {
std::ofstream out(tmpfile_);
ASSERT_TRUE(out.is_open());
streamPrint(out, "C%d %s %s %.4e\n", 1, "net1:1", "0", 1.5e-15);
streamPrint(out, "C%d %s %s %.4e\n", 2, "net1:2", "net1:3", 2.5e-15);
sta::print(out, "C{} {} {} {:.4e}\n", 1, "net1:1", "0", 1.5e-15);
sta::print(out, "C{} {} {} {:.4e}\n", 2, "net1:2", "net1:3", 2.5e-15);
out.close();
std::ifstream in(tmpfile_);
@ -847,12 +847,12 @@ TEST_F(StreamPrintTest, SpiceCapacitorFormat) {
EXPECT_TRUE(line2.find("C2") == 0);
}
// Test streamPrint with SPICE voltage source (used in writeClkedStepSource)
// Covers: streamPrint paths used by WriteSpice::writeClkedStepSource
// Test print with SPICE voltage source (used in writeClkedStepSource)
// Covers: print paths used by WriteSpice::writeClkedStepSource
TEST_F(StreamPrintTest, SpiceVoltageSource2) {
std::ofstream out(tmpfile_);
ASSERT_TRUE(out.is_open());
streamPrint(out, "v%s %s 0 pwl(0 %.3f %.3e %.3f)\n",
sta::print(out, "v{} {} 0 pwl(0 {:.3f} {:.3e} {:.3f})\n",
"clk", "clk_node", 0.0, 1e-9, 1.8);
out.close();
@ -863,16 +863,16 @@ TEST_F(StreamPrintTest, SpiceVoltageSource2) {
EXPECT_NE(line.find("pwl"), std::string::npos);
}
// Test streamPrint with SPICE waveform format (used in writeWaveformVoltSource)
// Covers: streamPrint paths used by WriteSpice::writeWaveformVoltSource
// Test print with SPICE waveform format (used in writeWaveformVoltSource)
// Covers: print paths used by WriteSpice::writeWaveformVoltSource
TEST_F(StreamPrintTest, SpiceWaveformFormat) {
std::ofstream out(tmpfile_);
ASSERT_TRUE(out.is_open());
streamPrint(out, "v%s %s 0 pwl(\n", "in", "in_node");
streamPrint(out, "+ %.3e %.3f\n", 0.0, 0.0);
streamPrint(out, "+ %.3e %.3f\n", 1e-10, 0.9);
streamPrint(out, "+ %.3e %.3f\n", 2e-10, 1.8);
streamPrint(out, "+)\n");
sta::print(out, "v{} {} 0 pwl(\n", "in", "in_node");
sta::print(out, "+ {:.3e} {:.3f}\n", 0.0, 0.0);
sta::print(out, "+ {:.3e} {:.3f}\n", 1e-10, 0.9);
sta::print(out, "+ {:.3e} {:.3f}\n", 2e-10, 1.8);
sta::print(out, "+)\n");
out.close();
std::ifstream in(tmpfile_);
@ -882,16 +882,16 @@ TEST_F(StreamPrintTest, SpiceWaveformFormat) {
EXPECT_NE(content.find("pwl"), std::string::npos);
}
// Test streamPrint with SPICE .measure format (used in spiceTrans context)
// Covers: streamPrint with RISE/FALL strings (used by WriteSpice::spiceTrans)
// Test print with SPICE .measure format (used in spiceTrans context)
// Covers: print with RISE/FALL strings (used by WriteSpice::spiceTrans)
TEST_F(StreamPrintTest, SpiceMeasureRiseFall) {
std::ofstream out(tmpfile_);
ASSERT_TRUE(out.is_open());
// This mimics how spiceTrans returns RISE/FALL strings
const char *rise_str = "RISE";
const char *fall_str = "FALL";
streamPrint(out, ".measure tran delay_rf trig v(in) val=0.9 %s=last\n", rise_str);
streamPrint(out, "+targ v(out) val=0.9 %s=last\n", fall_str);
sta::print(out, ".measure tran delay_rf trig v(in) val=0.9 {}=last\n", rise_str);
sta::print(out, "+targ v(out) val=0.9 {}=last\n", fall_str);
out.close();
std::ifstream in(tmpfile_);
@ -950,15 +950,15 @@ TEST_F(XyceCsvTest, ReadCsvManySignals) {
// R9_ tests for SPICE module coverage improvement
////////////////////////////////////////////////////////////////
// streamPrint: SPICE subcircuit definition (used by WriteSpice)
// print: SPICE subcircuit definition (used by WriteSpice)
TEST_F(StreamPrintTest, SpiceSubcktDefinition) {
std::ofstream out(tmpfile_);
ASSERT_TRUE(out.is_open());
streamPrint(out, ".subckt %s %s %s %s %s\n",
sta::print(out, ".subckt {} {} {} {} {}\n",
"INV_X1", "VDD", "VSS", "A", "Y");
streamPrint(out, "M1 Y A VDD VDD PMOS W=%.3e L=%.3e\n", 200e-9, 45e-9);
streamPrint(out, "M2 Y A VSS VSS NMOS W=%.3e L=%.3e\n", 100e-9, 45e-9);
streamPrint(out, ".ends %s\n", "INV_X1");
sta::print(out, "M1 Y A VDD VDD PMOS W={:.3e} L={:.3e}\n", 200e-9, 45e-9);
sta::print(out, "M2 Y A VSS VSS NMOS W={:.3e} L={:.3e}\n", 100e-9, 45e-9);
sta::print(out, ".ends {}\n", "INV_X1");
out.close();
std::ifstream in(tmpfile_);
@ -970,12 +970,12 @@ TEST_F(StreamPrintTest, SpiceSubcktDefinition) {
EXPECT_NE(content.find("NMOS"), std::string::npos);
}
// streamPrint: SPICE resistor network (used in writeParasiticNetwork)
// print: SPICE resistor network (used in writeParasiticNetwork)
TEST_F(StreamPrintTest, SpiceResistorNetwork) {
std::ofstream out(tmpfile_);
ASSERT_TRUE(out.is_open());
for (int i = 0; i < 10; i++) {
streamPrint(out, "R%d n%d n%d %.4e\n", i+1, i, i+1, 50.0 + i*10.0);
sta::print(out, "R{} n{} n{} {:.4e}\n", i+1, i, i+1, 50.0 + i*10.0);
}
out.close();
@ -986,12 +986,12 @@ TEST_F(StreamPrintTest, SpiceResistorNetwork) {
EXPECT_NE(content.find("R10"), std::string::npos);
}
// streamPrint: SPICE capacitor network (used in writeParasiticNetwork)
// print: SPICE capacitor network (used in writeParasiticNetwork)
TEST_F(StreamPrintTest, SpiceCapacitorNetwork) {
std::ofstream out(tmpfile_);
ASSERT_TRUE(out.is_open());
for (int i = 0; i < 10; i++) {
streamPrint(out, "C%d n%d 0 %.4e\n", i+1, i, 1e-15 * (i+1));
sta::print(out, "C{} n{} 0 {:.4e}\n", i+1, i, 1e-15 * (i+1));
}
out.close();
@ -1002,11 +1002,11 @@ TEST_F(StreamPrintTest, SpiceCapacitorNetwork) {
EXPECT_NE(content.find("C10"), std::string::npos);
}
// streamPrint: SPICE .lib directive
// print: SPICE .lib directive
TEST_F(StreamPrintTest, SpiceLibDirective) {
std::ofstream out(tmpfile_);
ASSERT_TRUE(out.is_open());
streamPrint(out, ".lib '%s' %s\n", "/path/to/models.lib", "tt");
sta::print(out, ".lib '{}' {}\n", "/path/to/models.lib", "tt");
out.close();
std::ifstream in(tmpfile_);
@ -1016,11 +1016,11 @@ TEST_F(StreamPrintTest, SpiceLibDirective) {
EXPECT_NE(line.find("tt"), std::string::npos);
}
// streamPrint: SPICE .option directive
// print: SPICE .option directive
TEST_F(StreamPrintTest, SpiceOptionDirective) {
std::ofstream out(tmpfile_);
ASSERT_TRUE(out.is_open());
streamPrint(out, ".option %s=%g %s=%g\n", "reltol", 1e-6, "abstol", 1e-12);
sta::print(out, ".option {}={:g} {}={:g}\n", "reltol", 1e-6, "abstol", 1e-12);
out.close();
std::ifstream in(tmpfile_);
@ -1030,11 +1030,11 @@ TEST_F(StreamPrintTest, SpiceOptionDirective) {
EXPECT_NE(line.find("reltol"), std::string::npos);
}
// streamPrint: SPICE .print directive
// print: SPICE .print directive
TEST_F(StreamPrintTest, SpicePrintDirective) {
std::ofstream out(tmpfile_);
ASSERT_TRUE(out.is_open());
streamPrint(out, ".print tran v(%s) v(%s) v(%s)\n",
sta::print(out, ".print tran v({}) v({}) v({})\n",
"input", "output", "clk");
out.close();
@ -1046,11 +1046,11 @@ TEST_F(StreamPrintTest, SpicePrintDirective) {
EXPECT_NE(line.find("v(output)"), std::string::npos);
}
// streamPrint: SPICE pulse source
// print: SPICE pulse source
TEST_F(StreamPrintTest, SpicePulseSource) {
std::ofstream out(tmpfile_);
ASSERT_TRUE(out.is_open());
streamPrint(out, "v%s %s 0 PULSE(%.3f %.3f %.3e %.3e %.3e %.3e %.3e)\n",
sta::print(out, "v{} {} 0 PULSE({:.3f} {:.3f} {:.3e} {:.3e} {:.3e} {:.3e} {:.3e})\n",
"clk", "clk_node", 0.0, 1.8, 0.0, 20e-12, 20e-12, 500e-12, 1e-9);
out.close();
@ -1061,13 +1061,13 @@ TEST_F(StreamPrintTest, SpicePulseSource) {
EXPECT_NE(line.find("PULSE"), std::string::npos);
}
// streamPrint: SPICE mutual inductance
// print: SPICE mutual inductance
TEST_F(StreamPrintTest, SpiceMutualInductance) {
std::ofstream out(tmpfile_);
ASSERT_TRUE(out.is_open());
streamPrint(out, "L%d %s %s %.4e\n", 1, "n1", "n2", 1e-9);
streamPrint(out, "L%d %s %s %.4e\n", 2, "n3", "n4", 1e-9);
streamPrint(out, "K%d L%d L%d %.4f\n", 1, 1, 2, 0.5);
sta::print(out, "L{} {} {} {:.4e}\n", 1, "n1", "n2", 1e-9);
sta::print(out, "L{} {} {} {:.4e}\n", 2, "n3", "n4", 1e-9);
sta::print(out, "K{} L{} L{} {:.4f}\n", 1, 1, 2, 0.5);
out.close();
std::ifstream in(tmpfile_);
@ -1077,11 +1077,11 @@ TEST_F(StreamPrintTest, SpiceMutualInductance) {
EXPECT_NE(content.find("K1"), std::string::npos);
}
// streamPrint: SPICE probe statement
// print: SPICE probe statement
TEST_F(StreamPrintTest, SpiceProbeStatement) {
std::ofstream out(tmpfile_);
ASSERT_TRUE(out.is_open());
streamPrint(out, ".probe v(%s) v(%s) i(%s)\n",
sta::print(out, ".probe v({}) v({}) i({})\n",
"out", "in", "v_supply");
out.close();
@ -1091,12 +1091,12 @@ TEST_F(StreamPrintTest, SpiceProbeStatement) {
EXPECT_NE(line.find(".probe"), std::string::npos);
}
// streamPrint: SPICE with escaped characters
// print: SPICE with escaped characters
TEST_F(StreamPrintTest, SpiceEscapedChars) {
std::ofstream out(tmpfile_);
ASSERT_TRUE(out.is_open());
streamPrint(out, "* Node: %s\n", "top/sub/inst:pin");
streamPrint(out, "R1 %s %s %.4e\n",
sta::print(out, "* Node: {}\n", "top/sub/inst:pin");
sta::print(out, "R1 {} {} {:.4e}\n",
"top/sub/inst:pin", "top/sub/inst:int", 100.0);
out.close();
@ -1106,25 +1106,25 @@ TEST_F(StreamPrintTest, SpiceEscapedChars) {
EXPECT_NE(content.find("top/sub/inst:pin"), std::string::npos);
}
// streamPrint: SPICE full deck structure
// print: SPICE full deck structure
TEST_F(StreamPrintTest, SpiceFullDeck) {
std::ofstream out(tmpfile_);
ASSERT_TRUE(out.is_open());
streamPrint(out, "* Full SPICE deck\n");
streamPrint(out, ".include \"%s\"\n", "models.spice");
streamPrint(out, ".subckt top VDD VSS IN OUT\n");
streamPrint(out, "R1 IN n1 %.2e\n", 50.0);
streamPrint(out, "C1 n1 VSS %.4e\n", 1e-15);
streamPrint(out, "xinv VDD VSS n1 OUT INV_X1\n");
streamPrint(out, ".ends top\n");
streamPrint(out, "\n");
streamPrint(out, "xinst VDD VSS IN OUT top\n");
streamPrint(out, "vvdd VDD 0 %.3f\n", 1.8);
streamPrint(out, "vvss VSS 0 0\n");
streamPrint(out, "vin IN 0 PULSE(0 %.3f 0 %.3e %.3e %.3e %.3e)\n",
sta::print(out, "* Full SPICE deck\n");
sta::print(out, ".include \"{}\"\n", "models.spice");
sta::print(out, ".subckt top VDD VSS IN OUT\n");
sta::print(out, "R1 IN n1 {:.2e}\n", 50.0);
sta::print(out, "C1 n1 VSS {:.4e}\n", 1e-15);
sta::print(out, "xinv VDD VSS n1 OUT INV_X1\n");
sta::print(out, ".ends top\n");
sta::print(out, "\n");
sta::print(out, "xinst VDD VSS IN OUT top\n");
sta::print(out, "vvdd VDD 0 {:.3f}\n", 1.8);
sta::print(out, "vvss VSS 0 0\n");
sta::print(out, "vin IN 0 PULSE(0 {:.3f} 0 {:.3e} {:.3e} {:.3e} {:.3e})\n",
1.8, 20e-12, 20e-12, 500e-12, 1e-9);
streamPrint(out, ".tran %.3e %.3e\n", 1e-13, 2e-9);
streamPrint(out, ".end\n");
sta::print(out, ".tran {:.3e} {:.3e}\n", 1e-13, 2e-9);
sta::print(out, ".end\n");
out.close();
std::ifstream in(tmpfile_);
@ -1345,11 +1345,11 @@ TEST_F(XyceCsvTest, ReadCsvAlternatingSign) {
EXPECT_EQ(waveforms.size(), 1u);
}
// streamPrint: SPICE .end directive
// print: SPICE .end directive
TEST_F(StreamPrintTest, SpiceEndDirective) {
std::ofstream out(tmpfile_);
ASSERT_TRUE(out.is_open());
streamPrint(out, ".end\n");
sta::print(out, ".end\n");
out.close();
std::ifstream in(tmpfile_);
@ -1734,7 +1734,7 @@ TEST_F(SpiceDesignTest, InstanceCellName) {
EXPECT_STREQ(cell_name, "DFF_X1");
}
// Verify streamPrint with SPICE subcircuit instance format for design cells
// Verify print with SPICE subcircuit instance format for design cells
TEST_F(SpiceDesignTest, StreamPrintSubcktInst) {
char tmpl[] = "/tmp/sta_spice_subckt_inst_XXXXXX";
int fd = mkstemp(tmpl);
@ -1749,7 +1749,7 @@ TEST_F(SpiceDesignTest, StreamPrintSubcktInst) {
std::ofstream out(tmpl);
ASSERT_TRUE(out.is_open());
streamPrint(out, "x%s VDD VSS %s\n", inst_name, cell_name);
sta::print(out, "x{} VDD VSS {}\n", inst_name, cell_name);
out.close();
std::ifstream in(tmpl);

View File

@ -842,7 +842,7 @@ TEST(ReportTest, RedirectStringBasic)
{
Report report;
report.redirectStringBegin();
report.reportLineString("hello world");
report.reportLine("hello world");
const char *result = report.redirectStringEnd();
EXPECT_NE(result, nullptr);
std::string s(result);
@ -853,8 +853,8 @@ TEST(ReportTest, RedirectStringMultipleLines)
{
Report report;
report.redirectStringBegin();
report.reportLineString("line1");
report.reportLineString("line2");
report.reportLine("line1");
report.reportLine("line2");
const char *result = report.redirectStringEnd();
std::string s(result);
EXPECT_NE(s.find("line1"), std::string::npos);
@ -866,7 +866,7 @@ TEST(ReportTest, RedirectStringStdString)
Report report;
report.redirectStringBegin();
std::string line = "std string line";
report.reportLineString(line);
report.reportLine(line);
const char *result = report.redirectStringEnd();
std::string s(result);
EXPECT_NE(s.find("std string line"), std::string::npos);
@ -886,7 +886,7 @@ TEST(ReportTest, ReportLineFormatted)
{
Report report;
report.redirectStringBegin();
report.reportLine("value=%d", 42);
report.report("value={}", 42);
const char *result = report.redirectStringEnd();
std::string s(result);
EXPECT_NE(s.find("value=42"), std::string::npos);
@ -897,7 +897,7 @@ TEST(ReportTest, LogToFile)
Report report;
const char *tmpfile = "/tmp/test_report_log.txt";
report.logBegin(tmpfile);
report.reportLineString("log test line");
report.reportLine("log test line");
report.logEnd();
// Verify file was created with content
FILE *f = fopen(tmpfile, "r");
@ -924,7 +924,7 @@ TEST(ReportTest, RedirectFileBegin)
Report report;
const char *tmpfile = "/tmp/test_report_redirect.txt";
report.redirectFileBegin(tmpfile);
report.reportLineString("redirected line");
report.reportLine("redirected line");
report.redirectFileEnd();
FILE *f = fopen(tmpfile, "r");
@ -943,12 +943,12 @@ TEST(ReportTest, RedirectFileAppendBegin)
// Write first
report.redirectFileBegin(tmpfile);
report.reportLineString("first");
report.reportLine("first");
report.redirectFileEnd();
// Append
report.redirectFileAppendBegin(tmpfile);
report.reportLineString("second");
report.reportLine("second");
report.redirectFileEnd();
FILE *f = fopen(tmpfile, "r");
@ -997,7 +997,7 @@ TEST(ReportTest, WarnBasic)
{
Report report;
report.redirectStringBegin();
report.warn(100, "something bad %d", 42);
report.warn(100, "something bad {}", 42);
const char *result = report.redirectStringEnd();
std::string s(result);
EXPECT_NE(s.find("Warning 100:"), std::string::npos);
@ -1008,7 +1008,7 @@ TEST(ReportTest, FileWarn)
{
Report report;
report.redirectStringBegin();
report.fileWarn(101, "test.v", 10, "missing %s", "semicolon");
report.fileWarn(101, "test.v", 10, "missing {}", "semicolon");
const char *result = report.redirectStringEnd();
std::string s(result);
EXPECT_NE(s.find("Warning 101:"), std::string::npos);
@ -1022,7 +1022,7 @@ TEST(ReportTest, VwarnBasic)
Report report;
report.redirectStringBegin();
// Use vwarn indirectly via warn (vwarn is called by warn internals)
report.warn(102, "vwarn test %s", "value");
report.warn(102, "warn test {}", "value");
const char *result = report.redirectStringEnd();
std::string s(result);
EXPECT_NE(s.find("Warning 102:"), std::string::npos);
@ -1031,14 +1031,14 @@ TEST(ReportTest, VwarnBasic)
TEST(ReportTest, ErrorThrows)
{
Report report;
EXPECT_THROW(report.error(200, "error message %d", 1), ExceptionMsg);
EXPECT_THROW(report.error(200, "error message {}", 1), ExceptionMsg);
}
TEST(ReportTest, ErrorMessageContent)
{
Report report;
try {
report.error(200, "specific error %s", "info");
report.error(200, "specific error {}", "info");
FAIL() << "Expected ExceptionMsg";
} catch (const ExceptionMsg &e) {
std::string what = e.what();
@ -1056,7 +1056,7 @@ TEST(ReportTest, FileErrorContent)
{
Report report;
try {
report.fileError(201, "test.sdc", 5, "unexpected token %s", "foo");
report.fileError(201, "test.sdc", 5, "unexpected token {}", "foo");
FAIL() << "Expected ExceptionMsg";
} catch (const ExceptionMsg &e) {
std::string what = e.what();
@ -1146,7 +1146,7 @@ TEST(ReportTest, LogAndConsoleSimultaneous)
const char *logfile = "/tmp/test_report_logconsole.txt";
report.logBegin(logfile);
// Print to console (with log capturing)
report.reportLineString("dual output");
report.reportLine("dual output");
report.logEnd();
FILE *f = fopen(logfile, "r");
@ -1177,38 +1177,35 @@ TEST(StringUtilTest, StringCopyNull)
EXPECT_EQ(copy, nullptr);
}
TEST(StringUtilTest, StdstrPrint)
TEST(StringUtilTest, StaFormat)
{
std::string s = stdstrPrint("value=%d", 42);
std::string s = sta::format("value={}", 42);
EXPECT_EQ(s, "value=42");
}
TEST(StringUtilTest, StringPrintToStdString)
TEST(StringUtilTest, StaFormatToStdString)
{
std::string s;
stringPrint(s, "test %s %d", "abc", 123);
std::string s = sta::format("test {} {}", "abc", 123);
EXPECT_EQ(s, "test abc 123");
}
TEST(StringUtilTest, StringAppendToStdString)
TEST(StringUtilTest, StaFormatAppendToStdString)
{
std::string s = "prefix ";
stringAppend(s, "suffix %d", 1);
s += sta::format("suffix {}", 1);
EXPECT_EQ(s, "prefix suffix 1");
}
TEST(StringUtilTest, StringPrintAllocates)
TEST(StringUtilTest, StaFormatAllocates)
{
char *s = stringPrint("number %d", 99);
EXPECT_STREQ(s, "number 99");
stringDelete(s);
std::string s = sta::format("number {}", 99);
EXPECT_EQ(s, "number 99");
}
TEST(StringUtilTest, StringPrintTmp)
TEST(StringUtilTest, StaFormatTmp)
{
char *s = stringPrintTmp("tmp %d", 42);
EXPECT_STREQ(s, "tmp 42");
// tmp strings should not be freed by the caller
std::string s = sta::format("tmp {}", 42);
EXPECT_EQ(s, "tmp 42");
}
TEST(StringUtilTest, MakeTmpString)
@ -1229,7 +1226,8 @@ TEST(StringUtilTest, MakeTmpStringFromStdString)
TEST(StringUtilTest, IsTmpString)
{
char *tmp = stringPrintTmp("test");
char *tmp = makeTmpString(10);
strcpy(tmp, "test");
EXPECT_TRUE(isTmpString(tmp));
char local[] = "local";
@ -1370,7 +1368,7 @@ TEST(DebugTest, ReportLine)
debug.setLevel("test", 1);
// Redirect output to string to capture the debug line
report.redirectStringBegin();
debug.reportLine("test", "value %d", 42);
debug.report("test", "value {}", 42);
const char *result = report.redirectStringEnd();
std::string s(result);
EXPECT_NE(s.find("test"), std::string::npos);
@ -1378,125 +1376,91 @@ TEST(DebugTest, ReportLine)
}
////////////////////////////////////////////////////////////////
// Helper functions to test va_list variants of Report
// Tests for variadic template Report methods (warn, fileWarn, error, fileError)
////////////////////////////////////////////////////////////////
static void callVwarn(Report &report, int id, const char *fmt, ...)
{
va_list args;
va_start(args, fmt);
report.vwarn(id, fmt, args);
va_end(args);
}
static void callVfileWarn(Report &report, int id, const char *filename,
int line, const char *fmt, ...)
{
va_list args;
va_start(args, fmt);
report.vfileWarn(id, filename, line, fmt, args);
va_end(args);
}
static void callVerror(Report &report, int id, const char *fmt, ...)
{
va_list args;
va_start(args, fmt);
report.verror(id, fmt, args);
va_end(args);
}
static void callVfileError(Report &report, int id, const char *filename,
int line, const char *fmt, ...)
{
va_list args;
va_start(args, fmt);
report.vfileError(id, filename, line, fmt, args);
va_end(args);
}
TEST(ReportVaTest, VwarnBasic)
TEST(ReportVaTest, WarnBasic)
{
Report report;
report.redirectStringBegin();
callVwarn(report, 300, "vwarn message %d", 42);
report.warn(300, "warn message {}", 42);
const char *result = report.redirectStringEnd();
std::string s(result);
EXPECT_NE(s.find("Warning 300:"), std::string::npos);
EXPECT_NE(s.find("vwarn message 42"), std::string::npos);
EXPECT_NE(s.find("warn message 42"), std::string::npos);
}
TEST(ReportVaTest, VwarnSuppressed)
TEST(ReportVaTest, WarnSuppressed)
{
Report report;
report.suppressMsgId(300);
report.redirectStringBegin();
callVwarn(report, 300, "suppressed vwarn");
report.warn(300, "suppressed warn");
const char *result = report.redirectStringEnd();
std::string s(result);
EXPECT_EQ(s.find("suppressed vwarn"), std::string::npos);
EXPECT_EQ(s.find("suppressed warn"), std::string::npos);
}
TEST(ReportVaTest, VfileWarnBasic)
TEST(ReportVaTest, FileWarnBasic)
{
Report report;
report.redirectStringBegin();
callVfileWarn(report, 301, "test.v", 15, "vfile warn msg %s", "detail");
report.fileWarn(301, "test.v", 15, "file warn msg {}", "detail");
const char *result = report.redirectStringEnd();
std::string s(result);
EXPECT_NE(s.find("Warning 301:"), std::string::npos);
EXPECT_NE(s.find("test.v"), std::string::npos);
EXPECT_NE(s.find("line 15"), std::string::npos);
EXPECT_NE(s.find("vfile warn msg detail"), std::string::npos);
EXPECT_NE(s.find("file warn msg detail"), std::string::npos);
}
TEST(ReportVaTest, VfileWarnSuppressed)
TEST(ReportVaTest, FileWarnSuppressed)
{
Report report;
report.suppressMsgId(301);
report.redirectStringBegin();
callVfileWarn(report, 301, "test.v", 15, "suppressed vfile warn");
report.fileWarn(301, "test.v", 15, "suppressed file warn");
const char *result = report.redirectStringEnd();
std::string s(result);
EXPECT_EQ(s.find("suppressed vfile warn"), std::string::npos);
EXPECT_EQ(s.find("suppressed file warn"), std::string::npos);
}
TEST(ReportVaTest, VerrorThrows)
TEST(ReportVaTest, ErrorThrows)
{
Report report;
EXPECT_THROW(callVerror(report, 400, "verror msg %d", 99), ExceptionMsg);
EXPECT_THROW(report.error(400, "error msg {}", 99), ExceptionMsg);
}
TEST(ReportVaTest, VerrorContent)
TEST(ReportVaTest, ErrorContent)
{
Report report;
try {
callVerror(report, 400, "verror content %s", "test");
report.error(400, "error content {}", "test");
FAIL();
} catch (const ExceptionMsg &e) {
std::string what = e.what();
EXPECT_NE(what.find("verror content test"), std::string::npos);
EXPECT_NE(what.find("error content test"), std::string::npos);
}
}
TEST(ReportVaTest, VfileErrorThrows)
TEST(ReportVaTest, FileErrorThrows)
{
Report report;
EXPECT_THROW(callVfileError(report, 401, "myfile.sdc", 20, "vfile error msg"),
EXPECT_THROW(report.fileError(401, "myfile.sdc", 20, "file error msg"),
ExceptionMsg);
}
TEST(ReportVaTest, VfileErrorContent)
TEST(ReportVaTest, FileErrorContent)
{
Report report;
try {
callVfileError(report, 401, "myfile.sdc", 20, "vfile error %d", 42);
report.fileError(401, "myfile.sdc", 20, "file error {}", 42);
FAIL();
} catch (const ExceptionMsg &e) {
std::string what = e.what();
EXPECT_NE(what.find("myfile.sdc"), std::string::npos);
EXPECT_NE(what.find("line 20"), std::string::npos);
EXPECT_NE(what.find("vfile error 42"), std::string::npos);
EXPECT_NE(what.find("file error 42"), std::string::npos);
}
}
@ -1507,7 +1471,7 @@ TEST(ReportTest, LongReportLine)
report.redirectStringBegin();
// Create a string longer than the initial 1000 char buffer
std::string long_str(2000, 'x');
report.reportLine("%s", long_str.c_str());
report.reportLine(long_str);
const char *result = report.redirectStringEnd();
std::string s(result);
EXPECT_NE(s.find(long_str), std::string::npos);
@ -1518,7 +1482,7 @@ TEST(ReportTest, LongWarnLine)
Report report;
report.redirectStringBegin();
std::string long_str(2000, 'y');
report.warn(500, "%s", long_str.c_str());
report.warn(500, "{}", long_str);
const char *result = report.redirectStringEnd();
std::string s(result);
EXPECT_NE(s.find("Warning 500:"), std::string::npos);
@ -1526,23 +1490,23 @@ TEST(ReportTest, LongWarnLine)
}
// Test ExceptionMsg suppressed flag
TEST(ReportVaTest, VerrorSuppressedFlag)
TEST(ReportVaTest, ErrorSuppressedFlag)
{
Report report;
report.suppressMsgId(400);
try {
callVerror(report, 400, "suppressed verror");
report.error(400, "suppressed error");
FAIL();
} catch (const ExceptionMsg &e) {
EXPECT_TRUE(e.suppressed());
}
}
TEST(ReportVaTest, VerrorNotSuppressedFlag)
TEST(ReportVaTest, ErrorNotSuppressedFlag)
{
Report report;
try {
callVerror(report, 400, "not suppressed");
report.error(400, "not suppressed");
FAIL();
} catch (const ExceptionMsg &e) {
EXPECT_FALSE(e.suppressed());
@ -1820,19 +1784,18 @@ TEST(TransitionCovTest, RiseFallToString)
// Additional StringUtil coverage
////////////////////////////////////////////////////////////////
TEST(StringUtilCovTest, StringPrintArgs)
TEST(StringUtilCovTest, StaFormatArgs)
{
// stringPrintArgs is called by stringPrint internally; test via stringPrint
char *s = stringPrint("args test %d %s", 42, "hello");
EXPECT_STREQ(s, "args test 42 hello");
stringDelete(s);
// Test sta::format with multiple arguments
std::string s = sta::format("args test {} {}", 42, "hello");
EXPECT_EQ(s, "args test 42 hello");
}
// stringDeleteCheck (only for non-tmp strings - should not crash)
TEST(StringUtilCovTest, StringDeleteCheckNonTmp)
{
ASSERT_NO_THROW(( [&](){
char *s = stringPrint("not tmp");
char *s = stringCopy("not tmp");
// This should not crash or exit; it's not a tmp string
stringDeleteCheck(s);
stringDelete(s);
@ -1849,23 +1812,21 @@ TEST(StringUtilCovTest, IsTmpStringHeap)
delete [] s;
}
// Long stringPrintTmp (forces buffer growth)
TEST(StringUtilCovTest, LongStringPrintTmp)
// Long sta::format string
TEST(StringUtilCovTest, LongStaFormat)
{
std::string long_str(500, 'z');
char *tmp = stringPrintTmp("%s", long_str.c_str());
EXPECT_STREQ(tmp, long_str.c_str());
std::string result = sta::format("{}", long_str);
EXPECT_EQ(result, long_str);
}
// stringAppend (char* version) inline in header
TEST(StringUtilCovTest, StringAppendCharPtr)
// std::string append
TEST(StringUtilCovTest, StringAppendStd)
{
char buf[100];
char *p = buf;
stringAppend(p, "hello");
stringAppend(p, " world");
*p = '\0';
EXPECT_STREQ(buf, "hello world");
std::string s;
s += "hello";
s += " world";
EXPECT_EQ(s, "hello world");
}
////////////////////////////////////////////////////////////////
@ -1886,7 +1847,7 @@ TEST(ReportCovTest, ReportLineStringEmpty)
{
Report report;
report.redirectStringBegin();
report.reportLineString("");
report.reportLine("");
const char *result = report.redirectStringEnd();
std::string s(result);
// Empty line should just have a newline
@ -1899,7 +1860,7 @@ TEST(ReportCovTest, ReportLineLongFormatted)
Report report;
report.redirectStringBegin();
std::string fmt_str(2000, 'a');
report.reportLine("%s end", fmt_str.c_str());
report.report("{} end", fmt_str);
const char *result = report.redirectStringEnd();
std::string s(result);
EXPECT_NE(s.find(fmt_str), std::string::npos);
@ -1914,12 +1875,12 @@ TEST(ReportCovTest, ReportRedirectSequence)
// Redirect to file first
report.redirectFileBegin(tmpfile);
report.reportLineString("file output");
report.reportLine("file output");
report.redirectFileEnd();
// Then redirect to string
report.redirectStringBegin();
report.reportLineString("string output");
report.reportLine("string output");
const char *result = report.redirectStringEnd();
std::string s(result);
EXPECT_NE(s.find("string output"), std::string::npos);
@ -1935,7 +1896,7 @@ TEST(ReportCovTest, LogDuringStringRedirect)
report.logBegin(logfile);
report.redirectStringBegin();
report.reportLineString("string only");
report.reportLine("string only");
const char *result = report.redirectStringEnd();
report.logEnd();
@ -1950,7 +1911,7 @@ TEST(ReportCovTest, WarnWithLongMessage)
Report report;
report.redirectStringBegin();
std::string long_msg(1500, 'w');
report.warn(999, "prefix %s suffix", long_msg.c_str());
report.warn(999, "prefix {} suffix", long_msg);
const char *result = report.redirectStringEnd();
std::string s(result);
EXPECT_NE(s.find("Warning 999:"), std::string::npos);
@ -1964,7 +1925,7 @@ TEST(ReportCovTest, FileWarnLongMessage)
Report report;
report.redirectStringBegin();
std::string long_msg(1500, 'f');
report.fileWarn(998, "bigfile.v", 100, "detail: %s", long_msg.c_str());
report.fileWarn(998, "bigfile.v", 100, "detail: {}", long_msg);
const char *result = report.redirectStringEnd();
std::string s(result);
EXPECT_NE(s.find("Warning 998:"), std::string::npos);
@ -1978,7 +1939,7 @@ TEST(ReportCovTest, ErrorLongMessage)
Report report;
std::string long_msg(1500, 'e');
try {
report.error(997, "err: %s", long_msg.c_str());
report.error(997, "err: {}", long_msg);
FAIL();
} catch (const ExceptionMsg &e) {
std::string what = e.what();
@ -1993,7 +1954,7 @@ TEST(ReportCovTest, FileErrorLongMessage)
Report report;
std::string long_msg(1500, 'x');
try {
report.fileError(996, "big.sdc", 50, "detail: %s", long_msg.c_str());
report.fileError(996, "big.sdc", 50, "detail: {}", long_msg);
FAIL();
} catch (const ExceptionMsg &e) {
std::string what = e.what();
@ -2396,14 +2357,14 @@ TEST(ReportCovTest, RedirectStringPrintMultiple)
EXPECT_STREQ(result, "abcdefghi");
}
// Test Report printToBuffer with va_list
// Covers: Report::printToBuffer(const char*, va_list)
TEST(ReportCovTest, PrintToBufferViaReportLine)
// Test Report::report with format args
// Covers: Report::report(std::string_view, Args&&...)
TEST(ReportCovTest, ReportFormatViaReport)
{
Report report;
report.redirectStringBegin();
// reportLine calls printToBuffer internally
report.reportLine("value=%d", 42);
// report() uses std::format style formatting
report.report("value={}", 42);
const char *result = report.redirectStringEnd();
std::string s(result);
EXPECT_NE(s.find("value=42"), std::string::npos);
@ -2414,7 +2375,7 @@ TEST(ReportCovTest, ReportLineString)
{
Report report;
report.redirectStringBegin();
report.reportLineString("test line");
report.reportLine("test line");
const char *result = report.redirectStringEnd();
std::string s(result);
EXPECT_NE(s.find("test line"), std::string::npos);
@ -2426,7 +2387,7 @@ TEST(ReportCovTest, ReportLineStringStd)
Report report;
report.redirectStringBegin();
std::string line = "std string line";
report.reportLineString(line);
report.reportLine(line);
const char *result = report.redirectStringEnd();
std::string s(result);
EXPECT_NE(s.find("std string line"), std::string::npos);
@ -2461,7 +2422,7 @@ TEST(ReportStdCovTest, PrintErrorConsoleViaWarn)
ASSERT_NO_THROW(( [&](){
Report *report = makeReportStd();
// warn uses printErrorConsole path
report->warn(9999, "test warning %d", 42);
report->warn(9999, "test warning {}", 42);
delete report;
}() ));
@ -2496,7 +2457,7 @@ TEST(ReportCovTest, LogBeginEnd)
Report report;
const char *logfile = "/tmp/sta_test_log_r5.log";
report.logBegin(logfile);
report.reportLine("log line %d", 1);
report.report("log line {}", 1);
report.logEnd();
// Verify log file exists and has content
std::ifstream in(logfile);
@ -2590,7 +2551,7 @@ TEST(GzStreamTest, GzStreamWriteRead)
TEST(ReportCovTest, ErrorThrowsException)
{
Report report;
EXPECT_THROW(report.error(1, "test error %s", "msg"), ExceptionMsg);
EXPECT_THROW(report.error(1, "test error {}", "msg"), ExceptionMsg);
}
// Test Report fileError throws ExceptionMsg
@ -2618,7 +2579,7 @@ TEST(ReportCovTest, ReportErrorFormatting)
{
Report report;
try {
report.error(999, "critical format test %s %d", "value", 42);
report.error(999, "critical format test {} {}", "value", 42);
FAIL();
} catch (const ExceptionMsg &e) {
std::string what = e.what();
@ -2632,7 +2593,7 @@ TEST(ReportCovTest, ReportFileErrorFormatting)
{
Report report;
try {
report.fileError(998, "critical.v", 42, "critical file error %s", "detail");
report.fileError(998, "critical.v", 42, "critical file error {}", "detail");
FAIL();
} catch (const ExceptionMsg &e) {
std::string what = e.what();
@ -2660,7 +2621,7 @@ TEST(ReportCovTest, ReportStdCreation)
ASSERT_NE(report, nullptr);
// Verify it works as a Report
report->redirectStringBegin();
report->reportLineString("test via ReportStd");
report->reportLine("test via ReportStd");
const char *result = report->redirectStringEnd();
EXPECT_NE(result, nullptr);
std::string s(result);
@ -2675,7 +2636,7 @@ TEST(ReportCovTest, ReportStdWarn)
Report *report = makeReportStd();
ASSERT_NE(report, nullptr);
report->redirectStringBegin();
report->warn(700, "reportstd warn test %d", 99);
report->warn(700, "reportstd warn test {}", 99);
const char *result = report->redirectStringEnd();
std::string s(result);
EXPECT_NE(s.find("Warning 700:"), std::string::npos);
@ -2701,7 +2662,7 @@ TEST(ReportCovTest, ReportPrintToBufferLong)
report.redirectStringBegin();
// Create a string exceeding the initial 1000-char buffer
std::string long_str(3000, 'Z');
report.reportLine("%s", long_str.c_str());
report.reportLine(long_str);
const char *result = report.redirectStringEnd();
std::string s(result);
EXPECT_NE(s.find(long_str), std::string::npos);
@ -2780,7 +2741,7 @@ TEST(ReportCovTest, WarnLongMessage)
Report report;
report.redirectStringBegin();
std::string long_msg(5000, 'W');
report.warn(800, "%s", long_msg.c_str());
report.warn(800, "{}", long_msg);
const char *result = report.redirectStringEnd();
std::string s(result);
EXPECT_NE(s.find("Warning 800:"), std::string::npos);
@ -2794,7 +2755,7 @@ TEST(ReportCovTest, FileWarnLongMessage2)
Report report;
report.redirectStringBegin();
std::string long_msg(2000, 'F');
report.fileWarn(801, "long_file.v", 999, "%s", long_msg.c_str());
report.fileWarn(801, "long_file.v", 999, "{}", long_msg);
const char *result = report.redirectStringEnd();
std::string s(result);
EXPECT_NE(s.find("Warning 801:"), std::string::npos);
@ -2841,13 +2802,13 @@ TEST(ReportCovTest, ErrorNotSuppressed)
// because it calls abort(). Instead, test printToBuffer and
// redirectStringPrint paths.
// Test Report::printToBuffer via reportLine
// Covers: Report::printToBuffer(const char*, va_list)
TEST(ReportCovTest, PrintToBufferViaReportLine2)
// Test Report::report with multiple format args
// Covers: Report::report(std::string_view, Args&&...)
TEST(ReportCovTest, ReportFormatViaReport2)
{
Report report;
report.redirectStringBegin();
report.reportLine("test %d %s %.2f", 42, "hello", 3.14);
report.report("test {} {} {:.2f}", 42, "hello", 3.14);
const char *result = report.redirectStringEnd();
std::string s(result);
EXPECT_NE(s.find("42"), std::string::npos);
@ -2878,23 +2839,23 @@ TEST(ReportCovTest, RedirectStringPrintLong)
Report report;
report.redirectStringBegin();
std::string long_str(5000, 'X');
report.reportLineString(long_str);
report.reportLine(long_str);
const char *result = report.redirectStringEnd();
std::string s(result);
EXPECT_NE(s.find("XXXXX"), std::string::npos);
}
// Test Report::printToBuffer with various format strings
// Covers: Report::printToBuffer(const char*, va_list)
TEST(ReportCovTest, PrintToBufferFormats)
// Test Report::report with various format strings
// Covers: Report::report(std::string_view, Args&&...)
TEST(ReportCovTest, ReportFormatVariousFormats)
{
Report report;
report.redirectStringBegin();
// Exercise various printf formats
report.reportLine("int: %d", 12345);
report.reportLine("float: %f", 1.5);
report.reportLine("string: %s", "test_string");
report.reportLine("hex: %x", 0xFF);
// Exercise various std::format specifiers
report.report("int: {}", 12345);
report.report("float: {}", 1.5);
report.report("string: {}", "test_string");
report.report("hex: {:x}", 0xFF);
const char *result = report.redirectStringEnd();
std::string s(result);
EXPECT_NE(s.find("12345"), std::string::npos);
@ -2908,9 +2869,9 @@ TEST(ReportStdCovTest, ReportStdConstructorAndPrint)
Report *report = makeReportStd();
ASSERT_NE(report, nullptr);
// warn() calls printErrorConsole
report->warn(10001, "R8 test warning %s", "message");
report->warn(10001, "R8 test warning {}", "message");
// reportLine calls printConsole
report->reportLine("R8 test print %d", 42);
report->report("R8 test print {}", 42);
delete report;
}
@ -2920,7 +2881,7 @@ TEST(ReportStdCovTest, PrintErrorConsoleViaFileWarn)
{
Report *report = makeReportStd();
ASSERT_NE(report, nullptr);
report->fileWarn(10002, "test_file.v", 100, "file warning %d", 99);
report->fileWarn(10002, "test_file.v", 100, "file warning {}", 99);
delete report;
}
@ -2930,7 +2891,7 @@ TEST(ReportCovTest, PrintToBufferEmpty)
{
Report report;
report.redirectStringBegin();
report.reportLine("%s", "");
report.reportLine("");
const char *result = report.redirectStringEnd();
// Should have at least a newline
EXPECT_NE(result, nullptr);
@ -2942,7 +2903,7 @@ TEST(ReportCovTest, WarnWithRedirect)
{
Report report;
report.redirectStringBegin();
report.warn(10003, "warning %d: %s", 1, "test");
report.warn(10003, "warning {}: {}", 1, "test");
const char *result = report.redirectStringEnd();
std::string s(result);
EXPECT_NE(s.find("Warning"), std::string::npos);
@ -2955,7 +2916,7 @@ TEST(ReportCovTest, FileWarnWithRedirect)
{
Report report;
report.redirectStringBegin();
report.fileWarn(10004, "myfile.tcl", 42, "file issue %s", "here");
report.fileWarn(10004, "myfile.tcl", 42, "file issue {}", "here");
const char *result = report.redirectStringEnd();
std::string s(result);
EXPECT_NE(s.find("Warning"), std::string::npos);

View File

@ -51,31 +51,31 @@ TEST_F(VerilogTest, InstanceWithSlash) {
// Verilog to STA conversions
TEST_F(VerilogTest, ModuleToSta) {
std::string name = "top";
std::string result = moduleVerilogToSta(&name);
std::string result = moduleVerilogToSta(name);
EXPECT_EQ(result, "top");
}
TEST_F(VerilogTest, InstanceToSta) {
std::string name = "inst1";
std::string result = instanceVerilogToSta(&name);
std::string result = instanceVerilogToSta(name);
EXPECT_EQ(result, "inst1");
}
TEST_F(VerilogTest, EscapedToSta) {
std::string name = "\\esc_name ";
std::string result = instanceVerilogToSta(&name);
std::string result = instanceVerilogToSta(name);
EXPECT_FALSE(result.empty());
}
TEST_F(VerilogTest, NetToSta) {
std::string name = "net1";
std::string result = netVerilogToSta(&name);
std::string result = netVerilogToSta(name);
EXPECT_EQ(result, "net1");
}
TEST_F(VerilogTest, PortToSta) {
std::string name = "port_a";
std::string result = portVerilogToSta(&name);
std::string result = portVerilogToSta(name);
EXPECT_EQ(result, "port_a");
}
@ -165,7 +165,7 @@ TEST_F(VerilogTest, CellEscapePrefix) {
// Verilog-to-STA conversions with escaped names
TEST_F(VerilogTest, EscapedModuleToSta) {
std::string name = "\\my/module ";
std::string result = moduleVerilogToSta(&name);
std::string result = moduleVerilogToSta(name);
// Should strip leading \ and trailing space, but escape special chars
EXPECT_FALSE(result.empty());
EXPECT_NE(result.front(), '\\');
@ -173,38 +173,38 @@ TEST_F(VerilogTest, EscapedModuleToSta) {
TEST_F(VerilogTest, EscapedNetToSta) {
std::string name = "\\net[0] ";
std::string result = netVerilogToSta(&name);
std::string result = netVerilogToSta(name);
EXPECT_FALSE(result.empty());
}
TEST_F(VerilogTest, EscapedPortToSta) {
std::string name = "\\port/a ";
std::string result = portVerilogToSta(&name);
std::string result = portVerilogToSta(name);
EXPECT_FALSE(result.empty());
}
TEST_F(VerilogTest, PlainModuleToSta) {
std::string name = "top_module";
std::string result = moduleVerilogToSta(&name);
std::string result = moduleVerilogToSta(name);
EXPECT_EQ(result, "top_module");
}
TEST_F(VerilogTest, PlainNetToSta) {
std::string name = "wire1";
std::string result = netVerilogToSta(&name);
std::string result = netVerilogToSta(name);
EXPECT_EQ(result, "wire1");
}
TEST_F(VerilogTest, PlainPortToSta) {
std::string name = "port_b";
std::string result = portVerilogToSta(&name);
std::string result = portVerilogToSta(name);
EXPECT_EQ(result, "port_b");
}
// Escaped name with brackets (bus notation)
TEST_F(VerilogTest, EscapedInstanceWithBracket) {
std::string name = "\\inst[0] ";
std::string result = instanceVerilogToSta(&name);
std::string result = instanceVerilogToSta(name);
EXPECT_FALSE(result.empty());
// Brackets should be escaped in STA name
EXPECT_NE(result.find("\\["), std::string::npos);
@ -213,7 +213,7 @@ TEST_F(VerilogTest, EscapedInstanceWithBracket) {
// Escaped name with divider
TEST_F(VerilogTest, EscapedInstanceWithDivider) {
std::string name = "\\u1/u2 ";
std::string result = instanceVerilogToSta(&name);
std::string result = instanceVerilogToSta(name);
EXPECT_FALSE(result.empty());
// Divider should be escaped in STA name
EXPECT_NE(result.find("\\/"), std::string::npos);
@ -222,14 +222,14 @@ TEST_F(VerilogTest, EscapedInstanceWithDivider) {
// Escaped name with escape character
TEST_F(VerilogTest, EscapedNameWithEscapeChar) {
std::string name = "\\esc\\val ";
std::string result = instanceVerilogToSta(&name);
std::string result = instanceVerilogToSta(name);
EXPECT_FALSE(result.empty());
}
// Escaped name without trailing space
TEST_F(VerilogTest, EscapedNoTrailingSpace) {
std::string name = "\\esc_name";
std::string result = instanceVerilogToSta(&name);
std::string result = instanceVerilogToSta(name);
EXPECT_FALSE(result.empty());
}
@ -303,7 +303,7 @@ TEST_F(VerilogTest, InstanceWithAt) {
// verilogToSta: escaped name with multiple special chars
TEST_F(VerilogTest, EscapedMultipleSpecial) {
std::string name = "\\u1/u2[3] ";
std::string result = instanceVerilogToSta(&name);
std::string result = instanceVerilogToSta(name);
EXPECT_FALSE(result.empty());
// Both / and [ and ] should be escaped
EXPECT_NE(result.find("\\/"), std::string::npos);
@ -314,7 +314,7 @@ TEST_F(VerilogTest, EscapedMultipleSpecial) {
// verilogToSta: escaped name with backslash inside
TEST_F(VerilogTest, EscapedWithBackslash) {
std::string name = "\\a\\b ";
std::string result = instanceVerilogToSta(&name);
std::string result = instanceVerilogToSta(name);
EXPECT_FALSE(result.empty());
// The backslash inside should be escaped as \\
EXPECT_NE(result.find("\\\\"), std::string::npos);
@ -342,25 +342,25 @@ TEST_F(VerilogTest, CellDoubleBackslash) {
// netVerilogToSta with plain name
TEST_F(VerilogTest, NetToStaPlain) {
std::string name = "simple_wire";
EXPECT_EQ(netVerilogToSta(&name), "simple_wire");
EXPECT_EQ(netVerilogToSta(name), "simple_wire");
}
// portVerilogToSta with plain name
TEST_F(VerilogTest, PortToStaPlain) {
std::string name = "port_clk";
EXPECT_EQ(portVerilogToSta(&name), "port_clk");
EXPECT_EQ(portVerilogToSta(name), "port_clk");
}
// moduleVerilogToSta plain
TEST_F(VerilogTest, ModuleToStaPlain) {
std::string name = "mod_top";
EXPECT_EQ(moduleVerilogToSta(&name), "mod_top");
EXPECT_EQ(moduleVerilogToSta(name), "mod_top");
}
// verilogToSta: escaped name without trailing space
TEST_F(VerilogTest, EscapedNoSpace) {
std::string name = "\\name";
std::string result = instanceVerilogToSta(&name);
std::string result = instanceVerilogToSta(name);
EXPECT_FALSE(result.empty());
// "ame" (without leading 'n' because 'n' is first char after \ which is stripped)
// Actually: ignoring leading '\', copy the rest. "name" has no trailing space.
@ -421,14 +421,14 @@ TEST_F(VerilogTest, InstanceWithBrackets) {
// verilogToSta: empty escaped name
TEST_F(VerilogTest, EmptyEscapedName) {
std::string name = "\\";
std::string result = instanceVerilogToSta(&name);
std::string result = instanceVerilogToSta(name);
EXPECT_TRUE(result.empty());
}
// verilogToSta: escaped name with only space
TEST_F(VerilogTest, EscapedOnlySpace) {
std::string name = "\\ ";
std::string result = instanceVerilogToSta(&name);
std::string result = instanceVerilogToSta(name);
EXPECT_TRUE(result.empty());
}
@ -454,28 +454,28 @@ TEST_F(VerilogTest, CellOnlySpecialChars) {
// instanceVerilogToSta: plain unescaped name
TEST_F(VerilogTest, UnescapedInstance) {
std::string name = "plain_inst";
std::string result = instanceVerilogToSta(&name);
std::string result = instanceVerilogToSta(name);
EXPECT_EQ(result, "plain_inst");
}
// netVerilogToSta: escaped name with bus notation
TEST_F(VerilogTest, EscapedNetBus) {
std::string name = "\\data[7:0] ";
std::string result = netVerilogToSta(&name);
std::string result = netVerilogToSta(name);
EXPECT_FALSE(result.empty());
}
// moduleVerilogToSta: escaped module name
TEST_F(VerilogTest, EscapedModule) {
std::string name = "\\mod/special ";
std::string result = moduleVerilogToSta(&name);
std::string result = moduleVerilogToSta(name);
EXPECT_FALSE(result.empty());
}
// portVerilogToSta: escaped port name
TEST_F(VerilogTest, EscapedPort) {
std::string name = "\\port$gen ";
std::string result = portVerilogToSta(&name);
std::string result = portVerilogToSta(name);
EXPECT_FALSE(result.empty());
}
@ -521,7 +521,7 @@ TEST_F(VerilogTest, PortWithPlus) {
// instanceVerilogToSta: escaped name with various special chars
TEST_F(VerilogTest, EscapedInstanceComplex) {
std::string name = "\\inst.a/b[c] ";
std::string result = instanceVerilogToSta(&name);
std::string result = instanceVerilogToSta(name);
EXPECT_FALSE(result.empty());
// The result should contain the original special characters in some form
EXPECT_GT(result.size(), 3u);
@ -530,21 +530,21 @@ TEST_F(VerilogTest, EscapedInstanceComplex) {
// netVerilogToSta: plain net with underscore
TEST_F(VerilogTest, PlainNetUnderscore) {
std::string name = "_net_wire_";
std::string result = netVerilogToSta(&name);
std::string result = netVerilogToSta(name);
EXPECT_EQ(result, "_net_wire_");
}
// portVerilogToSta: plain port with numbers
TEST_F(VerilogTest, PlainPortNumeric) {
std::string name = "port_123";
std::string result = portVerilogToSta(&name);
std::string result = portVerilogToSta(name);
EXPECT_EQ(result, "port_123");
}
// moduleVerilogToSta: plain module with mixed case
TEST_F(VerilogTest, PlainModuleMixedCase) {
std::string name = "MyModule_V2";
std::string result = moduleVerilogToSta(&name);
std::string result = moduleVerilogToSta(name);
EXPECT_EQ(result, "MyModule_V2");
}
@ -575,14 +575,14 @@ TEST_F(VerilogTest, PortWithPipe) {
// instanceVerilogToSta: escaped name without trailing space (edge case)
TEST_F(VerilogTest, EscapedNoTrailingSpaceComplex) {
std::string name = "\\inst/a[0]";
std::string result = instanceVerilogToSta(&name);
std::string result = instanceVerilogToSta(name);
EXPECT_FALSE(result.empty());
}
// cellVerilogName: very long name
TEST_F(VerilogTest, CellLongName) {
std::string long_name(200, 'a');
std::string result = cellVerilogName(long_name.c_str());
std::string result = cellVerilogName(long_name);
EXPECT_EQ(result, long_name);
}
@ -590,7 +590,7 @@ TEST_F(VerilogTest, CellLongName) {
TEST_F(VerilogTest, CellLongEscapedName) {
std::string long_name(200, 'a');
long_name[100] = '/';
std::string result = cellVerilogName(long_name.c_str());
std::string result = cellVerilogName(long_name);
EXPECT_EQ(result.front(), '\\');
EXPECT_EQ(result.back(), ' ');
}
@ -1014,21 +1014,21 @@ TEST_F(VerilogTest, InstanceWithLessThan) {
// VerilogToSta: net with bus range
TEST_F(VerilogTest, EscapedNetRange) {
std::string name = "\\data[7:0] ";
std::string result = netVerilogToSta(&name);
std::string result = netVerilogToSta(name);
EXPECT_FALSE(result.empty());
}
// VerilogToSta: module with digit prefix
TEST_F(VerilogTest, ModuleDigitPrefix) {
std::string name = "123module";
std::string result = moduleVerilogToSta(&name);
std::string result = moduleVerilogToSta(name);
EXPECT_EQ(result, "123module");
}
// portVerilogToSta: escaped
TEST_F(VerilogTest, EscapedPortComplex) {
std::string name = "\\port.a[0]/b ";
std::string result = portVerilogToSta(&name);
std::string result = portVerilogToSta(name);
EXPECT_FALSE(result.empty());
}
@ -1036,7 +1036,7 @@ TEST_F(VerilogTest, EscapedPortComplex) {
TEST_F(VerilogTest, RoundTripSpecialCell) {
// STA name with escaped bracket
std::string sta_name = "cell\\[0\\]";
std::string verilog = cellVerilogName(sta_name.c_str());
std::string verilog = cellVerilogName(sta_name);
EXPECT_FALSE(verilog.empty());
}
@ -1427,25 +1427,25 @@ TEST_F(VerilogTest, PortNameWithBacktick) {
// Verilog to STA conversions: edge cases
TEST_F(VerilogTest, EscapedInstanceOnlyBrackets) {
std::string name = "\\[0] ";
std::string result = instanceVerilogToSta(&name);
std::string result = instanceVerilogToSta(name);
EXPECT_FALSE(result.empty());
}
TEST_F(VerilogTest, EscapedNetOnlySlash) {
std::string name = "\\/ ";
std::string result = netVerilogToSta(&name);
std::string result = netVerilogToSta(name);
EXPECT_FALSE(result.empty());
}
TEST_F(VerilogTest, ModuleToStaEscapedComplex) {
std::string name = "\\mod.a/b[1] ";
std::string result = moduleVerilogToSta(&name);
std::string result = moduleVerilogToSta(name);
EXPECT_FALSE(result.empty());
}
TEST_F(VerilogTest, PortToStaEscapedBracket) {
std::string name = "\\port[3] ";
std::string result = portVerilogToSta(&name);
std::string result = portVerilogToSta(name);
EXPECT_FALSE(result.empty());
}
@ -1727,35 +1727,35 @@ TEST_F(VerilogTest, PortNameMixedSpecial) {
// Round-trip tests: staToVerilog -> verilogToSta should preserve identity for simple names
TEST_F(VerilogTest, RoundTripSimpleName) {
std::string sta_name = "simple_wire";
std::string verilog = netVerilogName(sta_name.c_str());
std::string back = netVerilogToSta(&verilog);
std::string verilog = netVerilogName(sta_name);
std::string back = netVerilogToSta(verilog);
EXPECT_EQ(back, sta_name);
}
TEST_F(VerilogTest, RoundTripSimpleCell) {
std::string sta_name = "my_cell_123";
std::string verilog = cellVerilogName(sta_name.c_str());
std::string verilog = cellVerilogName(sta_name);
EXPECT_EQ(verilog, sta_name); // no escaping needed
}
TEST_F(VerilogTest, RoundTripSimpleInstance) {
std::string sta_name = "u1_abc";
std::string verilog = instanceVerilogName(sta_name.c_str());
std::string back = instanceVerilogToSta(&verilog);
std::string verilog = instanceVerilogName(sta_name);
std::string back = instanceVerilogToSta(verilog);
EXPECT_EQ(back, sta_name);
}
TEST_F(VerilogTest, RoundTripSimplePort) {
std::string sta_name = "clk_in";
std::string verilog = portVerilogName(sta_name.c_str());
std::string back = portVerilogToSta(&verilog);
std::string verilog = portVerilogName(sta_name);
std::string back = portVerilogToSta(verilog);
EXPECT_EQ(back, sta_name);
}
TEST_F(VerilogTest, RoundTripSimpleModule) {
std::string sta_name = "top_module";
std::string verilog = cellVerilogName(sta_name.c_str());
std::string back = moduleVerilogToSta(&verilog);
std::string verilog = cellVerilogName(sta_name);
std::string back = moduleVerilogToSta(verilog);
EXPECT_EQ(back, sta_name);
}
@ -1802,7 +1802,7 @@ TEST_F(VerilogTest, DclBusPortName) {
TEST_F(VerilogTest, NetBusRangeConversion) {
// Verilog bus notation should convert properly
std::string verilog_name = "data[3]";
std::string net_name = netVerilogToSta(&verilog_name);
std::string net_name = netVerilogToSta(verilog_name);
EXPECT_FALSE(net_name.empty());
}
@ -1838,7 +1838,7 @@ TEST_F(VerilogTest, EmptyNames) {
// Covers: netVerilogToSta with bus notation
TEST_F(VerilogTest, BusVerilogToSta) {
std::string verilog_name = "bus[7:0]";
std::string bus = netVerilogToSta(&verilog_name);
std::string bus = netVerilogToSta(verilog_name);
EXPECT_FALSE(bus.empty());
}
@ -1846,7 +1846,7 @@ TEST_F(VerilogTest, BusVerilogToSta) {
// Covers: instanceVerilogToSta with escaped name
TEST_F(VerilogTest, EscapedInstanceToSta) {
std::string verilog_name = "\\inst[0] ";
std::string name = instanceVerilogToSta(&verilog_name);
std::string name = instanceVerilogToSta(verilog_name);
EXPECT_FALSE(name.empty());
}
@ -1854,10 +1854,10 @@ TEST_F(VerilogTest, EscapedInstanceToSta) {
// Covers: netVerilogToSta bracket handling
TEST_F(VerilogTest, NetVerilogToStaBrackets) {
std::string name1 = "wire1";
std::string net1 = netVerilogToSta(&name1);
std::string net1 = netVerilogToSta(name1);
EXPECT_EQ(net1, "wire1");
std::string name2 = "bus[0]";
std::string net2 = netVerilogToSta(&name2);
std::string net2 = netVerilogToSta(name2);
EXPECT_FALSE(net2.empty());
}
@ -1893,7 +1893,7 @@ TEST_F(VerilogTest, PortHierSep) {
// Covers: instanceVerilogToSta simple case
TEST_F(VerilogTest, InstanceToStaSimple) {
std::string verilog_name = "u1";
std::string name = instanceVerilogToSta(&verilog_name);
std::string name = instanceVerilogToSta(verilog_name);
EXPECT_EQ(name, "u1");
}