Skip to content

Commit

Permalink
ext/MinitScript: updated MinitScript
Browse files Browse the repository at this point in the history
  • Loading branch information
andreasdr committed Jan 8, 2025
1 parent 409a3b8 commit 4c404bf
Show file tree
Hide file tree
Showing 14 changed files with 266 additions and 63 deletions.
158 changes: 147 additions & 11 deletions ext/minitscript/src/minitscript/minitscript/ApplicationMethods.cpp
Original file line number Diff line number Diff line change
@@ -1,29 +1,38 @@
#include <array>
#include <cstdio>
#include <cstdlib>
#include <span>
#include <memory>
#include <span>
#include <vector>

#include <minitscript/minitscript.h>
#include <minitscript/minitscript/ApplicationMethods.h>
#include <minitscript/minitscript/MinitScript.h>
#include <minitscript/os/filesystem/FileSystem.h>
#include <minitscript/os/threading/Mutex.h>
#include <minitscript/os/threading/Thread.h>
#include <minitscript/utilities/Console.h>
#include <minitscript/utilities/Exception.h>
#include <minitscript/utilities/StringTools.h>

using std::array;
using std::make_unique;
using std::span;
using std::shared_ptr;
using std::unique_ptr;
using std::vector;

using minitscript::minitscript::ApplicationMethods;

using minitscript::minitscript::MinitScript;
using minitscript::os::filesystem::FileSystem;
using minitscript::utilities::Exception;

using _Console = minitscript::utilities::Console;
using _Exception = minitscript::utilities::Exception;
using _FileSystem = minitscript::os::filesystem::FileSystem;
using _Mutex = minitscript::os::threading::Mutex;
using _StringTools = minitscript::utilities::StringTools;
using _Thread = minitscript::os::threading::Thread;


