Fix bug with classes, use slim exclusively, add package private data and change rehaul cmake configs
This commit is contained in:
@@ -1,287 +1,255 @@
|
||||
#include "CrossLang.hpp"
|
||||
|
||||
namespace Tesses::CrossLang {
|
||||
static TList *VectorOfStringToList(GCList &ls, std::vector<std::string> &strs) {
|
||||
TList *list = TList::Create(ls);
|
||||
ls.GetGC()->BarrierBegin();
|
||||
for (auto &item : strs)
|
||||
list->Add(item);
|
||||
ls.GetGC()->BarrierEnd();
|
||||
return list;
|
||||
}
|
||||
static TList *EntriesToList(GCList &ls, std::vector<TClassEntry> &ents) {
|
||||
TList *list = TList::Create(ls);
|
||||
ls.GetGC()->BarrierBegin();
|
||||
for (auto &item : ents) {
|
||||
std::string modifier = "public";
|
||||
switch (item.modifier) {
|
||||
case TClassModifier::Public:
|
||||
modifier = "public";
|
||||
break;
|
||||
case TClassModifier::Private:
|
||||
modifier = "private";
|
||||
break;
|
||||
case TClassModifier::Protected:
|
||||
modifier = "protected";
|
||||
break;
|
||||
case TClassModifier::Static:
|
||||
modifier = "static";
|
||||
break;
|
||||
}
|
||||
|
||||
namespace Tesses::CrossLang
|
||||
{
|
||||
static TList* VectorOfStringToList(GCList& ls, std::vector<std::string>& strs)
|
||||
{
|
||||
TList* list = TList::Create(ls);
|
||||
ls.GetGC()->BarrierBegin();
|
||||
for(auto& item : strs)
|
||||
list->Add(item);
|
||||
ls.GetGC()->BarrierEnd();
|
||||
return list;
|
||||
list->Add(TDictionary::Create(
|
||||
ls,
|
||||
{TDItem("Name", item.name), TDItem("IsAbstract", item.isAbstract),
|
||||
TDItem("IsFunction", item.isFunction),
|
||||
TDItem("Documentation", item.documentation),
|
||||
TDItem("ChunkId", (int64_t)item.chunkId),
|
||||
TDItem("Arguments", VectorOfStringToList(ls, item.args)),
|
||||
TDItem("Modifier", modifier)}));
|
||||
}
|
||||
static TList* EntriesToList(GCList& ls, std::vector<TClassEntry>& ents)
|
||||
{
|
||||
TList* list=TList::Create(ls);
|
||||
ls.GetGC()->BarrierBegin();
|
||||
for(auto& item : ents)
|
||||
{
|
||||
std::string modifier = "public";
|
||||
switch(item.modifier)
|
||||
{
|
||||
case TClassModifier::Public:
|
||||
modifier = "public";
|
||||
break;
|
||||
case TClassModifier::Private:
|
||||
modifier = "private";
|
||||
break;
|
||||
case TClassModifier::Protected:
|
||||
modifier = "protected";
|
||||
break;
|
||||
case TClassModifier::Static:
|
||||
modifier = "static";
|
||||
break;
|
||||
}
|
||||
|
||||
list->Add(TDictionary::Create(ls,{
|
||||
TDItem("Name",item.name),
|
||||
TDItem("IsAbstract",item.isAbstract),
|
||||
TDItem("IsFunction",item.isFunction),
|
||||
TDItem("Documentation",item.documentation),
|
||||
TDItem("ChunkId",(int64_t)item.chunkId),
|
||||
TDItem("Arguments",VectorOfStringToList(ls,item.args)),
|
||||
TDItem("Modifier",modifier)
|
||||
}));
|
||||
ls.GetGC()->BarrierEnd();
|
||||
return list;
|
||||
}
|
||||
static TList *ClassInstanceToList(GCList &ls, TClassObject *co) {
|
||||
TList *list = TList::Create(ls);
|
||||
ls.GetGC()->BarrierBegin();
|
||||
for (auto &item : co->entries) {
|
||||
if (item.modifier == TClassModifier::Public) {
|
||||
list->Add(TDictionary::Create(
|
||||
ls,
|
||||
{TDItem("Name", item.name), TDItem("IsFunction", !item.canSet),
|
||||
TDItem("Owner", item.owner), TDItem("Value", item.value)}));
|
||||
}
|
||||
ls.GetGC()->BarrierEnd();
|
||||
return list;
|
||||
}
|
||||
static TList* ClassInstanceToList(GCList& ls, TClassObject* co)
|
||||
{
|
||||
TList* list=TList::Create(ls);
|
||||
ls.GetGC()->BarrierBegin();
|
||||
for(auto& item : co->entries)
|
||||
{
|
||||
if(item.modifier == TClassModifier::Public)
|
||||
{
|
||||
list->Add(TDictionary::Create(ls, {
|
||||
TDItem(
|
||||
"Name", item.name
|
||||
),
|
||||
TDItem(
|
||||
"IsFunction", !item.canSet
|
||||
),
|
||||
TDItem(
|
||||
"Owner", item.owner
|
||||
),
|
||||
TDItem(
|
||||
"Value", item.value
|
||||
)
|
||||
}));
|
||||
}
|
||||
}
|
||||
ls.GetGC()->BarrierEnd();
|
||||
return list;
|
||||
}
|
||||
TObject GetClassInfo(GCList& ls,TFile* f, uint32_t index)
|
||||
{
|
||||
return TDictionary::Create(ls,{
|
||||
TDItem("Name", JoinPeriod(f->classes.at(index).name)),
|
||||
TDItem("NameParts",VectorOfStringToList(ls,f->classes.at(index).name)),
|
||||
TDItem("Inherits", JoinPeriod(f->classes.at(index).inherits)),
|
||||
TDItem("InheritsParts",VectorOfStringToList(ls,f->classes.at(index).inherits)),
|
||||
TDItem("Documentation",f->classes.at(index).documentation),
|
||||
TDItem("Entries",EntriesToList(ls,f->classes.at(index).entry))
|
||||
});
|
||||
}
|
||||
static TObject Class_CreateInstance(TRootEnvironment* env,GCList& ls, std::vector<TObject> args)
|
||||
{
|
||||
TList* args_ls;
|
||||
if(!GetArgumentHeap(args,1,args_ls)) return nullptr;
|
||||
TList* list;
|
||||
TClassObject* obj;
|
||||
std::string str;
|
||||
if(GetArgumentHeap(args,0,list))
|
||||
{
|
||||
std::vector<std::string> clsName;
|
||||
for(int64_t i = 0; i < list->Count(); i++)
|
||||
{
|
||||
auto o = list->Get(i);
|
||||
if(GetObject(o,str)) clsName.push_back(str);
|
||||
}
|
||||
for(auto& item : env->classes)
|
||||
{
|
||||
auto& f=item.first->classes.at(item.second);
|
||||
|
||||
if(f.name.size() != clsName.size()) continue;
|
||||
|
||||
bool found=true;
|
||||
for(size_t i = 0; i < f.name.size(); i++)
|
||||
if(f.name[i] != clsName[i])
|
||||
{
|
||||
found=false;
|
||||
break;
|
||||
}
|
||||
if(found)
|
||||
{
|
||||
return TClassObject::Create(ls,item.first,item.second,env,args_ls->items);
|
||||
}
|
||||
else
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else if(GetArgument(args,0,str))
|
||||
{
|
||||
std::vector<std::string> clsName=Tesses::Framework::Http::HttpUtils::SplitString(str,".");
|
||||
for(auto& item : env->classes)
|
||||
{
|
||||
auto& f=item.first->classes.at(item.second);
|
||||
|
||||
if(f.name.size() != clsName.size()) continue;
|
||||
|
||||
bool found=true;
|
||||
for(size_t i = 0; i < f.name.size(); i++)
|
||||
if(f.name[i] != clsName[i])
|
||||
{
|
||||
found=false;
|
||||
break;
|
||||
}
|
||||
if(found)
|
||||
{
|
||||
return TClassObject::Create(ls,item.first,item.second,env,args_ls->items);
|
||||
|
||||
}
|
||||
else
|
||||
continue;
|
||||
}
|
||||
}
|
||||
ls.GetGC()->BarrierEnd();
|
||||
return list;
|
||||
}
|
||||
TObject GetClassInfo(GCList &ls, TFile *f, uint32_t index) {
|
||||
return TDictionary::Create(
|
||||
ls, {TDItem("Name", JoinPeriod(f->classes.at(index).name)),
|
||||
TDItem("NameParts",
|
||||
VectorOfStringToList(ls, f->classes.at(index).name)),
|
||||
TDItem("Inherits", JoinPeriod(f->classes.at(index).inherits)),
|
||||
TDItem("InheritsParts",
|
||||
VectorOfStringToList(ls, f->classes.at(index).inherits)),
|
||||
TDItem("Documentation", f->classes.at(index).documentation),
|
||||
TDItem("Entries", EntriesToList(ls, f->classes.at(index).entry))});
|
||||
}
|
||||
static TObject Class_CreateInstance(TRootEnvironment *env, GCList &ls,
|
||||
std::vector<TObject> args) {
|
||||
TList *args_ls;
|
||||
if (!GetArgumentHeap(args, 1, args_ls))
|
||||
return nullptr;
|
||||
}
|
||||
static TObject Class_GetClassNames(TRootEnvironment* env,GCList& ls, std::vector<TObject> args)
|
||||
{
|
||||
TList* list = TList::Create(ls);
|
||||
ls.GetGC()->BarrierBegin();
|
||||
for(auto& item : env->classes)
|
||||
{
|
||||
list->Add(JoinPeriod(item.first->classes.at(item.second).name));
|
||||
TList *list;
|
||||
TClassObject *obj;
|
||||
std::string str;
|
||||
if (GetArgumentHeap(args, 0, list)) {
|
||||
std::vector<std::string> clsName;
|
||||
for (int64_t i = 0; i < list->Count(); i++) {
|
||||
auto o = list->Get(i);
|
||||
if (GetObject(o, str))
|
||||
clsName.push_back(str);
|
||||
}
|
||||
ls.GetGC()->BarrierEnd();
|
||||
return list;
|
||||
}
|
||||
static TObject Class_GetInfo(TRootEnvironment* env,GCList& ls, std::vector<TObject> args)
|
||||
{
|
||||
|
||||
TList* list;
|
||||
TClassObject* obj;
|
||||
std::string str;
|
||||
if(GetArgumentHeap(args,0,list))
|
||||
{
|
||||
std::vector<std::string> clsName;
|
||||
for(int64_t i = 0; i < list->Count(); i++)
|
||||
{
|
||||
auto o = list->Get(i);
|
||||
if(GetObject(o,str)) clsName.push_back(str);
|
||||
}
|
||||
for(auto& item : env->classes)
|
||||
{
|
||||
auto& f=item.first->classes.at(item.second);
|
||||
|
||||
if(f.name.size() != clsName.size()) continue;
|
||||
|
||||
bool found=true;
|
||||
for(size_t i = 0; i < f.name.size(); i++)
|
||||
if(f.name[i] != clsName[i])
|
||||
{
|
||||
found=false;
|
||||
break;
|
||||
}
|
||||
if(found)
|
||||
{
|
||||
return GetClassInfo(ls,item.first,item.second);
|
||||
for (auto &item : env->classes) {
|
||||
auto &f = item.first->classes.at(item.second);
|
||||
|
||||
if (f.name.size() != clsName.size())
|
||||
continue;
|
||||
|
||||
bool found = true;
|
||||
for (size_t i = 0; i < f.name.size(); i++)
|
||||
if (f.name[i] != clsName[i]) {
|
||||
found = false;
|
||||
break;
|
||||
}
|
||||
else
|
||||
continue;
|
||||
}
|
||||
if (found) {
|
||||
return TClassObject::Create(ls, item.first, item.second, env,
|
||||
args_ls->items);
|
||||
} else
|
||||
continue;
|
||||
}
|
||||
else if(GetArgument(args,0,str))
|
||||
{
|
||||
std::vector<std::string> clsName=Tesses::Framework::Http::HttpUtils::SplitString(str,".");
|
||||
for(auto& item : env->classes)
|
||||
{
|
||||
auto& f=item.first->classes.at(item.second);
|
||||
|
||||
if(f.name.size() != clsName.size()) continue;
|
||||
|
||||
bool found=true;
|
||||
for(size_t i = 0; i < f.name.size(); i++)
|
||||
if(f.name[i] != clsName[i])
|
||||
{
|
||||
found=false;
|
||||
break;
|
||||
}
|
||||
if(found)
|
||||
{
|
||||
return GetClassInfo(ls,item.first,item.second);
|
||||
} else if (GetArgument(args, 0, str)) {
|
||||
std::vector<std::string> clsName =
|
||||
Tesses::Framework::Http::HttpUtils::SplitString(str, ".");
|
||||
for (auto &item : env->classes) {
|
||||
auto &f = item.first->classes.at(item.second);
|
||||
|
||||
if (f.name.size() != clsName.size())
|
||||
continue;
|
||||
|
||||
bool found = true;
|
||||
for (size_t i = 0; i < f.name.size(); i++)
|
||||
if (f.name[i] != clsName[i]) {
|
||||
found = false;
|
||||
break;
|
||||
}
|
||||
else
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else if(GetArgumentHeap(args,0,obj))
|
||||
{
|
||||
return GetClassInfo(ls,obj->file,obj->classIndex);
|
||||
}
|
||||
if (found) {
|
||||
return TClassObject::Create(ls, item.first, item.second, env,
|
||||
args_ls->items);
|
||||
|
||||
return nullptr;
|
||||
} else
|
||||
continue;
|
||||
}
|
||||
}
|
||||
void TStd::RegisterClass(std::shared_ptr<GC> gc, TRootEnvironment* env)
|
||||
{
|
||||
GCList ls(gc);
|
||||
env->permissions.canRegisterClass=true;
|
||||
TDictionary* cls= env->EnsureDictionary(gc, "Class");
|
||||
gc->BarrierBegin();
|
||||
|
||||
TExternalMethod* ext = TExternalMethod::Create(ls ,"Get the class info",{"classInstanceOrClassName"},[env](GCList& ls, std::vector<TObject> args)->TObject {
|
||||
return Class_GetInfo(env,ls,args);
|
||||
});
|
||||
ext->watch.push_back(env);
|
||||
|
||||
cls->SetValue("GetInfo",ext);
|
||||
return nullptr;
|
||||
}
|
||||
static TObject Class_GetClassNames(TRootEnvironment *env, GCList &ls,
|
||||
std::vector<TObject> args) {
|
||||
TList *list = TList::Create(ls);
|
||||
ls.GetGC()->BarrierBegin();
|
||||
for (auto &item : env->classes) {
|
||||
list->Add(JoinPeriod(item.first->classes.at(item.second).name));
|
||||
}
|
||||
ls.GetGC()->BarrierEnd();
|
||||
return list;
|
||||
}
|
||||
static TObject Class_GetInfo(TRootEnvironment *env, GCList &ls,
|
||||
std::vector<TObject> args) {
|
||||
|
||||
ext = TExternalMethod::Create(ls ,"Get the class names",{},[env](GCList& ls, std::vector<TObject> args)->TObject {
|
||||
return Class_GetClassNames(env,ls,args);
|
||||
});
|
||||
ext->watch.push_back(env);
|
||||
|
||||
cls->SetValue("GetClassNames",ext);
|
||||
ext = TExternalMethod::Create(ls ,"Create an instance of class",{"name","args"},[env](GCList& ls, std::vector<TObject> args)->TObject {
|
||||
return Class_CreateInstance(env,ls,args);
|
||||
});
|
||||
ext->watch.push_back(env);
|
||||
|
||||
cls->SetValue("CreateInstance",ext);
|
||||
cls->DeclareFunction(gc,"Name","Get class name via instance",{"instance"},[](GCList& ls, std::vector<TObject> args)->TObject {
|
||||
TClassObject* cls;
|
||||
if(GetArgumentHeap(args,0,cls))
|
||||
{
|
||||
return cls->name;
|
||||
}
|
||||
return "";
|
||||
});
|
||||
TList *list;
|
||||
TClassObject *obj;
|
||||
std::string str;
|
||||
if (GetArgumentHeap(args, 0, list)) {
|
||||
std::vector<std::string> clsName;
|
||||
for (int64_t i = 0; i < list->Count(); i++) {
|
||||
auto o = list->Get(i);
|
||||
if (GetObject(o, str))
|
||||
clsName.push_back(str);
|
||||
}
|
||||
for (auto &item : env->classes) {
|
||||
auto &f = item.first->classes.at(item.second);
|
||||
|
||||
if (f.name.size() != clsName.size())
|
||||
continue;
|
||||
|
||||
cls->DeclareFunction(gc, "GetInstanceInfo", "Get the instance specific info, including current values", {}, [](GCList& ls, std::vector<TObject> args)->TObject {
|
||||
TClassObject* co;
|
||||
if(GetArgumentHeap(args, 0, co))
|
||||
{
|
||||
bool found = true;
|
||||
for (size_t i = 0; i < f.name.size(); i++)
|
||||
if (f.name[i] != clsName[i]) {
|
||||
found = false;
|
||||
break;
|
||||
}
|
||||
if (found) {
|
||||
return GetClassInfo(ls, item.first, item.second);
|
||||
} else
|
||||
continue;
|
||||
}
|
||||
} else if (GetArgument(args, 0, str)) {
|
||||
std::vector<std::string> clsName =
|
||||
Tesses::Framework::Http::HttpUtils::SplitString(str, ".");
|
||||
for (auto &item : env->classes) {
|
||||
auto &f = item.first->classes.at(item.second);
|
||||
|
||||
if (f.name.size() != clsName.size())
|
||||
continue;
|
||||
|
||||
bool found = true;
|
||||
for (size_t i = 0; i < f.name.size(); i++)
|
||||
if (f.name[i] != clsName[i]) {
|
||||
found = false;
|
||||
break;
|
||||
}
|
||||
if (found) {
|
||||
return GetClassInfo(ls, item.first, item.second);
|
||||
} else
|
||||
continue;
|
||||
}
|
||||
} else if (GetArgumentHeap(args, 0, obj)) {
|
||||
return GetClassInfo(ls, obj->file, obj->classIndex);
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
void TStd::RegisterClass(std::shared_ptr<GC> gc, TRootEnvironment *env) {
|
||||
GCList ls(gc);
|
||||
env->permissions.canRegisterClass = true;
|
||||
TDictionary *cls = env->EnsureDictionary(gc, "Class");
|
||||
gc->BarrierBegin();
|
||||
|
||||
TExternalMethod *ext = TExternalMethod::Create(
|
||||
ls, "Get the class info", {"classInstanceOrClassName"},
|
||||
[env](GCList &ls, std::vector<TObject> args) -> TObject {
|
||||
return Class_GetInfo(env, ls, args);
|
||||
});
|
||||
ext->watch.push_back(env);
|
||||
|
||||
cls->SetValue("GetInfo", ext);
|
||||
|
||||
ext = TExternalMethod::Create(
|
||||
ls, "Get the class names", {},
|
||||
[env](GCList &ls, std::vector<TObject> args) -> TObject {
|
||||
return Class_GetClassNames(env, ls, args);
|
||||
});
|
||||
ext->watch.push_back(env);
|
||||
|
||||
cls->SetValue("GetClassNames", ext);
|
||||
ext = TExternalMethod::Create(
|
||||
ls, "Create an instance of class", {"name", "args"},
|
||||
[env](GCList &ls, std::vector<TObject> args) -> TObject {
|
||||
return Class_CreateInstance(env, ls, args);
|
||||
});
|
||||
ext->watch.push_back(env);
|
||||
|
||||
cls->SetValue("CreateInstance", ext);
|
||||
cls->DeclareFunction(gc, "Name", "Get class name via instance",
|
||||
{"instance"},
|
||||
[](GCList &ls, std::vector<TObject> args) -> TObject {
|
||||
TClassObject *cls;
|
||||
if (GetArgumentHeap(args, 0, cls)) {
|
||||
return cls->name;
|
||||
}
|
||||
return "";
|
||||
});
|
||||
|
||||
cls->DeclareFunction(
|
||||
gc, "GetInstanceInfo",
|
||||
"Get the instance specific info, including current values", {},
|
||||
[](GCList &ls, std::vector<TObject> args) -> TObject {
|
||||
TClassObject *co;
|
||||
if (GetArgumentHeap(args, 0, co)) {
|
||||
ls.GetGC()->BarrierBegin();
|
||||
auto res= TDictionary::Create(ls,
|
||||
{
|
||||
TDItem("Name", co->name),
|
||||
TDItem("File", co->file),
|
||||
TDItem("ClassIndex", (int64_t)co->classIndex),
|
||||
TDItem("InheritList", VectorOfStringToList(ls, co->inherit_tree)),
|
||||
TDItem("Entries", ClassInstanceToList(ls,co))
|
||||
}
|
||||
);
|
||||
auto res = TDictionary::Create(
|
||||
ls, {TDItem("Name", co->name), TDItem("File", co->file),
|
||||
TDItem("ClassIndex", (int64_t)co->classIndex),
|
||||
TDItem("InheritList",
|
||||
VectorOfStringToList(ls, co->inherit_tree)),
|
||||
TDItem("Entries", ClassInstanceToList(ls, co))});
|
||||
ls.GetGC()->BarrierEnd();
|
||||
return res;
|
||||
}
|
||||
return nullptr;
|
||||
});
|
||||
|
||||
gc->BarrierEnd();
|
||||
}
|
||||
}
|
||||
|
||||
gc->BarrierEnd();
|
||||
}
|
||||
} // namespace Tesses::CrossLang
|
||||
@@ -2,334 +2,237 @@
|
||||
#include "CrossLang.hpp"
|
||||
#include <iostream>
|
||||
|
||||
#if defined(GEKKO) || defined(__SWITCH__) || defined(_WIN32)
|
||||
#undef CROSSLANG_ENABLE_TERMIOS
|
||||
#endif
|
||||
|
||||
#ifdef CROSSLANG_ENABLE_TERMIOS
|
||||
#include <termios.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
namespace Tesses::CrossLang {
|
||||
#ifdef CROSSLANG_ENABLE_TERMIOS
|
||||
struct termios orig_termios;
|
||||
static void disableRawMode()
|
||||
{
|
||||
tcsetattr(0, TCSAFLUSH, &orig_termios);
|
||||
}
|
||||
#endif
|
||||
TObject Console_getEcho(GCList& ls, std::vector<TObject> args)
|
||||
{
|
||||
#ifdef CROSSLANG_ENABLE_TERMIOS
|
||||
struct termios raw;
|
||||
tcgetattr(0, &raw);
|
||||
return (raw.c_lflag & ECHO) > 0;
|
||||
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
TObject Console_setEcho(GCList& ls, std::vector<TObject> args)
|
||||
{
|
||||
if(args.size() == 1 && std::holds_alternative<bool>(args[0]))
|
||||
{
|
||||
bool cooked = std::get<bool>(args[0]);
|
||||
#ifdef CROSSLANG_ENABLE_TERMIOS
|
||||
struct termios raw;
|
||||
tcgetattr(0, &raw);
|
||||
if(cooked)
|
||||
{
|
||||
raw.c_lflag |= ECHO;
|
||||
}
|
||||
else
|
||||
{
|
||||
raw.c_lflag &= ~(ECHO);
|
||||
}
|
||||
|
||||
tcsetattr(0, TCSAFLUSH, &raw);
|
||||
|
||||
#endif
|
||||
return cooked;
|
||||
}
|
||||
TObject Console_getIsTTY(GCList &ls, std::vector<TObject> args) {
|
||||
|
||||
return Tesses::Framework::Console::IsTTY();
|
||||
}
|
||||
TObject Console_getEcho(GCList &ls, std::vector<TObject> args) {
|
||||
|
||||
return Tesses::Framework::Console::GetEcho();
|
||||
}
|
||||
TObject Console_setEcho(GCList &ls, std::vector<TObject> args) {
|
||||
if (args.size() == 1 && std::holds_alternative<bool>(args[0])) {
|
||||
bool cooked = std::get<bool>(args[0]);
|
||||
Tesses::Framework::Console::SetEcho(cooked);
|
||||
return cooked;
|
||||
}
|
||||
return Undefined();
|
||||
}
|
||||
TObject Console_getCanonical(GCList &ls, std::vector<TObject> args) {
|
||||
return Tesses::Framework::Console::GetCanonical();
|
||||
}
|
||||
TObject Console_setCanonical(GCList &ls, std::vector<TObject> args) {
|
||||
if (args.size() == 1 && std::holds_alternative<bool>(args[0])) {
|
||||
bool cooked = std::get<bool>(args[0]);
|
||||
Tesses::Framework::Console::SetCanonical(cooked);
|
||||
return cooked;
|
||||
}
|
||||
return Undefined();
|
||||
}
|
||||
TObject Console_getSignals(GCList &ls, std::vector<TObject> args) {
|
||||
return Tesses::Framework::Console::GetSignals();
|
||||
}
|
||||
TObject Console_setSignals(GCList &ls, std::vector<TObject> args) {
|
||||
if (args.size() == 1 && std::holds_alternative<bool>(args[0])) {
|
||||
bool cooked = std::get<bool>(args[0]);
|
||||
Tesses::Framework::Console::SetSignals(cooked);
|
||||
return cooked;
|
||||
}
|
||||
return Undefined();
|
||||
}
|
||||
|
||||
TObject Console_Read(GCList &ls, std::vector<TObject> args) {
|
||||
return (int64_t)Tesses::Framework::Console::Read();
|
||||
}
|
||||
TObject Console_ReadLine(GCList &ls, std::vector<TObject> args) {
|
||||
return Tesses::Framework::Console::ReadLine();
|
||||
}
|
||||
TObject Console_ReadPassword(GCList &ls, std::vector<TObject> args) {
|
||||
return Tesses::Framework::Console::ReadPassword();
|
||||
}
|
||||
TObject Console_Write(GCList &ls, std::vector<TObject> args) {
|
||||
if (args.size() < 1) {
|
||||
return Undefined();
|
||||
}
|
||||
TObject Console_getCanonical(GCList& ls, std::vector<TObject> args)
|
||||
{
|
||||
#ifdef CROSSLANG_ENABLE_TERMIOS
|
||||
struct termios raw;
|
||||
tcgetattr(0, &raw);
|
||||
return (raw.c_lflag & ICANON) > 0;
|
||||
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
TObject Console_setCanonical(GCList& ls, std::vector<TObject> args)
|
||||
{
|
||||
if(args.size() == 1 && std::holds_alternative<bool>(args[0]))
|
||||
{
|
||||
bool cooked = std::get<bool>(args[0]);
|
||||
#ifdef CROSSLANG_ENABLE_TERMIOS
|
||||
struct termios raw;
|
||||
tcgetattr(0, &raw);
|
||||
if(cooked)
|
||||
{
|
||||
raw.c_lflag |= ICANON;
|
||||
}
|
||||
else
|
||||
{
|
||||
raw.c_lflag &= ~(ICANON);
|
||||
}
|
||||
|
||||
tcsetattr(0, TCSAFLUSH, &raw);
|
||||
|
||||
#endif
|
||||
return cooked;
|
||||
}
|
||||
return Undefined();
|
||||
}
|
||||
TObject Console_getSignals(GCList& ls, std::vector<TObject> args)
|
||||
{
|
||||
#ifdef CROSSLANG_ENABLE_TERMIOS
|
||||
struct termios raw;
|
||||
tcgetattr(0, &raw);
|
||||
return (raw.c_lflag & ISIG) > 0;
|
||||
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
TObject Console_setSignals(GCList& ls, std::vector<TObject> args)
|
||||
{
|
||||
if(args.size() == 1 && std::holds_alternative<bool>(args[0]))
|
||||
{
|
||||
bool cooked = std::get<bool>(args[0]);
|
||||
#ifdef CROSSLANG_ENABLE_TERMIOS
|
||||
struct termios raw;
|
||||
tcgetattr(0, &raw);
|
||||
if(cooked)
|
||||
{
|
||||
raw.c_lflag |= ISIG;
|
||||
}
|
||||
else
|
||||
{
|
||||
raw.c_lflag &= ~(ISIG);
|
||||
}
|
||||
|
||||
tcsetattr(0, TCSAFLUSH, &raw);
|
||||
|
||||
#endif
|
||||
return cooked;
|
||||
}
|
||||
return Undefined();
|
||||
}
|
||||
|
||||
TObject Console_Read(GCList& ls, std::vector<TObject> args)
|
||||
{
|
||||
uint8_t byte;
|
||||
std::cin.read((char*)&byte,1);
|
||||
return std::cin.eof() ? (int64_t)-1 : (int64_t)byte;
|
||||
}
|
||||
TObject Console_ReadLine(GCList& ls, std::vector<TObject> args)
|
||||
{
|
||||
std::string str;
|
||||
std::getline(std::cin,str);
|
||||
return str;
|
||||
}
|
||||
TObject Console_Write(GCList& ls, std::vector<TObject> args)
|
||||
{
|
||||
if(args.size() < 1)
|
||||
{
|
||||
return Undefined();
|
||||
}
|
||||
std::cout << ToString(ls.GetGC(),args[0]);
|
||||
return Undefined();
|
||||
}
|
||||
TObject Console_Fatal(GCList& ls, std::vector<TObject> args)
|
||||
{
|
||||
if(args.size() < 1)
|
||||
{
|
||||
std::cout << "FATAL: <NO MESSAGE>" << std::endl;
|
||||
exit(1);
|
||||
}
|
||||
std::cout << "FATAL: " << ToString(ls.GetGC(),args[0]) << std::endl;
|
||||
Tesses::Framework::Console::Write(ToString(ls.GetGC(), args[0]));
|
||||
return Undefined();
|
||||
}
|
||||
TObject Console_Fatal(GCList &ls, std::vector<TObject> args) {
|
||||
if (args.size() < 1) {
|
||||
Tesses::Framework::Console::ErrorLine("FATAL: <NO MESSAGE>");
|
||||
exit(1);
|
||||
}
|
||||
TObject Console_WriteLine(GCList& ls, std::vector<TObject> args)
|
||||
{
|
||||
if(args.size() < 1)
|
||||
{
|
||||
std::cout << "\n";
|
||||
return Undefined();
|
||||
}
|
||||
std::cout << ToString(ls.GetGC(),args[0]) << "\n";
|
||||
return Undefined();
|
||||
}
|
||||
TObject Console_Error(GCList& ls, std::vector<TObject> args)
|
||||
{
|
||||
if(args.size() < 1)
|
||||
{
|
||||
return Undefined();
|
||||
}
|
||||
std::cerr << ToString(ls.GetGC(),args[0]);
|
||||
return Undefined();
|
||||
}
|
||||
TObject Console_ErrorLine(GCList& ls, std::vector<TObject> args)
|
||||
{
|
||||
if(args.size() < 1)
|
||||
{
|
||||
std::cout << "\n";
|
||||
return Undefined();
|
||||
}
|
||||
std::cerr << ToString(ls.GetGC(),args[0]) << "\n";
|
||||
return Undefined();
|
||||
}
|
||||
TObject Console_getIn(GCList& ls, std::vector<TObject> args)
|
||||
{
|
||||
return std::make_shared<Tesses::Framework::Streams::FileStream>(stdin,false,"r",false);
|
||||
}
|
||||
|
||||
TObject Console_getOut(GCList& ls, std::vector<TObject> args)
|
||||
{
|
||||
return std::make_shared<Tesses::Framework::Streams::FileStream>(stdout,false,"w",false);
|
||||
}
|
||||
TObject Console_getError(GCList& ls, std::vector<TObject> args)
|
||||
{
|
||||
return std::make_shared<Tesses::Framework::Streams::FileStream>(stderr,false,"w",false);
|
||||
}
|
||||
TObject Console_Clear(GCList& ls, std::vector<TObject> args)
|
||||
{
|
||||
//because I just really want a clear function
|
||||
#if defined(_WIN32)
|
||||
system("cls");
|
||||
#else
|
||||
std::cout << "\x1b[2J\x1b[H" << std::flush; //because of wii and stuff (dont want to rely on clear command)
|
||||
#endif
|
||||
return Undefined();
|
||||
}
|
||||
static void con_sz(int& w, int& h)
|
||||
{
|
||||
w = 0;
|
||||
h = 0;
|
||||
|
||||
|
||||
#if defined(_WIN32)
|
||||
|
||||
#elif defined(CROSSLANG_ENABLE_TERMIOS)
|
||||
if(!isatty(STDOUT_FILENO))
|
||||
return;
|
||||
struct winsize ws;
|
||||
if(ioctl(STDOUT_FILENO, TIOCGWINSZ, &ws) == 0)
|
||||
{
|
||||
w = ws.ws_col;
|
||||
h = ws.ws_row;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
TObject Console_ProgressBar(GCList& ls, std::vector<TObject> args)
|
||||
{
|
||||
//[=== ] 50%
|
||||
bool showBar = true;
|
||||
#if defined(CROSSLANG_ENABLE_TERMIOS)
|
||||
if(!isatty(STDOUT_FILENO)) showBar=false;
|
||||
#endif
|
||||
int64_t progress = 0;
|
||||
double pdbl = 0;
|
||||
GetArgument(args,0,pdbl);
|
||||
if(GetArgument(args,0,progress)) pdbl = progress / 100.0;
|
||||
if(pdbl < 0) pdbl=0;
|
||||
if(pdbl > 1) pdbl=1;
|
||||
|
||||
std::cout << "\r";
|
||||
if(showBar)
|
||||
{
|
||||
int w,h;
|
||||
con_sz(w,h);
|
||||
|
||||
int totalBlocks = w - 10;
|
||||
if(totalBlocks > 0)
|
||||
{
|
||||
std::cout << "[\033[0;32m";
|
||||
int i;
|
||||
int off = pdbl * totalBlocks;
|
||||
for(int i = 0; i < totalBlocks; i++)
|
||||
{
|
||||
if(i < off)
|
||||
std::cout << "=";
|
||||
else
|
||||
std::cout << " ";
|
||||
}
|
||||
|
||||
std::cout << "\033[0m] ";
|
||||
}
|
||||
}
|
||||
|
||||
std::cout << std::setw(3) << (int)(pdbl*100) << "%" << std::flush;
|
||||
return Undefined();
|
||||
}
|
||||
TObject Console_getSize(GCList& ls, std::vector<TObject> args)
|
||||
{
|
||||
#if defined(CROSSLANG_ENABLE_TERMIOS)
|
||||
if(!isatty(STDOUT_FILENO)) return nullptr;
|
||||
#endif
|
||||
int w, h;
|
||||
con_sz(w,h);
|
||||
TDictionary* dict = TDictionary::Create(ls,{
|
||||
TDItem("Width", (int64_t)w),
|
||||
TDItem("Height",(int64_t)h)
|
||||
});
|
||||
|
||||
return dict;
|
||||
}
|
||||
void TStd::RegisterConsole(std::shared_ptr<GC> gc,TRootEnvironment* env)
|
||||
{
|
||||
env->permissions.canRegisterConsole=true;
|
||||
if(env->permissions.customConsole != nullptr)
|
||||
{
|
||||
gc->BarrierBegin();
|
||||
env->DeclareVariable("Console", env->permissions.customConsole );
|
||||
gc->BarrierEnd();
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef CROSSLANG_ENABLE_TERMIOS
|
||||
tcgetattr(0, &orig_termios);
|
||||
atexit(disableRawMode);
|
||||
#endif
|
||||
GCList ls(gc);
|
||||
TDictionary* dict = TDictionary::Create(ls);
|
||||
|
||||
dict->DeclareFunction(gc,"getEcho","Get whether terminal is echoing characters read",{},Console_getEcho);
|
||||
dict->DeclareFunction(gc,"setEcho","Set whether terminal is echoing characters read",{"flag"},Console_setEcho);
|
||||
dict->DeclareFunction(gc,"getCanonical","Get whether terminal is buffering line by line (true) or byte by byte (false)",{},Console_getCanonical);
|
||||
dict->DeclareFunction(gc,"setCanonical","Set whether terminal is buffering line by line (true) or byte by byte (false)",{"flag"},Console_setCanonical);
|
||||
dict->DeclareFunction(gc,"getSignals","Get whether terminal is sending signals for CTRL+C (true) or via read (false)",{},Console_getSignals);
|
||||
dict->DeclareFunction(gc,"setSignals","Set whether terminal is sending signals for CTRL+C (true) or via read (false)",{"flag"},Console_setSignals);
|
||||
dict->DeclareFunction(gc,"Clear", "Clear the console",{},Console_Clear);
|
||||
dict->DeclareFunction(gc,"Read", "Reads a byte from stdin",{},Console_Read);
|
||||
dict->DeclareFunction(gc,"ReadLine","Reads line from stdin",{},Console_ReadLine);
|
||||
dict->DeclareFunction(gc,"Write","Write text \"text\" to stdout",{"text"},Console_Write);
|
||||
dict->DeclareFunction(gc,"WriteLine","Write text \"text\" to stdout with new line",{"$text"},Console_WriteLine);
|
||||
dict->DeclareFunction(gc,"Error", "Write text \"error\" to stderr",{"error"},Console_Error);
|
||||
dict->DeclareFunction(gc,"ErrorLine","Write text \"error\" to stderr",{"$error"},Console_ErrorLine);
|
||||
dict->DeclareFunction(gc,"ProgressBar","Draw progressbar", {}, Console_ProgressBar);
|
||||
if(env->permissions.canRegisterEverything)
|
||||
dict->DeclareFunction(gc,"Fatal","Stop the program with an optional error message",{"$text"},Console_Fatal);
|
||||
dict->DeclareFunction(gc,"getIn","Get stdin Stream",{},Console_getIn);
|
||||
dict->DeclareFunction(gc,"getOut","Get stdout Stream",{},Console_getOut);
|
||||
dict->DeclareFunction(gc,"getError", "Get stderr Stream",{},Console_getError);
|
||||
dict->DeclareFunction(gc, "getSize", "Get console size",{},Console_getSize);
|
||||
gc->BarrierBegin();
|
||||
env->DeclareVariable("Console", dict);
|
||||
auto _new = env->EnsureDictionary(gc,"New");
|
||||
_new->DeclareFunction(gc,"ConsoleReader","Read from console",{},[](GCList& ls,std::vector<TObject> args)->TObject {
|
||||
return std::make_shared<Tesses::Framework::TextStreams::ConsoleReader>();
|
||||
});
|
||||
_new->DeclareFunction(gc,"ConsoleWriter","Write to console",{"$isStderr"},[](GCList& ls,std::vector<TObject> args)->TObject {
|
||||
bool err;
|
||||
if(GetArgument(args,0,err)) return std::make_shared<Tesses::Framework::TextStreams::ConsoleWriter>(err);
|
||||
return std::make_shared<Tesses::Framework::TextStreams::ConsoleWriter>();
|
||||
});
|
||||
gc->BarrierEnd();
|
||||
}
|
||||
Tesses::Framework::Console::ErrorLine("FATAL: " +
|
||||
ToString(ls.GetGC(), args[0]));
|
||||
exit(1);
|
||||
}
|
||||
TObject Console_WriteLine(GCList &ls, std::vector<TObject> args) {
|
||||
if (args.size() < 1) {
|
||||
Tesses::Framework::Console::WriteLineView("");
|
||||
return Undefined();
|
||||
}
|
||||
Tesses::Framework::Console::WriteLine(ToString(ls.GetGC(), args[0]));
|
||||
|
||||
return Undefined();
|
||||
}
|
||||
TObject Console_Error(GCList &ls, std::vector<TObject> args) {
|
||||
if (args.size() < 1) {
|
||||
return Undefined();
|
||||
}
|
||||
Tesses::Framework::Console::Error(ToString(ls.GetGC(), args[0]));
|
||||
return Undefined();
|
||||
}
|
||||
TObject Console_ErrorLine(GCList &ls, std::vector<TObject> args) {
|
||||
if (args.size() < 1) {
|
||||
Tesses::Framework::Console::ErrorLine("");
|
||||
return Undefined();
|
||||
}
|
||||
Tesses::Framework::Console::ErrorLine(ToString(ls.GetGC(), args[0]));
|
||||
|
||||
return Undefined();
|
||||
}
|
||||
TObject Console_getIn(GCList &ls, std::vector<TObject> args) {
|
||||
return std::make_shared<Tesses::Framework::Streams::FileStream>(
|
||||
stdin, false, "r", false);
|
||||
}
|
||||
|
||||
TObject Console_getOut(GCList &ls, std::vector<TObject> args) {
|
||||
return std::make_shared<Tesses::Framework::Streams::FileStream>(
|
||||
stdout, false, "w", false);
|
||||
}
|
||||
TObject Console_getError(GCList &ls, std::vector<TObject> args) {
|
||||
return std::make_shared<Tesses::Framework::Streams::FileStream>(
|
||||
stderr, false, "w", false);
|
||||
}
|
||||
TObject Console_Clear(GCList &ls, std::vector<TObject> args) {
|
||||
Tesses::Framework::Console::Clear();
|
||||
return Undefined();
|
||||
}
|
||||
|
||||
TObject Console_ProgressBar(GCList &ls, std::vector<TObject> args) {
|
||||
double dbl;
|
||||
int64_t i64;
|
||||
if (GetArgument(args, 0, i64)) {
|
||||
Tesses::Framework::Console::ProgressBar((int)i64);
|
||||
} else if (GetArgument(args, 0, dbl)) {
|
||||
Tesses::Framework::Console::ProgressBar(dbl);
|
||||
}
|
||||
|
||||
return Undefined();
|
||||
}
|
||||
TObject Console_getSize(GCList &ls, std::vector<TObject> args) {
|
||||
auto sz = Tesses::Framework::Console::GetSize();
|
||||
TDictionary *dict =
|
||||
TDictionary::Create(ls, {TDItem("Width", (int64_t)sz.first),
|
||||
TDItem("Height", (int64_t)sz.second)});
|
||||
|
||||
return dict;
|
||||
}
|
||||
TObject Console_List(GCList &ls, std::vector<TObject> args) {
|
||||
if (!args.empty()) {
|
||||
GCList ls2(ls.GetGC());
|
||||
auto enumerator = TEnumerator::CreateFromObject(ls2, args[0]);
|
||||
std::vector<std::string> items;
|
||||
|
||||
while (enumerator->MoveNext(ls2.GetGC())) {
|
||||
auto item = enumerator->GetCurrent(ls2);
|
||||
items.push_back(ToString(ls2.GetGC(), item));
|
||||
}
|
||||
|
||||
return (int64_t)Tesses::Framework::Console::List(items);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
void TStd::RegisterConsole(std::shared_ptr<GC> gc, TRootEnvironment *env) {
|
||||
env->permissions.canRegisterConsole = true;
|
||||
if (env->permissions.customConsole != nullptr) {
|
||||
gc->BarrierBegin();
|
||||
env->DeclareVariable("Console", env->permissions.customConsole);
|
||||
gc->BarrierEnd();
|
||||
return;
|
||||
}
|
||||
|
||||
GCList ls(gc);
|
||||
TDictionary *dict = TDictionary::Create(ls);
|
||||
dict->DeclareFunction(
|
||||
gc, "getIsTTY",
|
||||
"Get whether terminal is a terminal or just piped to file", {},
|
||||
Console_getIsTTY);
|
||||
dict->DeclareFunction(gc, "getEcho",
|
||||
"Get whether terminal is echoing characters read", {},
|
||||
Console_getEcho);
|
||||
dict->DeclareFunction(gc, "setEcho",
|
||||
"Set whether terminal is echoing characters read",
|
||||
{"flag"}, Console_setEcho);
|
||||
dict->DeclareFunction(gc, "getCanonical",
|
||||
"Get whether terminal is buffering line by line "
|
||||
"(true) or byte by byte (false)",
|
||||
{}, Console_getCanonical);
|
||||
dict->DeclareFunction(gc, "setCanonical",
|
||||
"Set whether terminal is buffering line by line "
|
||||
"(true) or byte by byte (false)",
|
||||
{"flag"}, Console_setCanonical);
|
||||
dict->DeclareFunction(gc, "getSignals",
|
||||
"Get whether terminal is sending signals for CTRL+C "
|
||||
"(true) or via read (false)",
|
||||
{}, Console_getSignals);
|
||||
dict->DeclareFunction(gc, "setSignals",
|
||||
"Set whether terminal is sending signals for CTRL+C "
|
||||
"(true) or via read (false)",
|
||||
{"flag"}, Console_setSignals);
|
||||
dict->DeclareFunction(gc, "Clear", "Clear the console", {}, Console_Clear);
|
||||
dict->DeclareFunction(gc, "Read", "Reads a byte from stdin", {},
|
||||
Console_Read);
|
||||
dict->DeclareFunction(gc, "ReadLine", "Reads line from stdin", {},
|
||||
Console_ReadLine);
|
||||
dict->DeclareFunction(gc, "ReadPassword", "Reads password from stdin", {},
|
||||
Console_ReadPassword);
|
||||
dict->DeclareFunction(gc, "Write", "Write text \"text\" to stdout",
|
||||
{"text"}, Console_Write);
|
||||
dict->DeclareFunction(gc, "WriteLine",
|
||||
"Write text \"text\" to stdout with new line",
|
||||
{"$text"}, Console_WriteLine);
|
||||
dict->DeclareFunction(gc, "Error", "Write text \"error\" to stderr",
|
||||
{"error"}, Console_Error);
|
||||
dict->DeclareFunction(gc, "ErrorLine", "Write text \"error\" to stderr",
|
||||
{"$error"}, Console_ErrorLine);
|
||||
dict->DeclareFunction(gc, "ProgressBar", "Draw progressbar", {},
|
||||
Console_ProgressBar);
|
||||
dict->DeclareFunction(gc, "List", "Draw list", {"itemsitterator"},
|
||||
Console_List);
|
||||
if (env->permissions.canRegisterEverything)
|
||||
dict->DeclareFunction(gc, "Fatal",
|
||||
"Stop the program with an optional error message",
|
||||
{"$text"}, Console_Fatal);
|
||||
dict->DeclareFunction(gc, "getIn", "Get stdin Stream", {}, Console_getIn);
|
||||
dict->DeclareFunction(gc, "getOut", "Get stdout Stream", {},
|
||||
Console_getOut);
|
||||
dict->DeclareFunction(gc, "getError", "Get stderr Stream", {},
|
||||
Console_getError);
|
||||
dict->DeclareFunction(gc, "getSize", "Get console size", {},
|
||||
Console_getSize);
|
||||
gc->BarrierBegin();
|
||||
env->DeclareVariable("Console", dict);
|
||||
auto _new = env->EnsureDictionary(gc, "New");
|
||||
_new->DeclareFunction(
|
||||
gc, "ConsoleReader", "Read from console", {},
|
||||
[](GCList &ls, std::vector<TObject> args) -> TObject {
|
||||
return std::make_shared<
|
||||
Tesses::Framework::TextStreams::ConsoleReader>();
|
||||
});
|
||||
_new->DeclareFunction(
|
||||
gc, "ConsoleWriter", "Write to console", {"$isStderr"},
|
||||
[](GCList &ls, std::vector<TObject> args) -> TObject {
|
||||
bool err;
|
||||
if (GetArgument(args, 0, err))
|
||||
return std::make_shared<
|
||||
Tesses::Framework::TextStreams::ConsoleWriter>(err);
|
||||
return std::make_shared<
|
||||
Tesses::Framework::TextStreams::ConsoleWriter>();
|
||||
});
|
||||
gc->BarrierEnd();
|
||||
}
|
||||
} // namespace Tesses::CrossLang
|
||||
#endif
|
||||
|
||||
@@ -2,183 +2,173 @@
|
||||
|
||||
using namespace Tesses::Framework::Crypto;
|
||||
|
||||
namespace Tesses::CrossLang
|
||||
{
|
||||
static TObject Crypto_RandomBytes(GCList& ls, std::vector<TObject> args)
|
||||
{
|
||||
|
||||
int64_t size;
|
||||
std::string personalStr;
|
||||
if(GetArgument(args,0,size) && GetArgument(args,1,personalStr))
|
||||
{
|
||||
namespace Tesses::CrossLang {
|
||||
static TObject Crypto_RandomBytes(GCList &ls, std::vector<TObject> args) {
|
||||
|
||||
std::vector<uint8_t> bytes;
|
||||
bytes.resize((size_t)size);
|
||||
if(RandomBytes(bytes,personalStr))
|
||||
{
|
||||
auto ba = TByteArray::Create(ls);
|
||||
ba->data = bytes;
|
||||
return ba;
|
||||
}
|
||||
return nullptr;
|
||||
|
||||
|
||||
int64_t size;
|
||||
std::string personalStr;
|
||||
if (GetArgument(args, 0, size) && GetArgument(args, 1, personalStr)) {
|
||||
|
||||
std::vector<uint8_t> bytes;
|
||||
bytes.resize((size_t)size);
|
||||
if (RandomBytes(bytes, personalStr)) {
|
||||
auto ba = TByteArray::Create(ls);
|
||||
ba->data = bytes;
|
||||
return ba;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
static TObject Crypto_PBKDF2(GCList& ls, std::vector<TObject> args)
|
||||
{
|
||||
std::string pass;
|
||||
TByteArray* bArraySalt;
|
||||
int64_t itterations;
|
||||
int64_t keylength;
|
||||
int64_t shanum;
|
||||
if(GetArgument(args,0,pass) && GetArgumentHeap(args,1, bArraySalt) && GetArgument(args,2, itterations) && GetArgument(args,3,keylength) && GetArgument(args,4,shanum))
|
||||
{
|
||||
ShaVersion version = VERSION_SHA384;
|
||||
|
||||
switch(shanum)
|
||||
{
|
||||
case 1:
|
||||
version = VERSION_SHA1;
|
||||
break;
|
||||
case 224:
|
||||
version = VERSION_SHA224;
|
||||
break;
|
||||
case 256:
|
||||
version = VERSION_SHA256;
|
||||
break;
|
||||
default:
|
||||
case 384:
|
||||
version = VERSION_SHA384;
|
||||
break;
|
||||
case 512:
|
||||
version = VERSION_SHA512;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
static TObject Crypto_PBKDF2(GCList &ls, std::vector<TObject> args) {
|
||||
std::string pass;
|
||||
TByteArray *bArraySalt;
|
||||
int64_t itterations;
|
||||
int64_t keylength;
|
||||
int64_t shanum;
|
||||
if (GetArgument(args, 0, pass) && GetArgumentHeap(args, 1, bArraySalt) &&
|
||||
GetArgument(args, 2, itterations) && GetArgument(args, 3, keylength) &&
|
||||
GetArgument(args, 4, shanum)) {
|
||||
ShaVersion version = VERSION_SHA384;
|
||||
|
||||
std::vector<uint8_t> key;
|
||||
key.resize((size_t)keylength);
|
||||
|
||||
if(PBKDF2(key,pass,bArraySalt->data,(long)itterations,version))
|
||||
{
|
||||
TByteArray* ba = TByteArray::Create(ls);
|
||||
ba->data = key;
|
||||
return ba;
|
||||
}
|
||||
|
||||
switch (shanum) {
|
||||
case 1:
|
||||
version = VERSION_SHA1;
|
||||
break;
|
||||
case 224:
|
||||
version = VERSION_SHA224;
|
||||
break;
|
||||
case 256:
|
||||
version = VERSION_SHA256;
|
||||
break;
|
||||
default:
|
||||
case 384:
|
||||
version = VERSION_SHA384;
|
||||
break;
|
||||
case 512:
|
||||
version = VERSION_SHA512;
|
||||
break;
|
||||
}
|
||||
|
||||
std::vector<uint8_t> key;
|
||||
key.resize((size_t)keylength);
|
||||
|
||||
if (PBKDF2(key, pass, bArraySalt->data, (long)itterations, version)) {
|
||||
TByteArray *ba = TByteArray::Create(ls);
|
||||
ba->data = key;
|
||||
return ba;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
static TObject Crypto_Base64Encode(GCList &ls, std::vector<TObject> args) {
|
||||
TByteArray *byteArray;
|
||||
|
||||
static TObject Crypto_Base64Encode(GCList& ls, std::vector<TObject> args)
|
||||
{
|
||||
TByteArray* byteArray;
|
||||
|
||||
if(GetArgumentHeap(args,0,byteArray))
|
||||
{
|
||||
return Tesses::Framework::Crypto::Base64_Encode(byteArray->data);
|
||||
|
||||
if (GetArgumentHeap(args, 0, byteArray)) {
|
||||
return Tesses::Framework::Crypto::Base64_Encode(byteArray->data);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
static TObject Crypto_Base64Decode(GCList &ls, std::vector<TObject> args) {
|
||||
std::string str;
|
||||
if (GetArgument(args, 0, str)) {
|
||||
TByteArray *bArray = TByteArray::Create(ls);
|
||||
bArray->data = Tesses::Framework::Crypto::Base64_Decode(str);
|
||||
|
||||
}
|
||||
return "";
|
||||
}
|
||||
static TObject Crypto_Base64Decode(GCList& ls, std::vector<TObject> args)
|
||||
{
|
||||
std::string str;
|
||||
if(GetArgument(args,0,str))
|
||||
{
|
||||
TByteArray* bArray = TByteArray::Create(ls);
|
||||
bArray->data = Tesses::Framework::Crypto::Base64_Decode(str);
|
||||
return bArray;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
void TStd::RegisterCrypto(std::shared_ptr<GC> gc, TRootEnvironment *env) {
|
||||
|
||||
return bArray;
|
||||
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
void TStd::RegisterCrypto(std::shared_ptr<GC> gc,TRootEnvironment* env)
|
||||
{
|
||||
env->permissions.canRegisterCrypto = true;
|
||||
if (!HaveCrypto())
|
||||
return;
|
||||
GCList ls(gc);
|
||||
TDictionary *dict = TDictionary::Create(ls);
|
||||
dict->DeclareFunction(gc, "PBKDF2", "Hash passwords with PBKDF2",
|
||||
{"pass", "salt", "itterations", "keylen", "shanum"},
|
||||
Crypto_PBKDF2);
|
||||
dict->DeclareFunction(gc, "RandomBytes",
|
||||
"Create bytearray but with random bytes in it "
|
||||
"instead of zeros (this uses mbedtls by the way)",
|
||||
{"byteCount", "personalString"}, Crypto_RandomBytes);
|
||||
|
||||
env->permissions.canRegisterCrypto=true;
|
||||
if(!HaveCrypto()) return;
|
||||
GCList ls(gc);
|
||||
TDictionary* dict = TDictionary::Create(ls);
|
||||
dict->DeclareFunction(gc, "PBKDF2","Hash passwords with PBKDF2",{"pass","salt","itterations","keylen","shanum"},Crypto_PBKDF2);
|
||||
dict->DeclareFunction(gc, "RandomBytes","Create bytearray but with random bytes in it instead of zeros (this uses mbedtls by the way)",{"byteCount","personalString"},Crypto_RandomBytes);
|
||||
|
||||
dict->DeclareFunction(gc, "Base64Encode","Base64 encode",{"data"},Crypto_Base64Encode);
|
||||
dict->DeclareFunction(gc, "Base64Decode","Base64 decode",{"str"},Crypto_Base64Decode);
|
||||
dict->DeclareFunction(gc, "Sha1", "Hash with sha1 algorithm (please don't use sha1 unless you need to)",{"strm"}, [](GCList& ls, std::vector<TObject> args)->TObject {
|
||||
TByteArray* baSrc;
|
||||
dict->DeclareFunction(gc, "Base64Encode", "Base64 encode", {"data"},
|
||||
Crypto_Base64Encode);
|
||||
dict->DeclareFunction(gc, "Base64Decode", "Base64 decode", {"str"},
|
||||
Crypto_Base64Decode);
|
||||
dict->DeclareFunction(
|
||||
gc, "Sha1",
|
||||
"Hash with sha1 algorithm (please don't use sha1 unless you need to)",
|
||||
{"strm"}, [](GCList &ls, std::vector<TObject> args) -> TObject {
|
||||
TByteArray *baSrc;
|
||||
std::shared_ptr<Tesses::Framework::Streams::Stream> sho;
|
||||
|
||||
if(GetArgument(args, 0, sho))
|
||||
{
|
||||
if (GetArgument(args, 0, sho)) {
|
||||
auto bytes = Sha1::ComputeHash(sho);
|
||||
auto ba = TByteArray::Create(ls);
|
||||
ba->data = bytes;
|
||||
return ba;
|
||||
}
|
||||
if(GetArgumentHeap(args,0,baSrc))
|
||||
{
|
||||
auto bytes = Sha1::ComputeHash(baSrc->data.data(), baSrc->data.size());
|
||||
if (GetArgumentHeap(args, 0, baSrc)) {
|
||||
auto bytes =
|
||||
Sha1::ComputeHash(baSrc->data.data(), baSrc->data.size());
|
||||
auto ba = TByteArray::Create(ls);
|
||||
ba->data = bytes;
|
||||
return ba;
|
||||
}
|
||||
return Undefined();
|
||||
});
|
||||
dict->DeclareFunction(gc, "Sha256", "Hash with sha256 algorithm",{"strm","$is224"}, [](GCList& ls, std::vector<TObject> args)->TObject {
|
||||
TByteArray* baSrc;
|
||||
dict->DeclareFunction(
|
||||
gc, "Sha256", "Hash with sha256 algorithm", {"strm", "$is224"},
|
||||
[](GCList &ls, std::vector<TObject> args) -> TObject {
|
||||
TByteArray *baSrc;
|
||||
std::shared_ptr<Tesses::Framework::Streams::Stream> sho;
|
||||
bool is224=false;
|
||||
GetArgument(args,1,is224);
|
||||
bool is224 = false;
|
||||
GetArgument(args, 1, is224);
|
||||
|
||||
if(GetArgument(args, 0, sho))
|
||||
{
|
||||
auto bytes = Sha256::ComputeHash(sho,is224);
|
||||
if (GetArgument(args, 0, sho)) {
|
||||
auto bytes = Sha256::ComputeHash(sho, is224);
|
||||
auto ba = TByteArray::Create(ls);
|
||||
ba->data = bytes;
|
||||
return ba;
|
||||
}
|
||||
if(GetArgumentHeap(args,0,baSrc))
|
||||
{
|
||||
auto bytes = Sha256::ComputeHash(baSrc->data.data(), baSrc->data.size(), is224);
|
||||
if (GetArgumentHeap(args, 0, baSrc)) {
|
||||
auto bytes = Sha256::ComputeHash(baSrc->data.data(),
|
||||
baSrc->data.size(), is224);
|
||||
auto ba = TByteArray::Create(ls);
|
||||
ba->data = bytes;
|
||||
return ba;
|
||||
}
|
||||
return Undefined();
|
||||
});
|
||||
dict->DeclareFunction(gc, "Sha512", "Hash with sha512 algorithm",{"strm","$is384"}, [](GCList& ls, std::vector<TObject> args)->TObject {
|
||||
TByteArray* baSrc;
|
||||
dict->DeclareFunction(
|
||||
gc, "Sha512", "Hash with sha512 algorithm", {"strm", "$is384"},
|
||||
[](GCList &ls, std::vector<TObject> args) -> TObject {
|
||||
TByteArray *baSrc;
|
||||
std::shared_ptr<Tesses::Framework::Streams::Stream> sho;
|
||||
bool is384=false;
|
||||
GetArgument(args,1,is384);
|
||||
bool is384 = false;
|
||||
GetArgument(args, 1, is384);
|
||||
|
||||
if(GetArgument(args, 0, sho))
|
||||
{
|
||||
auto bytes = Sha512::ComputeHash(sho,is384);
|
||||
if (GetArgument(args, 0, sho)) {
|
||||
auto bytes = Sha512::ComputeHash(sho, is384);
|
||||
auto ba = TByteArray::Create(ls);
|
||||
ba->data = bytes;
|
||||
return ba;
|
||||
}
|
||||
if(GetArgumentHeap(args,0,baSrc))
|
||||
{
|
||||
auto bytes = Sha512::ComputeHash(baSrc->data.data(), baSrc->data.size(), is384);
|
||||
if (GetArgumentHeap(args, 0, baSrc)) {
|
||||
auto bytes = Sha512::ComputeHash(baSrc->data.data(),
|
||||
baSrc->data.size(), is384);
|
||||
auto ba = TByteArray::Create(ls);
|
||||
ba->data = bytes;
|
||||
return ba;
|
||||
}
|
||||
return Undefined();
|
||||
});
|
||||
gc->BarrierBegin();
|
||||
env->DeclareVariable("Crypto", dict);
|
||||
gc->BarrierEnd();
|
||||
|
||||
|
||||
}
|
||||
gc->BarrierBegin();
|
||||
env->DeclareVariable("Crypto", dict);
|
||||
gc->BarrierEnd();
|
||||
}
|
||||
} // namespace Tesses::CrossLang
|
||||
|
||||
@@ -1,149 +1,137 @@
|
||||
#include "CrossLang.hpp"
|
||||
|
||||
namespace Tesses::CrossLang
|
||||
{
|
||||
TObject Dictionary_FindByKey(GCList& ls, std::vector<TObject> args)
|
||||
{
|
||||
TList* dest = TList::Create(ls);
|
||||
ls.GetGC()->BarrierBegin();
|
||||
std::string key;
|
||||
if(GetArgument(args,1,key))
|
||||
{
|
||||
namespace Tesses::CrossLang {
|
||||
TObject Dictionary_FindByKey(GCList &ls, std::vector<TObject> args) {
|
||||
TList *dest = TList::Create(ls);
|
||||
ls.GetGC()->BarrierBegin();
|
||||
std::string key;
|
||||
if (GetArgument(args, 1, key)) {
|
||||
|
||||
std::function<void(TObject)> crawl;
|
||||
crawl = [&](TObject o) -> void {
|
||||
TDictionary* dict;
|
||||
TList* list;
|
||||
TAssociativeArray* aa;
|
||||
if(GetObjectHeap(o,aa))
|
||||
{
|
||||
std::string k0;
|
||||
for(auto& item : aa->items)
|
||||
{
|
||||
|
||||
if(GetObject(item.first,k0) && k0 == key) dest->Add(item.second);
|
||||
crawl(item.second);
|
||||
}
|
||||
std::function<void(TObject)> crawl;
|
||||
crawl = [&](TObject o) -> void {
|
||||
TDictionary *dict;
|
||||
TList *list;
|
||||
TAssociativeArray *aa;
|
||||
if (GetObjectHeap(o, aa)) {
|
||||
std::string k0;
|
||||
for (auto &item : aa->items) {
|
||||
|
||||
if (GetObject(item.first, k0) && k0 == key)
|
||||
dest->Add(item.second);
|
||||
crawl(item.second);
|
||||
}
|
||||
if(GetObjectHeap(o,dict))
|
||||
{
|
||||
for(auto& item : dict->items)
|
||||
{
|
||||
if(item.first == key) dest->Add(item.second);
|
||||
crawl(item.second);
|
||||
}
|
||||
}
|
||||
if (GetObjectHeap(o, dict)) {
|
||||
for (auto &item : dict->items) {
|
||||
if (item.first == key)
|
||||
dest->Add(item.second);
|
||||
crawl(item.second);
|
||||
}
|
||||
if(GetObjectHeap(o,list))
|
||||
{
|
||||
for(auto& item : list->items)
|
||||
{
|
||||
crawl(item);
|
||||
}
|
||||
}
|
||||
if (GetObjectHeap(o, list)) {
|
||||
for (auto &item : list->items) {
|
||||
crawl(item);
|
||||
}
|
||||
};
|
||||
crawl(args[0]);
|
||||
}
|
||||
ls.GetGC()->BarrierEnd();
|
||||
return dest;
|
||||
}
|
||||
};
|
||||
crawl(args[0]);
|
||||
}
|
||||
TObject Dictionary_Items(GCList& ls, std::vector<TObject> args)
|
||||
{
|
||||
|
||||
TDictionary* dict;
|
||||
TDynamicDictionary* dynDict;
|
||||
if(GetArgumentHeap(args,0,dynDict))
|
||||
{
|
||||
TDictionary* enumerableItem = TDictionary::Create(ls);
|
||||
ls.GetGC()->BarrierBegin();
|
||||
ls.GetGC()->BarrierEnd();
|
||||
return dest;
|
||||
}
|
||||
TObject Dictionary_Items(GCList &ls, std::vector<TObject> args) {
|
||||
|
||||
auto fn = TExternalMethod::Create(ls,"Get Enumerator for Dictionary",{},[dynDict](GCList& ls2, std::vector<TObject> args)->TObject {
|
||||
TDictionary *dict;
|
||||
TDynamicDictionary *dynDict;
|
||||
if (GetArgumentHeap(args, 0, dynDict)) {
|
||||
TDictionary *enumerableItem = TDictionary::Create(ls);
|
||||
ls.GetGC()->BarrierBegin();
|
||||
|
||||
auto fn = TExternalMethod::Create(
|
||||
ls, "Get Enumerator for Dictionary", {},
|
||||
[dynDict](GCList &ls2, std::vector<TObject> args) -> TObject {
|
||||
return dynDict->GetEnumerator(ls2);
|
||||
});
|
||||
fn->watch.push_back(dynDict);
|
||||
|
||||
enumerableItem->SetValue("GetEnumerator", fn);
|
||||
|
||||
ls.GetGC()->BarrierEnd();
|
||||
fn->watch.push_back(dynDict);
|
||||
|
||||
return enumerableItem;
|
||||
|
||||
}
|
||||
if(GetArgumentHeap(args,0,dict))
|
||||
{
|
||||
TDictionary* enumerableItem = TDictionary::Create(ls);
|
||||
ls.GetGC()->BarrierBegin();
|
||||
enumerableItem->SetValue("GetEnumerator", fn);
|
||||
|
||||
auto fn = TExternalMethod::Create(ls,"Get Enumerator for Dictionary",{"dict"},[dict](GCList& ls2, std::vector<TObject> args)->TObject {
|
||||
return TDictionaryEnumerator::Create(ls2,dict);
|
||||
ls.GetGC()->BarrierEnd();
|
||||
|
||||
return enumerableItem;
|
||||
}
|
||||
if (GetArgumentHeap(args, 0, dict)) {
|
||||
TDictionary *enumerableItem = TDictionary::Create(ls);
|
||||
ls.GetGC()->BarrierBegin();
|
||||
|
||||
auto fn = TExternalMethod::Create(
|
||||
ls, "Get Enumerator for Dictionary", {"dict"},
|
||||
[dict](GCList &ls2, std::vector<TObject> args) -> TObject {
|
||||
return TDictionaryEnumerator::Create(ls2, dict);
|
||||
});
|
||||
fn->watch.push_back(dict);
|
||||
|
||||
enumerableItem->SetValue("GetEnumerator", fn);
|
||||
|
||||
fn->watch.push_back(dict);
|
||||
|
||||
enumerableItem->SetValue("GetEnumerator", fn);
|
||||
|
||||
ls.GetGC()->BarrierEnd();
|
||||
|
||||
return enumerableItem;
|
||||
}
|
||||
|
||||
return Undefined();
|
||||
}
|
||||
TObject Dictionary_GetField(GCList &ls, std::vector<TObject> args) {
|
||||
TDictionary *dict;
|
||||
TDynamicDictionary *dynDict;
|
||||
std::string key;
|
||||
if (GetArgument(args, 1, key)) {
|
||||
if (GetArgumentHeap(args, 0, dict)) {
|
||||
ls.GetGC()->BarrierBegin();
|
||||
auto res = dict->GetValue(key);
|
||||
ls.GetGC()->BarrierEnd();
|
||||
|
||||
return enumerableItem;
|
||||
|
||||
return res;
|
||||
} else if (GetArgumentHeap(args, 0, dynDict)) {
|
||||
return dynDict->GetField(ls, key);
|
||||
}
|
||||
|
||||
return Undefined();
|
||||
}
|
||||
TObject Dictionary_GetField(GCList& ls, std::vector<TObject> args)
|
||||
{
|
||||
TDictionary* dict;
|
||||
TDynamicDictionary* dynDict;
|
||||
std::string key;
|
||||
if(GetArgument(args,1,key))
|
||||
{
|
||||
if(GetArgumentHeap(args,0,dict))
|
||||
{
|
||||
ls.GetGC()->BarrierBegin();
|
||||
auto res = dict->GetValue(key);
|
||||
ls.GetGC()->BarrierEnd();
|
||||
return res;
|
||||
}
|
||||
else if(GetArgumentHeap(args,0,dynDict))
|
||||
{
|
||||
return dynDict->GetField(ls,key);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
TObject Dictionary_SetField(GCList &ls, std::vector<TObject> args) {
|
||||
TDictionary *dict;
|
||||
TDynamicDictionary *dynDict;
|
||||
std::string key;
|
||||
if (args.size() == 3 && GetArgument(args, 1, key)) {
|
||||
if (GetArgumentHeap(args, 0, dict)) {
|
||||
ls.GetGC()->BarrierBegin();
|
||||
dict->SetValue(key, args[2]);
|
||||
ls.GetGC()->BarrierEnd();
|
||||
} else if (GetArgumentHeap(args, 0, dynDict)) {
|
||||
dynDict->SetField(ls, key, args[2]);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
TObject Dictionary_SetField(GCList& ls, std::vector<TObject> args)
|
||||
{
|
||||
TDictionary* dict;
|
||||
TDynamicDictionary* dynDict;
|
||||
std::string key;
|
||||
if(args.size() == 3 && GetArgument(args,1,key))
|
||||
{
|
||||
if(GetArgumentHeap(args,0,dict))
|
||||
{
|
||||
ls.GetGC()->BarrierBegin();
|
||||
dict->SetValue(key,args[2]);
|
||||
ls.GetGC()->BarrierEnd();
|
||||
}
|
||||
else if(GetArgumentHeap(args,0,dynDict))
|
||||
{
|
||||
dynDict->SetField(ls,key,args[2]);
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
void TStd::RegisterDictionary(std::shared_ptr<GC> gc,TRootEnvironment* env)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
void TStd::RegisterDictionary(std::shared_ptr<GC> gc, TRootEnvironment *env) {
|
||||
|
||||
env->permissions.canRegisterDictionary=true;
|
||||
GCList ls(gc);
|
||||
TDictionary* dict = TDictionary::Create(ls);
|
||||
|
||||
env->permissions.canRegisterDictionary = true;
|
||||
GCList ls(gc);
|
||||
TDictionary *dict = TDictionary::Create(ls);
|
||||
|
||||
gc->BarrierBegin();
|
||||
dict->DeclareFunction(gc, "FindByKey","Scan object recursively, return list of items with key",{"obj","key"}, Dictionary_FindByKey);
|
||||
dict->DeclareFunction(gc, "Items","Get Dictionary Item Enumerable, for the each(item : Dictionary.Items(myDict)){item.Key; item.Value;}",{"dictionary"},Dictionary_Items);
|
||||
dict->DeclareFunction(gc, "SetField","Set a field in dictionary",{"dict","key","value"},Dictionary_SetField);
|
||||
dict->DeclareFunction(gc, "GetField","Get a field in dictionary",{"dict","key"},Dictionary_GetField);
|
||||
gc->BarrierBegin();
|
||||
dict->DeclareFunction(
|
||||
gc, "FindByKey",
|
||||
"Scan object recursively, return list of items with key",
|
||||
{"obj", "key"}, Dictionary_FindByKey);
|
||||
dict->DeclareFunction(gc, "Items",
|
||||
"Get Dictionary Item Enumerable, for the each(item : "
|
||||
"Dictionary.Items(myDict)){item.Key; item.Value;}",
|
||||
{"dictionary"}, Dictionary_Items);
|
||||
dict->DeclareFunction(gc, "SetField", "Set a field in dictionary",
|
||||
{"dict", "key", "value"}, Dictionary_SetField);
|
||||
dict->DeclareFunction(gc, "GetField", "Get a field in dictionary",
|
||||
{"dict", "key"}, Dictionary_GetField);
|
||||
|
||||
env->DeclareVariable("Dictionary", dict);
|
||||
gc->BarrierEnd();
|
||||
}
|
||||
}
|
||||
env->DeclareVariable("Dictionary", dict);
|
||||
gc->BarrierEnd();
|
||||
}
|
||||
} // namespace Tesses::CrossLang
|
||||
@@ -5,165 +5,152 @@
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
namespace Tesses::CrossLang
|
||||
{
|
||||
using namespace Tesses::Framework::Platform::Environment;
|
||||
#if defined(_WIN32)
|
||||
static char EnvPathSeperator=';';
|
||||
#else
|
||||
static char EnvPathSeperator=':';
|
||||
#endif
|
||||
namespace Tesses::CrossLang {
|
||||
using namespace Tesses::Framework::Platform::Environment;
|
||||
#if defined(_WIN32)
|
||||
static char EnvPathSeperator = ';';
|
||||
#else
|
||||
static char EnvPathSeperator = ':';
|
||||
#endif
|
||||
|
||||
Tesses::Framework::Filesystem::VFSPath CrossLangConfigPath("");
|
||||
Tesses::Framework::Filesystem::VFSPath CrossLangConfigPath("");
|
||||
|
||||
|
||||
Tesses::Framework::Filesystem::VFSPath GetCrossLangConfigDir()
|
||||
{
|
||||
if(!CrossLangConfigPath.path.empty())
|
||||
return CrossLangConfigPath;
|
||||
|
||||
return SpecialFolders::GetConfig() / "Tesses" / "CrossLang";
|
||||
}
|
||||
Tesses::Framework::Filesystem::VFSPath GetCrossLangConfigDir() {
|
||||
if (!CrossLangConfigPath.path.empty())
|
||||
return CrossLangConfigPath;
|
||||
|
||||
|
||||
|
||||
static TObject Env_getCrossLangConfig(GCList& ls, std::vector<TObject> args)
|
||||
{
|
||||
return GetCrossLangConfigDir();
|
||||
}
|
||||
static TObject Env_getPlatform(GCList& ls, std::vector<TObject> args)
|
||||
{
|
||||
return Tesses::Framework::Platform::Environment::GetPlatform();
|
||||
}
|
||||
static TObject Env_GetAt(GCList& ls, std::vector<TObject> args)
|
||||
{
|
||||
std::string key;
|
||||
if(GetArgument(args,0,key))
|
||||
{
|
||||
auto v = GetVariable(key);
|
||||
if(v) return v.value();
|
||||
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
static TObject Env_SetAt(GCList& ls, std::vector<TObject> args)
|
||||
{
|
||||
std::string key;
|
||||
std::string value;
|
||||
if(GetArgument(args,0,key))
|
||||
{
|
||||
if(GetArgument(args,1,value))
|
||||
{
|
||||
SetVariable(key,value);
|
||||
|
||||
return value;
|
||||
}
|
||||
else
|
||||
{
|
||||
SetVariable(key,std::nullopt);
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
static TObject Env_getDownloads(GCList& ls, std::vector<TObject> args)
|
||||
{
|
||||
return SpecialFolders::GetDownloads();
|
||||
}
|
||||
static TObject Env_getMusic(GCList& ls, std::vector<TObject> args)
|
||||
{
|
||||
return SpecialFolders::GetMusic();
|
||||
}
|
||||
static TObject Env_getPictures(GCList& ls, std::vector<TObject> args)
|
||||
{
|
||||
return SpecialFolders::GetPictures();
|
||||
}
|
||||
static TObject Env_getVideos(GCList& ls, std::vector<TObject> args)
|
||||
{
|
||||
return SpecialFolders::GetVideos();
|
||||
}
|
||||
static TObject Env_getDocuments(GCList& ls, std::vector<TObject> args)
|
||||
{
|
||||
return SpecialFolders::GetDocuments();
|
||||
}
|
||||
static TObject Env_getConfig(GCList& ls, std::vector<TObject> args)
|
||||
{
|
||||
return SpecialFolders::GetConfig();
|
||||
}
|
||||
|
||||
static TObject Env_getDesktop(GCList& ls, std::vector<TObject> args)
|
||||
{
|
||||
return SpecialFolders::GetDesktop();
|
||||
}
|
||||
static TObject Env_getState(GCList& ls, std::vector<TObject> args)
|
||||
{
|
||||
return SpecialFolders::GetState();
|
||||
}
|
||||
static TObject Env_getCache(GCList& ls, std::vector<TObject> args)
|
||||
{
|
||||
return SpecialFolders::GetCache();
|
||||
}
|
||||
static TObject Env_getData(GCList& ls, std::vector<TObject> args)
|
||||
{
|
||||
return SpecialFolders::GetData();
|
||||
}
|
||||
static TObject Env_getUser(GCList& ls, std::vector<TObject> args)
|
||||
{
|
||||
return SpecialFolders::GetHomeFolder();
|
||||
}
|
||||
static TObject Env_GetRealExecutablePath(GCList& ls, std::vector<TObject> args)
|
||||
{
|
||||
Tesses::Framework::Filesystem::VFSPath p;
|
||||
if(GetArgumentAsPath(args,0,p))
|
||||
{
|
||||
return GetRealExecutablePath(p);
|
||||
}
|
||||
return Tesses::Framework::Filesystem::VFSPath();
|
||||
}
|
||||
static TObject Env_GetAll(GCList& ls, std::vector<TObject> args)
|
||||
{
|
||||
ls.GetGC()->BarrierBegin();
|
||||
TList* list = TList::Create(ls);
|
||||
std::vector<std::pair<std::string, std::string>> env;
|
||||
Tesses::Framework::Platform::Environment::GetEnvironmentVariables(env);
|
||||
for(auto& item : env)
|
||||
{
|
||||
list->Add(TDictionary::Create(ls,{TDItem("Key",item.first),TDItem("Value",item.second)}));
|
||||
}
|
||||
ls.GetGC()->BarrierEnd();
|
||||
return list;
|
||||
}
|
||||
static TObject Env_getLittleEndian(GCList& ls, std::vector<TObject> args)
|
||||
{
|
||||
return Tesses::Framework::Serialization::BitConverter::IsLittleEndian();
|
||||
}
|
||||
void TStd::RegisterEnv(std::shared_ptr<GC> gc, TRootEnvironment* env)
|
||||
{
|
||||
|
||||
env->permissions.canRegisterEnv=true;
|
||||
GCList ls(gc);
|
||||
TDictionary* dict = TDictionary::Create(ls);
|
||||
dict->DeclareFunction(gc,"GetAt","Get environment variable", {"key"}, Env_GetAt);
|
||||
dict->DeclareFunction(gc,"SetAt","Set environment variable", {"key","value"}, Env_SetAt);
|
||||
dict->DeclareFunction(gc,"GetAll","Get all of the environment variables",{},Env_GetAll);
|
||||
|
||||
dict->DeclareFunction(gc,"getDesktop","Get desktop folder",{},Env_getDesktop);
|
||||
dict->DeclareFunction(gc,"getDownloads","Get downloads folder",{},Env_getDownloads);
|
||||
dict->DeclareFunction(gc,"getDocuments","Get documents folder",{},Env_getDocuments);
|
||||
dict->DeclareFunction(gc,"getMusic","Get music folder",{},Env_getMusic);
|
||||
dict->DeclareFunction(gc,"getPictures","Get pictures folder",{},Env_getPictures);
|
||||
dict->DeclareFunction(gc,"getVideos","Get videos folder",{},Env_getVideos);
|
||||
dict->DeclareFunction(gc,"getState","Get state folder",{},Env_getState);
|
||||
dict->DeclareFunction(gc,"getCache","Get cache folder",{},Env_getCache);
|
||||
dict->DeclareFunction(gc,"getConfig","Get config folder",{},Env_getConfig);
|
||||
dict->DeclareFunction(gc,"getCrossLangConfig","Get crosslang configuration folder",{}, Env_getCrossLangConfig);
|
||||
dict->DeclareFunction(gc,"getData","Get data folder",{},Env_getData);
|
||||
dict->DeclareFunction(gc,"getUser","Get user folder",{},Env_getUser);
|
||||
dict->DeclareFunction(gc,"getPlatform","Get platform name",{},Env_getPlatform);
|
||||
dict->DeclareFunction(gc,"GetRealExecutablePath", "Get the absolute path for executable", {"path"},Env_GetRealExecutablePath);
|
||||
dict->DeclareFunction(gc, "getLittleEndian", "Is the platform little endian", {},Env_getLittleEndian);
|
||||
gc->BarrierBegin();
|
||||
dict->SetValue("EnvPathSeperator",EnvPathSeperator);
|
||||
env->SetVariable("Env", dict);
|
||||
gc->BarrierEnd();
|
||||
}
|
||||
return SpecialFolders::GetConfig() / "Tesses" / "CrossLang";
|
||||
}
|
||||
|
||||
static TObject Env_getCrossLangConfig(GCList &ls, std::vector<TObject> args) {
|
||||
return GetCrossLangConfigDir();
|
||||
}
|
||||
static TObject Env_getPlatform(GCList &ls, std::vector<TObject> args) {
|
||||
return Tesses::Framework::Platform::Environment::GetPlatform();
|
||||
}
|
||||
static TObject Env_GetAt(GCList &ls, std::vector<TObject> args) {
|
||||
std::string key;
|
||||
if (GetArgument(args, 0, key)) {
|
||||
auto v = GetVariable(key);
|
||||
if (v)
|
||||
return v.value();
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
static TObject Env_SetAt(GCList &ls, std::vector<TObject> args) {
|
||||
std::string key;
|
||||
std::string value;
|
||||
if (GetArgument(args, 0, key)) {
|
||||
if (GetArgument(args, 1, value)) {
|
||||
SetVariable(key, value);
|
||||
|
||||
return value;
|
||||
} else {
|
||||
SetVariable(key, std::nullopt);
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
static TObject Env_getDownloads(GCList &ls, std::vector<TObject> args) {
|
||||
return SpecialFolders::GetDownloads();
|
||||
}
|
||||
static TObject Env_getMusic(GCList &ls, std::vector<TObject> args) {
|
||||
return SpecialFolders::GetMusic();
|
||||
}
|
||||
static TObject Env_getPictures(GCList &ls, std::vector<TObject> args) {
|
||||
return SpecialFolders::GetPictures();
|
||||
}
|
||||
static TObject Env_getVideos(GCList &ls, std::vector<TObject> args) {
|
||||
return SpecialFolders::GetVideos();
|
||||
}
|
||||
static TObject Env_getDocuments(GCList &ls, std::vector<TObject> args) {
|
||||
return SpecialFolders::GetDocuments();
|
||||
}
|
||||
static TObject Env_getConfig(GCList &ls, std::vector<TObject> args) {
|
||||
return SpecialFolders::GetConfig();
|
||||
}
|
||||
|
||||
static TObject Env_getDesktop(GCList &ls, std::vector<TObject> args) {
|
||||
return SpecialFolders::GetDesktop();
|
||||
}
|
||||
static TObject Env_getState(GCList &ls, std::vector<TObject> args) {
|
||||
return SpecialFolders::GetState();
|
||||
}
|
||||
static TObject Env_getCache(GCList &ls, std::vector<TObject> args) {
|
||||
return SpecialFolders::GetCache();
|
||||
}
|
||||
static TObject Env_getData(GCList &ls, std::vector<TObject> args) {
|
||||
return SpecialFolders::GetData();
|
||||
}
|
||||
static TObject Env_getUser(GCList &ls, std::vector<TObject> args) {
|
||||
return SpecialFolders::GetHomeFolder();
|
||||
}
|
||||
static TObject Env_GetRealExecutablePath(GCList &ls,
|
||||
std::vector<TObject> args) {
|
||||
Tesses::Framework::Filesystem::VFSPath p;
|
||||
if (GetArgumentAsPath(args, 0, p)) {
|
||||
return GetRealExecutablePath(p);
|
||||
}
|
||||
return Tesses::Framework::Filesystem::VFSPath();
|
||||
}
|
||||
static TObject Env_GetAll(GCList &ls, std::vector<TObject> args) {
|
||||
ls.GetGC()->BarrierBegin();
|
||||
TList *list = TList::Create(ls);
|
||||
std::vector<std::pair<std::string, std::string>> env;
|
||||
Tesses::Framework::Platform::Environment::GetEnvironmentVariables(env);
|
||||
for (auto &item : env) {
|
||||
list->Add(TDictionary::Create(
|
||||
ls, {TDItem("Key", item.first), TDItem("Value", item.second)}));
|
||||
}
|
||||
ls.GetGC()->BarrierEnd();
|
||||
return list;
|
||||
}
|
||||
static TObject Env_getLittleEndian(GCList &ls, std::vector<TObject> args) {
|
||||
return Tesses::Framework::Serialization::BitConverter::IsLittleEndian();
|
||||
}
|
||||
void TStd::RegisterEnv(std::shared_ptr<GC> gc, TRootEnvironment *env) {
|
||||
|
||||
env->permissions.canRegisterEnv = true;
|
||||
GCList ls(gc);
|
||||
TDictionary *dict = TDictionary::Create(ls);
|
||||
dict->DeclareFunction(gc, "GetAt", "Get environment variable", {"key"},
|
||||
Env_GetAt);
|
||||
dict->DeclareFunction(gc, "SetAt", "Set environment variable",
|
||||
{"key", "value"}, Env_SetAt);
|
||||
dict->DeclareFunction(gc, "GetAll", "Get all of the environment variables",
|
||||
{}, Env_GetAll);
|
||||
|
||||
dict->DeclareFunction(gc, "getDesktop", "Get desktop folder", {},
|
||||
Env_getDesktop);
|
||||
dict->DeclareFunction(gc, "getDownloads", "Get downloads folder", {},
|
||||
Env_getDownloads);
|
||||
dict->DeclareFunction(gc, "getDocuments", "Get documents folder", {},
|
||||
Env_getDocuments);
|
||||
dict->DeclareFunction(gc, "getMusic", "Get music folder", {}, Env_getMusic);
|
||||
dict->DeclareFunction(gc, "getPictures", "Get pictures folder", {},
|
||||
Env_getPictures);
|
||||
dict->DeclareFunction(gc, "getVideos", "Get videos folder", {},
|
||||
Env_getVideos);
|
||||
dict->DeclareFunction(gc, "getState", "Get state folder", {}, Env_getState);
|
||||
dict->DeclareFunction(gc, "getCache", "Get cache folder", {}, Env_getCache);
|
||||
dict->DeclareFunction(gc, "getConfig", "Get config folder", {},
|
||||
Env_getConfig);
|
||||
dict->DeclareFunction(gc, "getCrossLangConfig",
|
||||
"Get crosslang configuration folder", {},
|
||||
Env_getCrossLangConfig);
|
||||
dict->DeclareFunction(gc, "getData", "Get data folder", {}, Env_getData);
|
||||
dict->DeclareFunction(gc, "getUser", "Get user folder", {}, Env_getUser);
|
||||
dict->DeclareFunction(gc, "getPlatform", "Get platform name", {},
|
||||
Env_getPlatform);
|
||||
dict->DeclareFunction(gc, "GetRealExecutablePath",
|
||||
"Get the absolute path for executable", {"path"},
|
||||
Env_GetRealExecutablePath);
|
||||
dict->DeclareFunction(gc, "getLittleEndian",
|
||||
"Is the platform little endian", {},
|
||||
Env_getLittleEndian);
|
||||
gc->BarrierBegin();
|
||||
dict->SetValue("EnvPathSeperator", EnvPathSeperator);
|
||||
env->SetVariable("Env", dict);
|
||||
gc->BarrierEnd();
|
||||
}
|
||||
} // namespace Tesses::CrossLang
|
||||
|
||||
@@ -1,57 +1,53 @@
|
||||
#include "CrossLang.hpp"
|
||||
|
||||
namespace Tesses::CrossLang {
|
||||
static TObject Helpers_CopyToProgress(GCList& ls, std::vector<TObject> args)
|
||||
{
|
||||
std::shared_ptr<Tesses::Framework::Streams::Stream> src;
|
||||
std::shared_ptr<Tesses::Framework::Streams::Stream> dest;
|
||||
double precision=1000.0;
|
||||
TCallable* callable;
|
||||
if(GetArgument(args,0,src) && GetArgument(args,1,dest) && GetArgumentHeap(args,2,callable))
|
||||
{
|
||||
GetArgument(args,3,precision);
|
||||
auto len = src->GetLength();
|
||||
callable->Call(ls,{0.0});
|
||||
if(len > 0)
|
||||
{
|
||||
std::vector<uint8_t> buff(1024);
|
||||
int64_t pos=0;
|
||||
int curPercent=0;
|
||||
int lastPercent=0;
|
||||
size_t read = 0;
|
||||
do {
|
||||
read = src->ReadBlock(buff.data(),buff.size());
|
||||
dest->WriteBlock(buff.data(),read);
|
||||
static TObject Helpers_CopyToProgress(GCList &ls, std::vector<TObject> args) {
|
||||
std::shared_ptr<Tesses::Framework::Streams::Stream> src;
|
||||
std::shared_ptr<Tesses::Framework::Streams::Stream> dest;
|
||||
double precision = 1000.0;
|
||||
TCallable *callable;
|
||||
if (GetArgument(args, 0, src) && GetArgument(args, 1, dest) &&
|
||||
GetArgumentHeap(args, 2, callable)) {
|
||||
GetArgument(args, 3, precision);
|
||||
auto len = src->GetLength();
|
||||
callable->Call(ls, {0.0});
|
||||
if (len > 0) {
|
||||
std::vector<uint8_t> buff(1024);
|
||||
int64_t pos = 0;
|
||||
int curPercent = 0;
|
||||
int lastPercent = 0;
|
||||
size_t read = 0;
|
||||
do {
|
||||
read = src->ReadBlock(buff.data(), buff.size());
|
||||
dest->WriteBlock(buff.data(), read);
|
||||
|
||||
if(read == 0) break;
|
||||
pos += (int64_t)read;
|
||||
if (read == 0)
|
||||
break;
|
||||
pos += (int64_t)read;
|
||||
|
||||
double percent = ((double)pos / len);
|
||||
percent *= precision;
|
||||
|
||||
curPercent = (int)percent;
|
||||
double percent = ((double)pos / len);
|
||||
percent *= precision;
|
||||
|
||||
|
||||
if(curPercent > lastPercent)
|
||||
{
|
||||
lastPercent = curPercent;
|
||||
callable->Call(ls,{curPercent/precision});
|
||||
}
|
||||
curPercent = (int)percent;
|
||||
|
||||
if (curPercent > lastPercent) {
|
||||
lastPercent = curPercent;
|
||||
callable->Call(ls, {curPercent / precision});
|
||||
}
|
||||
|
||||
} while(read != 0);
|
||||
}
|
||||
else {
|
||||
src->CopyTo(dest);
|
||||
|
||||
}
|
||||
callable->Call(ls,{1.0});
|
||||
} while (read != 0);
|
||||
} else {
|
||||
src->CopyTo(dest);
|
||||
}
|
||||
return Undefined();
|
||||
callable->Call(ls, {1.0});
|
||||
}
|
||||
void TStd::RegisterHelpers(std::shared_ptr<GC> gc, TRootEnvironment* env)
|
||||
{
|
||||
auto helpers=env->EnsureDictionary(gc,"Helpers");
|
||||
helpers->DeclareFunction(gc,"CopyToProgress","Copy Stream to another (but with progress event)",{"src","dest","progressCB","$precision"},Helpers_CopyToProgress);
|
||||
}
|
||||
}
|
||||
return Undefined();
|
||||
}
|
||||
void TStd::RegisterHelpers(std::shared_ptr<GC> gc, TRootEnvironment *env) {
|
||||
auto helpers = env->EnsureDictionary(gc, "Helpers");
|
||||
helpers->DeclareFunction(gc, "CopyToProgress",
|
||||
"Copy Stream to another (but with progress event)",
|
||||
{"src", "dest", "progressCB", "$precision"},
|
||||
Helpers_CopyToProgress);
|
||||
}
|
||||
} // namespace Tesses::CrossLang
|
||||
@@ -1,322 +1,341 @@
|
||||
#include "CrossLang.hpp"
|
||||
|
||||
namespace Tesses::CrossLang {
|
||||
static TObject FS_CreateArchive(GCList &ls, std::vector<TObject> args) {
|
||||
std::shared_ptr<Tesses::Framework::Filesystem::VFS> vfs;
|
||||
|
||||
std::shared_ptr<Tesses::Framework::Streams::Stream> strm;
|
||||
|
||||
namespace Tesses::CrossLang
|
||||
{
|
||||
static TObject FS_CreateArchive(GCList& ls, std::vector<TObject> args)
|
||||
{
|
||||
std::shared_ptr<Tesses::Framework::Filesystem::VFS> vfs;
|
||||
|
||||
std::shared_ptr<Tesses::Framework::Streams::Stream> strm;
|
||||
|
||||
std::string name;
|
||||
std::string version;
|
||||
std::string info;
|
||||
std::string icon="";
|
||||
TVMVersion version2;
|
||||
std::string name;
|
||||
std::string version;
|
||||
std::string info;
|
||||
std::string icon = "";
|
||||
TVMVersion version2;
|
||||
|
||||
if(GetArgument(args,0,vfs) && GetArgument(args,1,strm) && GetArgument(args,2,name) && GetArgument(args,4,info) && ((GetArgument(args,3,version) && TVMVersion::TryParse(version,version2)) || GetArgument(args,3,version2)))
|
||||
{
|
||||
GetArgument(args,5,icon);
|
||||
CrossArchiveCreate(vfs,strm,name,version2,info,icon);
|
||||
}
|
||||
return nullptr;
|
||||
if (GetArgument(args, 0, vfs) && GetArgument(args, 1, strm) &&
|
||||
GetArgument(args, 2, name) && GetArgument(args, 4, info) &&
|
||||
((GetArgument(args, 3, version) &&
|
||||
TVMVersion::TryParse(version, version2)) ||
|
||||
GetArgument(args, 3, version2))) {
|
||||
GetArgument(args, 5, icon);
|
||||
CrossArchiveCreate(vfs, strm, name, version2, info, icon);
|
||||
}
|
||||
static TObject FS_ExtractArchive(GCList& ls, std::vector<TObject> args)
|
||||
{
|
||||
std::shared_ptr<Tesses::Framework::Filesystem::VFS> vfs;
|
||||
|
||||
std::shared_ptr<Tesses::Framework::Streams::Stream> strm;
|
||||
|
||||
|
||||
if(GetArgument(args,0,strm) && GetArgument(args,1,vfs))
|
||||
{
|
||||
auto res = CrossArchiveExtract(strm,vfs);
|
||||
return nullptr;
|
||||
}
|
||||
static TObject FS_ExtractArchive(GCList &ls, std::vector<TObject> args) {
|
||||
std::shared_ptr<Tesses::Framework::Filesystem::VFS> vfs;
|
||||
|
||||
TDictionary* dict = TDictionary::Create(ls);
|
||||
ls.GetGC()->BarrierBegin();
|
||||
dict->SetValue("Name",res.first.first);
|
||||
dict->SetValue("Version",res.first.second.ToString());
|
||||
dict->SetValue("Info",res.second);
|
||||
ls.GetGC()->BarrierEnd();
|
||||
return dict;
|
||||
}
|
||||
return nullptr;
|
||||
std::shared_ptr<Tesses::Framework::Streams::Stream> strm;
|
||||
|
||||
if (GetArgument(args, 0, strm) && GetArgument(args, 1, vfs)) {
|
||||
auto res = CrossArchiveExtract(strm, vfs);
|
||||
|
||||
TDictionary *dict = TDictionary::Create(ls);
|
||||
ls.GetGC()->BarrierBegin();
|
||||
dict->SetValue("Name", res.first.first);
|
||||
dict->SetValue("Version", res.first.second.ToString());
|
||||
dict->SetValue("Info", res.second);
|
||||
ls.GetGC()->BarrierEnd();
|
||||
return dict;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
static TObject FS_ReadAllText(GCList& ls, std::vector<TObject> args)
|
||||
{
|
||||
Tesses::Framework::Filesystem::VFSPath path;
|
||||
static TObject FS_ReadAllText(GCList &ls, std::vector<TObject> args) {
|
||||
Tesses::Framework::Filesystem::VFSPath path;
|
||||
|
||||
std::shared_ptr<Tesses::Framework::Filesystem::VFS> vfs;
|
||||
|
||||
if(GetArgument(args,0,vfs) && GetArgumentAsPath(args,1,path))
|
||||
{
|
||||
return Tesses::Framework::Filesystem::Helpers::ReadAllText(vfs,path);
|
||||
}
|
||||
return "";
|
||||
std::shared_ptr<Tesses::Framework::Filesystem::VFS> vfs;
|
||||
|
||||
if (GetArgument(args, 0, vfs) && GetArgumentAsPath(args, 1, path)) {
|
||||
return Tesses::Framework::Filesystem::Helpers::ReadAllText(vfs, path);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
static TObject FS_ReadAllLines(GCList& ls, std::vector<TObject> args)
|
||||
{
|
||||
Tesses::Framework::Filesystem::VFSPath path;
|
||||
static TObject FS_ReadAllLines(GCList &ls, std::vector<TObject> args) {
|
||||
Tesses::Framework::Filesystem::VFSPath path;
|
||||
|
||||
std::shared_ptr<Tesses::Framework::Filesystem::VFS> vfs;
|
||||
|
||||
if(GetArgument(args,0,vfs) && GetArgumentAsPath(args,1,path))
|
||||
{
|
||||
std::vector<std::string> lines;
|
||||
std::shared_ptr<Tesses::Framework::Filesystem::VFS> vfs;
|
||||
|
||||
Tesses::Framework::Filesystem::Helpers::ReadAllLines(vfs,path,lines);
|
||||
if (GetArgument(args, 0, vfs) && GetArgumentAsPath(args, 1, path)) {
|
||||
std::vector<std::string> lines;
|
||||
|
||||
ls.GetGC()->BarrierBegin();
|
||||
auto items = TList::Create(ls);
|
||||
for(auto& l : lines) { items->Add(l);}
|
||||
ls.GetGC()->BarrierEnd();
|
||||
return items;
|
||||
Tesses::Framework::Filesystem::Helpers::ReadAllLines(vfs, path, lines);
|
||||
|
||||
ls.GetGC()->BarrierBegin();
|
||||
auto items = TList::Create(ls);
|
||||
for (auto &l : lines) {
|
||||
items->Add(l);
|
||||
}
|
||||
return nullptr;
|
||||
ls.GetGC()->BarrierEnd();
|
||||
return items;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
static TObject FS_ReadAllBytes(GCList& ls, std::vector<TObject> args)
|
||||
{
|
||||
Tesses::Framework::Filesystem::VFSPath path;
|
||||
std::shared_ptr<Tesses::Framework::Filesystem::VFS> vfs;
|
||||
|
||||
if(GetArgument(args,0,vfs) && GetArgumentAsPath(args,1,path))
|
||||
{
|
||||
auto res = TByteArray::Create(ls);
|
||||
Tesses::Framework::Filesystem::Helpers::ReadAllBytes(vfs,path,res->data);
|
||||
|
||||
return res;
|
||||
}
|
||||
return nullptr;
|
||||
static TObject FS_ReadAllBytes(GCList &ls, std::vector<TObject> args) {
|
||||
Tesses::Framework::Filesystem::VFSPath path;
|
||||
std::shared_ptr<Tesses::Framework::Filesystem::VFS> vfs;
|
||||
|
||||
if (GetArgument(args, 0, vfs) && GetArgumentAsPath(args, 1, path)) {
|
||||
auto res = TByteArray::Create(ls);
|
||||
Tesses::Framework::Filesystem::Helpers::ReadAllBytes(vfs, path,
|
||||
res->data);
|
||||
|
||||
return res;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
static TObject FS_WriteAllLines(GCList &ls, std::vector<TObject> args) {
|
||||
Tesses::Framework::Filesystem::VFSPath path;
|
||||
std::shared_ptr<Tesses::Framework::Filesystem::VFS> vfs;
|
||||
|
||||
static TObject FS_WriteAllLines(GCList& ls, std::vector<TObject> args)
|
||||
{
|
||||
Tesses::Framework::Filesystem::VFSPath path;
|
||||
std::shared_ptr<Tesses::Framework::Filesystem::VFS> vfs;
|
||||
|
||||
|
||||
TList* lines;
|
||||
if(GetArgument(args,0,vfs) && GetArgumentAsPath(args,1,path) && GetArgumentHeap(args,2,lines))
|
||||
{
|
||||
std::vector<std::string> content;
|
||||
ls.GetGC()->BarrierBegin();
|
||||
for(auto& item : lines->items)
|
||||
{
|
||||
if(std::holds_alternative<std::string>(item))
|
||||
TList *lines;
|
||||
if (GetArgument(args, 0, vfs) && GetArgumentAsPath(args, 1, path) &&
|
||||
GetArgumentHeap(args, 2, lines)) {
|
||||
std::vector<std::string> content;
|
||||
ls.GetGC()->BarrierBegin();
|
||||
for (auto &item : lines->items) {
|
||||
if (std::holds_alternative<std::string>(item))
|
||||
content.push_back(std::get<std::string>(item));
|
||||
}
|
||||
ls.GetGC()->BarrierEnd();
|
||||
Tesses::Framework::Filesystem::Helpers::WriteAllLines(vfs, path,
|
||||
content);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
static TObject FS_WriteAllText(GCList &ls, std::vector<TObject> args) {
|
||||
Tesses::Framework::Filesystem::VFSPath path;
|
||||
std::shared_ptr<Tesses::Framework::Filesystem::VFS> vfs;
|
||||
|
||||
std::string content;
|
||||
if (GetArgument(args, 0, vfs) && GetArgumentAsPath(args, 1, path) &&
|
||||
GetArgument(args, 2, content)) {
|
||||
Tesses::Framework::Filesystem::Helpers::WriteAllText(vfs, path,
|
||||
content);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
static TObject FS_WriteAllBytes(GCList &ls, std::vector<TObject> args) {
|
||||
Tesses::Framework::Filesystem::VFSPath path;
|
||||
|
||||
std::shared_ptr<Tesses::Framework::Filesystem::VFS> vfs;
|
||||
|
||||
TByteArray *bArray;
|
||||
if (GetArgument(args, 0, vfs) && GetArgumentAsPath(args, 1, path) &&
|
||||
GetArgumentHeap(args, 2, bArray)) {
|
||||
Tesses::Framework::Filesystem::Helpers::WriteAllBytes(vfs, path,
|
||||
bArray->data);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
class FS_Watcher : public TNativeObject {
|
||||
public:
|
||||
std::shared_ptr<Tesses::Framework::Filesystem::FSWatcher> watcher;
|
||||
|
||||
FS_Watcher(
|
||||
std::shared_ptr<Tesses::Framework::Filesystem::FSWatcher> watcher)
|
||||
: watcher(watcher) {}
|
||||
|
||||
TObject CallMethod(GCList &ls, std::string name,
|
||||
std::vector<TObject> args) {
|
||||
if (name == "getPath") {
|
||||
return watcher->GetPath();
|
||||
}
|
||||
if (name == "getFilesystem") {
|
||||
return watcher->GetFilesystem();
|
||||
}
|
||||
if (name == "setEnabled") {
|
||||
bool enabled;
|
||||
if (GetArgument(args, 0, enabled)) {
|
||||
watcher->SetEnabled(enabled);
|
||||
return enabled;
|
||||
}
|
||||
ls.GetGC()->BarrierEnd();
|
||||
Tesses::Framework::Filesystem::Helpers::WriteAllLines(vfs,path,content);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
static TObject FS_WriteAllText(GCList& ls, std::vector<TObject> args)
|
||||
{
|
||||
Tesses::Framework::Filesystem::VFSPath path;
|
||||
std::shared_ptr<Tesses::Framework::Filesystem::VFS> vfs;
|
||||
|
||||
|
||||
std::string content;
|
||||
if(GetArgument(args,0,vfs) && GetArgumentAsPath(args,1,path) && GetArgument(args,2,content))
|
||||
{
|
||||
Tesses::Framework::Filesystem::Helpers::WriteAllText(vfs,path,content);
|
||||
if (name == "getEnabled") {
|
||||
return watcher->GetEnabled();
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
static TObject FS_WriteAllBytes(GCList& ls, std::vector<TObject> args)
|
||||
{
|
||||
Tesses::Framework::Filesystem::VFSPath path;
|
||||
|
||||
std::shared_ptr<Tesses::Framework::Filesystem::VFS> vfs;
|
||||
|
||||
TByteArray* bArray;
|
||||
if(GetArgument(args,0,vfs) && GetArgumentAsPath(args,1,path) && GetArgumentHeap(args,2,bArray))
|
||||
{
|
||||
Tesses::Framework::Filesystem::Helpers::WriteAllBytes(vfs,path,bArray->data);
|
||||
if (name == "setEvents") {
|
||||
int64_t evts;
|
||||
if (GetArgument(args, 0, evts)) {
|
||||
watcher->events =
|
||||
(Tesses::Framework::Filesystem::FSWatcherEventType)evts;
|
||||
return evts;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class FS_Watcher : public TNativeObject {
|
||||
public:
|
||||
std::shared_ptr<Tesses::Framework::Filesystem::FSWatcher> watcher;
|
||||
|
||||
FS_Watcher(std::shared_ptr<Tesses::Framework::Filesystem::FSWatcher> watcher): watcher(watcher)
|
||||
{}
|
||||
|
||||
TObject CallMethod(GCList& ls, std::string name, std::vector<TObject> args)
|
||||
{
|
||||
if(name == "getPath")
|
||||
{
|
||||
return watcher->GetPath();
|
||||
}
|
||||
if(name == "getFilesystem")
|
||||
{
|
||||
return watcher->GetFilesystem();
|
||||
}
|
||||
if(name == "setEnabled")
|
||||
{
|
||||
bool enabled;
|
||||
if(GetArgument(args,0,enabled))
|
||||
{
|
||||
watcher->SetEnabled(enabled);
|
||||
return enabled;
|
||||
}
|
||||
}
|
||||
if(name == "getEnabled")
|
||||
{
|
||||
return watcher->GetEnabled();
|
||||
}
|
||||
if(name == "setEvents")
|
||||
{
|
||||
int64_t evts;
|
||||
if(GetArgument(args,0,evts))
|
||||
{
|
||||
watcher->events = (Tesses::Framework::Filesystem::FSWatcherEventType)evts;
|
||||
return evts;
|
||||
}
|
||||
}
|
||||
if(name == "getEvents")
|
||||
{
|
||||
return (int64_t)watcher->events;
|
||||
}
|
||||
if(name == "setCallback")
|
||||
{
|
||||
TCallable* callable=nullptr;
|
||||
if(GetArgumentHeap(args,0,callable))
|
||||
{
|
||||
auto markedT = CreateMarkedTObject(ls,callable);
|
||||
watcher->event = [markedT](Tesses::Framework::Filesystem::FSWatcherEvent& evt) -> void {
|
||||
GCList ls(markedT->GetGC());
|
||||
TObject o = markedT->GetObject();
|
||||
TCallable* callable;
|
||||
if(GetObjectHeap(o,callable))
|
||||
{
|
||||
auto isEvent = TExternalMethod::Create(ls,"",{},[evt](GCList& ls, std::vector<TObject> args)->TObject
|
||||
{
|
||||
if (name == "getEvents") {
|
||||
return (int64_t)watcher->events;
|
||||
}
|
||||
if (name == "setCallback") {
|
||||
TCallable *callable = nullptr;
|
||||
if (GetArgumentHeap(args, 0, callable)) {
|
||||
auto markedT = CreateMarkedTObject(ls, callable);
|
||||
watcher->event =
|
||||
[markedT](
|
||||
Tesses::Framework::Filesystem::FSWatcherEvent &evt)
|
||||
-> void {
|
||||
GCList ls(markedT->GetGC());
|
||||
TObject o = markedT->GetObject();
|
||||
TCallable *callable;
|
||||
if (GetObjectHeap(o, callable)) {
|
||||
auto isEvent = TExternalMethod::Create(
|
||||
ls, "", {},
|
||||
[evt](GCList &ls,
|
||||
std::vector<TObject> args) -> TObject {
|
||||
int64_t n;
|
||||
if(GetArgument(args,0,n))
|
||||
{
|
||||
if (GetArgument(args, 0, n)) {
|
||||
auto myevt = evt;
|
||||
return myevt.IsEvent((Tesses::Framework::Filesystem::FSWatcherEventType)n);
|
||||
|
||||
return myevt.IsEvent(
|
||||
(Tesses::Framework::Filesystem::
|
||||
FSWatcherEventType)n);
|
||||
}
|
||||
|
||||
return false;
|
||||
});
|
||||
auto toString = TExternalMethod::Create(ls,"",{},[evt](GCList& ls, std::vector<TObject> args)->TObject
|
||||
{
|
||||
auto toString = TExternalMethod::Create(
|
||||
ls, "", {},
|
||||
[evt](GCList &ls,
|
||||
std::vector<TObject> args) -> TObject {
|
||||
auto myevt = evt;
|
||||
return myevt.ToString();
|
||||
});
|
||||
|
||||
auto dict = TDictionary::Create(ls, {TDItem("IsDirectory",evt.isDir),TDItem("Type",(int64_t)evt.type),TDItem("Source",evt.src), TDItem("Destination",evt.dest),TDItem("ToString",toString),TDItem("IsEvent",isEvent)});
|
||||
callable->Call(ls,{dict});
|
||||
}
|
||||
};
|
||||
auto dict = TDictionary::Create(
|
||||
ls, {TDItem("IsDirectory", evt.isDir),
|
||||
TDItem("Type", (int64_t)evt.type),
|
||||
TDItem("Source", evt.src),
|
||||
TDItem("Destination", evt.dest),
|
||||
TDItem("ToString", toString),
|
||||
TDItem("IsEvent", isEvent)});
|
||||
callable->Call(ls, {dict});
|
||||
}
|
||||
else {
|
||||
watcher->event=nullptr;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
if(name == "Start")
|
||||
{
|
||||
watcher->SetEnabled(true);
|
||||
}
|
||||
if(name == "Stop")
|
||||
{
|
||||
watcher->SetEnabled(false);
|
||||
}
|
||||
if(name == "ToString")
|
||||
{
|
||||
return "FSWatcher";
|
||||
}
|
||||
return Undefined();
|
||||
};
|
||||
} else {
|
||||
watcher->event = nullptr;
|
||||
}
|
||||
|
||||
std::string TypeName() {
|
||||
return "FSWatcher";
|
||||
}
|
||||
};
|
||||
|
||||
TObject New_FSWatcher(GCList& ls, std::vector<TObject> args)
|
||||
{
|
||||
std::shared_ptr<Tesses::Framework::Filesystem::VFS> vfs;
|
||||
Tesses::Framework::Filesystem::VFSPath path;
|
||||
if(GetArgument(args,0,vfs) && GetArgumentAsPath(args,1,path))
|
||||
{
|
||||
return TNativeObject::Create<FS_Watcher>(ls,Tesses::Framework::Filesystem::FSWatcher::Create(vfs,path));
|
||||
return nullptr;
|
||||
}
|
||||
return nullptr;
|
||||
if (name == "Start") {
|
||||
watcher->SetEnabled(true);
|
||||
}
|
||||
if (name == "Stop") {
|
||||
watcher->SetEnabled(false);
|
||||
}
|
||||
if (name == "ToString") {
|
||||
return "FSWatcher";
|
||||
}
|
||||
return Undefined();
|
||||
}
|
||||
void TStd::RegisterIO(std::shared_ptr<GC> gc,TRootEnvironment* env, bool enable)
|
||||
{
|
||||
if(enable)
|
||||
{
|
||||
RegisterIO(gc,env,std::make_shared<Tesses::Framework::Filesystem::RelativeFilesystem>(Tesses::Framework::Filesystem::LocalFS, Tesses::Framework::Filesystem::VFSPath::GetAbsoluteCurrentDirectory()));
|
||||
}
|
||||
else
|
||||
{
|
||||
RegisterIO(gc,env,nullptr);
|
||||
}
|
||||
|
||||
std::string TypeName() { return "FSWatcher"; }
|
||||
};
|
||||
|
||||
TObject New_FSWatcher(GCList &ls, std::vector<TObject> args) {
|
||||
std::shared_ptr<Tesses::Framework::Filesystem::VFS> vfs;
|
||||
Tesses::Framework::Filesystem::VFSPath path;
|
||||
if (GetArgument(args, 0, vfs) && GetArgumentAsPath(args, 1, path)) {
|
||||
return TNativeObject::Create<FS_Watcher>(
|
||||
ls, Tesses::Framework::Filesystem::FSWatcher::Create(vfs, path));
|
||||
}
|
||||
void TStd::RegisterIO(std::shared_ptr<GC> gc,TRootEnvironment* env,std::shared_ptr<Tesses::Framework::Filesystem::RelativeFilesystem> fs)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
void TStd::RegisterIO(std::shared_ptr<GC> gc, TRootEnvironment *env,
|
||||
bool enable) {
|
||||
if (enable) {
|
||||
RegisterIO(
|
||||
gc, env,
|
||||
std::make_shared<Tesses::Framework::Filesystem::RelativeFilesystem>(
|
||||
Tesses::Framework::Filesystem::LocalFS,
|
||||
Tesses::Framework::Filesystem::VFSPath::
|
||||
GetAbsoluteCurrentDirectory()));
|
||||
} else {
|
||||
RegisterIO(gc, env, nullptr);
|
||||
}
|
||||
}
|
||||
void TStd::RegisterIO(
|
||||
std::shared_ptr<GC> gc, TRootEnvironment *env,
|
||||
std::shared_ptr<Tesses::Framework::Filesystem::RelativeFilesystem> fs) {
|
||||
|
||||
env->permissions.canRegisterIO=true;
|
||||
env->permissions.localfs = fs;
|
||||
GCList ls(gc);
|
||||
|
||||
gc->BarrierBegin();
|
||||
auto newDict = env->EnsureDictionary(gc, "New");
|
||||
newDict->DeclareFunction(gc,"FSWatcher","Watch a file/directory",{"vfs","path"}, New_FSWatcher);
|
||||
auto dict = env->EnsureDictionary(gc,"FS");
|
||||
dict->SetValue("SEEK_SET",(int64_t)Tesses::Framework::Streams::SeekOrigin::Begin);
|
||||
dict->SetValue("SEEK_CUR",(int64_t)Tesses::Framework::Streams::SeekOrigin::Current);
|
||||
dict->SetValue("SEEK_END",(int64_t)Tesses::Framework::Streams::SeekOrigin::End);
|
||||
dict->SetValue("FSWatcherEvents",TDictionary::Create(ls,
|
||||
{
|
||||
TDItem("None", (int64_t)Tesses::Framework::Filesystem::FSWatcherEventType::None),
|
||||
TDItem("Accessed", (int64_t)Tesses::Framework::Filesystem::FSWatcherEventType::Accessed),
|
||||
TDItem("AttributeChanged", (int64_t)Tesses::Framework::Filesystem::FSWatcherEventType::AttributeChanged),
|
||||
TDItem("Writen", (int64_t)Tesses::Framework::Filesystem::FSWatcherEventType::Writen),
|
||||
TDItem("Read", (int64_t)Tesses::Framework::Filesystem::FSWatcherEventType::Read),
|
||||
TDItem("Created", (int64_t)Tesses::Framework::Filesystem::FSWatcherEventType::Created),
|
||||
TDItem("Deleted", (int64_t)Tesses::Framework::Filesystem::FSWatcherEventType::Deleted),
|
||||
TDItem("WatchEntryDeleted", (int64_t)Tesses::Framework::Filesystem::FSWatcherEventType::WatchEntryDeleted),
|
||||
TDItem("Modified", (int64_t)Tesses::Framework::Filesystem::FSWatcherEventType::Modified),
|
||||
TDItem("WatchEntryMoved", (int64_t)Tesses::Framework::Filesystem::FSWatcherEventType::WatchEntryMoved),
|
||||
TDItem("MoveOld", (int64_t)Tesses::Framework::Filesystem::FSWatcherEventType::MoveOld),
|
||||
TDItem("MoveNew", (int64_t)Tesses::Framework::Filesystem::FSWatcherEventType::MoveNew),
|
||||
TDItem("Opened", (int64_t)Tesses::Framework::Filesystem::FSWatcherEventType::Opened),
|
||||
TDItem("Closed", (int64_t)Tesses::Framework::Filesystem::FSWatcherEventType::Closed),
|
||||
TDItem("Moved", (int64_t)Tesses::Framework::Filesystem::FSWatcherEventType::Moved),
|
||||
TDItem("All", (int64_t)Tesses::Framework::Filesystem::FSWatcherEventType::All)
|
||||
}
|
||||
));
|
||||
env->permissions.canRegisterIO = true;
|
||||
env->permissions.localfs = fs;
|
||||
GCList ls(gc);
|
||||
|
||||
if(fs)
|
||||
{
|
||||
|
||||
|
||||
dict->SetValue("Local", fs);
|
||||
dict->DeclareFunction(gc, "MakeFull", "Make absolute path from relative path",{"path"},[fs](GCList& ls, std::vector<TObject> args)->TObject{
|
||||
gc->BarrierBegin();
|
||||
auto newDict = env->EnsureDictionary(gc, "New");
|
||||
newDict->DeclareFunction(gc, "FSWatcher", "Watch a file/directory",
|
||||
{"vfs", "path"}, New_FSWatcher);
|
||||
auto dict = env->EnsureDictionary(gc, "FS");
|
||||
dict->SetValue("SEEK_SET",
|
||||
(int64_t)Tesses::Framework::Streams::SeekOrigin::Begin);
|
||||
dict->SetValue("SEEK_CUR",
|
||||
(int64_t)Tesses::Framework::Streams::SeekOrigin::Current);
|
||||
dict->SetValue("SEEK_END",
|
||||
(int64_t)Tesses::Framework::Streams::SeekOrigin::End);
|
||||
dict->SetValue(
|
||||
"FSWatcherEvents",
|
||||
TDictionary::Create(
|
||||
ls,
|
||||
{TDItem(
|
||||
"None",
|
||||
(int64_t)
|
||||
Tesses::Framework::Filesystem::FSWatcherEventType::None),
|
||||
TDItem("Accessed", (int64_t)Tesses::Framework::Filesystem::
|
||||
FSWatcherEventType::Accessed),
|
||||
TDItem("AttributeChanged",
|
||||
(int64_t)Tesses::Framework::Filesystem::FSWatcherEventType::
|
||||
AttributeChanged),
|
||||
TDItem(
|
||||
"Writen",
|
||||
(int64_t)
|
||||
Tesses::Framework::Filesystem::FSWatcherEventType::Writen),
|
||||
TDItem(
|
||||
"Read",
|
||||
(int64_t)
|
||||
Tesses::Framework::Filesystem::FSWatcherEventType::Read),
|
||||
TDItem("Created", (int64_t)Tesses::Framework::Filesystem::
|
||||
FSWatcherEventType::Created),
|
||||
TDItem("Deleted", (int64_t)Tesses::Framework::Filesystem::
|
||||
FSWatcherEventType::Deleted),
|
||||
TDItem("WatchEntryDeleted",
|
||||
(int64_t)Tesses::Framework::Filesystem::FSWatcherEventType::
|
||||
WatchEntryDeleted),
|
||||
TDItem("Modified", (int64_t)Tesses::Framework::Filesystem::
|
||||
FSWatcherEventType::Modified),
|
||||
TDItem("WatchEntryMoved", (int64_t)Tesses::Framework::Filesystem::
|
||||
FSWatcherEventType::WatchEntryMoved),
|
||||
TDItem("MoveOld", (int64_t)Tesses::Framework::Filesystem::
|
||||
FSWatcherEventType::MoveOld),
|
||||
TDItem("MoveNew", (int64_t)Tesses::Framework::Filesystem::
|
||||
FSWatcherEventType::MoveNew),
|
||||
TDItem(
|
||||
"Opened",
|
||||
(int64_t)
|
||||
Tesses::Framework::Filesystem::FSWatcherEventType::Opened),
|
||||
TDItem(
|
||||
"Closed",
|
||||
(int64_t)
|
||||
Tesses::Framework::Filesystem::FSWatcherEventType::Closed),
|
||||
TDItem(
|
||||
"Moved",
|
||||
(int64_t)
|
||||
Tesses::Framework::Filesystem::FSWatcherEventType::Moved),
|
||||
TDItem(
|
||||
"All",
|
||||
(int64_t)
|
||||
Tesses::Framework::Filesystem::FSWatcherEventType::All)}));
|
||||
|
||||
if (fs) {
|
||||
|
||||
dict->SetValue("Local", fs);
|
||||
dict->DeclareFunction(
|
||||
gc, "MakeFull", "Make absolute path from relative path", {"path"},
|
||||
[fs](GCList &ls, std::vector<TObject> args) -> TObject {
|
||||
Tesses::Framework::Filesystem::VFSPath path;
|
||||
if(GetArgumentAsPath(args,0,path))
|
||||
{
|
||||
if(path.relative)
|
||||
{
|
||||
if (GetArgumentAsPath(args, 0, path)) {
|
||||
if (path.relative) {
|
||||
auto myPath = fs->GetWorking() / path;
|
||||
myPath = myPath.CollapseRelativeParents();
|
||||
return myPath;
|
||||
@@ -325,37 +344,47 @@ namespace Tesses::CrossLang
|
||||
}
|
||||
return nullptr;
|
||||
});
|
||||
dict->DeclareFunction(gc,"getCurrentPath","Get current path",{},[fs](GCList& ls, std::vector<TObject> args)->TObject{
|
||||
dict->DeclareFunction(
|
||||
gc, "getCurrentPath", "Get current path", {},
|
||||
[fs](GCList &ls, std::vector<TObject> args) -> TObject {
|
||||
return fs->GetWorking();
|
||||
});
|
||||
dict->DeclareFunction(gc,"setCurrentPath","Set the current path",{"path"}, [fs](GCList& ls, std::vector<TObject> args)->TObject {
|
||||
dict->DeclareFunction(
|
||||
gc, "setCurrentPath", "Set the current path", {"path"},
|
||||
[fs](GCList &ls, std::vector<TObject> args) -> TObject {
|
||||
Tesses::Framework::Filesystem::VFSPath path;
|
||||
if(GetArgumentAsPath(args,0,path))
|
||||
{
|
||||
if(path.relative)
|
||||
{
|
||||
fs->SetWorking(path.MakeAbsolute(fs->GetWorking()));
|
||||
}
|
||||
else {
|
||||
fs->SetWorking(path);
|
||||
}
|
||||
if (GetArgumentAsPath(args, 0, path)) {
|
||||
if (path.relative) {
|
||||
fs->SetWorking(path.MakeAbsolute(fs->GetWorking()));
|
||||
} else {
|
||||
fs->SetWorking(path);
|
||||
}
|
||||
}
|
||||
return path;
|
||||
});
|
||||
}
|
||||
|
||||
dict->DeclareFunction(gc, "ReadAllText","Read all text from file", {"fs","filename"},FS_ReadAllText);
|
||||
dict->DeclareFunction(gc, "WriteAllText","Write all text to file", {"fs","filename","content"},FS_WriteAllText);
|
||||
|
||||
dict->DeclareFunction(gc, "ReadAllLines","Read all lines from file", {"fs","filename"},FS_ReadAllLines);
|
||||
dict->DeclareFunction(gc, "WriteAllLines","Write all lines to file", {"fs","filename","lines"},FS_WriteAllLines);
|
||||
|
||||
dict->DeclareFunction(gc, "ReadAllBytes","Read all bytes from file", {"fs","filename"},FS_ReadAllBytes);
|
||||
dict->DeclareFunction(gc, "WriteAllBytes","Write all bytes to file", {"fs","filename","content"},FS_WriteAllBytes);
|
||||
|
||||
dict->DeclareFunction(gc, "CreateArchive", "Create a crvm archive",{"fs","strm","name","version","info"},FS_CreateArchive);
|
||||
dict->DeclareFunction(gc,"ExtractArchive", "Extract a crvm archive",{"strm","vfs"},FS_ExtractArchive);
|
||||
|
||||
gc->BarrierEnd();
|
||||
}
|
||||
}
|
||||
|
||||
dict->DeclareFunction(gc, "ReadAllText", "Read all text from file",
|
||||
{"fs", "filename"}, FS_ReadAllText);
|
||||
dict->DeclareFunction(gc, "WriteAllText", "Write all text to file",
|
||||
{"fs", "filename", "content"}, FS_WriteAllText);
|
||||
|
||||
dict->DeclareFunction(gc, "ReadAllLines", "Read all lines from file",
|
||||
{"fs", "filename"}, FS_ReadAllLines);
|
||||
dict->DeclareFunction(gc, "WriteAllLines", "Write all lines to file",
|
||||
{"fs", "filename", "lines"}, FS_WriteAllLines);
|
||||
|
||||
dict->DeclareFunction(gc, "ReadAllBytes", "Read all bytes from file",
|
||||
{"fs", "filename"}, FS_ReadAllBytes);
|
||||
dict->DeclareFunction(gc, "WriteAllBytes", "Write all bytes to file",
|
||||
{"fs", "filename", "content"}, FS_WriteAllBytes);
|
||||
|
||||
dict->DeclareFunction(gc, "CreateArchive", "Create a crvm archive",
|
||||
{"fs", "strm", "name", "version", "info"},
|
||||
FS_CreateArchive);
|
||||
dict->DeclareFunction(gc, "ExtractArchive", "Extract a crvm archive",
|
||||
{"strm", "vfs"}, FS_ExtractArchive);
|
||||
|
||||
gc->BarrierEnd();
|
||||
}
|
||||
} // namespace Tesses::CrossLang
|
||||
@@ -2,206 +2,193 @@
|
||||
#include "CrossLang.hpp"
|
||||
using namespace Tesses::Framework::Serialization::Json;
|
||||
|
||||
namespace Tesses::CrossLang
|
||||
{
|
||||
namespace Tesses::CrossLang {
|
||||
|
||||
static bool IsValidForJson(TObject v)
|
||||
{
|
||||
if(std::holds_alternative<std::nullptr_t>(v)) return true;
|
||||
static bool IsValidForJson(TObject v) {
|
||||
if (std::holds_alternative<std::nullptr_t>(v))
|
||||
return true;
|
||||
|
||||
if(std::holds_alternative<int64_t>(v)) return true;
|
||||
if (std::holds_alternative<int64_t>(v))
|
||||
return true;
|
||||
|
||||
if(std::holds_alternative<double>(v)) return true;
|
||||
if (std::holds_alternative<double>(v))
|
||||
return true;
|
||||
|
||||
if (std::holds_alternative<bool>(v))
|
||||
return true;
|
||||
|
||||
if(std::holds_alternative<bool>(v)) return true;
|
||||
if (std::holds_alternative<std::string>(v))
|
||||
return true;
|
||||
|
||||
|
||||
if(std::holds_alternative<std::string>(v)) return true;
|
||||
|
||||
|
||||
if(std::holds_alternative<THeapObjectHolder>(v))
|
||||
{
|
||||
auto res = std::get<THeapObjectHolder>(v);
|
||||
auto ls = dynamic_cast<TList*>(res.obj);
|
||||
auto dict = dynamic_cast<TDictionary*>(res.obj);
|
||||
if(ls != nullptr) return true;
|
||||
if(dict != nullptr) return true;
|
||||
}
|
||||
return false;
|
||||
if (std::holds_alternative<THeapObjectHolder>(v)) {
|
||||
auto res = std::get<THeapObjectHolder>(v);
|
||||
auto ls = dynamic_cast<TList *>(res.obj);
|
||||
auto dict = dynamic_cast<TDictionary *>(res.obj);
|
||||
if (ls != nullptr)
|
||||
return true;
|
||||
if (dict != nullptr)
|
||||
return true;
|
||||
}
|
||||
static JToken JsonSerialize(TObject v)
|
||||
{
|
||||
if(std::holds_alternative<std::nullptr_t>(v)) return nullptr;
|
||||
if(std::holds_alternative<int64_t>(v)) return std::get<int64_t>(v);
|
||||
if(std::holds_alternative<double>(v)) return std::get<double>(v);
|
||||
if(std::holds_alternative<bool>(v)) return std::get<bool>(v);
|
||||
if(std::holds_alternative<std::string>(v)) return std::get<std::string>(v);
|
||||
if(std::holds_alternative<THeapObjectHolder>(v))
|
||||
{
|
||||
auto obj = std::get<THeapObjectHolder>(v).obj;
|
||||
auto ls = dynamic_cast<TList*>(obj);
|
||||
auto dict = dynamic_cast<TDictionary*>(obj);
|
||||
|
||||
if(ls != nullptr)
|
||||
{
|
||||
JArray items;
|
||||
for(int64_t i = 0; i < ls->Count(); i++)
|
||||
{
|
||||
auto val = ls->Get(i);
|
||||
if(IsValidForJson(val))
|
||||
items.Add(JsonSerialize(val));
|
||||
}
|
||||
return items;
|
||||
}
|
||||
|
||||
if(dict != nullptr)
|
||||
{
|
||||
JObject obj;
|
||||
for(auto item : dict->items)
|
||||
{
|
||||
if(IsValidForJson(item.second))
|
||||
obj.SetValue(item.first,JsonSerialize(item.second));
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
static JToken JsonSerialize(TObject v) {
|
||||
if (std::holds_alternative<std::nullptr_t>(v))
|
||||
return nullptr;
|
||||
}
|
||||
static TObject JsonEncode(GCList& ls2, std::vector<TObject> args)
|
||||
{
|
||||
if(args.size() >= 1)
|
||||
{
|
||||
bool indent = (args.size() == 2 && std::holds_alternative<bool>(args[1]) && std::get<bool>(args[1]));
|
||||
|
||||
auto json = JsonSerialize(args[0]);
|
||||
if (std::holds_alternative<int64_t>(v))
|
||||
return std::get<int64_t>(v);
|
||||
if (std::holds_alternative<double>(v))
|
||||
return std::get<double>(v);
|
||||
if (std::holds_alternative<bool>(v))
|
||||
return std::get<bool>(v);
|
||||
if (std::holds_alternative<std::string>(v))
|
||||
return std::get<std::string>(v);
|
||||
if (std::holds_alternative<THeapObjectHolder>(v)) {
|
||||
auto obj = std::get<THeapObjectHolder>(v).obj;
|
||||
auto ls = dynamic_cast<TList *>(obj);
|
||||
auto dict = dynamic_cast<TDictionary *>(obj);
|
||||
|
||||
return Json::Encode(json,indent);
|
||||
}
|
||||
return "null";
|
||||
}
|
||||
static TObject JsonDocEncode(GCList& ls2, std::vector<TObject> args)
|
||||
{
|
||||
if(args.size() >= 1)
|
||||
{
|
||||
bool indent = (args.size() == 2 && std::holds_alternative<bool>(args[1]) && std::get<bool>(args[1]));
|
||||
|
||||
auto json = JsonSerialize(args[0]);
|
||||
JArray ar;
|
||||
if(TryGetJToken(json,ar))
|
||||
return Json::DocEncode(ar,indent);
|
||||
|
||||
|
||||
}
|
||||
return "";
|
||||
}
|
||||
static TObject JsonDeserialize(GCList& ls2,JToken json)
|
||||
{
|
||||
if(std::holds_alternative<JUndefined>(json)) return nullptr;
|
||||
if(std::holds_alternative<std::nullptr_t>(json)) return nullptr;
|
||||
bool b;
|
||||
int64_t _i64;
|
||||
double _f64;
|
||||
std::string str;
|
||||
JArray arr;
|
||||
JObject obj;
|
||||
if(TryGetJToken(json,b)) return b;
|
||||
if(TryGetJToken(json,_i64)) return _i64;
|
||||
if(TryGetJToken(json,_f64)) return _f64;
|
||||
if(TryGetJToken(json,str)) return str;
|
||||
if(TryGetJToken(json,arr))
|
||||
{
|
||||
TList* ls = TList::Create(ls2);
|
||||
|
||||
for(auto& item : arr)
|
||||
{
|
||||
auto itemRes = JsonDeserialize(ls2,item);
|
||||
ls2.GetGC()->BarrierBegin();
|
||||
ls->Add(itemRes);
|
||||
ls2.GetGC()->BarrierEnd();
|
||||
if (ls != nullptr) {
|
||||
JArray items;
|
||||
for (int64_t i = 0; i < ls->Count(); i++) {
|
||||
auto val = ls->Get(i);
|
||||
if (IsValidForJson(val))
|
||||
items.Add(JsonSerialize(val));
|
||||
}
|
||||
return ls;
|
||||
return items;
|
||||
}
|
||||
if(TryGetJToken(json,obj))
|
||||
{
|
||||
|
||||
TDictionary* dict = TDictionary::Create(ls2);
|
||||
|
||||
|
||||
for(auto& item : obj)
|
||||
{
|
||||
|
||||
auto itemRes = JsonDeserialize(ls2,item.second);
|
||||
ls2.GetGC()->BarrierBegin();
|
||||
dict->SetValue(item.first,itemRes);
|
||||
ls2.GetGC()->BarrierEnd();
|
||||
if (dict != nullptr) {
|
||||
JObject obj;
|
||||
for (auto item : dict->items) {
|
||||
if (IsValidForJson(item.second))
|
||||
obj.SetValue(item.first, JsonSerialize(item.second));
|
||||
}
|
||||
return dict;
|
||||
return obj;
|
||||
}
|
||||
return Undefined();
|
||||
}
|
||||
static TObject JsonDecode(GCList& ls2,std::vector<TObject> args)
|
||||
{
|
||||
if(args.size() > 0 && std::holds_alternative<std::string>(args[0]))
|
||||
{
|
||||
|
||||
|
||||
return JsonDeserialize(ls2, Json::Decode(std::get<std::string>(args[0])));
|
||||
|
||||
|
||||
}
|
||||
return Undefined();
|
||||
}
|
||||
static TObject JsonDocDecode(GCList& ls2,std::vector<TObject> args)
|
||||
{
|
||||
if(args.size() > 0 && std::holds_alternative<std::string>(args[0]))
|
||||
{
|
||||
|
||||
|
||||
return JsonDeserialize(ls2, Json::DocDecode(std::get<std::string>(args[0])));
|
||||
|
||||
|
||||
}
|
||||
|
||||
return Undefined();
|
||||
}
|
||||
std::string Json_Encode(TObject o,bool indent)
|
||||
{
|
||||
return Json::Encode(JsonSerialize(o),indent);
|
||||
}
|
||||
TObject Json_Decode(GCList ls,std::string str)
|
||||
{
|
||||
return JsonDeserialize(ls,Json::Decode(str));
|
||||
}
|
||||
std::string Json_DocEncode(TObject o,bool indent)
|
||||
{
|
||||
auto obj = JsonSerialize(o);
|
||||
JArray ls;
|
||||
if(TryGetJToken(obj,ls))
|
||||
return Json::DocEncode(ls,indent);
|
||||
return "";
|
||||
}
|
||||
TObject Json_DocDecode(GCList ls,std::string str)
|
||||
{
|
||||
return JsonDeserialize(ls,Json::DocDecode(str));
|
||||
}
|
||||
void TStd::RegisterJson(std::shared_ptr<GC> gc,TRootEnvironment* env)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
static TObject JsonEncode(GCList &ls2, std::vector<TObject> args) {
|
||||
if (args.size() >= 1) {
|
||||
bool indent =
|
||||
(args.size() == 2 && std::holds_alternative<bool>(args[1]) &&
|
||||
std::get<bool>(args[1]));
|
||||
|
||||
env->permissions.canRegisterJSON=true;
|
||||
GCList ls(gc);
|
||||
TDictionary* dict = TDictionary::Create(ls);
|
||||
dict->DeclareFunction(gc, "Decode","Deserialize Json",{"jsonString"},JsonDecode);
|
||||
dict->DeclareFunction(gc, "Encode","Serialize Json",{"any","$indent"},JsonEncode);
|
||||
dict->DeclareFunction(gc, "DocDecode", "Deserialize JsonDoc", {"jsonDocString"},JsonDocDecode);
|
||||
dict->DeclareFunction(gc, "DocEncode", "Serialize JsonDoc", {"ls","$indent"},JsonDocEncode);
|
||||
|
||||
|
||||
|
||||
gc->BarrierBegin();
|
||||
env->DeclareVariable("Json", dict);
|
||||
gc->BarrierEnd();
|
||||
auto json = JsonSerialize(args[0]);
|
||||
|
||||
return Json::Encode(json, indent);
|
||||
}
|
||||
|
||||
}
|
||||
return "null";
|
||||
}
|
||||
static TObject JsonDocEncode(GCList &ls2, std::vector<TObject> args) {
|
||||
if (args.size() >= 1) {
|
||||
bool indent =
|
||||
(args.size() == 2 && std::holds_alternative<bool>(args[1]) &&
|
||||
std::get<bool>(args[1]));
|
||||
|
||||
auto json = JsonSerialize(args[0]);
|
||||
JArray ar;
|
||||
if (TryGetJToken(json, ar))
|
||||
return Json::DocEncode(ar, indent);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
static TObject JsonDeserialize(GCList &ls2, JToken json) {
|
||||
if (std::holds_alternative<JUndefined>(json))
|
||||
return nullptr;
|
||||
if (std::holds_alternative<std::nullptr_t>(json))
|
||||
return nullptr;
|
||||
bool b;
|
||||
int64_t _i64;
|
||||
double _f64;
|
||||
std::string str;
|
||||
JArray arr;
|
||||
JObject obj;
|
||||
if (TryGetJToken(json, b))
|
||||
return b;
|
||||
if (TryGetJToken(json, _i64))
|
||||
return _i64;
|
||||
if (TryGetJToken(json, _f64))
|
||||
return _f64;
|
||||
if (TryGetJToken(json, str))
|
||||
return str;
|
||||
if (TryGetJToken(json, arr)) {
|
||||
TList *ls = TList::Create(ls2);
|
||||
|
||||
for (auto &item : arr) {
|
||||
auto itemRes = JsonDeserialize(ls2, item);
|
||||
ls2.GetGC()->BarrierBegin();
|
||||
ls->Add(itemRes);
|
||||
ls2.GetGC()->BarrierEnd();
|
||||
}
|
||||
return ls;
|
||||
}
|
||||
if (TryGetJToken(json, obj)) {
|
||||
|
||||
TDictionary *dict = TDictionary::Create(ls2);
|
||||
|
||||
for (auto &item : obj) {
|
||||
|
||||
auto itemRes = JsonDeserialize(ls2, item.second);
|
||||
ls2.GetGC()->BarrierBegin();
|
||||
dict->SetValue(item.first, itemRes);
|
||||
ls2.GetGC()->BarrierEnd();
|
||||
}
|
||||
return dict;
|
||||
}
|
||||
return Undefined();
|
||||
}
|
||||
static TObject JsonDecode(GCList &ls2, std::vector<TObject> args) {
|
||||
if (args.size() > 0 && std::holds_alternative<std::string>(args[0])) {
|
||||
|
||||
return JsonDeserialize(ls2,
|
||||
Json::Decode(std::get<std::string>(args[0])));
|
||||
}
|
||||
return Undefined();
|
||||
}
|
||||
static TObject JsonDocDecode(GCList &ls2, std::vector<TObject> args) {
|
||||
if (args.size() > 0 && std::holds_alternative<std::string>(args[0])) {
|
||||
|
||||
return JsonDeserialize(ls2,
|
||||
Json::DocDecode(std::get<std::string>(args[0])));
|
||||
}
|
||||
|
||||
return Undefined();
|
||||
}
|
||||
std::string Json_Encode(TObject o, bool indent) {
|
||||
return Json::Encode(JsonSerialize(o), indent);
|
||||
}
|
||||
TObject Json_Decode(GCList ls, std::string str) {
|
||||
return JsonDeserialize(ls, Json::Decode(str));
|
||||
}
|
||||
std::string Json_DocEncode(TObject o, bool indent) {
|
||||
auto obj = JsonSerialize(o);
|
||||
JArray ls;
|
||||
if (TryGetJToken(obj, ls))
|
||||
return Json::DocEncode(ls, indent);
|
||||
return "";
|
||||
}
|
||||
TObject Json_DocDecode(GCList ls, std::string str) {
|
||||
return JsonDeserialize(ls, Json::DocDecode(str));
|
||||
}
|
||||
void TStd::RegisterJson(std::shared_ptr<GC> gc, TRootEnvironment *env) {
|
||||
|
||||
env->permissions.canRegisterJSON = true;
|
||||
GCList ls(gc);
|
||||
TDictionary *dict = TDictionary::Create(ls);
|
||||
dict->DeclareFunction(gc, "Decode", "Deserialize Json", {"jsonString"},
|
||||
JsonDecode);
|
||||
dict->DeclareFunction(gc, "Encode", "Serialize Json", {"any", "$indent"},
|
||||
JsonEncode);
|
||||
dict->DeclareFunction(gc, "DocDecode", "Deserialize JsonDoc",
|
||||
{"jsonDocString"}, JsonDocDecode);
|
||||
dict->DeclareFunction(gc, "DocEncode", "Serialize JsonDoc",
|
||||
{"ls", "$indent"}, JsonDocEncode);
|
||||
|
||||
gc->BarrierBegin();
|
||||
env->DeclareVariable("Json", dict);
|
||||
gc->BarrierEnd();
|
||||
}
|
||||
|
||||
} // namespace Tesses::CrossLang
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,84 +1,75 @@
|
||||
#include "CrossLang.hpp"
|
||||
|
||||
#if defined(GEKKO)
|
||||
#include <ogcsys.h>
|
||||
#include <gccore.h>
|
||||
#include <ogc/pad.h>
|
||||
#include <ogcsys.h>
|
||||
#if defined(HW_RVL)
|
||||
#include <wiiuse/wpad.h>
|
||||
#endif
|
||||
#endif
|
||||
namespace Tesses::CrossLang
|
||||
{
|
||||
#if defined(GEKKO)
|
||||
#if defined(HW_RVL)
|
||||
static TObject OGC_WPAD_ScanPads(GCList& ls, std::vector<TObject> args)
|
||||
{
|
||||
return (int64_t)WPAD_ScanPads();
|
||||
}
|
||||
static TObject OGC_WPAD_ButtonsUp(GCList& ls, std::vector<TObject> args)
|
||||
{
|
||||
int64_t chan;
|
||||
if(GetArgument(args,0,chan))
|
||||
namespace Tesses::CrossLang {
|
||||
#if defined(GEKKO)
|
||||
#if defined(HW_RVL)
|
||||
static TObject OGC_WPAD_ScanPads(GCList &ls, std::vector<TObject> args) {
|
||||
return (int64_t)WPAD_ScanPads();
|
||||
}
|
||||
static TObject OGC_WPAD_ButtonsUp(GCList &ls, std::vector<TObject> args) {
|
||||
int64_t chan;
|
||||
if (GetArgument(args, 0, chan))
|
||||
return (int64_t)WPAD_ButtonsUp((int)chan);
|
||||
return 0;
|
||||
}
|
||||
static TObject OGC_WPAD_ButtonsDown(GCList& ls, std::vector<TObject> args)
|
||||
{
|
||||
int64_t chan;
|
||||
if(GetArgument(args,0,chan))
|
||||
return 0;
|
||||
}
|
||||
static TObject OGC_WPAD_ButtonsDown(GCList &ls, std::vector<TObject> args) {
|
||||
int64_t chan;
|
||||
if (GetArgument(args, 0, chan))
|
||||
return (int64_t)WPAD_ButtonsDown((int)chan);
|
||||
return 0;
|
||||
}
|
||||
static TObject OGC_WPAD_ButtonsHeld(GCList& ls, std::vector<TObject> args)
|
||||
{
|
||||
int64_t chan;
|
||||
if(GetArgument(args,0,chan))
|
||||
return 0;
|
||||
}
|
||||
static TObject OGC_WPAD_ButtonsHeld(GCList &ls, std::vector<TObject> args) {
|
||||
int64_t chan;
|
||||
if (GetArgument(args, 0, chan))
|
||||
return (int64_t)WPAD_ButtonsDown((int)chan);
|
||||
return 0;
|
||||
}
|
||||
static TObject OGC_WPAD_BatteryLevel(GCList& ls, std::vector<TObject> args)
|
||||
{
|
||||
int64_t chan;
|
||||
if(GetArgument(args,0,chan))
|
||||
return 0;
|
||||
}
|
||||
static TObject OGC_WPAD_BatteryLevel(GCList &ls, std::vector<TObject> args) {
|
||||
int64_t chan;
|
||||
if (GetArgument(args, 0, chan))
|
||||
return (int64_t)WPAD_BatteryLevel((int)chan);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
void TStd::RegisterOGC(std::shared_ptr<GC> gc, TRootEnvironment* env)
|
||||
{
|
||||
GCList ls(gc);
|
||||
#if defined(GEKKO)
|
||||
|
||||
|
||||
gc->BarrierBegin();
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
void TStd::RegisterOGC(std::shared_ptr<GC> gc, TRootEnvironment *env) {
|
||||
GCList ls(gc);
|
||||
#if defined(GEKKO)
|
||||
|
||||
TDictionary* dict_ogc_pad = TDictionary::Create(ls);
|
||||
#if defined(HW_RVL)
|
||||
TDictionary* dict_rvl_wpad = TDictionary::Create(ls);
|
||||
dict_rvl_wpad->DeclareFunction(gc, "ScanPads","Scan wiimotes",{},OGC_WPAD_ScanPads);
|
||||
dict_rvl_wpad->DeclareFunction(gc, "ButtonsDown","Is button down",{"pad"},OGC_WPAD_ButtonsDown);
|
||||
dict_rvl_wpad->SetValue("BUTTON_A",(int64_t)WPAD_BUTTON_A);
|
||||
dict_rvl_wpad->SetValue("BUTTON_B",(int64_t)WPAD_BUTTON_B);
|
||||
dict_rvl_wpad->SetValue("BUTTON_HOME",(int64_t)WPAD_BUTTON_HOME);
|
||||
dict_rvl_wpad->SetValue("BUTTON_UP",(int64_t)WPAD_BUTTON_UP);
|
||||
dict_rvl_wpad->SetValue("BUTTON_DOWN",(int64_t)WPAD_BUTTON_DOWN);
|
||||
dict_rvl_wpad->SetValue("BUTTON_LEFT",(int64_t)WPAD_BUTTON_LEFT);
|
||||
dict_rvl_wpad->SetValue("BUTTON_RIGHT",(int64_t)WPAD_BUTTON_RIGHT);
|
||||
dict_rvl_wpad->SetValue("BUTTON_1",(int64_t)WPAD_BUTTON_1);
|
||||
dict_rvl_wpad->SetValue("BUTTON_2",(int64_t)WPAD_BUTTON_2);
|
||||
dict_rvl_wpad->SetValue("BUTTON_PLUS",(int64_t)WPAD_BUTTON_PLUS);
|
||||
dict_rvl_wpad->SetValue("BUTTON_MINUS",(int64_t)WPAD_BUTTON_MINUS);
|
||||
env->DeclareVariable("WPAD", dict_rvl_wpad);
|
||||
|
||||
#endif
|
||||
env->DeclareVariable("PAD", dict_ogc_pad);
|
||||
gc->BarrierEnd();
|
||||
#endif
|
||||
env->permissions.canRegisterOGC=true;
|
||||
|
||||
gc->BarrierBegin();
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
TDictionary *dict_ogc_pad = TDictionary::Create(ls);
|
||||
#if defined(HW_RVL)
|
||||
TDictionary *dict_rvl_wpad = TDictionary::Create(ls);
|
||||
dict_rvl_wpad->DeclareFunction(gc, "ScanPads", "Scan wiimotes", {},
|
||||
OGC_WPAD_ScanPads);
|
||||
dict_rvl_wpad->DeclareFunction(gc, "ButtonsDown", "Is button down", {"pad"},
|
||||
OGC_WPAD_ButtonsDown);
|
||||
dict_rvl_wpad->SetValue("BUTTON_A", (int64_t)WPAD_BUTTON_A);
|
||||
dict_rvl_wpad->SetValue("BUTTON_B", (int64_t)WPAD_BUTTON_B);
|
||||
dict_rvl_wpad->SetValue("BUTTON_HOME", (int64_t)WPAD_BUTTON_HOME);
|
||||
dict_rvl_wpad->SetValue("BUTTON_UP", (int64_t)WPAD_BUTTON_UP);
|
||||
dict_rvl_wpad->SetValue("BUTTON_DOWN", (int64_t)WPAD_BUTTON_DOWN);
|
||||
dict_rvl_wpad->SetValue("BUTTON_LEFT", (int64_t)WPAD_BUTTON_LEFT);
|
||||
dict_rvl_wpad->SetValue("BUTTON_RIGHT", (int64_t)WPAD_BUTTON_RIGHT);
|
||||
dict_rvl_wpad->SetValue("BUTTON_1", (int64_t)WPAD_BUTTON_1);
|
||||
dict_rvl_wpad->SetValue("BUTTON_2", (int64_t)WPAD_BUTTON_2);
|
||||
dict_rvl_wpad->SetValue("BUTTON_PLUS", (int64_t)WPAD_BUTTON_PLUS);
|
||||
dict_rvl_wpad->SetValue("BUTTON_MINUS", (int64_t)WPAD_BUTTON_MINUS);
|
||||
env->DeclareVariable("WPAD", dict_rvl_wpad);
|
||||
|
||||
#endif
|
||||
env->DeclareVariable("PAD", dict_ogc_pad);
|
||||
gc->BarrierEnd();
|
||||
#endif
|
||||
env->permissions.canRegisterOGC = true;
|
||||
}
|
||||
} // namespace Tesses::CrossLang
|
||||
@@ -1,83 +1,76 @@
|
||||
#include "CrossLang.hpp"
|
||||
|
||||
|
||||
|
||||
namespace Tesses::CrossLang
|
||||
{
|
||||
bool GetObjectAsPath(TObject& obj, Tesses::Framework::Filesystem::VFSPath& path, bool allowString)
|
||||
{
|
||||
if(GetObject(obj,path)) return true;
|
||||
std::string str;
|
||||
if(allowString && GetObject<std::string>(obj,str))
|
||||
{
|
||||
path = Tesses::Framework::Filesystem::VFSPath(str);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
namespace Tesses::CrossLang {
|
||||
bool GetObjectAsPath(TObject &obj, Tesses::Framework::Filesystem::VFSPath &path,
|
||||
bool allowString) {
|
||||
if (GetObject(obj, path))
|
||||
return true;
|
||||
std::string str;
|
||||
if (allowString && GetObject<std::string>(obj, str)) {
|
||||
path = Tesses::Framework::Filesystem::VFSPath(str);
|
||||
return true;
|
||||
}
|
||||
bool GetArgumentAsPath(std::vector<TObject>& args, size_t index, Tesses::Framework::Filesystem::VFSPath& path,bool allowString)
|
||||
{
|
||||
if(GetArgument(args,index,path)) return true;
|
||||
std::string str;
|
||||
if(allowString && GetArgument<std::string>(args,index,str))
|
||||
{
|
||||
path = Tesses::Framework::Filesystem::VFSPath(str);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
return false;
|
||||
}
|
||||
bool GetArgumentAsPath(std::vector<TObject> &args, size_t index,
|
||||
Tesses::Framework::Filesystem::VFSPath &path,
|
||||
bool allowString) {
|
||||
if (GetArgument(args, index, path))
|
||||
return true;
|
||||
std::string str;
|
||||
if (allowString && GetArgument<std::string>(args, index, str)) {
|
||||
path = Tesses::Framework::Filesystem::VFSPath(str);
|
||||
return true;
|
||||
}
|
||||
|
||||
static TObject Path_Root(GCList& ls, std::vector<TObject> args)
|
||||
{
|
||||
auto res = Tesses::Framework::Filesystem::VFSPath();\
|
||||
res.relative=false;
|
||||
return false;
|
||||
}
|
||||
|
||||
static TObject Path_Root(GCList &ls, std::vector<TObject> args) {
|
||||
auto res = Tesses::Framework::Filesystem::VFSPath();
|
||||
res.relative = false;
|
||||
return res;
|
||||
}
|
||||
static TObject Path_FromString(GCList &ls, std::vector<TObject> args) {
|
||||
std::string str;
|
||||
if (GetArgument(args, 0, str)) {
|
||||
return Tesses::Framework::Filesystem::VFSPath(str);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
static TObject Path_Create(GCList &ls, std::vector<TObject> args) {
|
||||
TList *myls;
|
||||
bool relative;
|
||||
if (GetArgument(args, 0, relative) && GetArgumentHeap(args, 1, myls)) {
|
||||
std::vector<std::string> items;
|
||||
for (int64_t i = 0; i < myls->Count(); i++) {
|
||||
std::string str;
|
||||
TObject o = myls->Get(i);
|
||||
if (GetObject<std::string>(o, str)) {
|
||||
items.push_back(str);
|
||||
}
|
||||
}
|
||||
auto res = Tesses::Framework::Filesystem::VFSPath(items);
|
||||
res.relative = relative;
|
||||
return res;
|
||||
}
|
||||
static TObject Path_FromString(GCList& ls, std::vector<TObject> args)
|
||||
{
|
||||
std::string str;
|
||||
if(GetArgument(args,0,str))
|
||||
{
|
||||
return Tesses::Framework::Filesystem::VFSPath(str);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
static TObject Path_Create(GCList& ls, std::vector<TObject> args)
|
||||
{
|
||||
TList* myls;
|
||||
bool relative;
|
||||
if(GetArgument(args,0,relative) && GetArgumentHeap(args,1,myls))
|
||||
{
|
||||
std::vector<std::string> items;
|
||||
for(int64_t i = 0; i < myls->Count(); i++)
|
||||
{
|
||||
std::string str;
|
||||
TObject o =myls->Get(i);
|
||||
if(GetObject<std::string>(o,str))
|
||||
{
|
||||
items.push_back(str);
|
||||
}
|
||||
}
|
||||
auto res = Tesses::Framework::Filesystem::VFSPath(items);
|
||||
res.relative = relative;
|
||||
return res;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
void TStd::RegisterPath(std::shared_ptr<GC> gc,TRootEnvironment* env)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
void TStd::RegisterPath(std::shared_ptr<GC> gc, TRootEnvironment *env) {
|
||||
|
||||
env->permissions.canRegisterPath=true;
|
||||
GCList ls(gc);
|
||||
TDictionary* dict = TDictionary::Create(ls);
|
||||
|
||||
gc->BarrierBegin();
|
||||
dict->DeclareFunction(gc,"FromString","Create a Path from string",{"path"},Path_FromString);
|
||||
|
||||
dict->DeclareFunction(gc,"Create","Create a Path from parts",{"relative","parts"},Path_Create);
|
||||
dict->DeclareFunction(gc,"Root","Create Absolute Root Path",{}, Path_Root);
|
||||
env->DeclareVariable("Path", dict);
|
||||
gc->BarrierEnd();
|
||||
}
|
||||
}
|
||||
env->permissions.canRegisterPath = true;
|
||||
GCList ls(gc);
|
||||
TDictionary *dict = TDictionary::Create(ls);
|
||||
|
||||
gc->BarrierBegin();
|
||||
dict->DeclareFunction(gc, "FromString", "Create a Path from string",
|
||||
{"path"}, Path_FromString);
|
||||
|
||||
dict->DeclareFunction(gc, "Create", "Create a Path from parts",
|
||||
{"relative", "parts"}, Path_Create);
|
||||
dict->DeclareFunction(gc, "Root", "Create Absolute Root Path", {},
|
||||
Path_Root);
|
||||
env->DeclareVariable("Path", dict);
|
||||
gc->BarrierEnd();
|
||||
}
|
||||
} // namespace Tesses::CrossLang
|
||||
@@ -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
|
||||
|
||||
@@ -3,228 +3,192 @@
|
||||
|
||||
#include <iostream>
|
||||
namespace Tesses::CrossLang {
|
||||
#if defined(TESSESFRAMEWORK_ENABLE_SQLITE)
|
||||
using namespace Tesses::Framework::Serialization;
|
||||
TObject Sqlite_Escape(GCList& ls, std::vector<TObject> args)
|
||||
{
|
||||
int64_t n;
|
||||
double d;
|
||||
bool b;
|
||||
#if defined(TESSESFRAMEWORK_ENABLE_SQLITE)
|
||||
using namespace Tesses::Framework::Serialization;
|
||||
TObject Sqlite_Escape(GCList &ls, std::vector<TObject> args) {
|
||||
int64_t n;
|
||||
double d;
|
||||
bool b;
|
||||
|
||||
|
||||
std::string str;
|
||||
if(GetArgument(args,0,str))
|
||||
{
|
||||
return SQLiteDatabase::Escape(str);
|
||||
}
|
||||
if(GetArgument(args,0,n))
|
||||
{
|
||||
return std::to_string(n);
|
||||
}
|
||||
if(GetArgument(args,0,b))
|
||||
{
|
||||
return b ? "1" : "0";
|
||||
}
|
||||
if(GetArgument(args,0,d))
|
||||
{
|
||||
return std::to_string(d);
|
||||
}
|
||||
|
||||
return "NULL";
|
||||
std::string str;
|
||||
if (GetArgument(args, 0, str)) {
|
||||
return SQLiteDatabase::Escape(str);
|
||||
}
|
||||
|
||||
TObject Sqlite_Prepare(GCList& ls, std::vector<TObject> args)
|
||||
{
|
||||
std::string str;
|
||||
TList* list;
|
||||
|
||||
std::string newStr = "";
|
||||
if(GetArgument(args,0,str) && GetArgumentHeap(args,1,list))
|
||||
{
|
||||
int64_t item = 0;
|
||||
|
||||
|
||||
for(size_t i = 0; i < str.size(); i++)
|
||||
{
|
||||
if(str[i] == '@' && (i+1>=str.size() || str[i+1] != '@'))
|
||||
{
|
||||
auto v = list->Get(item);
|
||||
int64_t n;
|
||||
double d;
|
||||
bool b;
|
||||
|
||||
|
||||
std::string str;
|
||||
if(GetObject(v,str))
|
||||
{
|
||||
newStr+= SQLiteDatabase::Escape(str);
|
||||
}
|
||||
else if(GetObject(v,n))
|
||||
{
|
||||
newStr+= std::to_string(n);
|
||||
}
|
||||
else if(GetObject(v,b))
|
||||
{
|
||||
newStr+= (b ? "1" : "0");
|
||||
}
|
||||
else if(GetObject(v,d))
|
||||
{
|
||||
newStr+= std::to_string(d);
|
||||
}
|
||||
else {
|
||||
|
||||
newStr+= "NULL";
|
||||
}
|
||||
}
|
||||
else {
|
||||
newStr+=str[i];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
return newStr;
|
||||
if (GetArgument(args, 0, n)) {
|
||||
return std::to_string(n);
|
||||
}
|
||||
|
||||
class SQLiteObject : public TNativeObject
|
||||
{
|
||||
public:
|
||||
SQLiteDatabase* db;
|
||||
SQLiteObject(Tesses::Framework::Filesystem::VFSPath path)
|
||||
{
|
||||
db=new SQLiteDatabase(path);
|
||||
}
|
||||
|
||||
std::string TypeName()
|
||||
{
|
||||
return "SQLiteDatabase";
|
||||
}
|
||||
void Close()
|
||||
{
|
||||
if(this->db == nullptr) return;
|
||||
delete this->db;
|
||||
this->db = nullptr;
|
||||
|
||||
}
|
||||
bool ToBool()
|
||||
{
|
||||
return this->db != nullptr;
|
||||
}
|
||||
|
||||
TObject CallMethod(GCList& ls,std::string name, std::vector<TObject> args)
|
||||
{
|
||||
if(name == "Close") this->Close();
|
||||
if(name == "Escape") {
|
||||
return Sqlite_Escape(ls,args);
|
||||
}
|
||||
if(name == "Prepare") {
|
||||
return Sqlite_Prepare(ls,args);
|
||||
}
|
||||
if(name == "Exec")
|
||||
{
|
||||
std::string arg;
|
||||
if(GetArgument(args,0,arg))
|
||||
{
|
||||
if(this->db == nullptr) return nullptr;
|
||||
std::vector<std::vector<std::pair<std::string, std::optional<std::string>>>> res;
|
||||
|
||||
this->db->Exec(arg,res);
|
||||
|
||||
TList* list = TList::Create(ls);
|
||||
|
||||
for(auto& item : res)
|
||||
{
|
||||
TDictionary* dict = TDictionary::Create(ls);
|
||||
for(auto& item2 : item)
|
||||
{
|
||||
if(item2.second)
|
||||
dict->SetValue(item2.first,item2.second.value());
|
||||
else
|
||||
dict->SetValue(item2.first,nullptr);
|
||||
}
|
||||
|
||||
list->Add(dict);
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
}
|
||||
return Undefined();
|
||||
}
|
||||
|
||||
|
||||
~SQLiteObject()
|
||||
{
|
||||
if(this->db != nullptr)
|
||||
delete this->db;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
TObject Sqlite_Open(GCList& ls, std::vector<TObject> args,TRootEnvironment* env)
|
||||
{
|
||||
Tesses::Framework::Filesystem::VFSPath p;
|
||||
if(GetArgumentAsPath(args,0,p))
|
||||
{
|
||||
if(env->permissions.sqlite3Scoped)
|
||||
{
|
||||
p = env->permissions.sqliteOffsetPath / p.CollapseRelativeParents();
|
||||
}
|
||||
|
||||
return TNativeObject::Create<SQLiteObject>(ls,p);
|
||||
}
|
||||
|
||||
return Undefined();
|
||||
|
||||
if (GetArgument(args, 0, b)) {
|
||||
return b ? "1" : "0";
|
||||
}
|
||||
TObject Sqlite_Exec(GCList& ls, std::vector<TObject> args)
|
||||
{
|
||||
SQLiteObject* sql;
|
||||
std::string cmd;
|
||||
if(GetArgumentHeap(args,0,sql) && GetArgument(args,1,cmd))
|
||||
{
|
||||
try {
|
||||
return sql->CallMethod(ls,"Exec",{cmd});
|
||||
} catch(std::runtime_error& ex)
|
||||
{
|
||||
return (std::string)ex.what();
|
||||
}
|
||||
}
|
||||
|
||||
return Undefined();
|
||||
|
||||
if (GetArgument(args, 0, d)) {
|
||||
return std::to_string(d);
|
||||
}
|
||||
|
||||
TObject Sqlite_Close(GCList& ls, std::vector<TObject> args)
|
||||
{
|
||||
SQLiteObject* sql;
|
||||
if(GetArgumentHeap(args,0,sql))
|
||||
{
|
||||
sql->Close();
|
||||
}
|
||||
return Undefined();
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
void TStd::RegisterSqlite(std::shared_ptr<GC> gc,TRootEnvironment* env)
|
||||
{
|
||||
|
||||
env->permissions.canRegisterSqlite=true;
|
||||
#if defined(TESSESFRAMEWORK_ENABLE_SQLITE)
|
||||
GCList ls(gc);
|
||||
TDictionary* dict = TDictionary::Create(ls);
|
||||
dict->DeclareFunction(gc,"Open","Opens the database (returns database handle or an error message as string or undefined)",{"filename"},[env](GCList& ls, std::vector<TObject> args)->TObject {
|
||||
return Sqlite_Open(ls,args,env);
|
||||
});
|
||||
dict->DeclareFunction(gc,"Exec","Execute sql (returns dictionary of columns key=value, an error message as string or undefined)",{"handle","sql"},Sqlite_Exec);
|
||||
dict->DeclareFunction(gc,"Close","Close sql database",{"handle"},Sqlite_Close);
|
||||
dict->DeclareFunction(gc,"Escape","Escape sql text",{"text"},Sqlite_Escape);
|
||||
dict->DeclareFunction(gc,"Prepare", "Prepare sql",{"sql","items"}, Sqlite_Prepare);
|
||||
|
||||
gc->BarrierBegin();
|
||||
env->DeclareVariable("Sqlite", dict);
|
||||
gc->BarrierEnd();
|
||||
#endif
|
||||
}
|
||||
return "NULL";
|
||||
}
|
||||
|
||||
TObject Sqlite_Prepare(GCList &ls, std::vector<TObject> args) {
|
||||
std::string str;
|
||||
TList *list;
|
||||
|
||||
std::string newStr = "";
|
||||
if (GetArgument(args, 0, str) && GetArgumentHeap(args, 1, list)) {
|
||||
int64_t item = 0;
|
||||
|
||||
for (size_t i = 0; i < str.size(); i++) {
|
||||
if (str[i] == '@' && (i + 1 >= str.size() || str[i + 1] != '@')) {
|
||||
auto v = list->Get(item);
|
||||
int64_t n;
|
||||
double d;
|
||||
bool b;
|
||||
|
||||
std::string str;
|
||||
if (GetObject(v, str)) {
|
||||
newStr += SQLiteDatabase::Escape(str);
|
||||
} else if (GetObject(v, n)) {
|
||||
newStr += std::to_string(n);
|
||||
} else if (GetObject(v, b)) {
|
||||
newStr += (b ? "1" : "0");
|
||||
} else if (GetObject(v, d)) {
|
||||
newStr += std::to_string(d);
|
||||
} else {
|
||||
|
||||
newStr += "NULL";
|
||||
}
|
||||
} else {
|
||||
newStr += str[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
return newStr;
|
||||
}
|
||||
|
||||
class SQLiteObject : public TNativeObject {
|
||||
public:
|
||||
SQLiteDatabase *db;
|
||||
SQLiteObject(Tesses::Framework::Filesystem::VFSPath path) {
|
||||
db = new SQLiteDatabase(path);
|
||||
}
|
||||
|
||||
std::string TypeName() { return "SQLiteDatabase"; }
|
||||
void Close() {
|
||||
if (this->db == nullptr)
|
||||
return;
|
||||
delete this->db;
|
||||
this->db = nullptr;
|
||||
}
|
||||
bool ToBool() { return this->db != nullptr; }
|
||||
|
||||
TObject CallMethod(GCList &ls, std::string name,
|
||||
std::vector<TObject> args) {
|
||||
if (name == "Close")
|
||||
this->Close();
|
||||
if (name == "Escape") {
|
||||
return Sqlite_Escape(ls, args);
|
||||
}
|
||||
if (name == "Prepare") {
|
||||
return Sqlite_Prepare(ls, args);
|
||||
}
|
||||
if (name == "Exec") {
|
||||
std::string arg;
|
||||
if (GetArgument(args, 0, arg)) {
|
||||
if (this->db == nullptr)
|
||||
return nullptr;
|
||||
std::vector<std::vector<
|
||||
std::pair<std::string, std::optional<std::string>>>>
|
||||
res;
|
||||
|
||||
this->db->Exec(arg, res);
|
||||
|
||||
TList *list = TList::Create(ls);
|
||||
|
||||
for (auto &item : res) {
|
||||
TDictionary *dict = TDictionary::Create(ls);
|
||||
for (auto &item2 : item) {
|
||||
if (item2.second)
|
||||
dict->SetValue(item2.first, item2.second.value());
|
||||
else
|
||||
dict->SetValue(item2.first, nullptr);
|
||||
}
|
||||
|
||||
list->Add(dict);
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
}
|
||||
return Undefined();
|
||||
}
|
||||
|
||||
~SQLiteObject() {
|
||||
if (this->db != nullptr)
|
||||
delete this->db;
|
||||
}
|
||||
};
|
||||
|
||||
TObject Sqlite_Open(GCList &ls, std::vector<TObject> args,
|
||||
TRootEnvironment *env) {
|
||||
Tesses::Framework::Filesystem::VFSPath p;
|
||||
if (GetArgumentAsPath(args, 0, p)) {
|
||||
if (env->permissions.sqlite3Scoped) {
|
||||
p = env->permissions.sqliteOffsetPath / p.CollapseRelativeParents();
|
||||
}
|
||||
|
||||
return TNativeObject::Create<SQLiteObject>(ls, p);
|
||||
}
|
||||
|
||||
return Undefined();
|
||||
}
|
||||
TObject Sqlite_Exec(GCList &ls, std::vector<TObject> args) {
|
||||
SQLiteObject *sql;
|
||||
std::string cmd;
|
||||
if (GetArgumentHeap(args, 0, sql) && GetArgument(args, 1, cmd)) {
|
||||
try {
|
||||
return sql->CallMethod(ls, "Exec", {cmd});
|
||||
} catch (std::runtime_error &ex) {
|
||||
return (std::string)ex.what();
|
||||
}
|
||||
}
|
||||
|
||||
return Undefined();
|
||||
}
|
||||
|
||||
TObject Sqlite_Close(GCList &ls, std::vector<TObject> args) {
|
||||
SQLiteObject *sql;
|
||||
if (GetArgumentHeap(args, 0, sql)) {
|
||||
sql->Close();
|
||||
}
|
||||
return Undefined();
|
||||
}
|
||||
|
||||
#endif
|
||||
void TStd::RegisterSqlite(std::shared_ptr<GC> gc, TRootEnvironment *env) {
|
||||
|
||||
env->permissions.canRegisterSqlite = true;
|
||||
#if defined(TESSESFRAMEWORK_ENABLE_SQLITE)
|
||||
GCList ls(gc);
|
||||
TDictionary *dict = TDictionary::Create(ls);
|
||||
dict->DeclareFunction(
|
||||
gc, "Open",
|
||||
"Opens the database (returns database handle or an error message as "
|
||||
"string or undefined)",
|
||||
{"filename"}, [env](GCList &ls, std::vector<TObject> args) -> TObject {
|
||||
return Sqlite_Open(ls, args, env);
|
||||
});
|
||||
dict->DeclareFunction(gc, "Exec",
|
||||
"Execute sql (returns dictionary of columns "
|
||||
"key=value, an error message as string or undefined)",
|
||||
{"handle", "sql"}, Sqlite_Exec);
|
||||
dict->DeclareFunction(gc, "Close", "Close sql database", {"handle"},
|
||||
Sqlite_Close);
|
||||
dict->DeclareFunction(gc, "Escape", "Escape sql text", {"text"},
|
||||
Sqlite_Escape);
|
||||
dict->DeclareFunction(gc, "Prepare", "Prepare sql", {"sql", "items"},
|
||||
Sqlite_Prepare);
|
||||
|
||||
gc->BarrierBegin();
|
||||
env->DeclareVariable("Sqlite", dict);
|
||||
gc->BarrierEnd();
|
||||
#endif
|
||||
}
|
||||
} // namespace Tesses::CrossLang
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,40 +1,42 @@
|
||||
#include "TessesFramework/Uuid.hpp"
|
||||
#include "CrossLang.hpp"
|
||||
#include "TessesFramework/Serialization/BitConverter.hpp"
|
||||
#include "TessesFramework/Uuid.hpp"
|
||||
|
||||
namespace Tesses::CrossLang {
|
||||
static TObject Uuid_NewUuid(GCList& ls, std::vector<TObject> args)
|
||||
{
|
||||
return Tesses::Framework::Uuid::Generate();
|
||||
static TObject Uuid_NewUuid(GCList &ls, std::vector<TObject> args) {
|
||||
return Tesses::Framework::Uuid::Generate();
|
||||
}
|
||||
static TObject Uuid_TryParse(GCList &ls, std::vector<TObject> args) {
|
||||
std::string str;
|
||||
Tesses::Framework::Uuid uuid;
|
||||
if (GetArgument(args, 0, str) &&
|
||||
Tesses::Framework::Uuid::TryParse(str, uuid))
|
||||
return uuid;
|
||||
return nullptr;
|
||||
}
|
||||
static TObject Uuid_FromBytes(GCList &ls, std::vector<TObject> args) {
|
||||
TByteArray *ba;
|
||||
int64_t index;
|
||||
if (GetArgumentHeap(args, 0, ba) && GetArgument(args, 1, index) &&
|
||||
(size_t)index < ba->data.size() &&
|
||||
(size_t)index + 16 <= ba->data.size()) {
|
||||
return Tesses::Framework::Serialization::BitConverter::ToUuid(
|
||||
ba->data[(size_t)index]);
|
||||
}
|
||||
static TObject Uuid_TryParse(GCList& ls, std::vector<TObject> args)
|
||||
{
|
||||
std::string str;
|
||||
Tesses::Framework::Uuid uuid;
|
||||
if(GetArgument(args, 0, str) && Tesses::Framework::Uuid::TryParse(str,uuid))
|
||||
return uuid;
|
||||
return nullptr;
|
||||
}
|
||||
static TObject Uuid_FromBytes(GCList& ls, std::vector<TObject> args)
|
||||
{
|
||||
TByteArray* ba;
|
||||
int64_t index;
|
||||
if(GetArgumentHeap(args,0,ba) && GetArgument(args, 1, index) && (size_t)index < ba->data.size() && (size_t)index + 16 <= ba->data.size())
|
||||
{
|
||||
return Tesses::Framework::Serialization::BitConverter::ToUuid(ba->data[(size_t)index]);
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void TStd::RegisterUuid(std::shared_ptr<GC> gc, TRootEnvironment* env)
|
||||
{
|
||||
gc->BarrierBegin();
|
||||
TDictionary* guid = env->EnsureDictionary(gc, "Uuid");
|
||||
guid->DeclareFunction(gc,"NewUuid","Create random uuid",{},Uuid_NewUuid);
|
||||
guid->DeclareFunction(gc, "TryParse","Try to parse",{"str"}, Uuid_TryParse);
|
||||
guid->DeclareFunction(gc, "FromBytes", "From bytes (big endian)",{"byteArray","offset"}, Uuid_FromBytes);
|
||||
|
||||
gc->BarrierEnd();
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void TStd::RegisterUuid(std::shared_ptr<GC> gc, TRootEnvironment *env) {
|
||||
gc->BarrierBegin();
|
||||
TDictionary *guid = env->EnsureDictionary(gc, "Uuid");
|
||||
guid->DeclareFunction(gc, "NewUuid", "Create random uuid", {},
|
||||
Uuid_NewUuid);
|
||||
guid->DeclareFunction(gc, "TryParse", "Try to parse", {"str"},
|
||||
Uuid_TryParse);
|
||||
guid->DeclareFunction(gc, "FromBytes", "From bytes (big endian)",
|
||||
{"byteArray", "offset"}, Uuid_FromBytes);
|
||||
|
||||
gc->BarrierEnd();
|
||||
}
|
||||
} // namespace Tesses::CrossLang
|
||||
@@ -1,123 +1,104 @@
|
||||
#include "CrossLang.hpp"
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
|
||||
namespace Tesses::CrossLang
|
||||
{
|
||||
namespace Tesses::CrossLang {
|
||||
|
||||
static TObject AstToTObject(GCList& ls,SyntaxNode node)
|
||||
{
|
||||
if(std::holds_alternative<std::nullptr_t>(node))
|
||||
static TObject AstToTObject(GCList &ls, SyntaxNode node) {
|
||||
if (std::holds_alternative<std::nullptr_t>(node))
|
||||
return nullptr;
|
||||
if(std::holds_alternative<int64_t>(node))
|
||||
{
|
||||
if (std::holds_alternative<int64_t>(node)) {
|
||||
return std::get<int64_t>(node);
|
||||
}
|
||||
if(std::holds_alternative<double>(node))
|
||||
{
|
||||
if (std::holds_alternative<double>(node)) {
|
||||
return std::get<double>(node);
|
||||
}
|
||||
if(std::holds_alternative<bool>(node))
|
||||
{
|
||||
if (std::holds_alternative<bool>(node)) {
|
||||
return std::get<bool>(node);
|
||||
}
|
||||
if(std::holds_alternative<std::string>(node))
|
||||
{
|
||||
if (std::holds_alternative<std::string>(node)) {
|
||||
std::string str = std::get<std::string>(node);
|
||||
return str;
|
||||
}
|
||||
if(std::holds_alternative<char>(node))
|
||||
{
|
||||
if (std::holds_alternative<char>(node)) {
|
||||
char c = std::get<char>(node);
|
||||
return c;
|
||||
}
|
||||
if(std::holds_alternative<Undefined>(node))
|
||||
{
|
||||
if (std::holds_alternative<Undefined>(node)) {
|
||||
auto r = TDictionary::Create(ls);
|
||||
ls.GetGC()->BarrierBegin();
|
||||
r->SetValue("Type",std::string(UndefinedExpression));
|
||||
r->SetValue("Type", std::string(UndefinedExpression));
|
||||
ls.GetGC()->BarrierEnd();
|
||||
return r;
|
||||
|
||||
}
|
||||
|
||||
|
||||
if(std::holds_alternative<AdvancedSyntaxNode>(node))
|
||||
{
|
||||
if (std::holds_alternative<AdvancedSyntaxNode>(node)) {
|
||||
auto asn = std::get<AdvancedSyntaxNode>(node);
|
||||
auto r = TDictionary::Create(ls);
|
||||
ls.GetGC()->BarrierBegin();
|
||||
r->SetValue("Type",asn.nodeName);
|
||||
r->SetValue("IsExpression",asn.isExpression);
|
||||
TList* ls2 = TList::Create(ls);
|
||||
for(auto item : asn.nodes)
|
||||
{
|
||||
ls2->Add(AstToTObject(ls,item));
|
||||
r->SetValue("Type", asn.nodeName);
|
||||
r->SetValue("IsExpression", asn.isExpression);
|
||||
TList *ls2 = TList::Create(ls);
|
||||
for (auto item : asn.nodes) {
|
||||
ls2->Add(AstToTObject(ls, item));
|
||||
}
|
||||
r->SetValue("Arguments", ls2);
|
||||
ls.GetGC()->BarrierEnd();
|
||||
return r;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
static TObject VM_SourceToAst(GCList& ls, std::vector<TObject> args)
|
||||
{
|
||||
std::string str;
|
||||
if(GetArgument(args,0,str))
|
||||
{
|
||||
std::stringstream strm(str);
|
||||
std::vector<LexToken> tokens;
|
||||
int res = Lex("memory.tcross",strm,tokens);
|
||||
if(res != 0)
|
||||
{
|
||||
throw VMException("Lex error at line: " + std::to_string(res));
|
||||
}
|
||||
Parser p(tokens);
|
||||
auto res2 =p.ParseRoot();
|
||||
return AstToTObject(ls,res2);
|
||||
return nullptr;
|
||||
}
|
||||
static TObject VM_SourceToAst(GCList &ls, std::vector<TObject> args) {
|
||||
std::string str;
|
||||
if (GetArgument(args, 0, str)) {
|
||||
std::stringstream strm(str);
|
||||
std::vector<LexToken> tokens;
|
||||
int res = Lex("memory.tcross", strm, tokens);
|
||||
if (res != 0) {
|
||||
throw VMException("Lex error at line: " + std::to_string(res));
|
||||
}
|
||||
return nullptr;
|
||||
Parser p(tokens);
|
||||
auto res2 = p.ParseRoot();
|
||||
return AstToTObject(ls, res2);
|
||||
}
|
||||
static TObject VM_Eval(GCList& ls, std::vector<TObject> args)
|
||||
{
|
||||
std::string str;
|
||||
if(GetArgument(args,0,str))
|
||||
{
|
||||
if(current_function != nullptr)
|
||||
{
|
||||
return current_function->env->Eval(ls,str);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
static TObject VM_Eval(GCList &ls, std::vector<TObject> args) {
|
||||
std::string str;
|
||||
if (GetArgument(args, 0, str)) {
|
||||
if (current_function != nullptr) {
|
||||
return current_function->env->Eval(ls, str);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
static TObject Failure(GCList& ls, std::string reason)
|
||||
{
|
||||
TDictionary* dict = TDictionary::Create(ls);
|
||||
ls.GetGC()->BarrierBegin();
|
||||
dict->SetValue("Success",false);
|
||||
dict->SetValue("Reason", reason);
|
||||
ls.GetGC()->BarrierEnd();
|
||||
return dict;
|
||||
}
|
||||
static TObject Success(GCList& ls)
|
||||
{
|
||||
TDictionary* dict = TDictionary::Create(ls);
|
||||
ls.GetGC()->BarrierBegin();
|
||||
dict->SetValue("Success",true);
|
||||
ls.GetGC()->BarrierEnd();
|
||||
return dict;
|
||||
}
|
||||
static TObject VM_getCurrentEnvironment(GCList& ls2,std::vector<TObject> args)
|
||||
{
|
||||
if(current_function != nullptr) return current_function->env;
|
||||
return Undefined();
|
||||
}
|
||||
static TObject VM_Compile(GCList& ls, std::vector<TObject> args)
|
||||
{
|
||||
try {
|
||||
TDictionary* dict;
|
||||
if(!GetArgumentHeap<TDictionary*>(args,0,dict)) return Undefined();
|
||||
return nullptr;
|
||||
}
|
||||
static TObject Failure(GCList &ls, std::string reason) {
|
||||
TDictionary *dict = TDictionary::Create(ls);
|
||||
ls.GetGC()->BarrierBegin();
|
||||
dict->SetValue("Success", false);
|
||||
dict->SetValue("Reason", reason);
|
||||
ls.GetGC()->BarrierEnd();
|
||||
return dict;
|
||||
}
|
||||
static TObject Success(GCList &ls) {
|
||||
TDictionary *dict = TDictionary::Create(ls);
|
||||
ls.GetGC()->BarrierBegin();
|
||||
dict->SetValue("Success", true);
|
||||
ls.GetGC()->BarrierEnd();
|
||||
return dict;
|
||||
}
|
||||
static TObject VM_getCurrentEnvironment(GCList &ls2,
|
||||
std::vector<TObject> args) {
|
||||
if (current_function != nullptr)
|
||||
return current_function->env;
|
||||
return Undefined();
|
||||
}
|
||||
static TObject VM_Compile(GCList &ls, std::vector<TObject> args) {
|
||||
try {
|
||||
TDictionary *dict;
|
||||
if (!GetArgumentHeap<TDictionary *>(args, 0, dict))
|
||||
return Undefined();
|
||||
/*
|
||||
VM.Compile
|
||||
{
|
||||
@@ -127,18 +108,20 @@ namespace Tesses::CrossLang
|
||||
Version = "",
|
||||
Dependencies = [{Name="Name", Version}],
|
||||
ResourceDirectory = "",
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
*/
|
||||
|
||||
std::string name = "Out";
|
||||
std::vector<std::pair<std::string,std::string>> sources;
|
||||
TVMVersion version(CROSSLANG_BYTECODE_MAJOR,CROSSLANG_BYTECODE_MINOR,CROSSLANG_BYTECODE_PATCH,CROSSLANG_BYTECODE_BUILD,CROSSLANG_BYTECODE_VERSIONSTAGE);
|
||||
std::vector<std::pair<std::string,TVMVersion>> dependencies;
|
||||
std::vector<std::pair<std::string,TVMVersion>> tools;
|
||||
std::vector<std::pair<std::string, std::string>> sources;
|
||||
TVMVersion version(CROSSLANG_BYTECODE_MAJOR, CROSSLANG_BYTECODE_MINOR,
|
||||
CROSSLANG_BYTECODE_PATCH, CROSSLANG_BYTECODE_BUILD,
|
||||
CROSSLANG_BYTECODE_VERSIONSTAGE);
|
||||
std::vector<std::pair<std::string, TVMVersion>> dependencies;
|
||||
std::vector<std::pair<std::string, TVMVersion>> tools;
|
||||
std::string info;
|
||||
std::string icon;
|
||||
bool debug=false;
|
||||
bool debug = false;
|
||||
std::shared_ptr<Tesses::Framework::Filesystem::VFS> vfs;
|
||||
|
||||
ls.GetGC()->BarrierBegin();
|
||||
@@ -151,116 +134,110 @@ namespace Tesses::CrossLang
|
||||
TObject _icon = dict->GetValue("Icon");
|
||||
TObject _comptime = dict->GetValue("CompTime");
|
||||
TObject _resourceFileSystem = dict->GetValue("ResourceFileSystem");
|
||||
|
||||
|
||||
TObject _out = dict->GetValue("Output");
|
||||
TObject _dbg = dict->GetValue("Debug");
|
||||
TList* _toolList;
|
||||
TList* _depList; TList* srcLst;
|
||||
TRootEnvironment* comptimeEnv=nullptr;
|
||||
GetObject<std::string>(_name,name);
|
||||
GetObject<std::string>(_info,info);
|
||||
GetObject<std::string>(_icon,icon);
|
||||
TList *_toolList;
|
||||
TList *_depList;
|
||||
TList *srcLst;
|
||||
TRootEnvironment *comptimeEnv = nullptr;
|
||||
GetObject<std::string>(_name, name);
|
||||
GetObject<std::string>(_info, info);
|
||||
GetObject<std::string>(_icon, icon);
|
||||
GetObject(_resourceFileSystem, vfs);
|
||||
GetObjectHeap(_comptime,comptimeEnv);
|
||||
GetObject(_dbg,debug);
|
||||
GetObjectHeap(_comptime, comptimeEnv);
|
||||
GetObject(_dbg, debug);
|
||||
std::string v2;
|
||||
if(GetObject<std::string>(_version,v2))
|
||||
if (GetObject<std::string>(_version, v2))
|
||||
TVMVersion::TryParse(v2, version);
|
||||
else
|
||||
GetObject(_version,version);
|
||||
GetObject(_version, version);
|
||||
|
||||
if(GetObjectHeap<TList*>(_dependencies,_depList))
|
||||
{
|
||||
for(int64_t i = 0; i < _depList->Count(); i++)
|
||||
{
|
||||
if (GetObjectHeap<TList *>(_dependencies, _depList)) {
|
||||
for (int64_t i = 0; i < _depList->Count(); i++) {
|
||||
TObject _dep = _depList->Get(i);
|
||||
TDictionary* _depD;
|
||||
if(GetObjectHeap<TDictionary*>(_dep, _depD))
|
||||
{
|
||||
TDictionary *_depD;
|
||||
if (GetObjectHeap<TDictionary *>(_dep, _depD)) {
|
||||
TObject _name2 = _depD->GetValue("Name");
|
||||
TObject _version2 = _depD->GetValue("Version");
|
||||
std::string name2;
|
||||
std::string version2;
|
||||
TVMVersion version02;
|
||||
|
||||
if(GetObject<std::string>(_name2,name2) && GetObject<std::string>(_version2,version2) && TVMVersion::TryParse(version2,version02))
|
||||
{
|
||||
dependencies.push_back(std::pair<std::string,TVMVersion>(name2, version02));
|
||||
}
|
||||
else if(GetObject<std::string>(_name2,name2) && GetObject(_version2,version02))
|
||||
{
|
||||
dependencies.push_back(std::pair<std::string,TVMVersion>(name2, version02));
|
||||
if (GetObject<std::string>(_name2, name2) &&
|
||||
GetObject<std::string>(_version2, version2) &&
|
||||
TVMVersion::TryParse(version2, version02)) {
|
||||
dependencies.push_back(
|
||||
std::pair<std::string, TVMVersion>(name2,
|
||||
version02));
|
||||
} else if (GetObject<std::string>(_name2, name2) &&
|
||||
GetObject(_version2, version02)) {
|
||||
dependencies.push_back(
|
||||
std::pair<std::string, TVMVersion>(name2,
|
||||
version02));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
if(GetObjectHeap<TList*>(_tools,_toolList))
|
||||
{
|
||||
for(int64_t i = 0; i < _toolList->Count(); i++)
|
||||
{
|
||||
if (GetObjectHeap<TList *>(_tools, _toolList)) {
|
||||
for (int64_t i = 0; i < _toolList->Count(); i++) {
|
||||
TObject _dep = _toolList->Get(i);
|
||||
TDictionary* _depD;
|
||||
if(GetObjectHeap<TDictionary*>(_dep, _depD))
|
||||
{
|
||||
TDictionary *_depD;
|
||||
if (GetObjectHeap<TDictionary *>(_dep, _depD)) {
|
||||
TObject _name2 = _depD->GetValue("Name");
|
||||
TObject _version2 = _depD->GetValue("Version");
|
||||
std::string name2;
|
||||
std::string version2;
|
||||
TVMVersion version02;
|
||||
|
||||
if(GetObject<std::string>(_name2,name2) && GetObject<std::string>(_version2,version2) && TVMVersion::TryParse(version2,version02))
|
||||
{
|
||||
tools.push_back(std::pair<std::string,TVMVersion>(name2, version02));
|
||||
}
|
||||
else if(GetObject<std::string>(_name2,name2) && GetObject(_version2,version02))
|
||||
{
|
||||
tools.push_back(std::pair<std::string,TVMVersion>(name2, version02));
|
||||
if (GetObject<std::string>(_name2, name2) &&
|
||||
GetObject<std::string>(_version2, version2) &&
|
||||
TVMVersion::TryParse(version2, version02)) {
|
||||
tools.push_back(std::pair<std::string, TVMVersion>(
|
||||
name2, version02));
|
||||
} else if (GetObject<std::string>(_name2, name2) &&
|
||||
GetObject(_version2, version02)) {
|
||||
tools.push_back(std::pair<std::string, TVMVersion>(
|
||||
name2, version02));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
if(GetObjectHeap<TList*>(_sources,srcLst))
|
||||
{
|
||||
for(int64_t i = 0; i < srcLst->Count(); i++)
|
||||
{
|
||||
if (GetObjectHeap<TList *>(_sources, srcLst)) {
|
||||
for (int64_t i = 0; i < srcLst->Count(); i++) {
|
||||
TObject _src = srcLst->Get(i);
|
||||
TDictionary* _srcD;
|
||||
if(GetObjectHeap<TDictionary*>(_src, _srcD))
|
||||
{
|
||||
TDictionary *_srcD;
|
||||
if (GetObjectHeap<TDictionary *>(_src, _srcD)) {
|
||||
TObject _sourceTxt = _srcD->GetValue("Source");
|
||||
TObject _filename = _srcD->GetValue("FileName");
|
||||
|
||||
|
||||
std::string srctxt = "";
|
||||
std::string filename = "memory_" + std::to_string(i) + ".tcross";
|
||||
std::string filename =
|
||||
"memory_" + std::to_string(i) + ".tcross";
|
||||
bool fromFile = false;
|
||||
|
||||
GetObject<std::string>(_sourceTxt,srctxt);
|
||||
GetObject<std::string>(_filename,filename);
|
||||
|
||||
|
||||
sources.push_back(std::pair<std::string,std::string>(srctxt,filename));
|
||||
GetObject<std::string>(_sourceTxt, srctxt);
|
||||
GetObject<std::string>(_filename, filename);
|
||||
|
||||
sources.push_back(
|
||||
std::pair<std::string, std::string>(srctxt, filename));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
ls.GetGC()->BarrierEnd();
|
||||
|
||||
std::vector<LexToken> tokens;
|
||||
for(auto source : sources)
|
||||
{
|
||||
for (auto source : sources) {
|
||||
std::stringstream strm(source.first);
|
||||
|
||||
int res = Lex(source.second, strm, tokens);
|
||||
if(res != 0)
|
||||
{
|
||||
return Failure(ls, "Lex error in file \"" + source.second + "\":" + std::to_string(res));
|
||||
if (res != 0) {
|
||||
return Failure(ls, "Lex error in file \"" + source.second +
|
||||
"\":" + std::to_string(res));
|
||||
}
|
||||
}
|
||||
Parser parser(tokens,ls.GetGC(),comptimeEnv);
|
||||
Parser parser(tokens, ls.GetGC(), comptimeEnv);
|
||||
parser.debug = debug;
|
||||
SyntaxNode n = parser.ParseRoot();
|
||||
CodeGen gen;
|
||||
@@ -274,147 +251,136 @@ namespace Tesses::CrossLang
|
||||
gen.icon = icon;
|
||||
std::string outpath;
|
||||
std::shared_ptr<Tesses::Framework::Streams::Stream> stream;
|
||||
if(GetObject(_out, stream))
|
||||
{
|
||||
if (GetObject(_out, stream)) {
|
||||
gen.Save(stream);
|
||||
}
|
||||
|
||||
|
||||
|
||||
return Success(ls);
|
||||
} catch(std::exception& ex)
|
||||
{
|
||||
return Failure(ls, ex.what());
|
||||
}
|
||||
} catch (std::exception &ex) {
|
||||
return Failure(ls, ex.what());
|
||||
}
|
||||
static TObject VM_GetStacktrace(GCList& ls, std::vector<TObject> args)
|
||||
{
|
||||
if(current_function != nullptr)
|
||||
{
|
||||
if(current_function->thread != nullptr)
|
||||
{
|
||||
TList* list = TList::Create(ls);
|
||||
ls.GetGC()->BarrierBegin();
|
||||
for(auto item : current_function->thread->call_stack_entries)
|
||||
{
|
||||
auto dict = TDictionary::Create(ls);
|
||||
if(item->callable->closure->name)
|
||||
dict->SetValue("Name", *item->callable->closure->name);
|
||||
|
||||
dict->SetValue("Closure", item->callable->closure);
|
||||
dict->SetValue("FileName", item->callable->file->name + "-" + item->callable->file->version.ToString() + ".crvm");
|
||||
dict->SetValue("IP",(int64_t)item->ip);
|
||||
if(item->srcline >= 1)
|
||||
{
|
||||
dict->SetValue("SourceFile", item->srcfile);
|
||||
dict->SetValue("SourceLine",item->srcline);
|
||||
}
|
||||
list->Add(dict);
|
||||
}
|
||||
ls.GetGC()->BarrierEnd();
|
||||
return list;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
void TStd::RegisterVM(std::shared_ptr<GC> gc,TRootEnvironment* env)
|
||||
{
|
||||
env->permissions.canRegisterVM=true;
|
||||
GCList ls(gc);
|
||||
}
|
||||
static TObject VM_GetStacktrace(GCList &ls, std::vector<TObject> args) {
|
||||
if (current_function != nullptr) {
|
||||
if (current_function->thread != nullptr) {
|
||||
TList *list = TList::Create(ls);
|
||||
ls.GetGC()->BarrierBegin();
|
||||
for (auto item : current_function->thread->call_stack_entries) {
|
||||
auto dict = TDictionary::Create(ls);
|
||||
if (item->callable->closure->name)
|
||||
dict->SetValue("Name", *item->callable->closure->name);
|
||||
|
||||
TDictionary* dict = TDictionary::Create(ls);
|
||||
dict->DeclareFunction(gc, "GetStacktrace","Get the current stack trace", {}, VM_GetStacktrace);
|
||||
dict->DeclareFunction(gc, "getRootEnvironmentAsDictionary","Get root environment as a dictionary",{},[env](GCList& ls, std::vector<TObject> args)-> TObject{
|
||||
dict->SetValue("Closure", item->callable->closure);
|
||||
dict->SetValue("FileName",
|
||||
item->callable->file->name + "-" +
|
||||
item->callable->file->version.ToString() +
|
||||
".crvm");
|
||||
dict->SetValue("IP", (int64_t)item->ip);
|
||||
if (item->srcline >= 1) {
|
||||
dict->SetValue("SourceFile", item->srcfile);
|
||||
dict->SetValue("SourceLine", item->srcline);
|
||||
}
|
||||
list->Add(dict);
|
||||
}
|
||||
ls.GetGC()->BarrierEnd();
|
||||
return list;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
void TStd::RegisterVM(std::shared_ptr<GC> gc, TRootEnvironment *env) {
|
||||
env->permissions.canRegisterVM = true;
|
||||
GCList ls(gc);
|
||||
|
||||
TDictionary *dict = TDictionary::Create(ls);
|
||||
dict->DeclareFunction(gc, "GetStacktrace", "Get the current stack trace",
|
||||
{}, VM_GetStacktrace);
|
||||
dict->DeclareFunction(
|
||||
gc, "getRootEnvironmentAsDictionary",
|
||||
"Get root environment as a dictionary", {},
|
||||
[env](GCList &ls, std::vector<TObject> args) -> TObject {
|
||||
return env->GetDictionary();
|
||||
});
|
||||
dict->DeclareFunction(gc, "getRootEnvironment","Get root environment, for reflection purposes",{},[env](GCList& ls2,std::vector<TObject> args)->TObject {return env;});
|
||||
dict->DeclareFunction(gc, "getCurrentEnvironment","Get current environment, for reflection purposes",{},VM_getCurrentEnvironment);
|
||||
dict->DeclareFunction(gc, "CreateEnvironment","Create root environment",{"$dict"},[env](GCList& ls,std::vector<TObject> args)->TObject{
|
||||
TDictionary* dict;
|
||||
if(GetArgumentHeap(args,0,dict))
|
||||
{
|
||||
auto renv = TRootEnvironment::Create(ls,dict);
|
||||
renv->permissions.customConsole = env->permissions.customConsole;
|
||||
dict->DeclareFunction(
|
||||
gc, "getRootEnvironment",
|
||||
"Get root environment, for reflection purposes", {},
|
||||
[env](GCList &ls2, std::vector<TObject> args) -> TObject {
|
||||
return env;
|
||||
});
|
||||
dict->DeclareFunction(gc, "getCurrentEnvironment",
|
||||
"Get current environment, for reflection purposes",
|
||||
{}, VM_getCurrentEnvironment);
|
||||
dict->DeclareFunction(
|
||||
gc, "CreateEnvironment", "Create root environment", {"$dict"},
|
||||
[env](GCList &ls, std::vector<TObject> args) -> TObject {
|
||||
TDictionary *dict;
|
||||
if (GetArgumentHeap(args, 0, dict)) {
|
||||
auto renv = TRootEnvironment::Create(ls, dict);
|
||||
renv->permissions.customConsole =
|
||||
env->permissions.customConsole;
|
||||
return renv;
|
||||
}
|
||||
else
|
||||
{
|
||||
auto renv = TRootEnvironment::Create(ls,TDictionary::Create(ls));
|
||||
renv->permissions.customConsole = env->permissions.customConsole;
|
||||
} else {
|
||||
auto renv =
|
||||
TRootEnvironment::Create(ls, TDictionary::Create(ls));
|
||||
renv->permissions.customConsole =
|
||||
env->permissions.customConsole;
|
||||
return renv;
|
||||
}
|
||||
});
|
||||
dict->DeclareFunction(gc, "LoadExecutable", "Load a crossvm executable",{"stream"},[](GCList& ls,std::vector<TObject> args)->TObject{
|
||||
dict->DeclareFunction(
|
||||
gc, "LoadExecutable", "Load a crossvm executable", {"stream"},
|
||||
[](GCList &ls, std::vector<TObject> args) -> TObject {
|
||||
std::shared_ptr<Tesses::Framework::Streams::Stream> strm;
|
||||
if(GetArgument(args,0,strm))
|
||||
{
|
||||
TFile* f =TFile::Create(ls);
|
||||
f->Load(ls.GetGC(),strm);
|
||||
if (GetArgument(args, 0, strm)) {
|
||||
TFile *f = TFile::Create(ls);
|
||||
f->Load(ls.GetGC(), strm);
|
||||
return f;
|
||||
}
|
||||
return nullptr;
|
||||
});
|
||||
#if defined(CROSSLANG_ENABLE_SUPERSLIM)
|
||||
dict->SetValue("SuperSlim", true);
|
||||
#else
|
||||
dict->SetValue("SuperSlim", false);
|
||||
#endif
|
||||
dict->DeclareFunction(gc, "Eval", "Eval source code",{"source"}, VM_Eval);
|
||||
dict->DeclareFunction(gc, "Compile", "Compile Source",{"dict"},VM_Compile);
|
||||
|
||||
dict->DeclareFunction(gc, "SourceToAst", "Convert source to ast", {"source"}, VM_SourceToAst);
|
||||
dict->DeclareFunction(gc, "getRuntimeVersion","Get the runtime version",{},[](GCList& ls,std::vector<TObject> args)->TObject {
|
||||
return TVMVersion(CROSSLANG_MAJOR,CROSSLANG_MINOR,CROSSLANG_PATCH,0,TVMVersionStage::DevVersion);
|
||||
});
|
||||
dict->DeclareFunction(gc, "getBytecodeVersion","Get the bytecode version",{},[](GCList& ls,std::vector<TObject> args)->TObject {
|
||||
return TVMVersion(CROSSLANG_BYTECODE_MAJOR,CROSSLANG_BYTECODE_MINOR,CROSSLANG_BYTECODE_PATCH,CROSSLANG_BYTECODE_BUILD,CROSSLANG_BYTECODE_VERSIONSTAGE);
|
||||
});
|
||||
dict->DeclareFunction(gc, "getIsRunning","Is the program still running",{},[](GCList& ls, std::vector<TObject> args)->TObject {
|
||||
return Tesses::Framework::TF_IsRunning();
|
||||
});
|
||||
dict->DeclareFunction(gc, "RunEventLoopItteration","Run Event Loop Itteration",{},[](GCList& ls, std::vector<TObject> args)->TObject {
|
||||
Tesses::Framework::TF_RunEventLoopItteration();
|
||||
return Undefined();
|
||||
});
|
||||
dict->DeclareFunction(gc, "RunEventLoop","Run Event Loop",{},[](GCList& ls, std::vector<TObject> args)->TObject {
|
||||
Tesses::Framework::TF_RunEventLoop();
|
||||
return Undefined();
|
||||
});
|
||||
dict->DeclareFunction(gc, "Merge", "Merge crvm files", {"srcVFS","sourcePath","destVFS"},[](GCList& ls, std::vector<TObject> args)->TObject {
|
||||
std::shared_ptr<Tesses::Framework::Filesystem::VFS> srcVFS;
|
||||
std::shared_ptr<Tesses::Framework::Filesystem::VFS> destVFS;
|
||||
Tesses::Framework::Filesystem::VFSPath sourcePath;
|
||||
if(GetArgument(args,0, srcVFS) && GetArgumentAsPath(args,1,sourcePath) && GetArgument(args,2,destVFS))
|
||||
return Merge(srcVFS, sourcePath, destVFS);
|
||||
return Undefined();
|
||||
});
|
||||
dict->DeclareFunction(gc, "Disassemble","Disassemble crvm file",{"strm","vfs","$generateJSON","$extractResources"},[](GCList& ls, std::vector<TObject> args)->TObject {
|
||||
std::shared_ptr<Tesses::Framework::Streams::Stream> strm;
|
||||
std::shared_ptr<Tesses::Framework::Filesystem::VFS> vfs;
|
||||
bool generateJSON=true;
|
||||
bool extractResources=true;
|
||||
if(GetArgument(args,0,strm) && GetArgument(args,1, vfs))
|
||||
{
|
||||
GetArgument(args,2,generateJSON);
|
||||
GetArgument(args,3,extractResources);
|
||||
Disassemble(strm,vfs, generateJSON, extractResources);
|
||||
}
|
||||
return Undefined();
|
||||
});
|
||||
dict->DeclareFunction(gc, "Assemble", "Assemble crvm file",{"vfs"},[](GCList& ls, std::vector<TObject> args)->TObject {
|
||||
std::shared_ptr<Tesses::Framework::Filesystem::VFS> vfs;
|
||||
if(GetArgument(args,0, vfs))
|
||||
return Assemble(vfs);
|
||||
return Undefined();
|
||||
});
|
||||
|
||||
gc->BarrierBegin();
|
||||
|
||||
|
||||
|
||||
env->DeclareVariable("VM", dict);
|
||||
|
||||
gc->BarrierEnd();
|
||||
}
|
||||
|
||||
}
|
||||
dict->DeclareFunction(gc, "Eval", "Eval source code", {"source"}, VM_Eval);
|
||||
dict->DeclareFunction(gc, "Compile", "Compile Source", {"dict"},
|
||||
VM_Compile);
|
||||
|
||||
dict->DeclareFunction(gc, "SourceToAst", "Convert source to ast",
|
||||
{"source"}, VM_SourceToAst);
|
||||
dict->DeclareFunction(
|
||||
gc, "getRuntimeVersion", "Get the runtime version", {},
|
||||
[](GCList &ls, std::vector<TObject> args) -> TObject {
|
||||
return TVMVersion(CROSSLANG_MAJOR, CROSSLANG_MINOR, CROSSLANG_PATCH,
|
||||
0, TVMVersionStage::DevVersion);
|
||||
});
|
||||
dict->DeclareFunction(
|
||||
gc, "getBytecodeVersion", "Get the bytecode version", {},
|
||||
[](GCList &ls, std::vector<TObject> args) -> TObject {
|
||||
return TVMVersion(
|
||||
CROSSLANG_BYTECODE_MAJOR, CROSSLANG_BYTECODE_MINOR,
|
||||
CROSSLANG_BYTECODE_PATCH, CROSSLANG_BYTECODE_BUILD,
|
||||
CROSSLANG_BYTECODE_VERSIONSTAGE);
|
||||
});
|
||||
dict->DeclareFunction(gc, "getIsRunning", "Is the program still running",
|
||||
{},
|
||||
[](GCList &ls, std::vector<TObject> args) -> TObject {
|
||||
return Tesses::Framework::TF_IsRunning();
|
||||
});
|
||||
dict->DeclareFunction(gc, "RunEventLoopItteration",
|
||||
"Run Event Loop Itteration", {},
|
||||
[](GCList &ls, std::vector<TObject> args) -> TObject {
|
||||
Tesses::Framework::TF_RunEventLoopItteration();
|
||||
return Undefined();
|
||||
});
|
||||
dict->DeclareFunction(gc, "RunEventLoop", "Run Event Loop", {},
|
||||
[](GCList &ls, std::vector<TObject> args) -> TObject {
|
||||
Tesses::Framework::TF_RunEventLoop();
|
||||
return Undefined();
|
||||
});
|
||||
|
||||
gc->BarrierBegin();
|
||||
|
||||
env->DeclareVariable("VM", dict);
|
||||
|
||||
gc->BarrierEnd();
|
||||
}
|
||||
|
||||
} // namespace Tesses::CrossLang
|
||||
Reference in New Issue
Block a user