lua+js: implement utils.file_info()

This commit introduces mp.utils.file_info() for querying information
on file paths, implemented for both Lua and Javascript.

The function takes a file path as an argument and returns a Lua table /
JS object upon success. The table/object will contain the values:
mode, size, atime, mtime, ctime and the convenience booleans is_file, is_dir.

On error, the Lua side will return `nil, error` and the Javascript side
will return `undefined` (and mark the last error).

This feature utilizes the already existing cross-platform `mp_stat()`
function.
This commit is contained in:
TSaaristo
2017-12-11 23:04:51 +02:00
committed by Jan Ekström
parent 47131365a3
commit 522bfe5be1
4 changed files with 109 additions and 0 deletions

View File

@@ -836,6 +836,41 @@ static void script_readdir(js_State *J, void *af)
}
}
static void script_file_info(js_State *J)
{
const char *path = js_tostring(J, 1);
struct stat statbuf;
if (stat(path, &statbuf) != 0) {
push_failure(J, "Cannot stat path");
return;
}
// Clear last error
set_last_error(jctx(J), 0, NULL);
const char * stat_names[] = {
"mode", "size",
"atime", "mtime", "ctime", NULL
};
const double stat_values[] = {
statbuf.st_mode,
statbuf.st_size,
statbuf.st_atime,
statbuf.st_mtime,
statbuf.st_ctime
};
// Create an object and add all fields
push_nums_obj(J, stat_names, stat_values);
// Convenience booleans
js_pushboolean(J, S_ISREG(statbuf.st_mode));
js_setproperty(J, -2, "is_file");
js_pushboolean(J, S_ISDIR(statbuf.st_mode));
js_setproperty(J, -2, "is_dir");
}
static void script_split_path(js_State *J)
{
const char *p = js_tostring(J, 1);
@@ -1255,6 +1290,7 @@ static const struct fn_entry main_fns[] = {
static const struct fn_entry utils_fns[] = {
AF_ENTRY(readdir, 2),
FN_ENTRY(file_info, 1),
FN_ENTRY(split_path, 1),
AF_ENTRY(join_path, 2),
AF_ENTRY(get_user_path, 1),

View File

@@ -1085,6 +1085,48 @@ static int script_readdir(lua_State *L)
return 1;
}
static int script_file_info(lua_State *L)
{
const char *path = luaL_checkstring(L, 1);
struct stat statbuf;
if (stat(path, &statbuf) != 0) {
lua_pushnil(L);
lua_pushstring(L, "error");
return 2;
}
lua_newtable(L); // Result stat table
const char * stat_names[] = {
"mode", "size",
"atime", "mtime", "ctime", NULL
};
const unsigned int stat_values[] = {
statbuf.st_mode,
statbuf.st_size,
statbuf.st_atime,
statbuf.st_mtime,
statbuf.st_ctime
};
// Add all fields
for (int i = 0; stat_names[i]; i++) {
lua_pushinteger(L, stat_values[i]);
lua_setfield(L, -2, stat_names[i]);
}
// Convenience booleans
lua_pushboolean(L, S_ISREG(statbuf.st_mode));
lua_setfield(L, -2, "is_file");
lua_pushboolean(L, S_ISDIR(statbuf.st_mode));
lua_setfield(L, -2, "is_dir");
// Return table
return 1;
}
static int script_split_path(lua_State *L)
{
const char *p = luaL_checkstring(L, 1);
@@ -1291,6 +1333,7 @@ static const struct fn_entry main_fns[] = {
static const struct fn_entry utils_fns[] = {
FN_ENTRY(readdir),
FN_ENTRY(file_info),
FN_ENTRY(split_path),
FN_ENTRY(join_path),
FN_ENTRY(subprocess),