void ApplicationMethods::registerConstants(MinitScript* minitScript) {
minitScript->setConstant("$application::EXITCODE_SUCCESS", MinitScript::Variable(static_cast<int64_t>(EXIT_SUCCESS)));
Expand Down Expand Up @@ -96,7 +105,7 @@ const string ApplicationMethods::execute(const string& command, int* exitCode, s
while (feof(pipe) == false) {
if (fgets(buffer.data(), buffer.size(), pipe) != nullptr) result += buffer.data();
}
} catch (Exception& exception) {
} catch (_Exception& exception) {
_Console::printLine("ApplicationMethods::execute(): An error occurred: " + string(exception.what()));
}
// get exit code, if we have a pipe
Expand All @@ -112,15 +121,15 @@ const string ApplicationMethods::execute(const string& command, int* exitCode, s
// store error to given string error pointer
if (error != nullptr) {
try {
*error = FileSystem::getContentAsString(
FileSystem::getPathName(errorFile),
FileSystem::getFileName(errorFile)
*error = _FileSystem::getContentAsString(
_FileSystem::getPathName(errorFile),
_FileSystem::getFileName(errorFile)
);
FileSystem::removeFile(
FileSystem::getPathName(errorFile),
FileSystem::getFileName(errorFile)
_FileSystem::removeFile(
_FileSystem::getPathName(errorFile),
_FileSystem::getFileName(errorFile)
);
} catch (Exception& exception) {
} catch (_Exception& exception) {
_Console::printLine("ApplicationMethods::execute(): An error occurred: " + string(exception.what()));
}
}
Expand Down Expand Up @@ -167,6 +176,133 @@ void ApplicationMethods::registerMethods(MinitScript* minitScript) {
};
minitScript->registerMethod(new MethodApplicationExecute(minitScript));
}
{
//
class MethodApplicationExecuteMultiple: public MinitScript::Method {
private:
MinitScript* minitScript { nullptr };
public:
MethodApplicationExecuteMultiple(MinitScript* minitScript):
MinitScript::Method(
{
{ .type = MinitScript::TYPE_ARRAY, .name = "commands", .optional = false, .reference = false, .nullable = false },
{ .type = MinitScript::TYPE_INTEGER, .name = "concurrency", .optional = true, .reference = false, .nullable = false }
},
MinitScript::TYPE_BOOLEAN
),
minitScript(minitScript) {}
const string getMethodName() override {
return "application.executeMultiple";
}
void executeMethod(span<MinitScript::Variable>& arguments, MinitScript::Variable& returnValue, const MinitScript::SubStatement& subStatement) override {
string command;
int64_t concurrency = 1;
if ((arguments.size() == 1 || arguments.size() == 2) &&
arguments[0].getType() == MinitScript::TYPE_ARRAY &&
MinitScript::getIntegerValue(arguments, 1, concurrency, true) == true) {
// collect commands
vector<string> commands;
auto arrayPtr = arguments[0].getArrayPointer();
if (arrayPtr != nullptr) {
for (auto arrayEntry: *arrayPtr) commands.push_back(arrayEntry->getValueAsString());
}
/**
* Execution commands container
*/
class ExecutionCommands {
private:
_Mutex mutex;
const vector<string>& commands;
int commandIdx { 0 };
public:
/**
* Constructor
* @param commands commands
*/
ExecutionCommands(const vector<string>& commands): mutex("cmdlist-mutex"), commands(commands) {
}
/**
* @return returns left command
*/
bool getCommand(string& command) {
mutex.lock();
if (commandIdx >= commands.size()) {
mutex.unlock();
return false;
}
command = commands[commandIdx++];
mutex.unlock();
return true;
}
/**
* Stop delivering commands
*/
void stop() {
mutex.lock();
commandIdx = commands.size();
mutex.unlock();
}
};
/**
* Execution thread
*/
class ExecutionThread: public _Thread {
private:
ExecutionCommands* executionCommands;
bool failure { false };
public:
/**
* Constructor
* @param commands commands
*/
ExecutionThread(ExecutionCommands* executionCommands): _Thread("execution-thread"), executionCommands(executionCommands) {
}
/**
* @returns returns if an error has occurred
*/
inline bool hadFailure() {
return failure;
}
/**
* Run
*/
void run() {
string command;
while (executionCommands->getCommand(command) == true) {
int exitCode;
string error;
_Console::printLine(command);
auto result = ApplicationMethods::execute(command, &exitCode, &error);
if (result.empty() == false)_Console::printLine(result);
if (exitCode != EXIT_SUCCESS) {
executionCommands->stop();
if (error.empty() == false)_Console::printLine(error);
failure = true;
}
}
}
};
// execute
ExecutionCommands executionCommands(commands);
vector<unique_ptr<ExecutionThread>> executionThreads;
executionThreads.resize(concurrency);
for (auto i = 0; i < concurrency; i++) executionThreads[i] = make_unique<ExecutionThread>(&executionCommands);
for (auto i = 0; i < concurrency; i++) executionThreads[i]->start();
for (auto i = 0; i < concurrency; i++) executionThreads[i]->join();
// failure
auto success = true;
for (auto i = 0; i < concurrency; i++) {
if (executionThreads[i]->hadFailure() == true) success = false;
}
returnValue.setValue(success);
//
} else {
MINITSCRIPT_METHODUSAGE_COMPLAIN(getMethodName());
}
}
};
minitScript->registerMethod(new MethodApplicationExecuteMultiple(minitScript));
}
//
if (minitScript->getContext() != nullptr) {
//
Expand Down
6 changes: 3 additions & 3 deletions ext/minitscript/src/minitscript/minitscript/ArrayMethods.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ void ArrayMethods::registerMethods(MinitScript* minitScript) {
void executeMethod(span<MinitScript::Variable>& arguments, MinitScript::Variable& returnValue, const MinitScript::SubStatement& subStatement) override {
returnValue.setType(MinitScript::TYPE_ARRAY);
for (const auto& argument: arguments) {
returnValue.pushArrayEntry(argument);
returnValue.pushArrayEntry(MinitScript::Variable::createNonReferenceVariable(&argument));
}
}
};
Expand Down Expand Up @@ -126,7 +126,7 @@ void ArrayMethods::registerMethods(MinitScript* minitScript) {
if (arguments.size() > 1 &&
arguments[0].getType() == MinitScript::TYPE_ARRAY) {
for (auto i = 1; i < arguments.size(); i++) {
arguments[0].pushArrayEntry(arguments[i]);
arguments[0].pushArrayEntry(MinitScript::Variable::createNonReferenceVariable(&arguments[i]));
}
} else {
MINITSCRIPT_METHODUSAGE_COMPLAIN(getMethodName());
Expand Down Expand Up @@ -190,7 +190,7 @@ void ArrayMethods::registerMethods(MinitScript* minitScript) {
if (arguments.size() == 3 &&
arguments[0].getType() == MinitScript::TYPE_ARRAY &&
MinitScript::getIntegerValue(arguments, 1, index) == true) {
arguments[0].setArrayEntry(index, arguments[2]);
arguments[0].setArrayEntry(index, MinitScript::Variable::createNonReferenceVariable(&arguments[2]));
} else {
MINITSCRIPT_METHODUSAGE_COMPLAIN(getMethodName());
}
Expand Down
17 changes: 9 additions & 8 deletions ext/minitscript/src/minitscript/minitscript/BaseMethods.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#include <span>
#include <unordered_map>
#include <utility>
#include <vector>

#include <minitscript/minitscript.h>
Expand Down Expand Up @@ -144,7 +145,7 @@ void BaseMethods::registerMethods(MinitScript* minitScript) {
// create method call arguments
vector<MinitScript::Variable> callArguments(1 + (arguments.size() - 3) / 2);
// this
callArguments[0] = move(arguments[1]);
callArguments[0] = std::move(arguments[1]);
// additional method call arguments
{
auto callArgumentIdx = 1;
Expand Down Expand Up @@ -176,7 +177,7 @@ void BaseMethods::registerMethods(MinitScript* minitScript) {
#endif
}
//
callArguments[callArgumentIdx] = move(arguments[argumentIdx + 1]);
callArguments[callArgumentIdx] = std::move(arguments[argumentIdx + 1]);
callArgumentIdx++;
}
}
Expand All @@ -191,12 +192,12 @@ void BaseMethods::registerMethods(MinitScript* minitScript) {
}
// write back arguments from call arguments
// this
arguments[1] = move(callArgumentsSpan[0]);
arguments[1] = std::move(callArgumentsSpan[0]);
// additional arguments
{
auto callArgumentIdx = 1;
for (auto argumentIdx = 3; argumentIdx < arguments.size(); argumentIdx+=2) {
arguments[argumentIdx] = move(callArgumentsSpan[callArgumentIdx]);
arguments[argumentIdx] = std::move(callArgumentsSpan[callArgumentIdx]);
callArgumentIdx++;
}
}
Expand Down Expand Up @@ -2394,10 +2395,10 @@ void BaseMethods::registerMethods(MinitScript* minitScript) {
// create method call arguments
vector<MinitScript::Variable> callArguments(arguments.size() - 2);
// this
callArguments[0] = move(arguments[0]);
callArguments[0] = std::move(arguments[0]);
//
for (auto argumentIdx = 3; argumentIdx < arguments.size(); argumentIdx++) {
callArguments[argumentIdx - 2] = move(arguments[argumentIdx]);
callArguments[argumentIdx - 2] = std::move(arguments[argumentIdx]);
}
//
span callArgumentsSpan(callArguments);
Expand All @@ -2411,11 +2412,11 @@ void BaseMethods::registerMethods(MinitScript* minitScript) {
//
// write back arguments from call arguments
// this
arguments[0] = move(callArguments[0]);
arguments[0] = std::move(callArguments[0]);
// additional arguments
{
for (auto argumentIdx = 3; argumentIdx < arguments.size(); argumentIdx++) {
arguments[argumentIdx] = move(callArguments[argumentIdx - 2]);
arguments[argumentIdx] = std::move(callArguments[argumentIdx - 2]);
}
}
} else {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#include <span>

#include <memory>
#include <span>
#include <utility>

#include <minitscript/minitscript.h>
#include <minitscript/minitscript/ContextMethods.h>
Expand Down Expand Up @@ -99,12 +99,12 @@ void ContextMethods::registerMethods(MinitScript* minitScript) {
#if defined (__clang__)
// Clang currently does not support initializing span using begin and end iterators,
vector<MinitScript::Variable> callArguments(arguments.size() - 2);
for (auto i = 2; i < arguments.size(); i++) callArguments[i - 2] = move(arguments[i]);
for (auto i = 2; i < arguments.size(); i++) callArguments[i - 2] = std::move(arguments[i]);
// call
span callArgumentsSpan(callArguments);
script->call(scriptIdx, callArgumentsSpan, returnValue);
// move back arguments
for (auto i = 2; i < arguments.size(); i++) arguments[i] = move(callArguments[i - 2]);
for (auto i = 2; i < arguments.size(); i++) arguments[i] = std::move(callArguments[i - 2]);
#else
span callArgumentsSpan(arguments.begin() + 2, arguments.end());
script->call(scriptIdx, callArgumentsSpan, returnValue);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,46 @@ void FileSystemMethods::registerMethods(MinitScript* minitScript) {
};
minitScript->registerMethod(new ScriptFileSystemGetFileSize(minitScript));
}
{
//
class ScriptFileSystemGetFileTimeStamp: public MinitScript::Method {
private:
MinitScript* minitScript { nullptr };
public:
ScriptFileSystemGetFileTimeStamp(MinitScript* minitScript):
MinitScript::Method(
{
{ .type = MinitScript::TYPE_STRING, .name = "pathName", .optional = false, .reference = false, .nullable = false },
{ .type = MinitScript::TYPE_STRING, .name = "fileName", .optional = false, .reference = false, .nullable = false }
},
MinitScript::TYPE_INTEGER,
false,
true
),
minitScript(minitScript) {
//
}
const string getMethodName() override {
return "filesystem.getFileTimeStamp";
}
void executeMethod(span<MinitScript::Variable>& arguments, MinitScript::Variable& returnValue, const MinitScript::SubStatement& subStatement) override {
string pathName;
string fileName;
if (arguments.size() == 2 &&
MinitScript::getStringValue(arguments, 0, pathName) == true &&
MinitScript::getStringValue(arguments, 1, fileName) == true) {
try {
returnValue.setValue(static_cast<int64_t>(_FileSystem::getFileTimeStamp(pathName, fileName)));
} catch (_Exception& exception) {
minitScript->_throw(string(exception.what()));
}
} else {
MINITSCRIPT_METHODUSAGE_COMPLAIN(getMethodName());
}
}
};
minitScript->registerMethod(new ScriptFileSystemGetFileTimeStamp(minitScript));
}
{
//
class ScriptFileSystemGetContentAsString: public MinitScript::Method {
Expand Down Expand Up @@ -750,7 +790,7 @@ void FileSystemMethods::registerMethods(MinitScript* minitScript) {
MinitScript::Method(
{
{ .type = MinitScript::TYPE_STRING, .name = "pathName", .optional = false, .reference = false, .nullable = false },
{ .type = MinitScript::TYPE_STRING, .name = "recursive", .optional = false, .reference = false, .nullable = false },
{ .type = MinitScript::TYPE_BOOLEAN, .name = "recursive", .optional = false, .reference = false, .nullable = false },
},
MinitScript::TYPE_NULL,
false,
Expand Down
2 changes: 1 addition & 1 deletion ext/minitscript/src/minitscript/minitscript/MapMethods.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ void MapMethods::registerMethods(MinitScript* minitScript) {
if (arguments.size() == 3 &&
arguments[0].getType() == MinitScript::TYPE_MAP &&
MinitScript::getStringValue(arguments, 1, key) == true) {
arguments[0].setMapEntry(key, arguments[2]);
arguments[0].setMapEntry(key, MinitScript::Variable::createNonReferenceVariable(&arguments[2]));
} else {
MINITSCRIPT_METHODUSAGE_COMPLAIN(getMethodName());
}
Expand Down
Loading

0 comments on commit 4c404bf

Please sign in to comment.