diff --git a/src/sst/core/impl/interactive/simpleDebug.cc b/src/sst/core/impl/interactive/simpleDebug.cc index 98727f57d..fb8277b0e 100644 --- a/src/sst/core/impl/interactive/simpleDebug.cc +++ b/src/sst/core/impl/interactive/simpleDebug.cc @@ -31,13 +31,14 @@ namespace SST::IMPL::Interactive { // Static Initialization +//TODO kg is there a naming convention for static vars? bool SimpleDebugger::autoCompleteEnable = true; std::ofstream SimpleDebugger::loggingFile; std::ifstream SimpleDebugger::replayFile; std::string SimpleDebugger::loggingFilePath = "sst-console.out"; std::string SimpleDebugger::replayFilePath = "sst-console.in"; bool SimpleDebugger::enLogging = false; -bool SimpleDebugger::confirm = true; +bool SimpleDebugger::confirm_ = true; SimpleDebugger::SimpleDebugger(Params& params) : InteractiveConsole() { @@ -736,7 +737,7 @@ SimpleDebugger::cmd_cd(std::vector& tokens) } bool loop_detected = false; - SST::Core::Serialization::ObjectMap* new_obj = obj_->selectVariable(selection, loop_detected); + SST::Core::Serialization::ObjectMap* new_obj = obj_->selectVariable(selection, loop_detected, confirm_); if ( !new_obj || (new_obj == obj_) ) { printf("Unknown object in cd command: %s\n", selection.c_str()); return false; @@ -1607,15 +1608,15 @@ SimpleDebugger::cmd_setConfirm(std::vector& tokens) } if ( (tokens[1] == "true") || (tokens[1] == "t") || (tokens[1] == "T") || (tokens[1] == "1") ) { - confirm = true; + confirm_ = true; return true; } else if ( (tokens[1] == "false") || (tokens[1] == "f") || (tokens[1] == "F") || (tokens[1] == "0") ) { - confirm = false; + confirm_ = false; return true; } - std::cout << "Invalid argument for confirm: must be true or false" << tokens[1] << std::endl; + std::cout << "Invalid argument for confirm: must be true or false. <" << tokens[1] << ">" << std::endl; return false; } @@ -1623,7 +1624,7 @@ bool SimpleDebugger::clear_watchlist() { - if ( confirm ) { + if ( confirm_ ) { std::string line; std::cout << "Do you want to delete all watchpoints? [yes, no]\n"; std::getline(std::cin, line); diff --git a/src/sst/core/impl/interactive/simpleDebug.h b/src/sst/core/impl/interactive/simpleDebug.h index 1f1e56d83..620ebfc78 100644 --- a/src/sst/core/impl/interactive/simpleDebug.h +++ b/src/sst/core/impl/interactive/simpleDebug.h @@ -297,7 +297,7 @@ class SimpleDebugger : public SST::InteractiveConsole // Keep track of all the WatchPoints std::vector> watch_points_; bool clear_watchlist(); - static bool confirm; // skk = true; // Ask for confirmation to clear watchlist + static bool confirm_; // skk = true; // Ask for confirmation to clear watchlist std::vector tokenize(std::vector& tokens, const std::string& input); diff --git a/src/sst/core/serialization/objectMap.cc b/src/sst/core/serialization/objectMap.cc index 2ada2008b..be0687da6 100644 --- a/src/sst/core/serialization/objectMap.cc +++ b/src/sst/core/serialization/objectMap.cc @@ -47,12 +47,12 @@ ObjectMap::selectParent() } ObjectMap* -ObjectMap::selectVariable(std::string name, bool& loop_detected) +ObjectMap::selectVariable(std::string name, bool& loop_detected, bool confirm) { // kg maybe there is a way we can go through this to detect problems // before changing objmap state to avoid memory corruption bugs. loop_detected = false; - ObjectMap* var = findVariable(name); + ObjectMap* var = findVariable(name, confirm); // TODO Would prefer this be a simple nullptr to avoid confusion (bugs) // If we get nullptr back, then it didn't exist. Just return this diff --git a/src/sst/core/serialization/objectMap.h b/src/sst/core/serialization/objectMap.h index bae7915d4..0746e4cd9 100644 --- a/src/sst/core/serialization/objectMap.h +++ b/src/sst/core/serialization/objectMap.h @@ -382,11 +382,12 @@ class ObjectMap TODO: prefer this return nullptr as bugs have occurred with incorrect use @param name Name of variable to select + @param confirm Prompt user to resolve duplicate match of name. Select first found if false. @return ObjectMap for specified variable, if it exists, this otherwise */ - ObjectMap* selectVariable(std::string name, bool& loop_detected); + ObjectMap* selectVariable(std::string name, bool& loop_detected, bool confirm = false); /** Adds a variable to this ObjectMap. NOTE: calls to this @@ -544,16 +545,52 @@ class ObjectMap Find a variable in this object map @param name Name of variable to find + @param confirm Prompt user to resolve duplicate match of name. Select first found if false. @return ObjectMap representing the requested variable if it is found, nullptr otherwise */ - ObjectMap* findVariable(const std::string& name) const + ObjectMap* findVariable(const std::string& name, bool confirm = false) const { +// TODO move body into objectMap.cc +#if 1 + // Would prefer we can uniquify the variable list whilst mapping and not use a multimap. + // Assuming multimap is sorted. + auto& variables = getVariables(); + auto range = variables.equal_range(name); + auto count = std::distance(range.first, range.second); + if ( count == 0 ) return nullptr; + if ( count == 1 || (!confirm) ) return range.first->second; + // more than 1 found and confirm is true + std::vector selections = {}; + for ( auto [it, end] = variables.equal_range(name); it != end; ++it ) + selections.push_back(it->second); + + std::cout << "[Found multiple entries for <" << name << ">]" << std::endl; + int remaining = 3; + int n; + std::string user_input; + while ( remaining-- > 0 ) { + for ( size_t i = 0; i < selections.size(); i++ ) + std::cout << i << ": " << selections[i]->getName() << " " << selections[i]->getType() << std::endl; + std::cout << "-1: None" << std::endl; + std::cout << "[?] "; + std::getline(std::cin, user_input); + std::stringstream ss(user_input); + if ( (ss >> n) && ss.eof() ) { + if ( n < 0 ) return nullptr; + if ( n < (int)selections.size() ) return selections[n]; + } + std::cout << "Invalid entry" << std::endl; + } + std::cout << "Too many attempts\n" << std::endl; + return nullptr; +#else auto& variables = getVariables(); for ( auto [it, end] = variables.equal_range(name); it != end; ++it ) return it->second; // For now, we return only the first match if multiple matches return nullptr; +#endif } /**