Commit 6d7f3a6c authored by twanvl's avatar twanvl

Added --script option for executing script files from the command line

parent 7c766a1a
...@@ -14,6 +14,9 @@ ...@@ -14,6 +14,9 @@
#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>
String read_utf8_line(wxInputStream& input, bool eat_bom = true, bool until_eof = false);
DECLARE_TYPEOF_COLLECTION(ScriptParseError); DECLARE_TYPEOF_COLLECTION(ScriptParseError);
...@@ -29,7 +32,9 @@ CLISetInterface::CLISetInterface(const SetP& set, bool quiet) ...@@ -29,7 +32,9 @@ CLISetInterface::CLISetInterface(const SetP& set, bool quiet)
ei.allow_writes_outside = true; ei.allow_writes_outside = true;
setExportInfoCwd(); setExportInfoCwd();
setSet(set); setSet(set);
run(); // show welcome logo
if (!quiet) showWelcome();
print_pending_errors();
} }
CLISetInterface::~CLISetInterface() { CLISetInterface::~CLISetInterface() {
...@@ -72,10 +77,7 @@ void CLISetInterface::setExportInfoCwd() { ...@@ -72,10 +77,7 @@ void CLISetInterface::setExportInfoCwd() {
// ----------------------------------------------------------------------------- : Running // ----------------------------------------------------------------------------- : Running
void CLISetInterface::run() { void CLISetInterface::run_interactive() {
// show welcome logo
if (!quiet) showWelcome();
print_pending_errors();
// loop // loop
running = true; running = true;
while (running) { while (running) {
...@@ -94,6 +96,52 @@ void CLISetInterface::run() { ...@@ -94,6 +96,52 @@ void CLISetInterface::run() {
} }
} }
bool CLISetInterface::run_script(ScriptP const& script) {
try {
WITH_DYNAMIC_ARG(export_info, &ei);
Context& ctx = getContext();
ScriptValueP result = ctx.eval(*script,false);
// show result (?)
cli << result->toCode() << ENDL;
return true;
} CATCH_ALL_ERRORS(true);
return false;
}
bool CLISetInterface::run_script_string(String const& command, bool multiline) {
vector<ScriptParseError> errors;
ScriptP script = parse(command,nullptr,false,errors);
if (errors.empty()) {
return run_script(script);
} else {
FOR_EACH(error,errors) {
if (multiline) {
cli.show_message(MESSAGE_ERROR, String::Format(_("On line %d:\t"), error.line) + error.what());
} else {
cli.show_message(MESSAGE_ERROR, error.what());
}
}
return false;
}
}
bool CLISetInterface::run_script_file(String const& filename) {
// read file
if (!wxFileExists(filename)) {
cli.show_message(MESSAGE_ERROR, _("File not found: ")+filename);
return false;
}
wxFileInputStream is(filename);
if (!is.Ok()) {
cli.show_message(MESSAGE_ERROR, _("Unable to open file: ")+filename);
return false;
}
wxBufferedInputStream bis(is);
String code = read_utf8_line(bis, true, true);
run_script_string(code);
return true;
}
void CLISetInterface::showWelcome() { void CLISetInterface::showWelcome() {
cli << _(" ___ \n") cli << _(" ___ \n")
_(" __ __ _ ___ _ ___ _ _ _ |__ \\ \n") _(" __ __ _ ___ _ ___ _ _ _ |__ \\ \n")
...@@ -198,19 +246,7 @@ void CLISetInterface::handleCommand(const String& command) { ...@@ -198,19 +246,7 @@ void CLISetInterface::handleCommand(const String& command) {
} else if (command == _("help")) { } else if (command == _("help")) {
cli << _("Use :help for help\n"); cli << _("Use :help for help\n");
} else { } else {
// parse command run_script_string(command);
vector<ScriptParseError> errors;
ScriptP script = parse(command,nullptr,false,errors);
if (!errors.empty()) {
FOR_EACH(error,errors) cli.show_message(MESSAGE_ERROR,error.what());
return;
}
// execute command
WITH_DYNAMIC_ARG(export_info, &ei);
Context& ctx = getContext();
ScriptValueP result = ctx.eval(*script,false);
// show result
cli << result->toCode() << ENDL;
} }
} catch (const Error& e) { } catch (const Error& e) {
cli.show_message(MESSAGE_ERROR,e.what()); cli.show_message(MESSAGE_ERROR,e.what());
......
...@@ -21,6 +21,11 @@ class CLISetInterface : public SetView { ...@@ -21,6 +21,11 @@ class CLISetInterface : public SetView {
/// The set is optional /// The set is optional
CLISetInterface(const SetP& set, bool quiet = false); CLISetInterface(const SetP& set, bool quiet = false);
~CLISetInterface(); ~CLISetInterface();
void run_interactive();
bool run_script(ScriptP const& script);
bool run_script_string(String const& code, bool multiline = false);
bool run_script_file(String const& filename);
protected: protected:
virtual void onAction(const Action&, bool) {} virtual void onAction(const Action&, bool) {}
virtual void onChangeSet(); virtual void onChangeSet();
...@@ -29,7 +34,6 @@ class CLISetInterface : public SetView { ...@@ -29,7 +34,6 @@ class CLISetInterface : public SetView {
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?
void run();
void showWelcome(); void showWelcome();
void showUsage(); void showUsage();
void handleCommand(const String& command); void handleCommand(const String& command);
......
...@@ -28,6 +28,8 @@ ...@@ -28,6 +28,8 @@
#include <wx/txtstrm.h> #include <wx/txtstrm.h>
#include <wx/socket.h> #include <wx/socket.h>
DECLARE_TYPEOF_COLLECTION(String);
// ----------------------------------------------------------------------------- : Main function/class // ----------------------------------------------------------------------------- : Main function/class
/// The application class for MSE. /// The application class for MSE.
...@@ -175,12 +177,14 @@ int MSE::OnRun() { ...@@ -175,12 +177,14 @@ int MSE::OnRun() {
cli << _("\n \tExport the cards in a set to image files,"); cli << _("\n \tExport the cards in a set to image files,");
cli << _("\n \tIMAGE is the same format as for 'export all card images'."); cli << _("\n \tIMAGE is the same format as for 'export all card images'.");
cli << _("\n\n ") << BRIGHT << _("--cli") << NORMAL << _(" [") cli << _("\n\n ") << BRIGHT << _("--cli") << NORMAL << _(" [")
<< PARAM << _("FILE") << NORMAL << _("] [")
<< BRIGHT << _("--quiet") << NORMAL << _("] [") << BRIGHT << _("--quiet") << NORMAL << _("] [")
<< BRIGHT << _("--raw") << NORMAL << _("]"); << BRIGHT << _("--raw") << NORMAL << _("] [")
<< BRIGHT << _("--script ") << NORMAL << PARAM << _("FILE") << NORMAL << _("] [")
<< PARAM << _("SETFILE") << NORMAL << _("]");
cli << _("\n \tStart the command line interface for performing commands on the set file."); cli << _("\n \tStart the command line interface for performing commands on the set file.");
cli << _("\n \tUse ") << BRIGHT << _("-q") << NORMAL << _(" or ") << BRIGHT << _("--quiet") << NORMAL << _(" to supress the startup banner and prompts."); cli << _("\n \tUse ") << BRIGHT << _("-q") << NORMAL << _(" or ") << BRIGHT << _("--quiet") << NORMAL << _(" to supress the startup banner and prompts.");
cli << _("\n \tUse ") << BRIGHT << _("-raw") << NORMAL << _(" for raw output mode."); cli << _("\n \tUse ") << BRIGHT << _("--raw") << NORMAL << _(" for raw output mode.");
cli << _("\n \tUse ") << BRIGHT << _("--script") << NORMAL << _(" to execute a script file.");
cli << _("\n\nRaw output mode is intended for use by other programs:"); cli << _("\n\nRaw output mode is intended for use by other programs:");
cli << _("\n - The only output is only in response to commands."); cli << _("\n - The only output is only in response to commands.");
cli << _("\n - For each command a single 'record' is written to the standard output."); cli << _("\n - For each command a single 'record' is written to the standard output.");
...@@ -200,20 +204,35 @@ int MSE::OnRun() { ...@@ -200,20 +204,35 @@ int MSE::OnRun() {
} else if (arg == _("--cli")) { } else if (arg == _("--cli")) {
// command line interface // command line interface
SetP set; SetP set;
vector<String> scripts;
bool quiet = false; bool quiet = false;
for (int i = 2 ; i < argc ; ++i) { for (int i = 2 ; i < argc ; ++i) {
String arg = argv[i]; String arg = argv[i];
wxFileName f(argv[i]); wxFileName f(argv[i]);
if (f.GetExt() == _("mse-set") || f.GetExt() == _("mse") || f.GetExt() == _("set")) { if (f.GetExt() == _("mse-set") || f.GetExt() == _("mse") || f.GetExt() == _("set")) {
set = import_set(arg); set = import_set(arg);
} else if (arg == _("-q") || arg == _("--quiet")) { } else if (arg == _("-q") || arg == _("--quiet") || arg == _("--silent")) {
quiet = true; quiet = true;
} else if (arg == _("-r") || arg == _("--raw")) { } else if (arg == _("-r") || arg == _("--raw")) {
quiet = true; quiet = true;
cli.enableRaw(); cli.enableRaw();
} else if ((arg == _("-s") || arg == _("--script")) && i+1 < argc) {
scripts.push_back(argv[i+1]);
++i;
} else if (arg == _("--color")) {
// ignore
} else {
handle_error(_("Invalid command line argument: ") + String(argv[i]));
} }
} }
CLISetInterface cli_interface(set,quiet); CLISetInterface cli_interface(set,quiet);
if (scripts.empty()) {
cli_interface.run_interactive();
} else {
FOR_EACH(script, scripts) {
cli_interface.run_script_file(script);
}
}
return EXIT_SUCCESS; return EXIT_SUCCESS;
} else if (arg == _("--export")) { } else if (arg == _("--export")) {
if (argc <= 2 || (argc <= 3 && starts_with(argv[2],_("--")))) { if (argc <= 2 || (argc <= 3 && starts_with(argv[2],_("--")))) {
...@@ -237,7 +256,7 @@ int MSE::OnRun() { ...@@ -237,7 +256,7 @@ int MSE::OnRun() {
export_images(set, set->cards, path, out, CONFLICT_NUMBER_OVERWRITE); export_images(set, set->cards, path, out, CONFLICT_NUMBER_OVERWRITE);
return EXIT_SUCCESS; return EXIT_SUCCESS;
} else { } else {
handle_error(_("Invalid command line argument:\n") + String(argv[1])); handle_error(_("Invalid command line argument: ") + String(argv[1]));
} }
} catch (const Error& e) { } catch (const Error& e) {
handle_error(e); handle_error(e);
...@@ -273,7 +292,12 @@ int MSE::OnExit() { ...@@ -273,7 +292,12 @@ int MSE::OnExit() {
void MSE::HandleEvent(wxEvtHandler *handler, wxEventFunction func, wxEvent& event) const { void MSE::HandleEvent(wxEvtHandler *handler, wxEventFunction func, wxEvent& event) const {
try { try {
wxApp::HandleEvent(handler, func, event); wxApp::HandleEvent(handler, func, event);
return;
} CATCH_ALL_ERRORS(true); } CATCH_ALL_ERRORS(true);
if (wxNotifyEvent* nev = dynamic_cast<wxNotifyEvent*>(&event)) {
// notifications about for instance list box selection will fail if an exception is thrown
nev->Veto();
}
} }
#if defined(_MSC_VER) && defined(_DEBUG) && defined(_CRT_WIDE) #if defined(_MSC_VER) && defined(_DEBUG) && defined(_CRT_WIDE)
......
...@@ -169,7 +169,7 @@ ...@@ -169,7 +169,7 @@
<Tool <Tool
Name="VCPostBuildEventTool" Name="VCPostBuildEventTool"
Description="Copy to output directory" Description="Copy to output directory"
CommandLine="copy &quot;$(OutDir)\mse.com&quot; &quot;..\build\$(ConfigurationName)\mse.com&quot;&#x0D;&#x0A;copy &quot;$(OutDir)\mse.com&quot; &quot;..\build\$(ConfigurationName) Unicode\mse.com&quot;&#x0D;&#x0A;copy &quot;$(OutDir)\mse.com&quot; &quot;..\build\Release Unicode fast build\mse.com&quot;&#x0D;&#x0A;" CommandLine="copy &quot;$(OutDir)\mse.com&quot; &quot;..\build\$(ConfigurationName)\mse.com&quot;&#x0D;&#x0A;copy &quot;$(OutDir)\mse.com&quot; &quot;..\build\$(ConfigurationName) Unicode\mse.com&quot;&#x0D;&#x0A;"
/> />
</Configuration> </Configuration>
</Configurations> </Configurations>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment