mirror of
https://git.tesses.org/tesses50/crosslang.git
synced 2026-06-01 18:25:32 +00:00
Fix bug with classes, use slim exclusively, add package private data and change rehaul cmake configs
This commit is contained in:
@@ -1,321 +1,285 @@
|
||||
#include "CrossLang.hpp"
|
||||
|
||||
namespace Tesses::CrossLang {
|
||||
class ProcessObject : public TNativeObject {
|
||||
public:
|
||||
ProcessObject() {
|
||||
arguments = nullptr;
|
||||
environment = nullptr;
|
||||
}
|
||||
ProcessObject(GCList &ls) {
|
||||
arguments = TList::Create(ls);
|
||||
environment = TList::Create(ls);
|
||||
process.includeThisEnv = true;
|
||||
process.redirectStdIn = false;
|
||||
|
||||
process.redirectStdOut = false;
|
||||
|
||||
namespace Tesses::CrossLang
|
||||
{
|
||||
class ProcessObject : public TNativeObject {
|
||||
public:
|
||||
ProcessObject()
|
||||
{
|
||||
arguments=nullptr;
|
||||
environment=nullptr;
|
||||
|
||||
}
|
||||
ProcessObject(GCList& ls)
|
||||
{
|
||||
arguments = TList::Create(ls);
|
||||
environment = TList::Create(ls);
|
||||
process.includeThisEnv=true;
|
||||
process.redirectStdIn=false;
|
||||
|
||||
process.redirectStdOut=false;
|
||||
|
||||
process.redirectStdErr=false;
|
||||
}
|
||||
TList* arguments;
|
||||
TList* environment;
|
||||
Tesses::Framework::Platform::Process process;
|
||||
std::string TypeName()
|
||||
{
|
||||
return "Process";
|
||||
}
|
||||
void Mark()
|
||||
{
|
||||
if(this->marked) return;
|
||||
this->marked=true;
|
||||
if(arguments != nullptr) arguments->Mark();
|
||||
if(environment != nullptr) environment->Mark();
|
||||
}
|
||||
TObject CallMethod(GCList& ls, std::string key, std::vector<TObject> args)
|
||||
{
|
||||
if(key == "setFileName" && GetArgument(args,0,process.name))
|
||||
{
|
||||
return process.name;
|
||||
}
|
||||
if(key == "getFileName")
|
||||
{
|
||||
return process.name;
|
||||
}
|
||||
|
||||
if(key == "setRedirectStandardInput" && GetArgument(args,0,process.redirectStdIn))
|
||||
{
|
||||
return process.redirectStdIn;
|
||||
}
|
||||
if(key == "getRedirectStandardInput")
|
||||
{
|
||||
return process.redirectStdIn;
|
||||
}
|
||||
if(key == "setRedirectStandardOutput" && GetArgument(args,0,process.redirectStdOut))
|
||||
{
|
||||
return process.redirectStdOut;
|
||||
}
|
||||
if(key == "getRedirectStandardOutput")
|
||||
{
|
||||
return process.redirectStdOut;
|
||||
}
|
||||
if(key == "setRedirectStandardError" && GetArgument(args,0,process.redirectStdErr))
|
||||
{
|
||||
return process.redirectStdErr;
|
||||
}
|
||||
if(key == "getRedirectStandardError")
|
||||
{
|
||||
return process.redirectStdErr;
|
||||
}
|
||||
if(key == "setWorkingDirectory" && GetArgument(args,0,process.workingDirectory))
|
||||
{
|
||||
return process.workingDirectory;
|
||||
}
|
||||
if(key == "getWorkingDirectory")
|
||||
{
|
||||
return process.workingDirectory;
|
||||
}
|
||||
if(key == "setInheritParentEnvironment" && GetArgument(args,0,process.includeThisEnv))
|
||||
{
|
||||
return process.includeThisEnv;
|
||||
}
|
||||
if(key == "getInheritParentEnvironment")
|
||||
{
|
||||
return process.includeThisEnv;
|
||||
}
|
||||
if(key == "getArguments")
|
||||
{
|
||||
if(arguments == nullptr) return nullptr;
|
||||
return arguments;
|
||||
}
|
||||
if(key == "setArguments")
|
||||
{
|
||||
if(GetArgumentHeap(args,0,arguments))
|
||||
{
|
||||
return arguments;
|
||||
}
|
||||
}
|
||||
if(key == "getEnvironment")
|
||||
{
|
||||
if(environment == nullptr) return nullptr;
|
||||
return environment;
|
||||
}
|
||||
if(key == "getEnvironment")
|
||||
{
|
||||
if(GetArgumentHeap(args,0,environment))
|
||||
{
|
||||
return environment;
|
||||
}
|
||||
}
|
||||
if(key == "Start")
|
||||
{
|
||||
this->process.args.push_back(process.name);
|
||||
if(arguments != nullptr)
|
||||
{
|
||||
for(int64_t i = 0; i < arguments->Count(); i++)
|
||||
{
|
||||
TObject argVal=arguments->Get(i);
|
||||
std::string argValStr;
|
||||
if(GetObject(argVal,argValStr))
|
||||
this->process.args.push_back(argValStr);
|
||||
}
|
||||
}
|
||||
if(environment != nullptr)
|
||||
{
|
||||
for(int64_t i = 0; i < environment->Count(); i++)
|
||||
{
|
||||
TObject arg = environment->Get(i);
|
||||
std::string argstr;
|
||||
if(GetObject(arg,argstr))
|
||||
{
|
||||
auto kvp = Tesses::Framework::Http::HttpUtils::SplitString(argstr,"=",2);
|
||||
if(kvp.size()==2)
|
||||
{
|
||||
process.env.push_back(std::pair<std::string,std::string>(kvp[0],kvp[1]));
|
||||
}
|
||||
else if(kvp.size()==1)
|
||||
{
|
||||
process.env.push_back(std::pair<std::string,std::string>(kvp[0],""));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return process.Start();
|
||||
}
|
||||
if(key == "Join" || key == "WaitForExit")
|
||||
{
|
||||
return (int64_t)process.WaitForExit();
|
||||
}
|
||||
if(key == "getHasExited")
|
||||
{
|
||||
return process.HasExited();
|
||||
}
|
||||
if(key == "Terminate")
|
||||
{
|
||||
process.Kill(SIGTERM);
|
||||
}
|
||||
if(key == "CloseStdInNow")
|
||||
{
|
||||
process.CloseStdInNow();
|
||||
|
||||
}
|
||||
int64_t k;
|
||||
if(key == "Kill" && GetArgument(args,0,k))
|
||||
{
|
||||
process.Kill((int)k);
|
||||
}
|
||||
if(key == "getStandardInput")
|
||||
{
|
||||
return process.GetStdinStream();
|
||||
}
|
||||
if(key == "getStandardOutput")
|
||||
{
|
||||
return process.GetStdoutStream();
|
||||
}
|
||||
if(key == "getStandardError")
|
||||
{
|
||||
return process.GetStderrStream();
|
||||
}
|
||||
return Undefined();
|
||||
}
|
||||
};
|
||||
static TObject Process_Start(GCList& ls, std::vector<TObject> args, TRootEnvironment* env)
|
||||
{
|
||||
|
||||
//Process.Start({
|
||||
// FileName = "git",
|
||||
// Arguments = ["clone","https://gitea.site.tesses.net/tesses50/crosslang.git"],
|
||||
// Environment = [],
|
||||
// InheritParentEnvironment=true
|
||||
//})
|
||||
|
||||
TDictionary* dict;
|
||||
|
||||
if(GetArgumentHeap(args,0,dict))
|
||||
{
|
||||
auto process = TNativeObject::Create<ProcessObject>(ls);
|
||||
auto name = dict->GetValue("FileName");
|
||||
auto inh = dict->GetValue("InheritParentEnvironment");
|
||||
auto rStdIn = dict->GetValue("RedirectStandardInput");
|
||||
auto rStdOut = dict->GetValue("RedirectStandardOutput");
|
||||
|
||||
auto rStdErr = dict->GetValue("RedirectStandardError");
|
||||
auto workingDirectory = dict->GetValue("WorkingDirectory");
|
||||
process->process.includeThisEnv=true;
|
||||
process->process.redirectStdIn=false;
|
||||
|
||||
process->process.redirectStdOut=false;
|
||||
|
||||
process->process.redirectStdErr=false;
|
||||
GetObject(inh,process->process.includeThisEnv);
|
||||
GetObject(rStdIn,process->process.redirectStdIn);
|
||||
GetObject(rStdOut,process->process.redirectStdOut);
|
||||
GetObject(rStdErr,process->process.redirectStdErr);
|
||||
|
||||
GetObject(name,process->process.name);
|
||||
|
||||
Tesses::Framework::Filesystem::VFSPath wdPath;
|
||||
if(env->permissions.localfs)
|
||||
{
|
||||
process->process.workingDirectory = env->permissions.localfs->GetWorking().ToString();
|
||||
}
|
||||
|
||||
if(GetObject(workingDirectory,wdPath))
|
||||
{
|
||||
process->process.workingDirectory= wdPath.MakeAbsolute().ToString();
|
||||
}
|
||||
|
||||
GetObject(workingDirectory,process->process.workingDirectory);
|
||||
|
||||
|
||||
|
||||
process->process.args.push_back(process->process.name);
|
||||
auto argumentsO = dict->GetValue("Arguments");
|
||||
TList* arguments;
|
||||
if(GetObjectHeap(argumentsO,arguments))
|
||||
{
|
||||
for(int64_t i = 0; i < arguments->Count(); i++)
|
||||
{
|
||||
TObject arg = arguments->Get(i);
|
||||
std::string argstr;
|
||||
if(GetObject(arg,argstr))
|
||||
{
|
||||
process->process.args.push_back(argstr);
|
||||
}
|
||||
}
|
||||
}
|
||||
argumentsO = dict->GetValue("Environment");
|
||||
if(GetObjectHeap(argumentsO,arguments))
|
||||
{
|
||||
for(int64_t i = 0; i < arguments->Count(); i++)
|
||||
{
|
||||
TObject arg = arguments->Get(i);
|
||||
std::string argstr;
|
||||
if(GetObject(arg,argstr))
|
||||
{
|
||||
auto kvp = Tesses::Framework::Http::HttpUtils::SplitString(argstr,"=",2);
|
||||
if(kvp.size()==2)
|
||||
{
|
||||
process->process.env.push_back(std::pair<std::string,std::string>(kvp[0],kvp[1]));
|
||||
}
|
||||
else if(kvp.size()==1)
|
||||
{
|
||||
process->process.env.push_back(std::pair<std::string,std::string>(kvp[0],""));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if(process->process.Start())
|
||||
{
|
||||
return process;
|
||||
}
|
||||
process.redirectStdErr = false;
|
||||
}
|
||||
TList *arguments;
|
||||
TList *environment;
|
||||
Tesses::Framework::Platform::Process process;
|
||||
std::string TypeName() { return "Process"; }
|
||||
void Mark() {
|
||||
if (this->marked)
|
||||
return;
|
||||
this->marked = true;
|
||||
if (arguments != nullptr)
|
||||
arguments->Mark();
|
||||
if (environment != nullptr)
|
||||
environment->Mark();
|
||||
}
|
||||
TObject CallMethod(GCList &ls, std::string key, std::vector<TObject> args) {
|
||||
if (key == "setFileName" && GetArgument(args, 0, process.name)) {
|
||||
return process.name;
|
||||
}
|
||||
if (key == "getFileName") {
|
||||
return process.name;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
void TStd::RegisterProcess(std::shared_ptr<GC> gc,TRootEnvironment* env)
|
||||
{
|
||||
|
||||
env->permissions.canRegisterProcess=true;
|
||||
GCList ls(gc);
|
||||
TDictionary* dict = TDictionary::Create(ls);
|
||||
|
||||
gc->BarrierBegin();
|
||||
auto processStart = TExternalMethod::Create(ls,"Start a process",{"process_object"},[env](GCList& ls, std::vector<TObject> args)->TObject{
|
||||
return Process_Start(ls,args,env);
|
||||
});
|
||||
processStart->watch.push_back(env);
|
||||
dict->SetValue("Start",processStart);
|
||||
|
||||
|
||||
env->SetVariable("Process",dict);
|
||||
auto process = env->EnsureDictionary(gc,"New");
|
||||
auto newProcess = TExternalMethod::Create(ls, "Create process",{},[env](GCList& ls, std::vector<TObject> args)->TObject {
|
||||
auto obj= TNativeObject::Create<ProcessObject>(ls,ls);
|
||||
if(env->permissions.localfs)
|
||||
{
|
||||
obj->process.workingDirectory = env->permissions.localfs->GetWorking().ToString();
|
||||
if (key == "setRedirectStandardInput" &&
|
||||
GetArgument(args, 0, process.redirectStdIn)) {
|
||||
return process.redirectStdIn;
|
||||
}
|
||||
if (key == "getRedirectStandardInput") {
|
||||
return process.redirectStdIn;
|
||||
}
|
||||
if (key == "setRedirectStandardOutput" &&
|
||||
GetArgument(args, 0, process.redirectStdOut)) {
|
||||
return process.redirectStdOut;
|
||||
}
|
||||
if (key == "getRedirectStandardOutput") {
|
||||
return process.redirectStdOut;
|
||||
}
|
||||
if (key == "setRedirectStandardError" &&
|
||||
GetArgument(args, 0, process.redirectStdErr)) {
|
||||
return process.redirectStdErr;
|
||||
}
|
||||
if (key == "getRedirectStandardError") {
|
||||
return process.redirectStdErr;
|
||||
}
|
||||
if (key == "setWorkingDirectory" &&
|
||||
GetArgument(args, 0, process.workingDirectory)) {
|
||||
return process.workingDirectory;
|
||||
}
|
||||
if (key == "getWorkingDirectory") {
|
||||
return process.workingDirectory;
|
||||
}
|
||||
if (key == "setInheritParentEnvironment" &&
|
||||
GetArgument(args, 0, process.includeThisEnv)) {
|
||||
return process.includeThisEnv;
|
||||
}
|
||||
if (key == "getInheritParentEnvironment") {
|
||||
return process.includeThisEnv;
|
||||
}
|
||||
if (key == "getArguments") {
|
||||
if (arguments == nullptr)
|
||||
return nullptr;
|
||||
return arguments;
|
||||
}
|
||||
if (key == "setArguments") {
|
||||
if (GetArgumentHeap(args, 0, arguments)) {
|
||||
return arguments;
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
if (key == "getEnvironment") {
|
||||
if (environment == nullptr)
|
||||
return nullptr;
|
||||
return environment;
|
||||
}
|
||||
if (key == "getEnvironment") {
|
||||
if (GetArgumentHeap(args, 0, environment)) {
|
||||
return environment;
|
||||
}
|
||||
}
|
||||
if (key == "Start") {
|
||||
this->process.args.push_back(process.name);
|
||||
if (arguments != nullptr) {
|
||||
for (int64_t i = 0; i < arguments->Count(); i++) {
|
||||
TObject argVal = arguments->Get(i);
|
||||
std::string argValStr;
|
||||
if (GetObject(argVal, argValStr))
|
||||
this->process.args.push_back(argValStr);
|
||||
}
|
||||
}
|
||||
if (environment != nullptr) {
|
||||
for (int64_t i = 0; i < environment->Count(); i++) {
|
||||
TObject arg = environment->Get(i);
|
||||
std::string argstr;
|
||||
if (GetObject(arg, argstr)) {
|
||||
auto kvp =
|
||||
Tesses::Framework::Http::HttpUtils::SplitString(
|
||||
argstr, "=", 2);
|
||||
if (kvp.size() == 2) {
|
||||
process.env.push_back(
|
||||
std::pair<std::string, std::string>(kvp[0],
|
||||
kvp[1]));
|
||||
} else if (kvp.size() == 1) {
|
||||
process.env.push_back(
|
||||
std::pair<std::string, std::string>(kvp[0],
|
||||
""));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return process.Start();
|
||||
}
|
||||
if (key == "Join" || key == "WaitForExit") {
|
||||
return (int64_t)process.WaitForExit();
|
||||
}
|
||||
if (key == "getHasExited") {
|
||||
return process.HasExited();
|
||||
}
|
||||
if (key == "Terminate") {
|
||||
process.Kill(SIGTERM);
|
||||
}
|
||||
if (key == "CloseStdInNow") {
|
||||
process.CloseStdInNow();
|
||||
}
|
||||
int64_t k;
|
||||
if (key == "Kill" && GetArgument(args, 0, k)) {
|
||||
process.Kill((int)k);
|
||||
}
|
||||
if (key == "getStandardInput") {
|
||||
return process.GetStdinStream();
|
||||
}
|
||||
if (key == "getStandardOutput") {
|
||||
return process.GetStdoutStream();
|
||||
}
|
||||
if (key == "getStandardError") {
|
||||
return process.GetStderrStream();
|
||||
}
|
||||
return Undefined();
|
||||
}
|
||||
};
|
||||
static TObject Process_Start(GCList &ls, std::vector<TObject> args,
|
||||
TRootEnvironment *env) {
|
||||
|
||||
// Process.Start({
|
||||
// FileName = "git",
|
||||
// Arguments =
|
||||
// ["clone","https://gitea.site.tesses.net/tesses50/crosslang.git"],
|
||||
// Environment = [],
|
||||
// InheritParentEnvironment=true
|
||||
// })
|
||||
|
||||
TDictionary *dict;
|
||||
|
||||
if (GetArgumentHeap(args, 0, dict)) {
|
||||
auto process = TNativeObject::Create<ProcessObject>(ls);
|
||||
auto name = dict->GetValue("FileName");
|
||||
auto inh = dict->GetValue("InheritParentEnvironment");
|
||||
auto rStdIn = dict->GetValue("RedirectStandardInput");
|
||||
auto rStdOut = dict->GetValue("RedirectStandardOutput");
|
||||
|
||||
auto rStdErr = dict->GetValue("RedirectStandardError");
|
||||
auto workingDirectory = dict->GetValue("WorkingDirectory");
|
||||
process->process.includeThisEnv = true;
|
||||
process->process.redirectStdIn = false;
|
||||
|
||||
process->process.redirectStdOut = false;
|
||||
|
||||
process->process.redirectStdErr = false;
|
||||
GetObject(inh, process->process.includeThisEnv);
|
||||
GetObject(rStdIn, process->process.redirectStdIn);
|
||||
GetObject(rStdOut, process->process.redirectStdOut);
|
||||
GetObject(rStdErr, process->process.redirectStdErr);
|
||||
|
||||
GetObject(name, process->process.name);
|
||||
|
||||
Tesses::Framework::Filesystem::VFSPath wdPath;
|
||||
if (env->permissions.localfs) {
|
||||
process->process.workingDirectory =
|
||||
env->permissions.localfs->GetWorking().ToString();
|
||||
}
|
||||
|
||||
if (GetObject(workingDirectory, wdPath)) {
|
||||
process->process.workingDirectory =
|
||||
wdPath.MakeAbsolute().ToString();
|
||||
}
|
||||
|
||||
GetObject(workingDirectory, process->process.workingDirectory);
|
||||
|
||||
process->process.args.push_back(process->process.name);
|
||||
auto argumentsO = dict->GetValue("Arguments");
|
||||
TList *arguments;
|
||||
if (GetObjectHeap(argumentsO, arguments)) {
|
||||
for (int64_t i = 0; i < arguments->Count(); i++) {
|
||||
TObject arg = arguments->Get(i);
|
||||
std::string argstr;
|
||||
if (GetObject(arg, argstr)) {
|
||||
process->process.args.push_back(argstr);
|
||||
}
|
||||
}
|
||||
}
|
||||
argumentsO = dict->GetValue("Environment");
|
||||
if (GetObjectHeap(argumentsO, arguments)) {
|
||||
for (int64_t i = 0; i < arguments->Count(); i++) {
|
||||
TObject arg = arguments->Get(i);
|
||||
std::string argstr;
|
||||
if (GetObject(arg, argstr)) {
|
||||
auto kvp = Tesses::Framework::Http::HttpUtils::SplitString(
|
||||
argstr, "=", 2);
|
||||
if (kvp.size() == 2) {
|
||||
process->process.env.push_back(
|
||||
std::pair<std::string, std::string>(kvp[0],
|
||||
kvp[1]));
|
||||
} else if (kvp.size() == 1) {
|
||||
process->process.env.push_back(
|
||||
std::pair<std::string, std::string>(kvp[0], ""));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (process->process.Start()) {
|
||||
return process;
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void TStd::RegisterProcess(std::shared_ptr<GC> gc, TRootEnvironment *env) {
|
||||
|
||||
env->permissions.canRegisterProcess = true;
|
||||
GCList ls(gc);
|
||||
TDictionary *dict = TDictionary::Create(ls);
|
||||
|
||||
gc->BarrierBegin();
|
||||
auto processStart = TExternalMethod::Create(
|
||||
ls, "Start a process", {"process_object"},
|
||||
[env](GCList &ls, std::vector<TObject> args) -> TObject {
|
||||
return Process_Start(ls, args, env);
|
||||
});
|
||||
newProcess->watch.push_back(env);
|
||||
process->SetValue("Process",newProcess);
|
||||
//process->DeclareFunction(gc, "Process", "Create process",{},New_Process);
|
||||
process->DeclareFunction(gc, "CGIServer", "Create a CGI Server",{"path"},[](GCList& ls, std::vector<TObject> args)->TObject{
|
||||
processStart->watch.push_back(env);
|
||||
dict->SetValue("Start", processStart);
|
||||
|
||||
env->SetVariable("Process", dict);
|
||||
auto process = env->EnsureDictionary(gc, "New");
|
||||
auto newProcess = TExternalMethod::Create(
|
||||
ls, "Create process", {},
|
||||
[env](GCList &ls, std::vector<TObject> args) -> TObject {
|
||||
auto obj = TNativeObject::Create<ProcessObject>(ls, ls);
|
||||
if (env->permissions.localfs) {
|
||||
obj->process.workingDirectory =
|
||||
env->permissions.localfs->GetWorking().ToString();
|
||||
}
|
||||
return obj;
|
||||
});
|
||||
newProcess->watch.push_back(env);
|
||||
process->SetValue("Process", newProcess);
|
||||
// process->DeclareFunction(gc, "Process", "Create process",{},New_Process);
|
||||
process->DeclareFunction(
|
||||
gc, "CGIServer", "Create a CGI Server", {"path"},
|
||||
[](GCList &ls, std::vector<TObject> args) -> TObject {
|
||||
Tesses::Framework::Filesystem::VFSPath path;
|
||||
if(GetArgumentAsPath(args,0,path))
|
||||
{
|
||||
return std::make_shared<Tesses::Framework::Http::CGIServer>(path);
|
||||
if (GetArgumentAsPath(args, 0, path)) {
|
||||
return std::make_shared<Tesses::Framework::Http::CGIServer>(
|
||||
path);
|
||||
}
|
||||
return Undefined();
|
||||
});
|
||||
gc->BarrierEnd();
|
||||
}
|
||||
gc->BarrierEnd();
|
||||
}
|
||||
} // namespace Tesses::CrossLang
|
||||
|
||||
Reference in New Issue
Block a user