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 <gtest/gtest.h>
#include "DelayFloat.hh" #include "Delay.hh"
#include "DelayScalar.hh"
#include "StaState.hh"
#include "MinMax.hh" #include "MinMax.hh"
#include "Graph.hh" #include "Graph.hh"
#include "Transition.hh" #include "Transition.hh"
@ -9,38 +11,55 @@
namespace sta { 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 { class DelayFloatTest : public ::testing::Test {
protected: protected:
void SetUp() override { void SetUp() override {
initDelayConstants(); 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) { TEST_F(DelayFloatTest, DelayZero) {
EXPECT_TRUE(delayZero(0.0f)); EXPECT_TRUE(delayZero(Delay(0.0f), sta()));
EXPECT_TRUE(delayZero(delay_zero)); EXPECT_TRUE(delayZero(delay_zero, sta()));
EXPECT_FALSE(delayZero(1.0f)); EXPECT_FALSE(delayZero(Delay(1.0f), sta()));
EXPECT_FALSE(delayZero(-1.0f)); EXPECT_FALSE(delayZero(Delay(-1.0f), sta()));
} }
TEST_F(DelayFloatTest, DelayEqual) { TEST_F(DelayFloatTest, DelayEqual) {
EXPECT_TRUE(delayEqual(1.0f, 1.0f)); EXPECT_TRUE(delayEqual(Delay(1.0f), Delay(1.0f), sta()));
EXPECT_TRUE(delayEqual(0.0f, 0.0f)); EXPECT_TRUE(delayEqual(Delay(0.0f), Delay(0.0f), sta()));
EXPECT_FALSE(delayEqual(1.0f, 2.0f)); EXPECT_FALSE(delayEqual(Delay(1.0f), Delay(2.0f), sta()));
} }
TEST_F(DelayFloatTest, DelayInf) { TEST_F(DelayFloatTest, DelayInf) {
// delayInf checks against STA's INF constant, not IEEE infinity // delayInf checks against STA's INF constant, not IEEE infinity
EXPECT_TRUE(delayInf(INF)); EXPECT_TRUE(delayInf(Delay(INF), sta()));
EXPECT_TRUE(delayInf(-INF)); EXPECT_TRUE(delayInf(Delay(-INF), sta()));
EXPECT_FALSE(delayInf(0.0f)); EXPECT_FALSE(delayInf(Delay(0.0f), sta()));
EXPECT_FALSE(delayInf(1e10f)); EXPECT_FALSE(delayInf(Delay(1e10f), sta()));
} }
TEST_F(DelayFloatTest, DelayLess) { TEST_F(DelayFloatTest, DelayLess) {
EXPECT_TRUE(delayLess(1.0f, 2.0f, nullptr)); EXPECT_TRUE(delayLess(Delay(1.0f), Delay(2.0f), sta()));
EXPECT_FALSE(delayLess(2.0f, 1.0f, nullptr)); EXPECT_FALSE(delayLess(Delay(2.0f), Delay(1.0f), sta()));
EXPECT_FALSE(delayLess(1.0f, 1.0f, nullptr)); EXPECT_FALSE(delayLess(Delay(1.0f), Delay(1.0f), sta()));
} }
TEST_F(DelayFloatTest, DelayRemove) { TEST_F(DelayFloatTest, DelayRemove) {
@ -50,11 +69,6 @@ TEST_F(DelayFloatTest, DelayRemove) {
EXPECT_FLOAT_EQ(result, 2.0f); 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) { TEST_F(DelayFloatTest, DelayInitValueMin) {
const Delay &init = delayInitValue(MinMax::min()); const Delay &init = delayInitValue(MinMax::min());
// Min init value should be a large positive number // Min init value should be a large positive number
@ -68,8 +82,8 @@ TEST_F(DelayFloatTest, DelayInitValueMax) {
} }
TEST_F(DelayFloatTest, MakeDelay) { TEST_F(DelayFloatTest, MakeDelay) {
Delay d = makeDelay(1.5f, 0.0f, 0.0f); Delay d = makeDelay(1.5f, 0.0f);
EXPECT_FLOAT_EQ(d, 1.5f); EXPECT_FLOAT_EQ(delayAsFloat(d), 1.5f);
} }
TEST_F(DelayFloatTest, DelayAsFloat) { TEST_F(DelayFloatTest, DelayAsFloat) {
@ -79,33 +93,33 @@ TEST_F(DelayFloatTest, DelayAsFloat) {
// Additional delay tests for improved coverage // Additional delay tests for improved coverage
TEST_F(DelayFloatTest, DelayGreater) { TEST_F(DelayFloatTest, DelayGreater) {
EXPECT_TRUE(delayGreater(2.0f, 1.0f, nullptr)); EXPECT_TRUE(delayGreater(Delay(2.0f), Delay(1.0f), sta()));
EXPECT_FALSE(delayGreater(1.0f, 2.0f, nullptr)); EXPECT_FALSE(delayGreater(Delay(1.0f), Delay(2.0f), sta()));
EXPECT_FALSE(delayGreater(1.0f, 1.0f, nullptr)); EXPECT_FALSE(delayGreater(Delay(1.0f), Delay(1.0f), sta()));
} }
TEST_F(DelayFloatTest, DelayLessEqual) { TEST_F(DelayFloatTest, DelayLessEqual) {
EXPECT_TRUE(delayLessEqual(1.0f, 2.0f, nullptr)); EXPECT_TRUE(delayLessEqual(Delay(1.0f), Delay(2.0f), sta()));
EXPECT_TRUE(delayLessEqual(1.0f, 1.0f, nullptr)); EXPECT_TRUE(delayLessEqual(Delay(1.0f), Delay(1.0f), sta()));
EXPECT_FALSE(delayLessEqual(2.0f, 1.0f, nullptr)); EXPECT_FALSE(delayLessEqual(Delay(2.0f), Delay(1.0f), sta()));
} }
TEST_F(DelayFloatTest, DelayGreaterEqual) { TEST_F(DelayFloatTest, DelayGreaterEqual) {
EXPECT_TRUE(delayGreaterEqual(2.0f, 1.0f, nullptr)); EXPECT_TRUE(delayGreaterEqual(Delay(2.0f), Delay(1.0f), sta()));
EXPECT_TRUE(delayGreaterEqual(1.0f, 1.0f, nullptr)); EXPECT_TRUE(delayGreaterEqual(Delay(1.0f), Delay(1.0f), sta()));
EXPECT_FALSE(delayGreaterEqual(1.0f, 2.0f, nullptr)); EXPECT_FALSE(delayGreaterEqual(Delay(1.0f), Delay(2.0f), sta()));
} }
TEST_F(DelayFloatTest, MakeDelayWithSigma) { TEST_F(DelayFloatTest, MakeDelayWithSigma) {
// In float mode, sigma is ignored // makeDelay(mean, std_dev) - sigma stored in Delay class
Delay d = makeDelay(2.5f, 0.1f, 0.2f); Delay d = makeDelay(2.5f, 0.1f);
EXPECT_FLOAT_EQ(d, 2.5f); EXPECT_FLOAT_EQ(delayAsFloat(d), 2.5f);
} }
TEST_F(DelayFloatTest, DelayNegative) { TEST_F(DelayFloatTest, DelayNegative) {
Delay d = -5.0f; Delay d = -5.0f;
EXPECT_FLOAT_EQ(delayAsFloat(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); EXPECT_EQ(v.paths(), nullptr);
} }
// Test Vertex slews // Test Vertex pin default
TEST(VertexStandaloneTest, Slews) TEST(VertexStandaloneTest, PinDefault)
{ {
Vertex v; 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) TEST(EdgeStandaloneTest, SetArcDelays)
{ {
Edge e; Edge e;
// Set and clear arc delays // Set and clear arc delays (setArcDelays takes float*)
ArcDelay *delays = new ArcDelay[4]; float *delays = new float[4];
for (int i = 0; i < 4; i++) for (int i = 0; i < 4; i++)
delays[i] = 0.0; delays[i] = 0.0f;
e.setArcDelays(delays); e.setArcDelays(delays);
EXPECT_NE(e.arcDelays(), nullptr); EXPECT_NE(e.arcDelays(), nullptr);
e.setArcDelays(nullptr); e.setArcDelays(nullptr);
@ -385,14 +400,14 @@ TEST_F(DelayFloatTest, DelayLessEqualMinMax)
{ {
// 4-arg delayLessEqual with MinMax // 4-arg delayLessEqual with MinMax
// With max: same as fuzzyLessEqual // With max: same as fuzzyLessEqual
EXPECT_TRUE(delayLessEqual(1.0f, 2.0f, MinMax::max(), nullptr)); EXPECT_TRUE(delayLessEqual(Delay(1.0f), Delay(2.0f), MinMax::max(), sta()));
EXPECT_TRUE(delayLessEqual(1.0f, 1.0f, MinMax::max(), nullptr)); EXPECT_TRUE(delayLessEqual(Delay(1.0f), Delay(1.0f), MinMax::max(), sta()));
EXPECT_FALSE(delayLessEqual(2.0f, 1.0f, MinMax::max(), nullptr)); EXPECT_FALSE(delayLessEqual(Delay(2.0f), Delay(1.0f), MinMax::max(), sta()));
// With min: same as fuzzyGreaterEqual (reversed) // With min: same as fuzzyGreaterEqual (reversed)
EXPECT_TRUE(delayLessEqual(2.0f, 1.0f, MinMax::min(), nullptr)); EXPECT_TRUE(delayLessEqual(Delay(2.0f), Delay(1.0f), MinMax::min(), sta()));
EXPECT_TRUE(delayLessEqual(1.0f, 1.0f, MinMax::min(), nullptr)); EXPECT_TRUE(delayLessEqual(Delay(1.0f), Delay(1.0f), MinMax::min(), sta()));
EXPECT_FALSE(delayLessEqual(1.0f, 2.0f, MinMax::min(), nullptr)); EXPECT_FALSE(delayLessEqual(Delay(1.0f), Delay(2.0f), MinMax::min(), sta()));
} }
//////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////
@ -413,7 +428,8 @@ TEST(EdgeStandaloneTest, DefaultState)
TEST(VertexStandaloneTest, SlewsDefault) TEST(VertexStandaloneTest, SlewsDefault)
{ {
Vertex v; 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 // Test Edge::arcDelayAnnotateBit - static method
@ -440,22 +456,14 @@ TEST(EdgeStandaloneTest, EdgeInitViaTimingArcSet)
EXPECT_EQ(e.timingArcSet(), nullptr); EXPECT_EQ(e.timingArcSet(), nullptr);
} }
// Test Vertex setSlews // Test Vertex initial state via public accessors
// Covers: Vertex::setSlews // Covers: Vertex default state
TEST(VertexStandaloneTest, SetSlews) TEST(VertexStandaloneTest, SetSlews)
{ {
Vertex v; Vertex v;
EXPECT_EQ(v.slews(), nullptr); // slews() and setSlews() are protected; verify public accessors instead
EXPECT_EQ(v.pin(), nullptr);
// Allocate some slews EXPECT_EQ(v.paths(), nullptr);
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;
} }
// Test Vertex setPaths // Test Vertex setPaths
@ -541,14 +549,12 @@ TEST(EdgeStandaloneTest, SetTimingArcSetNull)
EXPECT_EQ(e.timingArcSet(), nullptr); EXPECT_EQ(e.timingArcSet(), nullptr);
} }
// Test Vertex setSlews indirectly - slews_ is protected // Test Vertex public accessors for initial state
// Covers: Vertex::setSlews path // Covers: Vertex::paths, Vertex::setPaths
TEST(VertexStandaloneTest, VertexSlewsProtected) TEST(VertexStandaloneTest, VertexSlewsProtected)
{ {
Vertex v; Vertex v;
// Initially slews_ is nullptr // slews() is protected; verify public setPaths/paths instead
EXPECT_EQ(v.slews(), nullptr);
// setPaths is public - at least verify paths
v.setPaths(nullptr); v.setPaths(nullptr);
EXPECT_EQ(v.paths(), nullptr); EXPECT_EQ(v.paths(), nullptr);
} }
@ -673,7 +679,8 @@ TEST(EdgeStandaloneTest, ArcDelaysSetAndAccess)
{ {
Edge e; Edge e;
EXPECT_EQ(e.arcDelays(), nullptr); 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++) for (int i = 0; i < 8; i++)
delays[i] = static_cast<float>(i) * 1e-12f; delays[i] = static_cast<float>(i) * 1e-12f;
e.setArcDelays(delays); e.setArcDelays(delays);
@ -773,14 +780,14 @@ TEST(EdgeStandaloneTest, MultipleFlagCombinations)
TEST_F(DelayFloatTest, DelayLessEqualMinMaxVariant) TEST_F(DelayFloatTest, DelayLessEqualMinMaxVariant)
{ {
// With max: standard less-equal // With max: standard less-equal
EXPECT_TRUE(delayLessEqual(1.0f, 2.0f, MinMax::max(), nullptr)); EXPECT_TRUE(delayLessEqual(Delay(1.0f), Delay(2.0f), MinMax::max(), sta()));
EXPECT_TRUE(delayLessEqual(2.0f, 2.0f, MinMax::max(), nullptr)); EXPECT_TRUE(delayLessEqual(Delay(2.0f), Delay(2.0f), MinMax::max(), sta()));
EXPECT_FALSE(delayLessEqual(3.0f, 2.0f, MinMax::max(), nullptr)); EXPECT_FALSE(delayLessEqual(Delay(3.0f), Delay(2.0f), MinMax::max(), sta()));
// With min: reversed (greater-equal) // With min: reversed (greater-equal)
EXPECT_TRUE(delayLessEqual(3.0f, 2.0f, MinMax::min(), nullptr)); EXPECT_TRUE(delayLessEqual(Delay(3.0f), Delay(2.0f), MinMax::min(), sta()));
EXPECT_TRUE(delayLessEqual(2.0f, 2.0f, MinMax::min(), nullptr)); EXPECT_TRUE(delayLessEqual(Delay(2.0f), Delay(2.0f), MinMax::min(), sta()));
EXPECT_FALSE(delayLessEqual(1.0f, 2.0f, MinMax::min(), nullptr)); 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) { TEST_F(UnitTest, AsString) {
Unit unit(1e-9f, "s", 3); Unit unit(1e-9f, "s", 3);
const char *str = unit.asString(1e-9f); std::string str = unit.asString(1e-9f);
EXPECT_NE(str, nullptr); EXPECT_FALSE(str.empty());
// Should produce something like "1.000" // Should produce something like "1.000"
} }
@ -1268,8 +1268,8 @@ TEST(InternalPowerTest, DirectConstruction) {
InternalPower pwr(nullptr, nullptr, nullptr, when_expr, models); InternalPower pwr(nullptr, nullptr, nullptr, when_expr, models);
EXPECT_EQ(pwr.when(), when_expr.get()); EXPECT_EQ(pwr.when(), when_expr.get());
EXPECT_EQ(pwr.relatedPgPin(), nullptr); EXPECT_EQ(pwr.relatedPgPin(), nullptr);
EXPECT_EQ(pwr.model(RiseFall::rise()), nullptr); EXPECT_EQ(pwr.model(RiseFall::rise()).model(), nullptr);
EXPECT_EQ(pwr.model(RiseFall::fall()), nullptr); EXPECT_EQ(pwr.model(RiseFall::fall()).model(), nullptr);
} }
//////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////
@ -1450,26 +1450,27 @@ TEST_F(LinearModelTest, GateLinearModelConstruct) {
TEST_F(LinearModelTest, GateLinearModelGateDelay) { TEST_F(LinearModelTest, GateLinearModelGateDelay) {
GateLinearModel model(cell_, 1.0f, 2.0f); GateLinearModel model(cell_, 1.0f, 2.0f);
ArcDelay gate_delay; float gate_delay;
Slew drvr_slew; float drvr_slew;
// delay = intrinsic + resistance * load_cap = 1.0 + 2.0 * 3.0 = 7.0 // 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); model.gateDelay(nullptr, 0.0f, 3.0f, gate_delay, drvr_slew);
EXPECT_FLOAT_EQ(delayAsFloat(gate_delay), 7.0f); EXPECT_FLOAT_EQ(gate_delay, 7.0f);
EXPECT_FLOAT_EQ(delayAsFloat(drvr_slew), 0.0f); EXPECT_FLOAT_EQ(drvr_slew, 0.0f);
} }
TEST_F(LinearModelTest, GateLinearModelZeroLoad) { TEST_F(LinearModelTest, GateLinearModelZeroLoad) {
GateLinearModel model(cell_, 2.5f, 1.0f); GateLinearModel model(cell_, 2.5f, 1.0f);
ArcDelay gate_delay; float gate_delay;
Slew drvr_slew; float drvr_slew;
// delay = 2.5 + 1.0 * 0.0 = 2.5 // delay = 2.5 + 1.0 * 0.0 = 2.5
model.gateDelay(nullptr, 0.0f, 0.0f, false, gate_delay, drvr_slew); model.gateDelay(nullptr, 0.0f, 0.0f, gate_delay, drvr_slew);
EXPECT_FLOAT_EQ(delayAsFloat(gate_delay), 2.5f); EXPECT_FLOAT_EQ(gate_delay, 2.5f);
} }
TEST_F(LinearModelTest, GateLinearModelReportGateDelay) { TEST_F(LinearModelTest, GateLinearModelReportGateDelay) {
GateLinearModel model(cell_, 1.0f, 2.0f); 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()); EXPECT_FALSE(report.empty());
// Report should contain "Delay =" // Report should contain "Delay ="
EXPECT_NE(report.find("Delay"), std::string::npos); EXPECT_NE(report.find("Delay"), std::string::npos);
@ -1477,23 +1478,27 @@ TEST_F(LinearModelTest, GateLinearModelReportGateDelay) {
TEST_F(LinearModelTest, CheckLinearModelConstruct) { TEST_F(LinearModelTest, CheckLinearModelConstruct) {
CheckLinearModel model(cell_, 3.0f); 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); EXPECT_FLOAT_EQ(delayAsFloat(delay), 3.0f);
} }
TEST_F(LinearModelTest, CheckLinearModelCheckDelay) { TEST_F(LinearModelTest, CheckLinearModelCheckDelay) {
CheckLinearModel model(cell_, 5.5f); CheckLinearModel model(cell_, 5.5f);
// checkDelay always returns intrinsic_ regardless of other params // 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); 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); EXPECT_FLOAT_EQ(delayAsFloat(delay2), 5.5f);
} }
TEST_F(LinearModelTest, CheckLinearModelReportCheckDelay) { TEST_F(LinearModelTest, CheckLinearModelReportCheckDelay) {
CheckLinearModel model(cell_, 2.0f); CheckLinearModel model(cell_, 2.0f);
std::string report = model.reportCheckDelay(nullptr, 0.0f, nullptr, 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_FALSE(report.empty());
EXPECT_NE(report.find("Check"), std::string::npos); EXPECT_NE(report.find("Check"), std::string::npos);
} }
@ -1505,24 +1510,24 @@ TEST_F(LinearModelTest, CheckLinearModelReportCheckDelay) {
TEST(InternalPowerTest, ModelAccess) { TEST(InternalPowerTest, ModelAccess) {
InternalPowerModels models{}; InternalPowerModels models{};
InternalPower pwr(nullptr, nullptr, nullptr, nullptr, models); InternalPower pwr(nullptr, nullptr, nullptr, nullptr, models);
// Initially models should be nullptr // Initially models should have null inner TableModel
EXPECT_EQ(pwr.model(RiseFall::rise()), nullptr); EXPECT_EQ(pwr.model(RiseFall::rise()).model(), nullptr);
EXPECT_EQ(pwr.model(RiseFall::fall()), nullptr); EXPECT_EQ(pwr.model(RiseFall::fall()).model(), nullptr);
} }
TEST(InternalPowerTest, WithModel) { TEST(InternalPowerTest, WithModel) {
// Create a minimal model: Table -> TableModel -> InternalPowerModel // Create a minimal model: Table -> TableModel -> InternalPowerModel
TablePtr tbl = std::make_shared<Table>(1.0f); TablePtr tbl = std::make_shared<Table>(1.0f);
TableModel *table_model = new TableModel(tbl, nullptr, auto table_model = std::make_shared<TableModel>(tbl, nullptr,
ScaleFactorType::internal_power, ScaleFactorType::internal_power,
RiseFall::rise()); RiseFall::rise());
auto power_model = std::make_shared<InternalPowerModel>(table_model); InternalPowerModel power_model(table_model);
InternalPowerModels models{}; InternalPowerModels models{};
models[RiseFall::riseIndex()] = power_model; models[RiseFall::riseIndex()] = power_model;
InternalPower pwr(nullptr, nullptr, nullptr, nullptr, models); InternalPower pwr(nullptr, nullptr, nullptr, nullptr, models);
EXPECT_EQ(pwr.model(RiseFall::rise()), power_model.get()); EXPECT_NE(pwr.model(RiseFall::rise()).model(), nullptr);
EXPECT_EQ(pwr.model(RiseFall::fall()), nullptr); EXPECT_EQ(pwr.model(RiseFall::fall()).model(), nullptr);
} }
//////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////
@ -3473,9 +3478,9 @@ TEST(LibertyUtilTest, PortLibertyToStaWithBrackets) {
TEST(InternalPowerModelTest, PowerLookupOrder0) { TEST(InternalPowerModelTest, PowerLookupOrder0) {
TablePtr tbl = std::make_shared<Table>(5.0f); TablePtr tbl = std::make_shared<Table>(5.0f);
TableModel *table_model = new TableModel(tbl, nullptr, auto table_model = std::make_shared<TableModel>(tbl, nullptr,
ScaleFactorType::internal_power, ScaleFactorType::internal_power,
RiseFall::rise()); RiseFall::rise());
InternalPowerModel model(table_model); InternalPowerModel model(table_model);
LibertyLibrary lib("test_lib", "test.lib"); LibertyLibrary lib("test_lib", "test.lib");
TestCell cell(&lib, "INV", "test.lib"); TestCell cell(&lib, "INV", "test.lib");
@ -3485,9 +3490,9 @@ TEST(InternalPowerModelTest, PowerLookupOrder0) {
TEST(InternalPowerModelTest, ReportPowerOrder0) { TEST(InternalPowerModelTest, ReportPowerOrder0) {
TablePtr tbl = std::make_shared<Table>(3.0f); TablePtr tbl = std::make_shared<Table>(3.0f);
TableModel *table_model = new TableModel(tbl, nullptr, auto table_model = std::make_shared<TableModel>(tbl, nullptr,
ScaleFactorType::internal_power, ScaleFactorType::internal_power,
RiseFall::rise()); RiseFall::rise());
InternalPowerModel model(table_model); InternalPowerModel model(table_model);
LibertyLibrary lib("test_lib", "test.lib"); LibertyLibrary lib("test_lib", "test.lib");
TestCell cell(&lib, "INV", "test.lib"); TestCell cell(&lib, "INV", "test.lib");
@ -3505,9 +3510,9 @@ TEST(InternalPowerModelTest, PowerLookupOrder1) {
values.push_back(1.0f); values.push_back(1.0f);
values.push_back(3.0f); values.push_back(3.0f);
TablePtr tbl = std::make_shared<Table>(std::move(values), axis); TablePtr tbl = std::make_shared<Table>(std::move(values), axis);
TableModel *table_model = new TableModel(tbl, nullptr, auto table_model = std::make_shared<TableModel>(tbl, nullptr,
ScaleFactorType::internal_power, ScaleFactorType::internal_power,
RiseFall::rise()); RiseFall::rise());
InternalPowerModel model(table_model); InternalPowerModel model(table_model);
LibertyLibrary lib("test_lib", "test.lib"); LibertyLibrary lib("test_lib", "test.lib");
TestCell cell(&lib, "INV", "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); FloatSeq row1; row1.push_back(3.0f); row1.push_back(4.0f);
values.push_back(std::move(row0)); values.push_back(std::move(row1)); values.push_back(std::move(row0)); values.push_back(std::move(row1));
TablePtr tbl = std::make_shared<Table>(std::move(values), axis1, axis2); TablePtr tbl = std::make_shared<Table>(std::move(values), axis1, axis2);
TableModel *table_model = new TableModel(tbl, nullptr, auto table_model = std::make_shared<TableModel>(tbl, nullptr,
ScaleFactorType::internal_power, ScaleFactorType::internal_power,
RiseFall::rise()); RiseFall::rise());
InternalPowerModel model(table_model); InternalPowerModel model(table_model);
LibertyLibrary lib("test_lib", "test.lib"); LibertyLibrary lib("test_lib", "test.lib");
TestCell cell(&lib, "INV", "test.lib"); TestCell cell(&lib, "INV", "test.lib");

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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