Skip to content

Commit

Permalink
Address issue #4859: DR thinks an entity name of the form "Cylinder01…
Browse files Browse the repository at this point in the history
…" 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.
  • Loading branch information
codereader committed Sep 24, 2018
1 parent e7bf170 commit 749e321
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 18 deletions.
20 changes: 13 additions & 7 deletions radiant/namespace/ComplexName.cpp
Expand Up @@ -4,43 +4,49 @@
#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
_name = string::trim_right_copy(fullname, "1234567890");

// Get the trimmed part and take it as postfix
std::string postFixStr = fullname.substr(_name.size());
_postFix = string::convert<int>(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())
Expand Down
18 changes: 10 additions & 8 deletions radiant/namespace/ComplexName.h
Expand Up @@ -3,19 +3,21 @@
#include <string>
#include <set>

/// Set of unique integer postfixes
typedef std::set<int> PostfixSet;
/// Set of unique postfixes, e.g. "1", "6" or "04"
typedef std::set<std::string> 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);
Expand All @@ -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;
}
Expand All @@ -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);
};
7 changes: 4 additions & 3 deletions radiant/namespace/UniqueNameSet.h
Expand Up @@ -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<std::string, PostfixSet> Names;
Names _names;
Expand Down Expand Up @@ -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();
Expand Down

0 comments on commit 749e321

Please sign in to comment.