mirror of
https://github.com/ValKmjolnir/Nasal-Interpreter.git
synced 2026-05-24 13:35:43 +08:00
✨ split dylib and unix lib
This commit is contained in:
146
src/unix_lib.cpp
146
src/unix_lib.cpp
@@ -1,5 +1,151 @@
|
||||
#include "unix_lib.h"
|
||||
|
||||
const auto dir_type_name = "dir";
|
||||
|
||||
void dir_entry_destructor(void* ptr) {
|
||||
#ifndef _MSC_VER
|
||||
closedir((DIR*)ptr);
|
||||
#else
|
||||
FindClose(ptr);
|
||||
#endif
|
||||
}
|
||||
|
||||
var builtin_pipe(var* local, gc& ngc) {
|
||||
#ifndef _WIN32
|
||||
i32 fd[2];
|
||||
var res = ngc.alloc(vm_vec);
|
||||
if (pipe(fd)==-1) {
|
||||
return nas_err("pipe", "failed to create pipe");
|
||||
}
|
||||
res.vec().elems.push_back(var::num((f64)fd[0]));
|
||||
res.vec().elems.push_back(var::num((f64)fd[1]));
|
||||
return res;
|
||||
#endif
|
||||
return nas_err("pipe", "not supported");
|
||||
}
|
||||
|
||||
var builtin_fork(var* local, gc& ngc) {
|
||||
#ifndef _WIN32
|
||||
f64 res=fork();
|
||||
if (res<0) {
|
||||
return nas_err("fork", "failed to fork a process");
|
||||
}
|
||||
return var::num((f64)res);
|
||||
#endif
|
||||
return nas_err("fork", "not supported");
|
||||
}
|
||||
|
||||
var builtin_waitpid(var* local, gc& ngc) {
|
||||
var pid = local[1];
|
||||
var nohang = local[2];
|
||||
if (pid.type!=vm_num || nohang.type!=vm_num) {
|
||||
return nas_err("waitpid", "pid and nohang must be number");
|
||||
}
|
||||
#ifndef _WIN32
|
||||
i32 ret_pid,status;
|
||||
ret_pid = waitpid(pid.num(),&status,nohang.num()==0? 0:WNOHANG);
|
||||
var vec = ngc.alloc(vm_vec);
|
||||
vec.vec().elems.push_back(var::num((f64)ret_pid));
|
||||
vec.vec().elems.push_back(var::num((f64)status));
|
||||
return vec;
|
||||
#endif
|
||||
return nas_err("waitpid", "not supported");
|
||||
}
|
||||
|
||||
var builtin_opendir(var* local, gc& ngc) {
|
||||
var path = local[1];
|
||||
if (path.type!=vm_str) {
|
||||
return nas_err("opendir", "\"path\" must be string");
|
||||
}
|
||||
#ifdef _MSC_VER
|
||||
WIN32_FIND_DATAA data;
|
||||
HANDLE p;
|
||||
p = FindFirstFileA((path.str()+"\\*.*").c_str(),&data);
|
||||
if (p==INVALID_HANDLE_VALUE) {
|
||||
return nas_err("opendir", "cannot open dir <"+path.str()+">");
|
||||
}
|
||||
#else
|
||||
DIR* p = opendir(path.str().c_str());
|
||||
if (!p) {
|
||||
return nas_err("opendir", "cannot open dir <"+path.str()+">");
|
||||
}
|
||||
#endif
|
||||
var ret = ngc.alloc(vm_obj);
|
||||
ret.obj().set(dir_type_name, dir_entry_destructor, p);
|
||||
return ret;
|
||||
}
|
||||
|
||||
var builtin_readdir(var* local, gc& ngc) {
|
||||
var handle = local[1];
|
||||
if (!handle.objchk(dir_type_name)) {
|
||||
return nas_err("readdir", "not a valid dir handle");
|
||||
}
|
||||
#ifdef _MSC_VER
|
||||
WIN32_FIND_DATAA data;
|
||||
if (!FindNextFileA(handle.obj().ptr,&data)) {
|
||||
return nil;
|
||||
}
|
||||
return ngc.newstr(data.cFileName);
|
||||
#else
|
||||
dirent* p = readdir((DIR*)handle.obj().ptr);
|
||||
return p? ngc.newstr(p->d_name):nil;
|
||||
#endif
|
||||
}
|
||||
|
||||
var builtin_closedir(var* local, gc& ngc) {
|
||||
var handle = local[1];
|
||||
if (!handle.objchk(dir_type_name)) {
|
||||
return nas_err("closedir", "not a valid dir handle");
|
||||
}
|
||||
handle.obj().clear();
|
||||
return nil;
|
||||
}
|
||||
|
||||
var builtin_chdir(var* local, gc& ngc) {
|
||||
var path = local[1];
|
||||
if (path.type!=vm_str) {
|
||||
return var::num((f64)-1);
|
||||
}
|
||||
return var::num((f64)chdir(path.str().c_str()));
|
||||
}
|
||||
|
||||
var builtin_environ(var* local, gc& ngc) {
|
||||
var res = ngc.temp = ngc.alloc(vm_vec);
|
||||
auto& vec = res.vec().elems;
|
||||
for(char** env = environ; *env; ++env) {
|
||||
vec.push_back(ngc.newstr(*env));
|
||||
}
|
||||
ngc.temp = nil;
|
||||
return res;
|
||||
}
|
||||
|
||||
var builtin_getcwd(var* local, gc& ngc) {
|
||||
char buf[1024];
|
||||
if (!getcwd(buf, sizeof(buf))) {
|
||||
return nil;
|
||||
}
|
||||
return ngc.newstr(buf);
|
||||
}
|
||||
|
||||
var builtin_getenv(var* local, gc& ngc) {
|
||||
var envvar = local[1];
|
||||
if (envvar.type!=vm_str) {
|
||||
return nas_err("getenv", "\"envvar\" must be string");
|
||||
}
|
||||
char* res = getenv(envvar.str().c_str());
|
||||
return res? ngc.newstr(res):nil;
|
||||
}
|
||||
|
||||
nasal_builtin_table unix_lib_native[] = {
|
||||
{"__pipe", builtin_pipe},
|
||||
{"__fork", builtin_fork},
|
||||
{"__waitpid", builtin_waitpid},
|
||||
{"__opendir", builtin_opendir},
|
||||
{"__readdir", builtin_readdir},
|
||||
{"__closedir", builtin_closedir},
|
||||
{"__chdir", builtin_chdir},
|
||||
{"__environ", builtin_environ},
|
||||
{"__getcwd", builtin_getcwd},
|
||||
{"__getenv", builtin_getenv},
|
||||
{nullptr, nullptr}
|
||||
};
|
||||
Reference in New Issue
Block a user