@@ -95,8 +95,33 @@ public Q_SLOTS:
95
95
96
96
private:
97
97
interfaces::Node& m_node;
98
+ bool executeConsoleHelpConsole (const std::vector<std::string>& parsed_command, const WalletModel* wallet_model, const bool exec_help = false );
99
+ bool executeConsoleOnlyCommand (const std::string& command, const WalletModel* wallet_model);
100
+ // std::map mapping strings to methods member of RPCExecutor class
101
+ // Keys must be strings with commands and (optionally) parameters in "canonical" form (separated by single space)
102
+ // Keys should match the beggining of user input commands (user commands can have more parameters than the key)
103
+ std::map<std::string, bool (RPCExecutor::*)(const std::vector<std::string>&, const WalletModel*, const bool )> m_method_map{
104
+ {" help-console" , &RPCExecutor::executeConsoleHelpConsole}};
98
105
};
99
106
107
+ /* *
108
+ * Small and fast parser supporting console command syntax, with limited functionality.
109
+ * Splits a command line string into a vector with command at position 0, and parameters after
110
+ *
111
+ * @param[in] strCommand Command line to parse
112
+ *
113
+ * @return a vector of strings with command and parameters
114
+ */
115
+ std::vector<std::string> parseHelper (const std::string& strCommand)
116
+ {
117
+ // Split while recognizing the several characters that can be used as separators in the GUI console
118
+ std::vector<std::string> vec{SplitString (strCommand, " ()," )};
119
+ // Remove empty strings produced by consecutive separators
120
+ auto should_remove{[](const std::string& str) { return str.empty (); }};
121
+ vec.erase (std::remove_if (vec.begin (), vec.end (), should_remove), vec.end ());
122
+ return vec;
123
+ }
124
+
100
125
/* * Class for handling RPC timers
101
126
* (used for e.g. re-locking the wallet after a timeout)
102
127
*/
@@ -414,35 +439,15 @@ void RPCExecutor::request(const QString &command, const WalletModel* wallet_mode
414
439
std::string result;
415
440
std::string executableCommand = command.toStdString () + " \n " ;
416
441
417
- // Catch the console-only-help command before RPC call is executed and reply with help text as-if a RPC reply.
418
- if (executableCommand == " help-console\n " ) {
419
- Q_EMIT reply (RPCConsole::CMD_REPLY, QString ((" \n "
420
- " This console accepts RPC commands using the standard syntax.\n "
421
- " example: getblockhash 0\n\n "
422
-
423
- " This console can also accept RPC commands using the parenthesized syntax.\n "
424
- " example: getblockhash(0)\n\n "
425
-
426
- " Commands may be nested when specified with the parenthesized syntax.\n "
427
- " example: getblock(getblockhash(0) 1)\n\n "
428
-
429
- " A space or a comma can be used to delimit arguments for either syntax.\n "
430
- " example: getblockhash 0\n "
431
- " getblockhash,0\n\n "
432
-
433
- " Named results can be queried with a non-quoted key string in brackets using the parenthesized syntax.\n "
434
- " example: getblock(getblockhash(0) 1)[tx]\n\n "
435
-
436
- " Results without keys can be queried with an integer in brackets using the parenthesized syntax.\n "
437
- " example: getblock(getblockhash(0),1)[tx][0]\n\n " )));
438
- return ;
439
- }
440
- if (!RPCConsole::RPCExecuteCommandLine (m_node, result, executableCommand, nullptr , wallet_model)) {
441
- Q_EMIT reply (RPCConsole::CMD_ERROR, QString (" Parse error: unbalanced ' or \" " ));
442
- return ;
442
+ // Attempt to execute console-only commands
443
+ if (!RPCExecutor::executeConsoleOnlyCommand (command.toStdString (), wallet_model)) {
444
+ // Send to the RPC command parser if not console-only
445
+ if (!RPCConsole::RPCExecuteCommandLine (m_node, result, executableCommand, nullptr , wallet_model)) {
446
+ Q_EMIT reply (RPCConsole::CMD_ERROR, QString (" Parse error: unbalanced ' or \" " ));
447
+ return ;
448
+ }
449
+ Q_EMIT reply (RPCConsole::CMD_REPLY, QString::fromStdString (result));
443
450
}
444
-
445
- Q_EMIT reply (RPCConsole::CMD_REPLY, QString::fromStdString (result));
446
451
}
447
452
catch (UniValue& objError)
448
453
{
@@ -463,6 +468,59 @@ void RPCExecutor::request(const QString &command, const WalletModel* wallet_mode
463
468
}
464
469
}
465
470
471
+ /* *
472
+ * @brief Executes the console-only command "help-console".
473
+ * @param parsed_command A vector of strings with command and parameters, usually generated by RPCExecutor::parseHelper
474
+ * @param wallet_model WalletModel to use for the command
475
+ * @return True if the command was executed, false otherwise.
476
+ */
477
+ bool RPCExecutor::executeConsoleHelpConsole (const std::vector<std::string>& parsed_command, const WalletModel* wallet_model, const bool exec_help)
478
+ {
479
+ // Reply with help text as-if a RPC reply.
480
+ Q_EMIT reply (RPCConsole::CMD_REPLY,
481
+ QString (" \n "
482
+ " This console accepts RPC commands using the standard syntax.\n "
483
+ " example: getblockhash 0\n\n "
484
+ " This console can also accept RPC commands using the parenthesized syntax.\n "
485
+ " example: getblockhash(0)\n\n "
486
+ " Commands may be nested when specified with the parenthesized syntax.\n "
487
+ " example: getblock(getblockhash(0) 1)\n\n "
488
+ " A space or a comma can be used to delimit arguments for either syntax.\n "
489
+ " example: getblockhash 0\n "
490
+ " getblockhash,0\n\n "
491
+ " Named results can be queried with a non-quoted key string in brackets using the parenthesized syntax.\n "
492
+ " example: getblock(getblockhash(0) 1)[tx]\n\n "
493
+ " Results without keys can be queried with an integer in brackets using the parenthesized syntax.\n "
494
+ " example: getblock(getblockhash(0),1)[tx][0]\n\n " ));
495
+ return true ;
496
+ }
497
+
498
+ /* *
499
+ * Catches console-only command before a RPC call is executed
500
+ *
501
+ * @param[in] command Command line to execute
502
+ * @param[in] wallet_model Wallet model to use
503
+ * @return true if command was handled by this method (even on errors), false otherwise
504
+ *
505
+ */
506
+ bool RPCExecutor::executeConsoleOnlyCommand (const std::string& command, const WalletModel* wallet_model)
507
+ {
508
+ // Parse command line into a vector of strings
509
+ const std::vector<std::string> parsed_command{parseHelper (command)};
510
+
511
+ if (parsed_command.empty ()) return false ;
512
+
513
+ std::string method = parsed_command[0 ];
514
+ bool exec_help = false ;
515
+ if (method == " help" && parsed_command.size () > 1 ) {
516
+ exec_help = true ;
517
+ method = parsed_command[1 ];
518
+ }
519
+ auto it_method = m_method_map.find (method);
520
+ if (it_method == m_method_map.end ()) return false ; // method not found
521
+ return (this ->*(it_method->second ))(parsed_command, wallet_model, exec_help);
522
+ }
523
+
466
524
RPCConsole::RPCConsole (interfaces::Node& node, const PlatformStyle *_platformStyle, QWidget *parent) :
467
525
QWidget(parent),
468
526
m_node(node),
0 commit comments