Updated Path. Some work towards loading dirs.

This commit is contained in:
Christoffer Lerno
2023-03-11 18:32:44 +01:00
parent 7a2d73c690
commit 2607062cb6
6 changed files with 114 additions and 15 deletions

View File

@@ -29,6 +29,7 @@ fault IoError
OUT_OF_DISK,
INVALID_PUSHBACK,
EOF,
CANNOT_READ_DIR,
TOO_MANY_DESCRIPTORS,
FILE_IS_DIR,
READ_ONLY,

View File

@@ -1,10 +1,13 @@
module std::io::path;
import std::collections::list;
const PathEnv DEFAULT_PATH_ENV = env::os_is_win32() ? PathEnv.WIN32 : PathEnv.POSIX;
const char PREFERRED_SEPARATOR_WIN32 = '\\';
const char PREFERRED_SEPARATOR_POSIX = '/';
const char PREFERRED_SEPARATOR = env::os_is_win32() ? PREFERRED_SEPARATOR_WIN32 : PREFERRED_SEPARATOR_POSIX;
typedef PathList = List<Path>;
fault PathResult
{
INVALID_PATH,
@@ -100,6 +103,8 @@ fn Path! Path.append(Path path, String filename, Allocator* using = mem::heap())
};
}
fn Path! Path.tappend(Path path, String filename) => path.append(filename, mem::temp());
fn Path! temp_directory(Allocator* using = mem::heap())
{
return os::native_temp_directory(using);
@@ -214,8 +219,25 @@ fn String! normalize(String path_str, PathEnv path_env = DEFAULT_PATH_ENV)
i++;
continue;
case 2:
// We're walking back, doing so when already at the root is invalid.
if (len == path_start) return PathResult.INVALID_PATH!;
// This is an error: /a/../..
if (len == path_start && has_root) return PathResult.INVALID_PATH!;
// If this .. at the start, or after ../? If so, we just copy ..
if (len == path_start ||
(len - path_start >= 3 && path_str[len - 1] == path_separator
&& path_str[len - 3] == '.' && path_str[len - 3] == '.' &&
(len - 3 == 0 || path_str[len - 4] == path_separator)))
{
if (i != len)
{
path_str[len] = '.';
path_str[len + 1] = '.';
}
len += 2;
if (len < path_len) path_str[len++] = path_separator;
i += 2;
continue;
}
// Step back, now looking at '/' abc/def/. -> abc/def/
len--;
// Step back until finding a separator or the start.
@@ -241,6 +263,8 @@ fn String! normalize(String path_str, PathEnv path_env = DEFAULT_PATH_ENV)
return path_str[:len];
}
fn ZString Path.as_zstr(Path path) => (ZString)path.path_string.ptr;
fn String Path.root_directory(Path path)
{
String path_str = path.as_str();

View File

@@ -3,6 +3,7 @@ import libc;
$if (env::os_is_darwin()):
struct DarwinTimespec @private
{
long tv_sec;

View File

@@ -13,6 +13,40 @@ fn Path! native_temp_directory(Allocator* using = mem::heap())
return path::new("/tmp", using);
}
$if (env::COMPILER_LIBC_AVAILABLE):
extern fn void* opendir(ZString);
extern fn void closedir(void*);
const DT_UNKNOWN = 0;
const DT_FIFO = 1;
const DT_CHR = 2;
const DT_DIR = 4;
const DT_BLK = 6;
const DT_REG = 8;
const DT_LNK = 10;
const DT_SOCK = 12;
const DT_WHT = 14;
fn void! native_readdir(PathList* list, Path dir, bool no_dirs, bool no_symlinks, String mask, Allocator* using)
{
void* directory = opendir(dir.as_str() ? dir.as_zstr() : (ZString)".");
defer if (directory) closedir(directory);
if (!directory) return (dir.is_dir() ? IoError.CANNOT_READ_DIR : IoError.FILE_NOT_DIR)!;
NativeDirentry* entry;
while ((entry = readdir(directory)))
{
String name = ((ZString)&entry.name).as_str();
if (!name || name == "." || name == "..") continue;
if (entry.type == DT_LNK && no_symlinks) continue;
if (entry.type == DT_DIR && no_dirs) continue;
Path path = path::new(name.copy(using), using)!!;
list.append(path);
}
}
$endif;
$endif;
$if (!env::os_is_darwin() && !env::os_is_win32()):
@@ -67,4 +101,42 @@ fn bool native_is_file(String path)
$endif;
$endif;
$endif;
$switch (env::OS_TYPE):
$case IOS:
$case MACOSX:
$case TVOS:
$case WATCHOS:
extern fn NativeDirentry* readdir(void*) @extern("readdir$INODE64");
struct NativeDirentry
{
usz ino;
usz seekoff;
ushort reclen;
ushort namelen;
char type;
char[1024] name;
}
$case LINUX:
extern fn NativeDirentry* readdir(void*);
struct NativeDirentry
{
usz ino;
isz seekoff;
ushort reclen;
char type;
char[*] name;
}
$default:
// Fix this as we go along.
extern fn NativeDirentry* readdir(void*);
struct NativeDirentry
{
usz ino;
isz seekoff;
ushort reclen;
char type;
char[*] name;
}
$endswitch;