diff --git a/scripts/test.py b/scripts/test.py index b3a4dd9..219a1ad 100755 --- a/scripts/test.py +++ b/scripts/test.py @@ -158,6 +158,9 @@ def __init__(self): os.chdir(output_path+"/unit") os.mkdir("valid_dir") open("valid_file","w").close() + filewithsize = open("file_18b","w") + filewithsize.write( "0123456789abcdef01" ) + filewithsize.close() for test in tests: f = open("bam.lua", "w") @@ -222,7 +225,7 @@ def __init__(self): os.mkdir(os.path.join(output_path, "unit")) # run smaller unit tests -if len(tests) == 0: +if len(tests) == 0 or "unittests" in tests: unittests() # run bigger test cases diff --git a/src/base.lua b/src/base.lua index dcde6f5..de4b184 100644 --- a/src/base.lua +++ b/src/base.lua @@ -22,6 +22,20 @@ IsFile = bam_isfile err=0 : if bam_fileexist("invalid_file") then error("") end @END]]-- Exist = bam_fileexist + +--[[@UNITTESTS + err=0 : if bam_filesize("file_18b") ~= 18 then error("") end + err=0 : if bam_filesize("invalid_file") ~= nil then error("") end +@END]]-- +GetFileSize = bam_filesize + +-- unit test here is just later than time of writing, but before twice that (2080 something) +--[[@UNITTESTS + err=0 : if bam_filetimestamp("valid_file") < 1749565586.0 then error("") end + err=0 : if bam_filetimestamp("valid_file") > (1749565586.0 * 2) then error("") end +@END]]-- +GetFileTimeStamp = bam_filetimestamp + NodeExist = bam_nodeexist SetFilter = bam_set_filter AddOutput = bam_add_output @@ -402,11 +416,23 @@ CollectDirs = bam_collectdirs @END]]-- CollectDirsRecursive = bam_collectdirsrecursive +-- bam_isdir is already tested above, so we can use it to verify mkdir/rmdir +--[[@UNITTESTS + err=0 : if not bam_mkdir("mkdir_unittest_dir") then error("") end + err=0 : if not bam_isdir("mkdir_unittest_dir") then error("") end + err=0 : if not bam_rmdir("mkdir_unittest_dir") then error("") end + err=0 : if bam_isdir("mkdir_unittest_dir") then error("") end +@END]]-- --[[@FUNCTION MakeDirectory(path) Creates the requested directory. @END]]-- MakeDirectory = bam_mkdir +--[[@FUNCTION RemoveDirectory(path) + Removes the directory (if empty) +@END]]-- +RemoveDirectory = bam_rmdir + --[[@FUNCTION MakeDirectories(filename) Creates the path upto the filename. diff --git a/src/luafuncs.c b/src/luafuncs.c index 90bb395..1ef5015 100644 --- a/src/luafuncs.c +++ b/src/luafuncs.c @@ -592,6 +592,16 @@ int lf_mkdir(struct lua_State *L) return 1; } +int lf_rmdir(struct lua_State *L) +{ + luaL_checknumarg_eq(L, 1); + if(file_removedir(luaL_checklstring(L,1,NULL)) == 0) + lua_pushboolean(L, 1); + else + lua_pushnil(L); + return 1; +} + int lf_mkdirs(struct lua_State *L) { luaL_checknumarg_eq(L, 1); @@ -633,6 +643,29 @@ int lf_isdir(struct lua_State *L) return 1; } +int lf_filetimestamp(struct lua_State * L) { + luaL_checknumarg_eq(L, 1); + + time_t timestamp = file_timestamp(luaL_checklstring(L, 1, NULL)); + if (timestamp != 0) + lua_pushnumber(L, (LUA_NUMBER)timestamp); + else + lua_pushnil(L); + return 1; +} + +int lf_filesize(struct lua_State * L) { + luaL_checknumarg_eq(L, 1); + time_t timestamp = 0; + unsigned int isregular = 0; + unsigned int isdir = 0; + uint64 size = 0; + if(file_stat( luaL_checklstring(L, 1, NULL), ×tamp, &isregular, &isdir, &size) == 0 ) + lua_pushnumber(L, (LUA_NUMBER)size); + else + lua_pushnil(L); + return 1; +} int lf_istable(lua_State *L) { diff --git a/src/luafuncs.h b/src/luafuncs.h index 17836a5..065f01a 100644 --- a/src/luafuncs.h +++ b/src/luafuncs.h @@ -51,10 +51,13 @@ int lf_path_hash(struct lua_State *L); /* support, files and dirs */ int lf_mkdir(struct lua_State *L); +int lf_rmdir(struct lua_State *L); int lf_mkdirs(struct lua_State *L); int lf_fileexist(struct lua_State *L); int lf_isdir(struct lua_State *L); int lf_isfile(struct lua_State *L); +int lf_filetimestamp(struct lua_State * L); +int lf_filesize(struct lua_State * L); /* table functions*/ int lf_table_walk(struct lua_State *L); diff --git a/src/main.c b/src/main.c index 2bbc70a..f44a8d1 100644 --- a/src/main.c +++ b/src/main.c @@ -410,8 +410,11 @@ int register_lua_globals(struct lua_State *lua, const char* script_directory, co lua_register(lua, L_FUNCTION_PREFIX"loadfile", lf_loadfile); lua_register(lua, L_FUNCTION_PREFIX"mkdir", lf_mkdir); + lua_register(lua, L_FUNCTION_PREFIX"rmdir", lf_rmdir); lua_register(lua, L_FUNCTION_PREFIX"mkdirs", lf_mkdirs); lua_register(lua, L_FUNCTION_PREFIX"fileexist", lf_fileexist); + lua_register(lua, L_FUNCTION_PREFIX"filetimestamp", lf_filetimestamp); + lua_register(lua, L_FUNCTION_PREFIX"filesize", lf_filesize); lua_register(lua, L_FUNCTION_PREFIX"nodeexist", lf_nodeexist); lua_register(lua, L_FUNCTION_PREFIX"hash", lf_hash); lua_register(lua, L_FUNCTION_PREFIX"sleep", lf_sleep); diff --git a/src/statcache.c b/src/statcache.c index 96565d5..7752bdb 100644 --- a/src/statcache.c +++ b/src/statcache.c @@ -59,7 +59,8 @@ struct STATCACHE_ENTRY* statcache_getstat_int(struct STATCACHE* statcache, const entry->hashid = namehash; unsigned int isregular = 0; unsigned int isdir = 0; - if(file_stat(filename, &entry->timestamp, &isregular, &isdir) == 0) + uint64 size = 0; + if(file_stat(filename, &entry->timestamp, &isregular, &isdir, &size) == 0) { entry->isregular = isregular; entry->isdir = isdir; diff --git a/src/support.c b/src/support.c index ed0601b..30aaeb3 100644 --- a/src/support.c +++ b/src/support.c @@ -474,7 +474,7 @@ time_t timestamp() { return time(NULL); } -int file_stat(const char *filename, time_t* stamp, unsigned int* isregular, unsigned int* isdir) +int file_stat(const char *filename, time_t* stamp, unsigned int* isregular, unsigned int* isdir, uint64* size) { #ifdef BAM_FAMILY_WINDOWS struct _stati64 s; @@ -483,11 +483,13 @@ int file_stat(const char *filename, time_t* stamp, unsigned int* isregular, unsi *stamp = 0; *isregular = 0; *isdir = 0; + *size = 0; return 1; } *stamp = s.st_mtime; *isregular = (s.st_mode&_S_IFREG) != 0; *isdir = (s.st_mode&_S_IFDIR) != 0; + *size = s.st_size; #else struct stat s; if (stat(filename, &s) != 0) @@ -495,16 +497,19 @@ int file_stat(const char *filename, time_t* stamp, unsigned int* isregular, unsi *stamp = 0; *isregular = 0; *isdir = 0; + *size = 0; return 1; } #if defined(BAM_PLATFORM_MACOSX) *stamp = s.st_mtimespec.tv_sec; *isregular = S_ISREG(s.st_mode); *isdir = S_ISDIR(s.st_mode); + *size = s.st_size; #else *stamp = s.st_mtime; *isregular = S_ISREG(s.st_mode); *isdir = S_ISDIR(s.st_mode); + *size = s.st_size; #endif #endif return 0; @@ -514,17 +519,30 @@ time_t file_timestamp(const char * filename) { unsigned int isregular = 0; unsigned int isdir = 0; time_t timestamp; - if (file_stat(filename, ×tamp, &isregular, &isdir) == 0) + uint64 size = 0; + if (file_stat(filename, ×tamp, &isregular, &isdir, &size) == 0) return timestamp; else return 0; } +time_t file_size(const char * filename) { + unsigned int isregular = 0; + unsigned int isdir = 0; + time_t timestamp; + uint64 size = 0; + if (file_stat(filename, ×tamp, &isregular, &isdir, &size) == 0) + return size; + else + return 0; +} + int file_isregular(const char * filename) { unsigned int isregular = 0; unsigned int isdir = 0; time_t timestamp; - if (file_stat(filename, ×tamp, &isregular, &isdir) == 0) + uint64 size = 0; + if (file_stat(filename, ×tamp, &isregular, &isdir, &size) == 0) return isregular; else return 0; @@ -534,7 +552,8 @@ int file_isdir(const char * filename) { unsigned int isregular = 0; unsigned int isdir = 0; time_t timestamp; - if (file_stat(filename, ×tamp, &isregular, &isdir) == 0) + uint64 size = 0; + if (file_stat(filename, ×tamp, &isregular, &isdir, &size) == 0) return isdir; else return 0; @@ -553,6 +572,19 @@ int file_createdir(const char *path) return -1; } +int file_removedir(const char *path) +{ + int r; +#ifdef BAM_FAMILY_WINDOWS + r = _rmdir(path); +#else + r = rmdir(path); +#endif + if(r == 0 || errno == EEXIST) + return 0; + return -1; +} + void file_touch(const char *filename) { #ifdef BAM_FAMILY_WINDOWS diff --git a/src/support.h b/src/support.h index 08b4d3b..7b96344 100644 --- a/src/support.h +++ b/src/support.h @@ -8,9 +8,11 @@ /* if compiled with -pedantic-errors it will complain about long long not being a C90 thing. */ __extension__ typedef unsigned long long hash_t; __extension__ typedef long long int64; + __extension__ typedef unsigned long long uint64; #else typedef unsigned long long hash_t; typedef long long int64; + typedef unsigned long long uint64; #endif #if defined(__GNUC__) @@ -66,8 +68,9 @@ time_t timestamp(); time_t file_timestamp(const char *filename); int file_isregular(const char *path); int file_isdir(const char *path); -int file_stat(const char *filename, time_t* stamp, unsigned int* isregular, unsigned int* isdir); +int file_stat(const char *filename, time_t* stamp, unsigned int* isregular, unsigned int* isdir, uint64* size); int file_createdir(const char *path); +int file_removedir(const char *path); int file_createpath(const char *output_name); void file_touch(const char *filename); void file_listdirectory(const char *path, void (*callback)(const char *fullpath, const char *filename, int dir, void *user), void *user);