mirror of
https://github.com/amyinspace/MagicSetEditor2.git
synced 2026-06-12 21:47:00 -04:00
command line interface can now execute scripts
git-svn-id: svn://svn.code.sf.net/p/magicseteditor/code/trunk@1053 0fc631ac-6414-0410-93d0-97cfa31319b6
This commit is contained in:
+90
-16
@@ -10,11 +10,17 @@
|
|||||||
#include <util/error.hpp>
|
#include <util/error.hpp>
|
||||||
#include <cli/cli_main.hpp>
|
#include <cli/cli_main.hpp>
|
||||||
#include <cli/text_io_handler.hpp>
|
#include <cli/text_io_handler.hpp>
|
||||||
|
#include <script/functions/functions.hpp>
|
||||||
|
#include <data/format/formats.hpp>
|
||||||
|
#include <wx/process.h>
|
||||||
|
|
||||||
|
DECLARE_TYPEOF_COLLECTION(ScriptParseError);
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------- : Command line interface
|
// ----------------------------------------------------------------------------- : Command line interface
|
||||||
|
|
||||||
CLISetInterface::CLISetInterface()
|
CLISetInterface::CLISetInterface()
|
||||||
: quiet(false)
|
: quiet(false)
|
||||||
|
, our_context(nullptr)
|
||||||
{
|
{
|
||||||
if (!cli.haveConsole()) {
|
if (!cli.haveConsole()) {
|
||||||
throw Error(_("Can not run command line interface without a console;\nstart MSE with \"mse.com --cli\""));
|
throw Error(_("Can not run command line interface without a console;\nstart MSE with \"mse.com --cli\""));
|
||||||
@@ -22,6 +28,20 @@ CLISetInterface::CLISetInterface()
|
|||||||
run();
|
run();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CLISetInterface::~CLISetInterface() {
|
||||||
|
delete our_context;
|
||||||
|
}
|
||||||
|
|
||||||
|
Context& CLISetInterface::getContext() {
|
||||||
|
if (!our_context) {
|
||||||
|
our_context = new Context();
|
||||||
|
init_script_functions(*our_context);
|
||||||
|
}
|
||||||
|
return *our_context;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------- : Running
|
||||||
|
|
||||||
void CLISetInterface::run() {
|
void CLISetInterface::run() {
|
||||||
// show welcome logo
|
// show welcome logo
|
||||||
if (!quiet) showWelcome();
|
if (!quiet) showWelcome();
|
||||||
@@ -49,23 +69,77 @@ void CLISetInterface::showWelcome() {
|
|||||||
cli.flush();
|
cli.flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CLISetInterface::showUsage() {
|
||||||
|
cli << _(" Commands available from the prompt:\n\n");
|
||||||
|
cli << _(" <expression> Execute a script expression, display the result\n");
|
||||||
|
cli << _(" :help Show this help page.\n");
|
||||||
|
cli << _(" :load <setfile> Load a different set file.\n");
|
||||||
|
cli << _(" :quit Exit the MSE command line interface.\n");
|
||||||
|
cli << _(" :! <command> Perform a shell command.\n");
|
||||||
|
cli << _("\n Commands can be abreviated to their first letter if there is no ambiguity.\n\n");
|
||||||
|
}
|
||||||
|
|
||||||
void CLISetInterface::handleCommand(const String& command) {
|
void CLISetInterface::handleCommand(const String& command) {
|
||||||
if (command.empty()) {
|
try {
|
||||||
// empty, ignore
|
if (command.empty()) {
|
||||||
} else if (command == _(":q") || command == _(":quit")) {
|
// empty, ignore
|
||||||
if (!quiet) {
|
} else if (command.GetChar(0) == _(':')) {
|
||||||
cli << _("Goodbye\n"); cli.flush();
|
// :something
|
||||||
|
size_t space = min(command.find_first_of(_(' ')), command.size());
|
||||||
|
String before = command.substr(0,space);
|
||||||
|
String arg = space + 1 < command.size() ? command.substr(space+1) : wxEmptyString;
|
||||||
|
if (before == _(":q") || before == _(":quit")) {
|
||||||
|
if (!quiet) {
|
||||||
|
cli << _("Goodbye\n"); cli.flush();
|
||||||
|
}
|
||||||
|
running = false;
|
||||||
|
} else if (before == _(":?") || before == _(":h") || before == _(":help")) {
|
||||||
|
showUsage();
|
||||||
|
} else if (before == _(":l") || before == _(":load")) {
|
||||||
|
if (arg.empty()) {
|
||||||
|
cli << _("Give a filename to open.\n");
|
||||||
|
} else {
|
||||||
|
setSet(import_set(arg));
|
||||||
|
}
|
||||||
|
} else if (before == _(":!")) {
|
||||||
|
if (arg.empty()) {
|
||||||
|
cli << _("Give a shell command to execute.\n");
|
||||||
|
} else {
|
||||||
|
#ifdef __WXMSW__
|
||||||
|
_wsystem(arg.c_str());
|
||||||
|
#elif UNICODE
|
||||||
|
wxCharBuffer buf = arg.fn_str();
|
||||||
|
system(buf);
|
||||||
|
#else
|
||||||
|
system(arg.c_str());
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
cli << _("Unknown command, type :help for help.\n");
|
||||||
|
}
|
||||||
|
} else if (command == _("exit") || command == _("quit")) {
|
||||||
|
cli << _("Use :quit to quit\n");
|
||||||
|
} else if (command == _("help")) {
|
||||||
|
cli << _("Use :help for help\n");
|
||||||
|
} else {
|
||||||
|
// parse command
|
||||||
|
vector<ScriptParseError> errors;
|
||||||
|
ScriptP script = parse(command,set.get(),false,errors);
|
||||||
|
if (!errors.empty()) {
|
||||||
|
FOR_EACH(error,errors) showError(error.what());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// execute command
|
||||||
|
Context& ctx = set ? set->getContext() : getContext();
|
||||||
|
ScriptValueP result = ctx.eval(*script,false);
|
||||||
|
// show result
|
||||||
|
cli << result->toCode() << ENDL;
|
||||||
}
|
}
|
||||||
running = false;
|
} catch (const Error& e) {
|
||||||
} else if (command == _(":?") || command == _(":help")) {
|
showError(e.what());
|
||||||
// TODO show help
|
|
||||||
} else if (command == _("exit") || command == _("quit")) {
|
|
||||||
cli << _("Use :quit to quit\n"); cli.flush();
|
|
||||||
} else if (command.GetChar(0) == _(':')) {
|
|
||||||
cli << _("Unknown command, type :help for help.\n"); cli.flush();
|
|
||||||
} else {
|
|
||||||
// execute command
|
|
||||||
// TODO
|
|
||||||
cli << _("You said:\n") << command << ENDL; cli.flush();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CLISetInterface::showError(const String& error) {
|
||||||
|
cli << RED << _("ERROR: ") << NORMAL << replace_all(error,_("\n"),_(" ")) << ENDL;
|
||||||
|
}
|
||||||
|
|||||||
+13
-3
@@ -10,19 +10,29 @@
|
|||||||
// ----------------------------------------------------------------------------- : Includes
|
// ----------------------------------------------------------------------------- : Includes
|
||||||
|
|
||||||
#include <util/prec.hpp>
|
#include <util/prec.hpp>
|
||||||
|
#include <data/set.hpp>
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------- : Command line interface
|
// ----------------------------------------------------------------------------- : Command line interface
|
||||||
|
|
||||||
class CLISetInterface {
|
class CLISetInterface : public SetView {
|
||||||
public:
|
public:
|
||||||
CLISetInterface();
|
CLISetInterface();
|
||||||
|
~CLISetInterface();
|
||||||
|
protected:
|
||||||
|
void onAction(const Action&, bool) {}
|
||||||
private:
|
private:
|
||||||
bool quiet;
|
bool quiet; ///< Supress prompts and other non-vital stuff
|
||||||
bool running;
|
bool running; ///< Still running?
|
||||||
|
|
||||||
void run();
|
void run();
|
||||||
void showWelcome();
|
void showWelcome();
|
||||||
|
void showUsage();
|
||||||
void handleCommand(const String& command);
|
void handleCommand(const String& command);
|
||||||
|
void showError(const String& error);
|
||||||
|
|
||||||
|
/// our own context, when no set is loaded
|
||||||
|
Context& getContext();
|
||||||
|
Context* our_context;
|
||||||
};
|
};
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------- : EOF
|
// ----------------------------------------------------------------------------- : EOF
|
||||||
|
|||||||
@@ -41,6 +41,7 @@ struct Transfer {
|
|||||||
|
|
||||||
DWORD WINAPI TransferThread(Transfer*);
|
DWORD WINAPI TransferThread(Transfer*);
|
||||||
BOOL WINAPI HandleCtrlEvent(DWORD type);
|
BOOL WINAPI HandleCtrlEvent(DWORD type);
|
||||||
|
void CopyFileBuffer(HANDLE output, char* buffer, DWORD size);
|
||||||
void InitEscapeTranslation(HANDLE console);
|
void InitEscapeTranslation(HANDLE console);
|
||||||
void PerformEscapeCode(HANDLE console, char command, int argc, int argv[]);
|
void PerformEscapeCode(HANDLE console, char command, int argc, int argv[]);
|
||||||
|
|
||||||
@@ -158,12 +159,13 @@ BOOL WINAPI HandleCtrlEvent(DWORD type) {
|
|||||||
DWORD exit_code = 1;
|
DWORD exit_code = 1;
|
||||||
// try to exit child process cleanly
|
// try to exit child process cleanly
|
||||||
// TODO: don't exit child on Ctrl+C
|
// TODO: don't exit child on Ctrl+C
|
||||||
/*CopyFileBuffer(TODO,":quit\n",6);
|
CopyFileBuffer(in_mine,":quit\n",6);
|
||||||
|
CopyFileBuffer(out_real,":quit\n",6);
|
||||||
if (WaitForSingleObject(child_process_info.hProcess,100) == WAIT_OBJECT_0) {
|
if (WaitForSingleObject(child_process_info.hProcess,100) == WAIT_OBJECT_0) {
|
||||||
GetExitCodeProcess(child_process_info.hProcess, &exit_code);
|
GetExitCodeProcess(child_process_info.hProcess, &exit_code);
|
||||||
} else {*/
|
} else {
|
||||||
TerminateProcess(child_process_info.hProcess,1);
|
TerminateProcess(child_process_info.hProcess,1);
|
||||||
//}
|
}
|
||||||
// exit this process
|
// exit this process
|
||||||
ExitProcess(exit_code);
|
ExitProcess(exit_code);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|||||||
Reference in New Issue
Block a user