diff --git a/CMakeLists.txt b/CMakeLists.txt index 60932b82..973cfb0d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -237,7 +237,6 @@ set(STA_SOURCE util/StringSeq.cc util/StringSet.cc util/StringUtil.cc - util/TokenParser.cc util/Transition.cc verilog/VerilogReader.cc diff --git a/include/sta/StringUtil.hh b/include/sta/StringUtil.hh index c222d53b..cdb9b1b7 100644 --- a/include/sta/StringUtil.hh +++ b/include/sta/StringUtil.hh @@ -33,6 +33,8 @@ namespace sta { +using StdStringSeq = std::vector; + inline bool stringEq(const char *str1, const char *str2) @@ -201,12 +203,9 @@ deleteTmpStrings(); void trimRight(std::string &str); -using StringVector = std::vector; - -void -split(const std::string &text, - const std::string &delims, - // Return values. - StringVector &tokens); +// Spit text into delimiter separated tokens and skip whitepace. +StdStringSeq +parseTokens(const std::string &s, + const char delimiter); } // namespace diff --git a/include/sta/TokenParser.hh b/include/sta/TokenParser.hh deleted file mode 100644 index 27db37f9..00000000 --- a/include/sta/TokenParser.hh +++ /dev/null @@ -1,62 +0,0 @@ -// OpenSTA, Static Timing Analyzer -// Copyright (c) 2025, Parallax Software, Inc. -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . -// -// The origin of this software must not be misrepresented; you must not -// claim that you wrote the original software. -// -// Altered source versions must be plainly marked as such, and must not be -// misrepresented as being the original software. -// -// This notice may not be removed or altered from any source distribution. - -#pragma once - -#include -#include - -namespace sta { - -using StdStringSeq = std::vector; - -// Iterate over the tokens in str separated by character sep. -// Similar in functionality to strtok, but does not leave the string -// side-effected. This is preferable to using strtok because it leaves -// string terminators where the separators were. -// Using STL string functions to parse tokens is messy and extremely slow -// on the RogueWave/Solaris implementation, apparently because of mutexes -// on temporary strings. -class TokenParser -{ -public: - TokenParser(const char *str, - const char *delimiters); - bool hasNext(); - char *next(); - -private: - const char *delimiters_; - char *token_; - char *token_end_; - char token_delimiter_; - bool first_; -}; - -// Parse delimiter separated tokens and skipp spaces. -StdStringSeq -parseTokens(const std::string &s, - const char delimiter); - -} // namespace diff --git a/liberty/LibertyReader.cc b/liberty/LibertyReader.cc index 974ab7ec..c070e3dd 100644 --- a/liberty/LibertyReader.cc +++ b/liberty/LibertyReader.cc @@ -33,7 +33,6 @@ #include "EnumNameMap.hh" #include "Report.hh" #include "Debug.hh" -#include "TokenParser.hh" #include "Units.hh" #include "Transition.hh" #include "FuncExpr.hh" diff --git a/spice/WriteSpice.cc b/spice/WriteSpice.cc index cce1989b..8d55d8c7 100644 --- a/spice/WriteSpice.cc +++ b/spice/WriteSpice.cc @@ -213,8 +213,7 @@ WriteSpice::writeSubckts(StdStringSet &cell_names) string line; while (getline(lib_subckts_stream, line)) { // .subckt [args..] - StringVector tokens; - split(line, " \t", tokens); + StdStringSeq tokens = parseTokens(line, ' '); if (tokens.size() >= 2 && stringEqual(tokens[0].c_str(), ".subckt")) { const char *cell_name = tokens[1].c_str(); @@ -261,11 +260,11 @@ WriteSpice::writeSubckts(StdStringSet &cell_names) void WriteSpice::recordSpicePortNames(const char *cell_name, - StringVector &tokens) + StdStringSeq &tokens) { LibertyCell *cell = network_->findLibertyCell(cell_name); if (cell) { - StringVector &spice_port_names = cell_spice_port_names_[cell_name]; + StdStringSeq &spice_port_names = cell_spice_port_names_[cell_name]; for (size_t i = 2; i < tokens.size(); i++) { const char *port_name = tokens[i].c_str(); LibertyPort *port = cell->findLibertyPort(port_name); @@ -290,8 +289,7 @@ WriteSpice::findCellSubckts(StdStringSet &cell_names) string line; while (getline(lib_subckts_stream, line)) { // .subckt [args..] - StringVector tokens; - split(line, " \t", tokens); + StdStringSeq tokens = parseTokens(line, ' '); if (tokens.size() >= 2 && stringEqual(tokens[0].c_str(), ".subckt")) { const char *cell_name = tokens[1].c_str(); @@ -304,7 +302,7 @@ WriteSpice::findCellSubckts(StdStringSet &cell_names) else { // Process previous statement. if (tolower(stmt[0]) == 'x') { - split(stmt, " \t", tokens); + StdStringSeq tokens = parseTokens(line, ' '); string &subckt_cell = tokens[tokens.size() - 1]; cell_names.insert(subckt_cell); } @@ -329,7 +327,7 @@ WriteSpice::writeSubcktInst(const Instance *inst) const char *inst_name = network_->pathName(inst); LibertyCell *cell = network_->libertyCell(inst); const char *cell_name = cell->name(); - StringVector &spice_port_names = cell_spice_port_names_[cell_name]; + StdStringSeq &spice_port_names = cell_spice_port_names_[cell_name]; streamPrint(spice_stream_, "x%s", inst_name); for (string subckt_port_name : spice_port_names) { const char *subckt_port_cname = subckt_port_name.c_str(); @@ -357,7 +355,7 @@ WriteSpice::writeSubcktInstVoltSrcs(const Instance *inst, { LibertyCell *cell = network_->libertyCell(inst); const char *cell_name = cell->name(); - StringVector &spice_port_names = cell_spice_port_names_[cell_name]; + StdStringSeq &spice_port_names = cell_spice_port_names_[cell_name]; const char *inst_name = network_->pathName(inst); debugPrint(debug_, "write_spice", 2, "subckt %s", cell->name()); diff --git a/spice/WriteSpice.hh b/spice/WriteSpice.hh index 3e55e294..aee55dfe 100644 --- a/spice/WriteSpice.hh +++ b/spice/WriteSpice.hh @@ -40,9 +40,9 @@ namespace sta { using ParasiticNodeMap = std::map; -using CellSpicePortNames = std::map; -using LibertyPortLogicValues = std::map; using StdStringSeq = std::vector; +using CellSpicePortNames = std::map; +using LibertyPortLogicValues = std::map; // Utilities for writing a spice deck. class WriteSpice : public StaState @@ -69,7 +69,7 @@ protected: void writeSubckts(StdStringSet &cell_names); void findCellSubckts(StdStringSet &cell_names); void recordSpicePortNames(const char *cell_name, - StringVector &tokens); + StdStringSeq &tokens); void writeSubcktInst(const Instance *inst); void writeSubcktInstVoltSrcs(const Instance *inst, LibertyPortLogicValues &port_values, diff --git a/util/StringUtil.cc b/util/StringUtil.cc index a0b8c154..6a8680e4 100644 --- a/util/StringUtil.cc +++ b/util/StringUtil.cc @@ -269,12 +269,11 @@ trimRight(string &str) str.erase(str.find_last_not_of(" ") + 1); } -void +StdStringSeq split(const string &text, - const string &delims, - // Return values. - StringVector &tokens) + const string &delims) { + StdStringSeq tokens; auto start = text.find_first_not_of(delims); auto end = text.find_first_of(delims, start); while (end != string::npos) { @@ -284,6 +283,28 @@ split(const string &text, } if (start != string::npos) tokens.push_back(text.substr(start)); + return tokens; +} + +// Parse space separated tokens. +StdStringSeq +parseTokens(const std::string &s, + const char delimiter) +{ + StdStringSeq tokens; + size_t i = 0; + while (i < s.size()) { + while (i < s.size() && std::isspace(s[i])) + ++i; + size_t start = i; + while (i < s.size() && s[i] != delimiter) + ++i; + if (start < i) { + tokens.emplace_back(s, start, i - start); + ++i; + } + } + return tokens; } } // namespace diff --git a/util/TokenParser.cc b/util/TokenParser.cc deleted file mode 100644 index d0a44859..00000000 --- a/util/TokenParser.cc +++ /dev/null @@ -1,113 +0,0 @@ -// OpenSTA, Static Timing Analyzer -// Copyright (c) 2025, Parallax Software, Inc. -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . -// -// The origin of this software must not be misrepresented; you must not -// claim that you wrote the original software. -// -// Altered source versions must be plainly marked as such, and must not be -// misrepresented as being the original software. -// -// This notice may not be removed or altered from any source distribution. - -#include "TokenParser.hh" - -#include -#include - -namespace sta { - -TokenParser::TokenParser(const char *str, - const char *delimiters) : - delimiters_(delimiters), - token_(const_cast(str)), - token_delimiter_('\0'), - first_(true) -{ - // Skip leading spaces. - while (*token_ != '\0' && isspace(*token_)) - token_++; - token_end_ = strpbrk(token_, delimiters_); - if (token_end_) { - // Save the delimiter. - token_delimiter_ = *token_end_; - // Replace the separator with a terminator. - *token_end_ = '\0'; - } -} - -bool -TokenParser::hasNext() -{ - if (!first_) { - // Replace the previous separator. - if (token_end_) { - *token_end_ = token_delimiter_; - token_ = token_end_ + 1; - // Skip spaces. - while (*token_ != '\0' && isspace(*token_)) - token_++; - // Skip delimiters. - while (*token_ != '\0' && strchr(delimiters_,*token_) != nullptr) - token_++; - if (*token_ == '\0') - token_ = nullptr; - else { - token_end_ = strpbrk(token_, delimiters_); - if (token_end_) { - // Save the delimiter. - token_delimiter_ = *token_end_; - // Replace the separator with a terminator. - *token_end_ = '\0'; - } - } - } - else - token_ = nullptr; - } - return token_ != nullptr; -} - -char * -TokenParser::next() -{ - first_ = false; - return token_; -} - -//////////////////////////////////////////////////////////////// - -// Parse space separated tokens. -StdStringSeq -parseTokens(const std::string &s, - const char delimiter) -{ - StdStringSeq tokens; - size_t i = 0; - while (i < s.size()) { - while (i < s.size() && std::isspace(s[i])) - ++i; - size_t start = i; - while (i < s.size() && s[i] != delimiter) - ++i; - if (start < i) { - tokens.emplace_back(s, start, i - start); - ++i; - } - } - return tokens; -} - -} // namespace