From 749e321cd91f38f0643368425c0a7305584dad09 Mon Sep 17 00:00:00 2001 From: codereader Date: Mon, 24 Sep 2018 11:10:52 +0200 Subject: [PATCH] Address issue #4859: DR thinks an entity name of the form "Cylinder01" is the same as "Cylinder1". The ComplexName structure is now keeping the string representation of the number postfix (e.g. "01") to check against name/postfix collisions when merging namespaces or renaming entities. --- radiant/namespace/ComplexName.cpp | 20 +++++++++++++------- radiant/namespace/ComplexName.h | 18 ++++++++++-------- radiant/namespace/UniqueNameSet.h | 7 ++++--- 3 files changed, 27 insertions(+), 18 deletions(-) diff --git a/radiant/namespace/ComplexName.cpp b/radiant/namespace/ComplexName.cpp index 609c5cbae3..9e77d6df0c 100644 --- a/radiant/namespace/ComplexName.cpp +++ b/radiant/namespace/ComplexName.cpp @@ -4,6 +4,8 @@ #include "string/trim.h" #include "string/convert.h" +const std::string ComplexName::EMPTY_POSTFIX("-"); + ComplexName::ComplexName(const std::string& fullname) { // Retrieve the name by cutting off the trailing number @@ -11,36 +13,40 @@ ComplexName::ComplexName(const std::string& fullname) // Get the trimmed part and take it as postfix std::string postFixStr = fullname.substr(_name.size()); - _postFix = string::convert(postFixStr, -1); + + // Assign the empty Postfix placeholder if we didn't find any numbers + _postFix = !postFixStr.empty() ? postFixStr : EMPTY_POSTFIX; } std::string ComplexName::getFullname() const { - return _name + (_postFix == -1 ? "" : string::to_string(_postFix)); + return _name + (_postFix != EMPTY_POSTFIX ? _postFix : ""); } namespace { // Find the first integer not in the given set - int findFirstUnusedNumber(const PostfixSet& set) + std::string findFirstUnusedNumber(const PostfixSet& set) { static const int LOWEST_VAL = 1; for (int i = LOWEST_VAL; i < INT_MAX; ++i) { - if (set.find(i) == set.end()) + std::string testPostfix = string::to_string(i); + + if (set.find(testPostfix) == set.end()) { // Found an unused value - return i; + return testPostfix; } } // Pathological case, could not find a value - return INT_MAX; + return string::to_string(INT_MAX); } } -int ComplexName::makePostfixUnique(const PostfixSet& postfixes) +std::string ComplexName::makePostfixUnique(const PostfixSet& postfixes) { // If our postfix is already in the set, change it to a unique value if (postfixes.find(_postFix) != postfixes.end()) diff --git a/radiant/namespace/ComplexName.h b/radiant/namespace/ComplexName.h index 534dbf4ecf..86bbb4b86c 100644 --- a/radiant/namespace/ComplexName.h +++ b/radiant/namespace/ComplexName.h @@ -3,19 +3,21 @@ #include #include -/// Set of unique integer postfixes -typedef std::set PostfixSet; +/// Set of unique postfixes, e.g. "1", "6" or "04" +typedef std::set PostfixSet; -/// Name consisting of initial text and optional unique-making numeric postfix +/// Name consisting of initial text and optional unique-making number-postfix +/// e.g. "Carl" + "6", or "Mary" + "03" class ComplexName { // Initial name text std::string _name; - // Numeric postfix. -1 is considered as invalid/empty postfix - int _postFix; + // The number postfix in string form. "-" is considered an invalid/empty postfix + std::string _postFix; public: + static const std::string EMPTY_POSTFIX; // "-" /// Construct a ComplexName from the given full name string ComplexName(const std::string& fullname); @@ -29,8 +31,8 @@ class ComplexName return _name; } - /// Get the numeric postfix (-1 indicates no postfix is used) - int getPostfix() const + /// Get the numeric postfix ("-" indicates no postfix is used) + std::string getPostfix() const { return _postFix; } @@ -43,5 +45,5 @@ class ComplexName * \param postfixes * Set of existing postfixes which must not be used. */ - int makePostfixUnique(const PostfixSet& postfixes); + std::string makePostfixUnique(const PostfixSet& postfixes); }; diff --git a/radiant/namespace/UniqueNameSet.h b/radiant/namespace/UniqueNameSet.h index 6bf4e47345..43022ec1bd 100644 --- a/radiant/namespace/UniqueNameSet.h +++ b/radiant/namespace/UniqueNameSet.h @@ -7,13 +7,13 @@ /** * \brief - * A set which maps name prefixes (e.g. "func_static_") to the set of integer + * A set which maps name prefixes (e.g. "func_static_") to the set of * postfixes which are used in the current map. */ class UniqueNameSet { // This maps name prefixes to a set of used postfixes - // e.g. "func_static_" => [1,3,4,5,10] + // e.g. "func_static_" => ["1","3","4","5","05","10"] // Allows fairly quick lookup of used names and postfixes typedef std::map Names; Names _names; @@ -126,7 +126,8 @@ class UniqueNameSet PostfixSet& postfixSet = found->second; ComplexName uniqueName(name); - int postfix = uniqueName.makePostfixUnique(postfixSet); + + std::string postfix = uniqueName.makePostfixUnique(postfixSet); postfixSet.insert(postfix); return uniqueName.getFullname();