Add support for running script files (indicated by .mse-script extension) from the command line.

This commit is contained in:
Twan van Laarhoven
2020-04-20 01:38:19 +02:00
parent a2b1d2bd80
commit 3dbd03511f
6 changed files with 55 additions and 17 deletions
+31 -7
View File
@@ -14,12 +14,15 @@
#include <script/profiler.hpp> #include <script/profiler.hpp>
#include <data/format/formats.hpp> #include <data/format/formats.hpp>
#include <wx/process.h> #include <wx/process.h>
#include <wx/wfstream.h>
DECLARE_TYPEOF_COLLECTION(ScriptParseError); DECLARE_TYPEOF_COLLECTION(ScriptParseError);
String read_utf8_line(wxInputStream& input, bool until_eof = false);
// ----------------------------------------------------------------------------- : Command line interface // ----------------------------------------------------------------------------- : Command line interface
CLISetInterface::CLISetInterface(const SetP& set, bool quiet) CLISetInterface::CLISetInterface(const SetP& set, bool quiet, bool run)
: quiet(quiet) : quiet(quiet)
, our_context(nullptr) , our_context(nullptr)
{ {
@@ -29,11 +32,7 @@ CLISetInterface::CLISetInterface(const SetP& set, bool quiet)
ei.allow_writes_outside = true; ei.allow_writes_outside = true;
setExportInfoCwd(); setExportInfoCwd();
setSet(set); setSet(set);
run(); if (run) this->run();
}
CLISetInterface::~CLISetInterface() {
delete our_context;
} }
Context& CLISetInterface::getContext() { Context& CLISetInterface::getContext() {
@@ -41,8 +40,9 @@ Context& CLISetInterface::getContext() {
return set->getContext(); return set->getContext();
} else { } else {
if (!our_context) { if (!our_context) {
our_context = new Context(); our_context = make_unique<Context>();
init_script_functions(*our_context); init_script_functions(*our_context);
scope = our_context->openScope();
} }
return *our_context; return *our_context;
} }
@@ -72,6 +72,30 @@ void CLISetInterface::setExportInfoCwd() {
// ----------------------------------------------------------------------------- : Running // ----------------------------------------------------------------------------- : 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() { void CLISetInterface::run() {
// show welcome logo // show welcome logo
if (!quiet) showWelcome(); if (!quiet) showWelcome();
+7 -6
View File
@@ -17,15 +17,14 @@
// ----------------------------------------------------------------------------- : Command line interface // ----------------------------------------------------------------------------- : Command line interface
class CLISetInterface : public SetView { class CLISetInterface : public SetView {
public: public:
/// The set is optional /// The set is optional
CLISetInterface(const SetP& set, bool quiet = false); CLISetInterface(const SetP& set, bool quiet = false, bool run = true);
~CLISetInterface(); protected:
protected:
virtual void onAction(const Action&, bool) {} virtual void onAction(const Action&, bool) {}
virtual void onChangeSet(); virtual void onChangeSet();
virtual void onBeforeChangeSet(); virtual void onBeforeChangeSet();
private: private:
bool quiet; ///< Supress prompts and other non-vital stuff bool quiet; ///< Supress prompts and other non-vital stuff
bool running; ///< Still running? bool running; ///< Still running?
@@ -40,7 +39,7 @@ class CLISetInterface : public SetView {
/// our own context, when no set is loaded /// our own context, when no set is loaded
Context& getContext(); Context& getContext();
Context* our_context; unique_ptr<Context> our_context;
size_t scope; size_t scope;
// export info, so we can write files // export info, so we can write files
@@ -48,5 +47,7 @@ class CLISetInterface : public SetView {
void setExportInfoCwd(); void setExportInfoCwd();
}; };
bool run_script_file(String const& filename);
// ----------------------------------------------------------------------------- : EOF // ----------------------------------------------------------------------------- : EOF
#endif #endif
+5
View File
@@ -172,7 +172,12 @@ void TextIOHandler::show_message(MessageType type, String const& message) {
} else { } else {
*this << RED << _("ERROR: ") << NORMAL << replace_all(message,_("\n"),_("\n ")) << ENDL; *this << RED << _("ERROR: ") << NORMAL << replace_all(message,_("\n"),_("\n ")) << ENDL;
} }
encountered_errors = true;
flush(); flush();
stream = stdout; stream = stdout;
if (raw_mode) raw_mode_status = max(raw_mode_status, type == MESSAGE_WARNING ? 1 : 2); if (raw_mode) raw_mode_status = max(raw_mode_status, type == MESSAGE_WARNING ? 1 : 2);
} }
bool TextIOHandler::shown_errors() const {
return encountered_errors;
}
+4 -2
View File
@@ -18,7 +18,7 @@ extern const Char *BRIGHT, *NORMAL, *PARAM, *FILE_EXT, *GRAY, *RED, *ENDL;
/// Command line input / output handler /// Command line input / output handler
class TextIOHandler { class TextIOHandler {
public: public:
void init(); void init();
/// Do we have a console to read/write from/to? /// Do we have a console to read/write from/to?
@@ -38,6 +38,7 @@ class TextIOHandler {
/// Show an error or warning message /// Show an error or warning message
void show_message(MessageType type, String const& message); void show_message(MessageType type, String const& message);
bool shown_errors() const;
/// Enable raw mode /// Enable raw mode
void enableRaw(); void enableRaw();
@@ -45,13 +46,14 @@ class TextIOHandler {
/// Has no effect unless enableRaw() was called /// Has no effect unless enableRaw() was called
void flushRaw(); void flushRaw();
private: private:
bool have_console; bool have_console;
bool escapes; bool escapes;
FILE* stream; FILE* stream;
String buffer; ///< Buffer when not writing to console String buffer; ///< Buffer when not writing to console
bool raw_mode; bool raw_mode;
int raw_mode_status; int raw_mode_status;
bool encountered_errors = false;
}; };
/// The global TextIOHandler object /// The global TextIOHandler object
+1
View File
@@ -92,6 +92,7 @@ int main(int argc, char** argv) {
} else { } else {
// not a .com file, error message // not a .com file, error message
fprintf(stderr, "This executable should be named <something>.com\n"); fprintf(stderr, "This executable should be named <something>.com\n");
return EXIT_FAILURE;
} }
// win32 structures for child program // win32 structures for child program
+7 -2
View File
@@ -103,12 +103,12 @@ int MSE::OnRun() {
wxFileName f(arg.Mid(0,arg.find_last_not_of(_("\\/"))+1)); wxFileName f(arg.Mid(0,arg.find_last_not_of(_("\\/"))+1));
if (f.GetExt() == _("mse-symbol")) { if (f.GetExt() == _("mse-symbol")) {
// Show the symbol editor // Show the symbol editor
Window* wnd = new SymbolWindow(nullptr, argv[1]); Window* wnd = new SymbolWindow(nullptr, arg);
wnd->Show(); wnd->Show();
return runGUI(); return runGUI();
} else if (f.GetExt() == _("mse-set") || f.GetExt() == _("mse") || f.GetExt() == _("set")) { } else if (f.GetExt() == _("mse-set") || f.GetExt() == _("mse") || f.GetExt() == _("set")) {
// Show the set window // Show the set window
Window* wnd = new SetWindow(nullptr, import_set(argv[1])); Window* wnd = new SetWindow(nullptr, import_set(arg));
wnd->Show(); wnd->Show();
return runGUI(); return runGUI();
} else if (f.GetExt() == _("mse-installer")) { } else if (f.GetExt() == _("mse-installer")) {
@@ -124,6 +124,11 @@ int MSE::OnRun() {
PackagesWindow wnd(nullptr, installer); PackagesWindow wnd(nullptr, installer);
wnd.ShowModal(); wnd.ShowModal();
return EXIT_SUCCESS; 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")) { } else if (arg == _("--symbol-editor")) {
Window* wnd = new SymbolWindow(nullptr); Window* wnd = new SymbolWindow(nullptr);
wnd->Show(); wnd->Show();