mirror of
https://github.com/amyinspace/MagicSetEditor2.git
synced 2026-06-10 04:57:00 -04:00
Add support for running script files (indicated by .mse-script extension) from the command line.
This commit is contained in:
+31
-7
@@ -14,12 +14,15 @@
|
||||
#include <script/profiler.hpp>
|
||||
#include <data/format/formats.hpp>
|
||||
#include <wx/process.h>
|
||||
#include <wx/wfstream.h>
|
||||
|
||||
DECLARE_TYPEOF_COLLECTION(ScriptParseError);
|
||||
|
||||
String read_utf8_line(wxInputStream& input, bool until_eof = false);
|
||||
|
||||
// ----------------------------------------------------------------------------- : Command line interface
|
||||
|
||||
CLISetInterface::CLISetInterface(const SetP& set, bool quiet)
|
||||
CLISetInterface::CLISetInterface(const SetP& set, bool quiet, bool run)
|
||||
: quiet(quiet)
|
||||
, our_context(nullptr)
|
||||
{
|
||||
@@ -29,11 +32,7 @@ CLISetInterface::CLISetInterface(const SetP& set, bool quiet)
|
||||
ei.allow_writes_outside = true;
|
||||
setExportInfoCwd();
|
||||
setSet(set);
|
||||
run();
|
||||
}
|
||||
|
||||
CLISetInterface::~CLISetInterface() {
|
||||
delete our_context;
|
||||
if (run) this->run();
|
||||
}
|
||||
|
||||
Context& CLISetInterface::getContext() {
|
||||
@@ -41,8 +40,9 @@ Context& CLISetInterface::getContext() {
|
||||
return set->getContext();
|
||||
} else {
|
||||
if (!our_context) {
|
||||
our_context = new Context();
|
||||
our_context = make_unique<Context>();
|
||||
init_script_functions(*our_context);
|
||||
scope = our_context->openScope();
|
||||
}
|
||||
return *our_context;
|
||||
}
|
||||
@@ -72,6 +72,30 @@ void CLISetInterface::setExportInfoCwd() {
|
||||
|
||||
// ----------------------------------------------------------------------------- : Running
|
||||
|
||||
String read_file(String const& filename) {
|
||||
wxFileInputStream stream(filename);
|
||||
if (!stream.IsOk()) throw FileNotFoundError(_("<unknown>"), filename);
|
||||
eat_utf8_bom(stream);
|
||||
return read_utf8_line(stream, true);
|
||||
}
|
||||
|
||||
bool run_script_file(String const& filename) {
|
||||
String contents = read_file(filename);
|
||||
// parse
|
||||
vector<ScriptParseError> errors;
|
||||
ScriptP script = parse(contents, nullptr, false, errors);
|
||||
if (!errors.empty()) {
|
||||
FOR_EACH(error, errors) cli.show_message(MESSAGE_ERROR, error.what());
|
||||
return false;
|
||||
}
|
||||
// run
|
||||
Context ctx;
|
||||
init_script_functions(ctx);
|
||||
ScriptValueP result = ctx.eval(*script, false);
|
||||
// ignore result
|
||||
return true;
|
||||
}
|
||||
|
||||
void CLISetInterface::run() {
|
||||
// show welcome logo
|
||||
if (!quiet) showWelcome();
|
||||
|
||||
@@ -17,15 +17,14 @@
|
||||
// ----------------------------------------------------------------------------- : Command line interface
|
||||
|
||||
class CLISetInterface : public SetView {
|
||||
public:
|
||||
public:
|
||||
/// The set is optional
|
||||
CLISetInterface(const SetP& set, bool quiet = false);
|
||||
~CLISetInterface();
|
||||
protected:
|
||||
CLISetInterface(const SetP& set, bool quiet = false, bool run = true);
|
||||
protected:
|
||||
virtual void onAction(const Action&, bool) {}
|
||||
virtual void onChangeSet();
|
||||
virtual void onBeforeChangeSet();
|
||||
private:
|
||||
private:
|
||||
bool quiet; ///< Supress prompts and other non-vital stuff
|
||||
bool running; ///< Still running?
|
||||
|
||||
@@ -40,7 +39,7 @@ class CLISetInterface : public SetView {
|
||||
|
||||
/// our own context, when no set is loaded
|
||||
Context& getContext();
|
||||
Context* our_context;
|
||||
unique_ptr<Context> our_context;
|
||||
size_t scope;
|
||||
|
||||
// export info, so we can write files
|
||||
@@ -48,5 +47,7 @@ class CLISetInterface : public SetView {
|
||||
void setExportInfoCwd();
|
||||
};
|
||||
|
||||
bool run_script_file(String const& filename);
|
||||
|
||||
// ----------------------------------------------------------------------------- : EOF
|
||||
#endif
|
||||
|
||||
@@ -172,7 +172,12 @@ void TextIOHandler::show_message(MessageType type, String const& message) {
|
||||
} else {
|
||||
*this << RED << _("ERROR: ") << NORMAL << replace_all(message,_("\n"),_("\n ")) << ENDL;
|
||||
}
|
||||
encountered_errors = true;
|
||||
flush();
|
||||
stream = stdout;
|
||||
if (raw_mode) raw_mode_status = max(raw_mode_status, type == MESSAGE_WARNING ? 1 : 2);
|
||||
}
|
||||
|
||||
bool TextIOHandler::shown_errors() const {
|
||||
return encountered_errors;
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@ extern const Char *BRIGHT, *NORMAL, *PARAM, *FILE_EXT, *GRAY, *RED, *ENDL;
|
||||
|
||||
/// Command line input / output handler
|
||||
class TextIOHandler {
|
||||
public:
|
||||
public:
|
||||
void init();
|
||||
|
||||
/// Do we have a console to read/write from/to?
|
||||
@@ -38,6 +38,7 @@ class TextIOHandler {
|
||||
|
||||
/// Show an error or warning message
|
||||
void show_message(MessageType type, String const& message);
|
||||
bool shown_errors() const;
|
||||
|
||||
/// Enable raw mode
|
||||
void enableRaw();
|
||||
@@ -45,13 +46,14 @@ class TextIOHandler {
|
||||
/// Has no effect unless enableRaw() was called
|
||||
void flushRaw();
|
||||
|
||||
private:
|
||||
private:
|
||||
bool have_console;
|
||||
bool escapes;
|
||||
FILE* stream;
|
||||
String buffer; ///< Buffer when not writing to console
|
||||
bool raw_mode;
|
||||
int raw_mode_status;
|
||||
bool encountered_errors = false;
|
||||
};
|
||||
|
||||
/// The global TextIOHandler object
|
||||
|
||||
@@ -92,6 +92,7 @@ int main(int argc, char** argv) {
|
||||
} else {
|
||||
// not a .com file, error message
|
||||
fprintf(stderr, "This executable should be named <something>.com\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
// win32 structures for child program
|
||||
|
||||
+7
-2
@@ -103,12 +103,12 @@ int MSE::OnRun() {
|
||||
wxFileName f(arg.Mid(0,arg.find_last_not_of(_("\\/"))+1));
|
||||
if (f.GetExt() == _("mse-symbol")) {
|
||||
// Show the symbol editor
|
||||
Window* wnd = new SymbolWindow(nullptr, argv[1]);
|
||||
Window* wnd = new SymbolWindow(nullptr, arg);
|
||||
wnd->Show();
|
||||
return runGUI();
|
||||
} else if (f.GetExt() == _("mse-set") || f.GetExt() == _("mse") || f.GetExt() == _("set")) {
|
||||
// Show the set window
|
||||
Window* wnd = new SetWindow(nullptr, import_set(argv[1]));
|
||||
Window* wnd = new SetWindow(nullptr, import_set(arg));
|
||||
wnd->Show();
|
||||
return runGUI();
|
||||
} else if (f.GetExt() == _("mse-installer")) {
|
||||
@@ -124,6 +124,11 @@ int MSE::OnRun() {
|
||||
PackagesWindow wnd(nullptr, installer);
|
||||
wnd.ShowModal();
|
||||
return EXIT_SUCCESS;
|
||||
} else if (f.GetExt() == _("mse-script")) {
|
||||
// Run a script file
|
||||
if (!run_script_file(arg)) return EXIT_FAILURE;
|
||||
if (cli.shown_errors()) return EXIT_FAILURE;
|
||||
return EXIT_SUCCESS;
|
||||
} else if (arg == _("--symbol-editor")) {
|
||||
Window* wnd = new SymbolWindow(nullptr);
|
||||
wnd->Show();
|
||||
|
||||
Reference in New Issue
Block a user