diff --git a/liberty/LibertyReader.cc b/liberty/LibertyReader.cc index 811cf400..880a682e 100644 --- a/liberty/LibertyReader.cc +++ b/liberty/LibertyReader.cc @@ -2533,10 +2533,10 @@ LibertyReader::beginPin(LibertyGroup *group) if (param->isString()) { const char *name = param->stringValue(); debugPrint1(debug_, "liberty", 1, " port %s\n", name); - if (isBusName(name, brkt_left, brkt_right)) + if (isBusName(name, brkt_left, brkt_right, escape_)) // Pins not inside a bus group with bus names are not really // busses, so escape the brackets. - name = escapeChars(name, brkt_left, brkt_right, '\\'); + name = escapeChars(name, brkt_left, brkt_right, escape_); LibertyPort *port = builder_->makePort(cell_, name); ports_->push_back(port); setPortDefaults(port); @@ -2768,9 +2768,9 @@ LibertyReader::findPort(LibertyCell *cell, if (port == nullptr) { char brkt_left = library_->busBrktLeft(); char brkt_right = library_->busBrktRight(); - if (isBusName(port_name, brkt_left, brkt_right)) { + if (isBusName(port_name, brkt_left, brkt_right, escape_)) { // Pins at top level with bus names have escaped brackets. - port_name = escapeChars(port_name, brkt_left, brkt_right, '\\'); + port_name = escapeChars(port_name, brkt_left, brkt_right, escape_); port = cell->findLibertyPort(port_name); } } @@ -5165,7 +5165,7 @@ PortNameBitIterator::init(const char *port_name) int from, to; char *bus_name; parseBusRange(port_name, library->busBrktLeft(), library->busBrktRight(), - bus_name, from, to); + '\\', bus_name, from, to); if (bus_name) { port = visitor_->findPort(cell_, port_name); if (port) { diff --git a/liberty/LibertyReaderPvt.hh b/liberty/LibertyReaderPvt.hh index 892f3bea..b13cf050 100644 --- a/liberty/LibertyReaderPvt.hh +++ b/liberty/LibertyReaderPvt.hh @@ -573,6 +573,7 @@ protected: float energy_scale_; float distance_scale_; bool have_resistance_unit_; + static constexpr char escape_ = '\\'; private: DISALLOW_COPY_AND_ASSIGN(LibertyReader); diff --git a/network/ConcreteLibrary.cc b/network/ConcreteLibrary.cc index 018e62e8..059e104f 100644 --- a/network/ConcreteLibrary.cc +++ b/network/ConcreteLibrary.cc @@ -24,6 +24,8 @@ namespace sta { +static constexpr char escape_ = '\\'; + ConcreteLibrary::ConcreteLibrary(const char *name, const char *filename, bool is_liberty) : @@ -374,7 +376,7 @@ ConcreteCell::groupBusPorts(const char bus_brkt_left, const char *port_name = port->name(); char *bus_name; int index; - parseBusName(port_name, bus_brkts_left, bus_brkts_right, + parseBusName(port_name, bus_brkts_left, bus_brkts_right, escape_, bus_name, index); if (bus_name) { if (!port->isBusBit()) { @@ -414,7 +416,7 @@ ConcreteCell::groupBusPorts(const char bus_brkt_left, ConcretePort *port = member_iter.next(); char *bus_name; int index; - parseBusName(port->name(), bus_brkts_left, bus_brkts_right, + parseBusName(port->name(), bus_brkts_left, bus_brkts_right, escape_, bus_name, index); port->setBusBitIndex(index); stringDelete(bus_name); diff --git a/network/ParseBus.cc b/network/ParseBus.cc index 4dfef34e..fc0306f2 100644 --- a/network/ParseBus.cc +++ b/network/ParseBus.cc @@ -28,10 +28,15 @@ using std::string; bool isBusName(const char *name, const char brkt_left, - const char brkt_right) + const char brkt_right, + char escape) { - size_t len_1 = strlen(name) - 1; - if (name[len_1] == brkt_right) { + size_t len = strlen(name); + // Shortest bus name is a[0]. + if (len >= 4 + // Escaped bus brackets are not buses. + && name[len - 2] != escape + && name[len - 1] == brkt_right) { const char *left = strrchr(name, brkt_left); return left != nullptr; } @@ -43,38 +48,45 @@ void parseBusName(const char *name, const char brkt_left, const char brkt_right, + char escape, // Return values. char *&bus_name, int &index) { const char brkts_left[2] = {brkt_left, '\0'}; const char brkts_right[2] = {brkt_right, '\0'}; - parseBusName(name, brkts_left, brkts_right, bus_name, index); + parseBusName(name, brkts_left, brkts_right, escape, bus_name, index); } void parseBusName(const char *name, const char *brkts_left, const char *brkts_right, + char escape, // Return values. char *&bus_name, int &index) { bus_name = nullptr; - size_t len_1 = strlen(name) - 1; - char last_ch = name[len_1]; - const char *brkt_right_ptr = strchr(brkts_right, last_ch); - if (brkt_right_ptr) { - size_t brkt_index = brkt_right_ptr - brkts_right; - char brkt_left = brkts_left[brkt_index]; - const char *left = strrchr(name, brkt_left); - if (left) { - size_t bus_name_len = left - name; - bus_name = new char[bus_name_len + 1]; - strncpy(bus_name, name, bus_name_len); - bus_name[bus_name_len] = '\0'; - // Simple bus subscript. - index = atoi(left + 1); + size_t len = strlen(name); + // Shortest bus name is a[0]. + if (len >= 4 + // Escaped bus brackets are not buses. + && name[len - 2] != escape) { + char last_ch = name[len - 1]; + const char *brkt_right_ptr = strchr(brkts_right, last_ch); + if (brkt_right_ptr) { + size_t brkt_index = brkt_right_ptr - brkts_right; + char brkt_left = brkts_left[brkt_index]; + const char *left = strrchr(name, brkt_left); + if (left) { + size_t bus_name_len = left - name; + bus_name = new char[bus_name_len + 1]; + strncpy(bus_name, name, bus_name_len); + bus_name[bus_name_len] = '\0'; + // Simple bus subscript. + index = atoi(left + 1); + } } } } @@ -83,6 +95,7 @@ void parseBusRange(const char *name, const char brkt_left, const char brkt_right, + char escape, // Return values. char *&bus_name, int &from, @@ -90,39 +103,45 @@ parseBusRange(const char *name, { const char brkts_left[2] = {brkt_left, '\0'}; const char brkts_right[2] = {brkt_right, '\0'}; - parseBusRange(name, brkts_left, brkts_right, bus_name, from, to); + parseBusRange(name, brkts_left, brkts_right, escape, bus_name, from, to); } void parseBusRange(const char *name, const char *brkts_left, const char *brkts_right, + char escape, // Return values. char *&bus_name, int &from, int &to) { bus_name = nullptr; - size_t len_1 = strlen(name) - 1; - char last_ch = name[len_1]; - const char *brkt_right_ptr = strchr(brkts_right, last_ch); - if (brkt_right_ptr) { - size_t brkt_index = brkt_right_ptr - brkts_right; - char brkt_left = brkts_left[brkt_index]; - const char *left = strrchr(name, brkt_left); - if (left) { - // Check for bus range. - const char range_sep = ':'; - const char *range = strchr(name, range_sep); - if (range) { - size_t bus_name_len = left - name; - bus_name = new char[bus_name_len + 1]; - strncpy(bus_name, name, bus_name_len); - bus_name[bus_name_len] = '\0'; - // No need to terminate bus subscript because atoi stops - // scanning at first non-digit character. - from = atoi(left + 1); - to = atoi(range + 1); + size_t len = strlen(name); + // Shortest bus range is a[1:0]. + if (len >= 6 + // Escaped bus brackets are not buses. + && name[len - 2] != escape) { + char last_ch = name[len - 1]; + const char *brkt_right_ptr = strchr(brkts_right, last_ch); + if (brkt_right_ptr) { + size_t brkt_index = brkt_right_ptr - brkts_right; + char brkt_left = brkts_left[brkt_index]; + const char *left = strrchr(name, brkt_left); + if (left) { + // Check for bus range. + const char range_sep = ':'; + const char *range = strchr(name, range_sep); + if (range) { + size_t bus_name_len = left - name; + bus_name = new char[bus_name_len + 1]; + strncpy(bus_name, name, bus_name_len); + bus_name[bus_name_len] = '\0'; + // No need to terminate bus subscript because atoi stops + // scanning at first non-digit character. + from = atoi(left + 1); + to = atoi(range + 1); + } } } } diff --git a/network/ParseBus.hh b/network/ParseBus.hh index 7d0ad859..88eeb3d9 100644 --- a/network/ParseBus.hh +++ b/network/ParseBus.hh @@ -23,7 +23,8 @@ namespace sta { bool isBusName(const char *name, const char brkt_left, - const char brkt_right); + const char brkt_right, + char escape); // Parse name as a bus. // signal @@ -36,6 +37,7 @@ void parseBusName(const char *name, const char brkt_left, const char brkt_right, + char escape, // Return values. char *&bus_name, int &index); @@ -44,6 +46,7 @@ void parseBusName(const char *name, const char *brkts_left, const char *brkts_right, + char escape, // Return values. char *&bus_name, int &index); @@ -55,6 +58,7 @@ void parseBusRange(const char *name, const char brkt_left, const char brkt_right, + char escape, // Return values. char *&bus_name, int &from, @@ -65,6 +69,7 @@ void parseBusRange(const char *name, const char *brkts_left, const char *brkts_right, + char escape, // Return values. char *&bus_name, int &from, diff --git a/network/SdcNetwork.cc b/network/SdcNetwork.cc index 5e2a24ae..98732c02 100644 --- a/network/SdcNetwork.cc +++ b/network/SdcNetwork.cc @@ -583,7 +583,7 @@ SdcNetwork::findPort(const Cell *cell, // Look for matches after escaping brackets. char *bus_name; int index; - parseBusName(name, '[', ']', bus_name, index); + parseBusName(name, '[', ']', pathEscape(), bus_name, index); if (bus_name) { const char *escaped1 = escapeBrackets(name, this); port = network_->findPort(cell, escaped1); @@ -611,7 +611,7 @@ SdcNetwork::findPortsMatching(const Cell *cell, // Look for matches after escaping brackets. char *bus_name; int index; - parseBusName(pattern->pattern(), '[', ']', bus_name, index); + parseBusName(pattern->pattern(), '[', ']', pathEscape(), bus_name, index); if (bus_name) { const char *escaped1 = escapeBrackets(pattern->pattern(), this); PatternMatch escaped_pattern1(escaped1, pattern); @@ -804,7 +804,7 @@ SdcNetwork::findPin(const Instance *instance, // Look for match after escaping brackets. char *bus_name; int index; - parseBusName(port_name, '[', ']', bus_name, index); + parseBusName(port_name, '[', ']', pathEscape(), bus_name, index); if (bus_name) { const char *escaped1 = escapeBrackets(port_name, this); pin = network_->findPin(instance, escaped1); diff --git a/network/VerilogNamespace.cc b/network/VerilogNamespace.cc index eb096018..038e8591 100644 --- a/network/VerilogNamespace.cc +++ b/network/VerilogNamespace.cc @@ -35,7 +35,7 @@ netVerilogName(const char *sta_name, { char *bus_name; int index; - parseBusName(sta_name, '[', ']', bus_name, index); + parseBusName(sta_name, '[', ']', escape, bus_name, index); if (bus_name) { const char *vname = stringPrintTmp("%s[%d]", staToVerilog(bus_name, escape),