Move fs.basename and fs.dirname into the path library, create errors.h

This commit is contained in:
Jeremy Baxter 2023-08-10 08:14:05 +12:00
parent 18597a772e
commit 7ff02fbbb1
6 changed files with 142 additions and 95 deletions

98
lpath.c Normal file
View file

@ -0,0 +1,98 @@
/***
* File system path manipulation.
* @module path
*/
#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
#include <libgen.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <lua.h>
#include <lauxlib.h>
#include "callisto.h"
#include "errors.h"
#include "util.h"
/***
* Returns the last component of the given pathname,
* removing any trailing '/' characters. If the given
* path consists entirely of '/' characters, the string
* `"/"` is returned. If *path* is an empty string,
* the string `"."` is returned.
*
* This function may return nil if the given
* pathname exceeds the system's path length
* limit (On most Linux systems this will be 4096).
*
* @function basename
* @usage path.basename(arg[0])
* @tparam string path The path to process.
*/
static int
path_basename(lua_State *L)
{
const char *ret;
char *path; /* parameter 1 (string) */
path = strndup(luaL_checkstring(L, 1), lua_rawlen(L, 1));
ret = basename(path);
if (ret == NULL && errno == ENAMETOOLONG) /* check if path is too long */
return lfail(L, E_PATHNAMETOOLONG);
lua_pushstring(L, ret);
return 1;
}
/***
* Returns the parent directory of the pathname
* given. Any trailing '/' characters are not
* counted as part of the directory name.
* If the given path is an empty string or contains
* no '/' characters, the string `"."` is returned,
* signifying the current directory.
*
* This function may return nil if the given
* pathname exceeds the system's path length
* limit (On most Linux systems this will be 4096).
*
* @function dirname
* @usage path.dirname(arg[0])
* @tparam string path The path to process.
*/
static int
path_dirname(lua_State *L)
{
const char *ret;
char *path; /* parameter 1 (string) */
path = strndup(luaL_checkstring(L, 1), lua_rawlen(L, 1));
ret = dirname(path);
if (ret == NULL && errno == ENAMETOOLONG) /* check if path is too long */
return lfail(L, E_PATHNAMETOOLONG);
lua_pushstring(L, ret);
return 1;
}
static const luaL_Reg pathlib[] = {
{"basename", path_basename},
{"dirname", path_dirname},
{NULL, NULL}
};
int
luaopen_path(lua_State *L)
{
luaL_newlib(L, pathlib);
return 1;
}