Tasmota/lib/libesp32/Berry/src/be_oslib.c
2021-04-12 19:53:35 +02:00

272 lines
6.9 KiB
C

/********************************************************************
** Copyright (c) 2018-2020 Guan Wenliang
** This file is part of the Berry default interpreter.
** skiars@qq.com, https://github.com/Skiars/berry
** See Copyright Notice in the LICENSE file or at
** https://github.com/Skiars/berry/blob/master/LICENSE
********************************************************************/
#include "be_object.h"
#include "be_strlib.h"
#include "be_mem.h"
#include "be_sys.h"
#include <string.h>
#include <stdlib.h>
#define FNAME_BUF_SIZE 512
#if BE_USE_OS_MODULE
#if !BE_USE_FILE_SYSTEM
#error the dependent macro BE_USE_FILE_SYSTEM must be enabled
#endif
static int m_getcwd(bvm *vm)
{
char *buf = be_malloc(vm, FNAME_BUF_SIZE);
if (be_getcwd(buf, FNAME_BUF_SIZE)) {
be_pushstring(vm, buf);
} else {
be_pushstring(vm, "");
}
be_free(vm, buf, FNAME_BUF_SIZE);
be_return(vm);
}
static int m_chdir(bvm *vm)
{
if (be_top(vm) >= 1 && be_isstring(vm, 1)) {
int res = be_chdir(be_tostring(vm, 1));
be_pushbool(vm, res == 0);
}
be_return(vm);
}
static int m_mkdir(bvm *vm)
{
int res = 1;
if (be_top(vm) >= 1 && be_isstring(vm, 1)) {
res = be_mkdir(be_tostring(vm, 1));
}
be_pushbool(vm, res == 0);
be_return(vm);
}
static int m_remove(bvm *vm)
{
int res = 1;
if (be_top(vm) >= 1 && be_isstring(vm, 1)) {
res = be_unlink(be_tostring(vm, 1));
}
be_pushbool(vm, res == 0);
be_return(vm);
}
static int m_listdir(bvm *vm)
{
int res;
bdirinfo info;
if (be_top(vm) >= 1 && be_isstring(vm, 1)) {
res = be_dirfirst(&info, be_tostring(vm, 1));
} else {
res = be_dirfirst(&info, ".");
}
be_newobject(vm, "list");
while (res == 0) {
const char *fn = info.name;
if (strcmp(fn, ".") && strcmp(fn, "..")) {
be_pushstring(vm, fn);
be_data_push(vm, -2);
be_pop(vm, 1);
}
res = be_dirnext(&info);
}
be_dirclose(&info);
be_pop(vm, 1);
be_return(vm);
}
static int m_system(bvm *vm)
{
int res = -1, i, argc = be_top(vm);
if (argc > 0) {
be_tostring(vm, 1);
be_pushstring(vm, " ");
for (i = 2; i <= argc; ++i) {
be_strconcat(vm, 1); /* add " " */
be_tostring(vm, i);
be_pushvalue(vm, i);
be_strconcat(vm, 1); /* concat arg */
be_pop(vm, 1);
}
be_pop(vm, argc);
res = system(be_tostring(vm, 1));
}
be_pushint(vm, res);
be_return(vm);
}
static int m_exit(bvm *vm)
{
int status = 0;
if (be_top(vm)) {
if (be_isint(vm, 1)) {
status = be_toindex(vm, 1); /* get the exit code */
} else if (be_isbool(vm, 1)) {
status = be_tobool(vm, 1) - 1; /* true: 0, false: -1 */
} else {
status = -1;
}
}
be_exit(vm, status);
be_return_nil(vm);
}
static int m_path_isdir(bvm *vm)
{
const char *path = NULL;
if (be_top(vm) >= 1 && be_isstring(vm, 1)) {
path = be_tostring(vm, 1);
}
be_pushbool(vm, be_isdir(path));
be_return(vm);
}
static int m_path_isfile(bvm *vm)
{
const char *path = NULL;
if (be_top(vm) >= 1 && be_isstring(vm, 1)) {
path = be_tostring(vm, 1);
}
be_pushbool(vm, be_isfile(path));
be_return(vm);
}
static int m_path_split(bvm *vm)
{
if (be_top(vm) >= 1 && be_isstring(vm, 1)) {
const char *path = be_tostring(vm, 1);
const char *split = be_splitpath(path);
size_t len = split - path;
if (split > path + 1 && split[-1] == '/') {
const char *p = split - 1;
for (; p >= path && *p == '/'; --p);
if (p >= path) {
len = p - path + 1;
}
}
be_getbuiltin(vm, "list");
be_pushnstring(vm, path, len);
be_pushstring(vm, split);
be_call(vm, 2);
be_return(vm);
}
be_return_nil(vm);
}
static int m_path_splitext(bvm *vm)
{
if (be_top(vm) >= 1 && be_isstring(vm, 1)) {
const char *path = be_tostring(vm, 1);
const char *split = be_splitname(path);
be_getbuiltin(vm, "list");
be_pushnstring(vm, path, split - path);
be_pushstring(vm, split);
be_call(vm, 2);
be_return(vm);
}
be_return_nil(vm);
}
static int m_path_exists(bvm *vm)
{
const char *path = NULL;
if (be_top(vm) >= 1 && be_isstring(vm, 1)) {
path = be_tostring(vm, 1);
}
be_pushbool(vm, be_isexist(path));
be_return(vm);
}
static int m_path_join(bvm *vm)
{
char *buf, *p;
int i, len = 0, argc = be_top(vm);
for (i = 1; i <= argc; ++i) {
if (be_isstring(vm, i)) {
len += be_strlen(vm, i) + 1;
} else {
be_raise(vm, "type_error", "arguments must be string");
}
}
buf = p = be_malloc(vm, (size_t)len + 1);
for (i = 1; i <= argc; ++i) {
int l = be_strlen(vm, i);
const char *s = be_tostring(vm, i);
if (s[0] == '/') {
p = buf;
}
strcpy(p, s);
p += l;
if (l && s[l - 1] != '/' && i != argc) {
*p++ = '/';
}
}
be_pushnstring(vm, buf, p - buf);
be_free(vm, buf, (size_t)len + 1);
be_return(vm);
}
#if !BE_USE_PRECOMPILED_OBJECT
be_native_module_attr_table(path) {
be_native_module_function("isdir", m_path_isdir),
be_native_module_function("isfile", m_path_isfile),
be_native_module_function("exists", m_path_exists),
be_native_module_function("split", m_path_split),
be_native_module_function("splitext", m_path_splitext),
be_native_module_function("join", m_path_join)
};
static be_define_native_module(path, NULL);
be_native_module_attr_table(os) {
be_native_module_function("getcwd", m_getcwd),
be_native_module_function("chdir", m_chdir),
be_native_module_function("mkdir", m_mkdir),
be_native_module_function("remove", m_remove),
be_native_module_function("listdir", m_listdir),
be_native_module_function("system", m_system),
be_native_module_function("exit", m_exit),
be_native_module_module("path", be_native_module(path))
};
be_define_native_module(os, NULL);
#else
/* @const_object_info_begin
module path (scope: local, file: os_path, depend: BE_USE_OS_MODULE) {
isdir, func(m_path_isdir)
isfile, func(m_path_isfile)
exists, func(m_path_exists)
split, func(m_path_split)
splitext, func(m_path_splitext)
join, func(m_path_join)
}
@const_object_info_end */
#include "../generate/be_fixed_os_path.h"
/* @const_object_info_begin
module os (scope: global, depend: BE_USE_OS_MODULE) {
getcwd, func(m_getcwd)
chdir, func(m_chdir)
mkdir, func(m_mkdir)
remove, func(m_remove)
listdir, func(m_listdir)
system, func(m_system)
exit, func(m_exit)
path, module(m_libpath)
}
@const_object_info_end */
#include "../generate/be_fixed_os.h"
#endif
#endif /* BE_USE_OS_MODULE */