3232
3333namespace SST ::IMPL::Interactive {
3434
35- enum class ConsoleCommandGroup { GENERAL, NAVIGATION, STATE, WATCH, SIMULATION, LOGGING, MISC };
35+ enum class ConsoleCommandGroup { GENERAL, NAVIGATION, STATE, WATCH, SIMULATION, LOGGING, MISC, USER };
3636
3737const std::map<ConsoleCommandGroup, std::string> GroupText {
3838 { ConsoleCommandGroup::GENERAL, " General" },
@@ -42,16 +42,26 @@ const std::map<ConsoleCommandGroup, std::string> GroupText {
4242 { ConsoleCommandGroup::SIMULATION, " Simulation" },
4343 { ConsoleCommandGroup::LOGGING, " Logging" },
4444 { ConsoleCommandGroup::MISC, " Misc" },
45+ { ConsoleCommandGroup::USER, " User Defined" },
4546};
4647
48+ // Each bit of mask enables verbosity for different debug features.
49+ // This is primarily for developers.
4750enum class VERBOSITY_MASK : uint32_t {
4851 WATCHPOINTS = 0b0001'0000 // 0x10
4952};
5053
54+ enum class LINE_ENTRY_MODE : int {
55+ NORMAL, // line is executed as a command
56+ DEFINE, // line is captured in user defined command sequence
57+ DOCUMENT, // documenting a user defined command
58+ };
59+
5160// Encapsulate a console command.
5261class ConsoleCommand
5362{
5463public:
64+ // Constructor for built-in commands has callback
5565 ConsoleCommand (std::string str_long, std::string str_short, std::string str_help, ConsoleCommandGroup group,
5666 std::function<void (std::vector<std::string>& tokens)> func) :
5767 str_long_ (str_long),
@@ -60,17 +70,28 @@ class ConsoleCommand
6070 group_ (group),
6171 func_ (func)
6272 {}
63- const std::string& str_long () const { return str_long_; }
64- const std::string& str_short () const { return str_short_; }
65- const std::string& str_help () const { return str_help_; }
73+ // Constructor for user-defined commands
74+ ConsoleCommand (std::string str_long) :
75+ str_long_ (str_long),
76+ str_short_ (str_long),
77+ str_help_ (" user defined command" ),
78+ group_ (ConsoleCommandGroup::USER)
79+ {}
80+ ConsoleCommand () {}; // default constructor
81+ const std::string& str_long () const { return str_long_; }
82+ const std::string& str_short () const { return str_short_; }
83+ const std::string& str_help () const { return str_help_; }
84+ void setUserHelp (std::string& help) { str_help_ = help; }
85+
86+ // Command Execution
87+ void exec (std::vector<std::string>& tokens) { return func_ (tokens); }
88+
6689 const ConsoleCommandGroup& group () const { return group_; }
67- void exec (std::vector<std::string>& tokens) { return func_ (tokens); }
6890 bool match (const std::string& token)
6991 {
7092 std::string lctoken = toLower (token);
7193 if ( lctoken.size () == str_long_.size () && lctoken == toLower (str_long_) ) return true ;
7294 if ( lctoken.size () == str_short_.size () && lctoken == toLower (str_short_) ) return true ;
73-
7495 return false ;
7596 }
7697 friend std::ostream& operator <<(std::ostream& os, const ConsoleCommand c)
@@ -84,13 +105,14 @@ class ConsoleCommand
84105 std::string str_short_;
85106 std::string str_help_;
86107 ConsoleCommandGroup group_;
87- std::function<void (std::vector<std::string>& tokens)> func_;
108+ std::function<void (std::vector<std::string>& tokens)> func_ = {} ;
88109 std::string toLower (std::string s)
89110 {
90111 std::transform (s.begin (), s.end (), s.begin (), ::tolower);
91112 return s;
92113 }
93- };
114+
115+ }; // class ConsoleCommand
94116
95117class CommandHistoryBuffer
96118{
@@ -102,8 +124,10 @@ class CommandHistoryBuffer
102124 std::vector<std::string>& getBuffer ();
103125 enum BANG_RC { INVALID, ECHO_ONLY, EXEC, NOP };
104126 BANG_RC bang (const std::string& token, std::string& newcmd);
127+ void enable (bool en) { en_ = en; }
105128
106129private:
130+ bool en_ = true ;
107131 int cur_ = 0 ;
108132 int nxt_ = 0 ;
109133 int sz_ = 0 ;
@@ -117,6 +141,94 @@ class CommandHistoryBuffer
117141 bool searchAny (const std::string& s, std::string& newcmd);
118142};
119143
144+ class CommandRegistry
145+ {
146+
147+ public:
148+ // Construction
149+ CommandRegistry () {}
150+ CommandRegistry (const std::vector<ConsoleCommand> in) :
151+ registry (in)
152+ {}
153+ // Access
154+ std::vector<ConsoleCommand>& getRegistryVector () { return registry; }
155+ std::vector<ConsoleCommand>& getUserRegistryVector () { return user_registry; }
156+ enum SEARCH_TYPE { ALL, BUILTIN, USER };
157+ std::pair<ConsoleCommand, bool > const seek (std::string token, SEARCH_TYPE search_type);
158+ // User defined command entry
159+ bool beginUserCommand (std::string name);
160+ void appendUserCommand (std::string token0, std::string line);
161+ void commitUserCommand ();
162+ std::vector<std::string>* userCommandInsts (std::string key)
163+ {
164+ if ( user_defined_commands.find (key) == user_defined_commands.end () ) return nullptr ;
165+ return &user_defined_commands[key];
166+ }
167+ // User defined command help doc entry
168+ bool beginDocCommand (std::string name);
169+ void appendDocCommand (std::string line);
170+ void commitDocCommand ();
171+ bool commandIsEmpty (const std::string key)
172+ {
173+ if ( user_defined_commands.find (key) == user_defined_commands.end () ) return true ;
174+ if ( user_defined_commands[key].size () == 0 ) return true ;
175+ return false ;
176+ };
177+
178+ // User defined command help from vector
179+ void addHelp (std::string key, std::vector<std::string>& vec);
180+ // Detailed Command Help (public for now)
181+ std::map<std::string, std::string> cmdHelp;
182+
183+ private:
184+ // built-in commands
185+ std::vector<ConsoleCommand> registry = {};
186+ // user defined commands
187+ std::vector<ConsoleCommand> user_registry = {};
188+ std::map<std::string, std::vector<std::string>> user_defined_commands = {};
189+ std::string user_command_wip = " " ;
190+ std::vector<std::string> user_doc_wip = {};
191+
192+ // Last searched command with valid indicator
193+ std::pair<ConsoleCommand, bool > last_seek_command = {};
194+ }; // class CommandRegistry
195+
196+ // Support for nesting user defined commands
197+ class ExecState
198+ {
199+ public:
200+ // Constructor for entering a new user command
201+ ExecState (ConsoleCommand cmd, std::vector<std::string> tokens, std::vector<std::string>* insts) :
202+ cmd_ (cmd),
203+ tokens_ (tokens),
204+ insts_ (insts),
205+ index_ (0 ),
206+ user_ (true )
207+ {
208+ assert (insts_->size () > 0 );
209+ };
210+ ExecState () {};
211+ bool ret () { return ret_; }
212+ // Advance state and return the next user instruction
213+ std::string next ()
214+ {
215+ assert (user_);
216+ assert (!ret_);
217+ assert (insts_);
218+ assert (index_ < insts_->size ());
219+ ret_ = (index_ + 1 ) == insts_->size ();
220+ return insts_->at (index_++);
221+ }
222+
223+ private:
224+ ConsoleCommand cmd_ = {}; // user command in progress
225+ std::vector<std::string> tokens_ = {}; // command args
226+ std::vector<std::string>* insts_ = nullptr ; // command sequence
227+ size_t index_ = 0 ; // command pointer
228+ bool user_ = false ; // in user command
229+ bool ret_ = false ; // user command complete, return to caller
230+ }; // class ExecState
231+
120232class SimpleDebugger : public SST ::InteractiveConsole
121233{
122234
@@ -138,7 +250,8 @@ class SimpleDebugger : public SST::InteractiveConsole
138250 explicit SimpleDebugger(Params& params);
139251 ~SimpleDebugger();
140252
141- void execute(const std::string& msg) override;
253+ int execute(const std::string& msg) override;
254+ void summary() override;
142255
143256 // Callbacks from command line completions
144257 void get_listing_strings(std::list<std::string>&);
@@ -151,8 +264,9 @@ class SimpleDebugger : public SST::InteractiveConsole
151264 // directory as far as we can.
152265 std::vector<std::string> name_stack;
153266
154- SST::Core::Serialization::ObjectMap* obj_ = nullptr;
155- bool done = false;
267+ SST::Core::Serialization::ObjectMap* obj_ = nullptr;
268+ bool done = false;
269+ int retState = -1; // -1 DONE, -2 SUMAMRY, positive number is threadID
156270
157271 bool autoCompleteEnable = true;
158272
@@ -166,8 +280,12 @@ class SimpleDebugger : public SST::InteractiveConsole
166280 std::string replayFilePath = " sst-console.in" ;
167281 bool enLogging = false;
168282
169- // command injection
170- std::stringstream injectedCommand; // TODO use ConsoleCommand object
283+ // command injection (for sst --replay option)
284+ std::stringstream injectedCommand;
285+
286+ // execution state management for nested user commands
287+ ExecState eState = {};
288+ std::stack<ExecState> eStack = {};
171289
172290 // Keep a pointer to the ObjectMap for the top level Component
173291 SST::Core::Serialization::ObjectMapDeferred<BaseComponent>* base_comp_ = nullptr;
@@ -182,6 +300,8 @@ class SimpleDebugger : public SST::InteractiveConsole
182300 // Navigation
183301 void cmd_help(std::vector<std::string>& UNUSED(tokens));
184302 void cmd_verbose(std::vector<std::string>&(tokens));
303+ void cmd_info(std::vector<std::string>& UNUSED(tokens));
304+ void cmd_thread(std::vector<std::string>& tokens);
185305 void cmd_pwd(std::vector<std::string>& UNUSED(tokens));
186306 void cmd_ls(std::vector<std::string>& UNUSED(tokens));
187307 void cmd_cd(std::vector<std::string>& tokens);
@@ -192,6 +312,9 @@ class SimpleDebugger : public SST::InteractiveConsole
192312 void cmd_time(std::vector<std::string>& tokens);
193313 void cmd_watch(std::vector<std::string>& tokens);
194314 void cmd_unwatch(std::vector<std::string>& tokens);
315+ #ifdef __CT_RECURSE__
316+ void cmd_examine(std::vector<std::string>& tokens);
317+ #endif
195318
196319 // Simulation Control
197320 void cmd_run(std::vector<std::string>& tokens);
@@ -219,22 +342,25 @@ class SimpleDebugger : public SST::InteractiveConsole
219342 // Reset terminal
220343 void cmd_clear(std::vector<std::string>& UNUSED(tokens));
221344
345+ // User defined commands
346+ void cmd_define(std::vector<std::string>& tokens);
347+ void cmd_document(std::vector<std::string>& tokens);
348+
222349 // LLDB/GDB helper
223350 void cmd_spinThread(std::vector<std::string>& tokens);
224351
352+ // command entry point
225353 void dispatch_cmd(std::string& cmd);
226354
227355 // Command Registry
228- std::vector<ConsoleCommand> cmdRegistry;
229-
230- // Detailed Command Help
231- std::map<std::string, std::string> cmdHelp;
356+ CommandRegistry cmdRegistry;
232357
233358 // Command History
234359 CommandHistoryBuffer cmdHistoryBuf;
235360
236361 // Command Line Editor
237- CmdLineEditor cmdLineEditor;
362+ CmdLineEditor cmdLineEditor;
363+ LINE_ENTRY_MODE line_entry_mode = LINE_ENTRY_MODE::NORMAL;
238364
239365 // Verbosity controlled console printing
240366 uint32_t verbosity = 0;
0 commit comments