diff --git a/lib/libesp32/berry_tasmota/include/be_port.h b/lib/libesp32/berry_tasmota/include/be_port.h new file mode 100644 index 000000000..91e7fe8fa --- /dev/null +++ b/lib/libesp32/berry_tasmota/include/be_port.h @@ -0,0 +1,10 @@ +/******************************************************************** + * Tasmota - constants used in be_port and be_path_tasmota.lib.c + *******************************************************************/ +#define MPATH_MKDIR 0 +#define MPATH_RMDIR 1 +#define MPATH_LISTDIR 2 +#define MPATH_ISDIR 3 +#define MPATH_EXISTS 4 +#define MPATH_MODIFIED 5 +#define MPATH_REMOVE 6 diff --git a/lib/libesp32/berry_tasmota/src/be_path_tasmota_lib.c b/lib/libesp32/berry_tasmota/src/be_path_tasmota_lib.c index 4c327b0ca..1822abcc1 100644 --- a/lib/libesp32/berry_tasmota/src/be_path_tasmota_lib.c +++ b/lib/libesp32/berry_tasmota/src/be_path_tasmota_lib.c @@ -18,48 +18,32 @@ #include "be_sys.h" #include -// from be_port.c -extern int m_path_listdir(bvm *vm); -extern int m_path_mkdir(bvm *vm); -extern int m_path_rmdir(bvm *vm); +// provides MPATH_ constants +#include "be_port.h" -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)); - } else { - be_pushbool(vm, bfalse); - } - be_return(vm); +// from be_port.cpp, becasue it uses c++ +extern int _m_path_action(bvm *vm, int8_t action); + +static int m_path_listdir(bvm *vm){ + return _m_path_action(vm, MPATH_LISTDIR); } -extern time_t be_last_modified(void *hfile); - -static int m_path_last_modified(bvm *vm) -{ - if (be_top(vm) >= 1 && be_isstring(vm, 1)) { - const char *path = be_tostring(vm, 1); - void * f = be_fopen(path, "r"); - if (f) { - be_pushint(vm, be_last_modified(f)); - be_fclose(f); - be_return(vm); - } - } - be_return_nil(vm); +static int m_path_isdir(bvm *vm){ + return _m_path_action(vm, MPATH_ISDIR); } - -static int m_path_remove(bvm *vm) -{ - const char *path = NULL; - if (be_top(vm) >= 1 && be_isstring(vm, 1)) { - path = be_tostring(vm, 1); - be_pushbool(vm, be_unlink(path)); - } else { - be_pushbool(vm, bfalse); - } - be_return(vm); +static int m_path_mkdir(bvm *vm) { + return _m_path_action(vm, MPATH_MKDIR); +} +static int m_path_rmdir(bvm *vm) { + return _m_path_action(vm, MPATH_RMDIR); +} +static int m_path_exists(bvm *vm) { + return _m_path_action(vm, MPATH_EXISTS); +} +static int m_path_last_modified(bvm *vm){ + return _m_path_action(vm, MPATH_MODIFIED); +} +static int m_path_remove(bvm *vm){ + return _m_path_action(vm, MPATH_REMOVE); } extern int be_format_fs(void); @@ -80,6 +64,7 @@ module path (scope: global, file: tasmota_path) { exists, func(m_path_exists) last_modified, func(m_path_last_modified) listdir, func(m_path_listdir) + isdir, func(m_path_isdir) remove, func(m_path_remove) format, func(m_path_format) mkdir, func(m_path_mkdir) diff --git a/lib/libesp32/berry_tasmota/src/be_port.cpp b/lib/libesp32/berry_tasmota/src/be_port.cpp index 4eef6d044..0cfac3573 100644 --- a/lib/libesp32/berry_tasmota/src/be_port.cpp +++ b/lib/libesp32/berry_tasmota/src/be_port.cpp @@ -98,69 +98,111 @@ BERRY_API void be_writebuffer(const char *buffer, size_t length) // be_fwrite(stdout, buffer, length); } - +// provides MPATH_ constants +#include "be_port.h" extern "C" { - int m_path_listdir(bvm *vm) - { + // this combined action is called from be_path_tasmota_lib.c + // by using a single function, we save >200 bytes of flash + // by reducing code repetition. + int _m_path_action(bvm *vm, int8_t action){ #ifdef USE_UFILESYS + // if this changes to not -1, we push it as a bool + int res = -1; + // this tells us to return the vm, not nil + int returnit = 0; + + // comment out if nil return is OK to save some flash + switch (action){ + case MPATH_EXISTS: + case MPATH_REMOVE: + res = 0; + break; + } + if (be_top(vm) >= 1 && be_isstring(vm, 1)) { const char *path = be_tostring(vm, 1); - be_newobject(vm, "list"); - - File dir = ffsp->open(path, "r"); - if (dir) { - dir.rewindDirectory(); - while (1) { - File entry = dir.openNextFile(); - if (!entry) { - break; - } - const char * fn = entry.name(); - if (strcmp(fn, ".") && strcmp(fn, "..")) { - be_pushstring(vm, fn); - be_data_push(vm, -2); - be_pop(vm, 1); - } - - } - } - be_pop(vm, 1); - be_return(vm); - - } -#endif // USE_UFILESYS - be_return_nil(vm); - } - - static int _m_path_mkdir_rmdir(bvm *vm, int remove) { -#ifdef USE_UFILESYS - const char *path = NULL; - if (be_top(vm) >= 1 && be_isstring(vm, 1)) { - path = be_tostring(vm, 1); - int res = 0; if (path != nullptr) { - if (remove) - res = zip_ufsp.rmdir(path); - else - res = zip_ufsp.mkdir(path); - } + switch (action){ + case MPATH_EXISTS: + res = be_isexist(path); + break; + case MPATH_REMOVE: + res = be_unlink(path); + break; + case MPATH_RMDIR: + res = zip_ufsp.rmdir(path); + break; + case MPATH_MKDIR: + res = zip_ufsp.mkdir(path); + break; + case MPATH_LISTDIR: + be_newobject(vm, "list"); // add our list object and fall through + returnit = 1; + case MPATH_ISDIR: + case MPATH_MODIFIED: { + // listdir and isdir both need to open the file. + + // we use be_fopen because it pre-pends with '/'. + // without this TAS fails to find stuff at boot... + File *dir = (File *)be_fopen(path, "r"); + if (dir) { + switch (action){ + case MPATH_LISTDIR: + // fill out the list object + dir->rewindDirectory(); + while (1) { + File entry = dir->openNextFile(); + if (!entry) { + break; + } + const char * fn = entry.name(); + if (strcmp(fn, ".") && strcmp(fn, "..")) { + be_pushstring(vm, fn); + be_data_push(vm, -2); + be_pop(vm, 1); + } + } + break; + case MPATH_ISDIR: + // push bool belowthe only one to push an int, so do it here. + res = dir->isDirectory(); + break; + case MPATH_MODIFIED: + // the only one to push an int, so do it here. + be_pushint(vm, dir->getLastWrite()); + returnit = 1; + break; + } + be_fclose(dir); + } + } break; + } + + // these + switch (action){ + case MPATH_LISTDIR: + // if it was list, pop always + be_pop(vm, 1); + break; + } + } // invalid filename -> nil return + } // not a string, or no arg -> nil return unless see below + + // if we get here, and it was exists or remove, return false always + // i.e. it's false for no filename or null filename. + + // if it was a boolean result + if (res != -1){ be_pushbool(vm, res); - } else { - be_pushbool(vm, bfalse); + returnit = 1; } - be_return(vm); -#else // USE_UFILESYS - be_return_nil(vm); + if (returnit){ + be_return(vm); + } + #endif // USE_UFILESYS + be_return_nil(vm); } - - int m_path_mkdir(bvm *vm) { - return _m_path_mkdir_rmdir(vm, 0); - } - int m_path_rmdir(bvm *vm) { - return _m_path_mkdir_rmdir(vm, 1); - } - } BERRY_API char* be_readstring(char *buffer, size_t size)