SST 16.0.0
Structural Simulation Toolkit
debugCommands.h
1// Copyright 2009-2026 NTESS. Under the terms
2// of Contract DE-NA0003525 with NTESS, the U.S.
3// Government retains certain rights in this software.
4//
5// Copyright (c) 2009-2026, NTESS
6// All rights reserved.
7//
8// This file is part of the SST software package. For license
9// information, see the LICENSE file in the top level directory of the
10// distribution.
11
12#ifndef SST_CORE_IMPL_INTERACTIVE_DEBUGCOMMANDS_H
13#define SST_CORE_IMPL_INTERACTIVE_DEBUGCOMMANDS_H
14
15#include <cassert>
16#include <cstddef>
17#include <functional>
18#include <map>
19#include <ostream>
20#include <string>
21#include <utility>
22#include <vector>
23
24namespace SST::IMPL::Interactive {
25
26enum class ConsoleCommandGroup { GENERAL, NAVIGATION, STATE, WATCH, SIMULATION, LOGGING, MISC, USER };
27enum class ExecutionType { SERIAL, THREAD, RANK_SERIAL, RANK_PARALLEL };
28
29const std::map<ConsoleCommandGroup, std::string> GroupText {
30 { ConsoleCommandGroup::GENERAL, "General" },
31 { ConsoleCommandGroup::NAVIGATION, "Navigation" },
32 { ConsoleCommandGroup::STATE, "State" },
33 { ConsoleCommandGroup::WATCH, "Watch/Trace" },
34 { ConsoleCommandGroup::SIMULATION, "Simulation" },
35 { ConsoleCommandGroup::LOGGING, "Logging" },
36 { ConsoleCommandGroup::MISC, "Misc" },
37 { ConsoleCommandGroup::USER, "User Defined" },
38};
39
40// Each bit of mask enables verbosity for different debug features.
41// This is primarily for developers.
42enum class VERBOSITY_MASK : uint32_t {
43 WATCHPOINTS = 0b0001'0000 // 0x10
44};
45
46enum class LINE_ENTRY_MODE : int {
47 NORMAL, // line is executed as a command
48 DEFINE, // line is captured in user defined command sequence
49 DOCUMENT, // documenting a user defined command
50};
51
52// Encapsulate a console command.
53class ConsoleCommand
54{
55public:
56 // Constructor for built-in commands has callback - console only
57 ConsoleCommand(std::string str_long, std::string str_short, std::string str_help, ConsoleCommandGroup group,
58 std::function<bool(std::string& cmd_str)> func) :
59 str_long_(str_long),
60 str_short_(str_short),
61 str_help_(str_help),
62 group_(group),
63 func_(func)
64 {}
65
66 // Constructor for built-in commands has callback - remote calls
67 ConsoleCommand(std::string str_long, std::string str_short, std::string str_help, ConsoleCommandGroup group,
68 ExecutionType exec_type, std::function<bool(std::string& cmd_str)> func_serial,
69 std::function<bool(std::string& cmd_str)> func_thread,
70 std::function<bool(std::string& cmd_str)> func_rank_serial,
71 std::function<bool(std::string& cmd_str)> func_rank_parallel,
72 std::function<bool(std::vector<std::string>& tokens)> func_remote) :
73 str_long_(str_long),
74 str_short_(str_short),
75 str_help_(str_help),
76 group_(group),
77 exec_type_(exec_type),
78 func_serial_(func_serial),
79 func_thread_(func_thread),
80 func_rank_serial_(func_rank_serial),
81 func_rank_parallel_(func_rank_parallel),
82 func_remote_(func_remote)
83 {
84 // Serial
85 if ( exec_type_ == ExecutionType::SERIAL ) {
86 func_ = func_serial_;
87 }
88 // Thread (single rank, multiple threads)
89 else if ( exec_type_ == ExecutionType::THREAD ) {
90 func_ = func_thread_;
91 }
92 // Rank Serial (multiple ranks, single thread per rank)
93 else if ( exec_type_ == ExecutionType::RANK_SERIAL ) {
94 func_ = func_rank_serial_;
95 }
96 // Rank Parallel (multiple ranks, multiple threads per rank)
97 else {
98 func_ = func_rank_parallel_;
99 }
100 }
101
102 // Constructor for user-defined commands
103 ConsoleCommand(std::string str_long) :
104 str_long_(str_long),
105 str_short_(str_long),
106 str_help_("user defined command"),
107 group_(ConsoleCommandGroup::USER)
108 {}
109
110 ConsoleCommand() {}; // default constructor
111 const std::string& str_long() const { return str_long_; }
112 const std::string& str_short() const { return str_short_; }
113 const std::string& str_help() const { return str_help_; }
114 void setUserHelp(std::string& help) { str_help_ = help; }
115 const ConsoleCommandGroup& group() const { return group_; }
116 // Command Execution
117 bool exec(std::string& cmd_str) { return func_(cmd_str); }
118 bool exec_serial(std::string& cmd_str) { return func_serial_(cmd_str); }
119 bool exec_thread(std::string& cmd_str) { return func_thread_(cmd_str); }
120 bool exec_rank_serial(std::string& cmd_str) { return func_rank_serial_(cmd_str); }
121 bool exec_rank_parallel(std::string& cmd_str) { return func_rank_parallel_(cmd_str); }
122 bool exec_remote(std::vector<std::string>& tokens) { return func_remote_(tokens); }
123 bool match(const std::string& token)
124 {
125 std::string lctoken = toLower(token);
126 if ( lctoken.size() == str_long_.size() && lctoken == toLower(str_long_) ) return true;
127 if ( lctoken.size() == str_short_.size() && lctoken == toLower(str_short_) ) return true;
128 return false;
129 }
130 friend std::ostream& operator<<(std::ostream& os, const ConsoleCommand c)
131 {
132 os << c.str_long_ << " (" << c.str_short_ << ") " << c.str_help_;
133 return os;
134 }
135
136private:
137 std::string str_long_;
138 std::string str_short_;
139 std::string str_help_;
140 ConsoleCommandGroup group_;
141 ExecutionType exec_type_;
142
143 std::function<bool(std::string& cmd_str)> func_;
144 std::function<bool(std::string& cmd_str)> func_serial_;
145 std::function<bool(std::string& cmd_str)> func_thread_;
146 std::function<bool(std::string& cmd_str)> func_rank_serial_;
147 std::function<bool(std::string& cmd_str)> func_rank_parallel_;
148 std::function<bool(std::vector<std::string>& tokens)> func_remote_;
149
150 std::string toLower(std::string s)
151 {
152 std::transform(s.begin(), s.end(), s.begin(), ::tolower);
153 return s;
154 }
155
156}; // class ConsoleCommand
157
158class CommandHistoryBuffer
159{
160public:
161 const int MAX_CMDS = 200;
162 CommandHistoryBuffer() { buf_.resize(MAX_CMDS); }
163 void append(std::string s);
164 void print(int num);
165 std::vector<std::string>& getBuffer();
166 enum BANG_RC { INVALID, ECHO_ONLY, EXEC, NOP };
167 BANG_RC bang(const std::string& token, std::string& newcmd);
168 void enable(bool en) { en_ = en; }
169
170private:
171 bool en_ = true;
172 int cur_ = 0;
173 int nxt_ = 0;
174 int sz_ = 0;
175 int count_ = 0;
176 std::vector<std::pair<std::size_t, std::string>> buf_; // actual history with index number
177 std::vector<std::string> stringBuffer_; // copy of history strings provided to command line editor
178 // support for ! history retrieval
179 bool findEvent(const std::string& s, std::string& newcmd);
180 bool findOffset(const std::string& s, std::string& newcmd);
181 bool searchFirst(const std::string& s, std::string& newcmd);
182 bool searchAny(const std::string& s, std::string& newcmd);
183};
184
185class CommandRegistry
186{
187
188public:
189 // Construction
190 CommandRegistry() {}
191 CommandRegistry(const std::vector<ConsoleCommand> in) :
192 registry(in)
193 {}
194 // Access
195 std::vector<ConsoleCommand>& getRegistryVector() { return registry; }
196 std::vector<ConsoleCommand>& getUserRegistryVector() { return user_registry; }
197 enum SEARCH_TYPE { ALL, BUILTIN, USER };
198 std::pair<ConsoleCommand, bool> const seek(std::string token, SEARCH_TYPE search_type);
199 // User defined command entry
200 bool beginUserCommand(std::string name);
201 void appendUserCommand(std::string token0, std::string line);
202 void commitUserCommand();
203 std::vector<std::string>* userCommandInsts(std::string key)
204 {
205 if ( user_defined_commands.find(key) == user_defined_commands.end() ) return nullptr;
206 return &user_defined_commands[key];
207 }
208 // User defined command help doc entry
209 bool beginDocCommand(std::string name);
210 void appendDocCommand(std::string line);
211 void commitDocCommand();
212 bool commandIsEmpty(const std::string key)
213 {
214 if ( user_defined_commands.find(key) == user_defined_commands.end() ) return true;
215 if ( user_defined_commands[key].size() == 0 ) return true;
216 return false;
217 };
218
219 // User defined command help from vector
220 void addHelp(std::string key, std::vector<std::string>& vec);
221 // Detailed Command Help (public for now)
222 std::map<std::string, std::string> cmdHelp;
223
224private:
225 // built-in commands
226 std::vector<ConsoleCommand> registry = {};
227 // user defined commands
228 std::vector<ConsoleCommand> user_registry = {};
229 std::map<std::string, std::vector<std::string>> user_defined_commands = {};
230 std::string user_command_wip = "";
231 std::vector<std::string> user_doc_wip = {};
232
233 // Last searched command with valid indicator
234 std::pair<ConsoleCommand, bool> last_seek_command = {};
235}; // class CommandRegistry
236
237// Support for nesting user defined commands
238class ExecState
239{
240public:
241 // Constructor for entering a new user command
242 ExecState(ConsoleCommand cmd, std::vector<std::string> tokens, std::vector<std::string>* insts) :
243 cmd_(cmd),
244 tokens_(tokens),
245 insts_(insts),
246 index_(0),
247 user_(true)
248 {
249 assert(insts_->size() > 0);
250 };
251 ExecState() {};
252 bool ret() { return ret_; }
253 // Advance state and return the next user instruction
254 std::string next()
255 {
256 assert(user_);
257 assert(!ret_);
258 assert(insts_);
259 assert(index_ < insts_->size());
260 ret_ = (index_ + 1) == insts_->size();
261 return insts_->at(index_++);
262 }
263
264private:
265 ConsoleCommand cmd_ = {}; // user command in progress
266 std::vector<std::string> tokens_ = {}; // command args
267 std::vector<std::string>* insts_ = nullptr; // command sequence
268 size_t index_ = 0; // command pointer
269 bool user_ = false; // in user command
270 bool ret_ = false; // user command complete, return to caller
271}; // class ExecState
272
273} // namespace SST::IMPL::Interactive
274
275#endif
Definition debugCommands.h:54