From d5b01d3a8f0db59f4a51057a9bf9bb4985d2a309 Mon Sep 17 00:00:00 2001 From: Christoffer Lerno Date: Mon, 19 Jun 2023 17:27:04 +0200 Subject: [PATCH] Native ls --- .github/workflows/main.yml | 2 ++ lib/std/io/os/fileinfo_other.c3 | 4 +-- lib/std/io/os/fileinfo_win32.c3 | 61 +++++++++++++++------------------ lib/std/io/path.c3 | 14 +++++--- lib/std/os/win32/files.c3 | 23 ++++++++++++- resources/examples/ls.c3 | 10 ++++++ 6 files changed, 73 insertions(+), 41 deletions(-) create mode 100644 resources/examples/ls.c3 diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index f021e1a63..2a32bb92f 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -39,6 +39,7 @@ jobs: ..\build\${{ matrix.build_type }}\c3c.exe compile-run examples\contextfree\boolerr.c3 ..\build\${{ matrix.build_type }}\c3c.exe compile-run examples\load_world.c3 ..\build\${{ matrix.build_type }}\c3c.exe compile-run examples\process.c3 + ..\build\${{ matrix.build_type }}\c3c.exe compile-run examples\ls.c3 - name: Build testproject @@ -256,6 +257,7 @@ jobs: ../build/c3c compile-run examples/contextfree/boolerr.c3 ../build/c3c compile-run examples/load_world.c3 ../build/c3c compile-run examples/process.c3 + ../build/c3c compile-run examples/ls.c3 - name: Compile run unit tests run: | diff --git a/lib/std/io/os/fileinfo_other.c3 b/lib/std/io/os/fileinfo_other.c3 index a3aa917a0..84f1419e1 100644 --- a/lib/std/io/os/fileinfo_other.c3 +++ b/lib/std/io/os/fileinfo_other.c3 @@ -17,7 +17,7 @@ struct NativeDirentry char[*] name @if(!env::os_is_darwin()); } -module std::io::file::os @if(!env::os_is_win32()); +module std::io::file::os @if(!env::WIN32); // native_temp_directory, for non Win32 @@ -47,7 +47,7 @@ const DT_LNK = 10; const DT_SOCK = 12; const DT_WHT = 14; -fn PathList! native_readdir(Path dir, bool no_dirs, bool no_symlinks, String mask, Allocator* using) +fn PathList! native_ls(Path dir, bool no_dirs, bool no_symlinks, String mask, Allocator* using) { PathList list; list.init(.using = using); diff --git a/lib/std/io/os/fileinfo_win32.c3 b/lib/std/io/os/fileinfo_win32.c3 index 81a6c431c..fc8ac76cb 100644 --- a/lib/std/io/os/fileinfo_win32.c3 +++ b/lib/std/io/os/fileinfo_win32.c3 @@ -1,28 +1,6 @@ -module std::io::file::os @if(env::os_is_win32()); +module std::io::file::os @if(env::WIN32); import std::os::win32; -const Win32_DWORD FILE_ATTRIBUTE_READONLY = 0x01; -const Win32_DWORD FILE_ATTRIBUTE_HIDDEN = 0x02; -const Win32_DWORD FILE_ATTRIBUTE_SYSTEM = 0x04; -const Win32_DWORD FILE_ATTRIBUTE_DIRECTORY = 0x10; -const Win32_DWORD FILE_ATTRIBUTE_ARCHIVE = 0x20; -const Win32_DWORD FILE_ATTRIBUTE_DEVICE = 0x40; -const Win32_DWORD FILE_ATTRIBUTE_NORMAL = 0x80; -const Win32_DWORD FILE_ATTRIBUTE_TEMPORARY = 0x100; -const Win32_DWORD FILE_ATTRIBUTE_SPARSE_FILE = 0x200; -const Win32_DWORD FILE_ATTRIBUTE_REPARSE_POINT = 0x400; -const Win32_DWORD FILE_ATTRIBUTE_COMPRESSED = 0x800; -const Win32_DWORD FILE_ATTRIBUTE_OFFLINE = 0x1000; -const Win32_DWORD FILE_ATTRIBUTE_NOT_CONTENT_INDEXED = 0x2000; -const Win32_DWORD FILE_ATTRIBUTE_ENCRYPTED = 0x4000; -const Win32_DWORD FILE_ATTRIBUTE_INTEGRITY_STREAM = 0x8000; -const Win32_DWORD FILE_ATTRIBUTE_VIRTUAL = 0x10000; -const Win32_DWORD FILE_ATTRIBUTE_NO_SCRUB_DATA = 0x20000; -const Win32_DWORD FILE_ATTRIBUTE_EA = 0x40000; -const Win32_DWORD FILE_ATTRIBUTE_PINNED = 0x80000; -const Win32_DWORD FILE_ATTRIBUTE_UNPINNED = 0x100000; -const Win32_DWORD FILE_ATTRIBUTE_RECALL_ON_OPEN = 0x40000; -const Win32_DWORD FILE_ATTRIBUTE_RECALL_ON_DATA_ACCESS = 0x400000; fn usz! native_file_size(String path) { @@ -74,7 +52,7 @@ fn void! native_rmtree(Path path) String filename = string::from_zutf16(&find_data.cFileName, mem::temp())!; if (filename == "." || filename == "..") continue; Path file_path = path.tappend(filename)!; - if (find_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) + if (find_data.dwFileAttributes & win32::FILE_ATTRIBUTE_DIRECTORY) { native_rmtree(file_path)!; } @@ -98,13 +76,28 @@ fn Path! native_temp_directory(Allocator* using = mem::heap()) }; } -/* - - }else if(method == file_size_methods::get_attributes){ - WIN32_FILE_ATTRIBUTE_DATA file_attr_data; - if(GetFileAttributesEx(path, GetFileExInfoStandard, &file_attr_data)){ - file_size.LowPart = file_attr_data.nFileSizeLow; - file_size.HighPart = file_attr_data.nFileSizeHigh; - } - } -*/ +fn PathList! native_ls(Path dir, bool no_dirs, bool no_symlinks, String mask, Allocator* using) +{ + PathList list; + list.init(.using = using); + @stack_mem(1024; Allocator* mem) + { + Char16* result = dir.as_str().concat(`\*`).to_utf16(.using = mem)!!; + list.append(path::new("test")); + Win32_WIN32_FIND_DATAW find_data; + Win32_HANDLE find = win32::findFirstFileW(result, &find_data); + if (find == win32::INVALID_HANDLE_VALUE) return IoError.CANNOT_READ_DIR?; + defer win32::findClose(find); + do + { + if (no_dirs && (find_data.dwFileAttributes & win32::FILE_ATTRIBUTE_DIRECTORY)) continue; + @stack_mem(480; Allocator* mem2) + { + String filename = string::from_zutf16(&find_data.cFileName, mem2)!; + if (filename == ".." || filename == ".") continue; + list.append(path::new(filename, using)); + }; + } while (win32::findNextFileW(find, &find_data)); + return list; + }; +} diff --git a/lib/std/io/path.c3 b/lib/std/io/path.c3 index 526d8a57b..72c677033 100644 --- a/lib/std/io/path.c3 +++ b/lib/std/io/path.c3 @@ -58,9 +58,9 @@ macro bool is_win32_separator(char c) return c == '/' || c == '\\'; } -fn Path[]! ls(Path path) +fn PathList! ls(Path dir, bool no_dirs = false, bool no_symlinks = false, String mask = "", Allocator* using = mem::heap()) { - unreachable(); + return os::native_ls(dir, no_dirs, no_symlinks, mask, using); } enum MkdirPermissions @@ -70,8 +70,6 @@ enum MkdirPermissions USER_AND_ADMIN } - - fn bool! mkdir(Path path, bool recursive = false, MkdirPermissions permissions = NORMAL) { if (!path.path_string.len) return PathResult.INVALID_PATH?; @@ -108,6 +106,14 @@ fn Path! new(String path, Allocator* using = mem::heap(), PathEnv path_env = DEF return { normalize(path.copy(using), path_env), path_env }; } +fn Path! new_win32_zutf16(Char16* path, Allocator* using = mem::heap()) +{ + @stack_mem(480; Allocator* mem) + { + return path::new(string::from_zutf16(path, .using = mem)!, .using = using); + }; +} + fn Path! new_windows(String path, Allocator* using = mem::heap()) { return new(path, using, WIN32); diff --git a/lib/std/os/win32/files.c3 b/lib/std/os/win32/files.c3 index f60e9ab76..a8bb621fc 100644 --- a/lib/std/os/win32/files.c3 +++ b/lib/std/os/win32/files.c3 @@ -54,7 +54,28 @@ extern fn Win32_BOOL findClose(Win32_HANDLE hFindFile) @extern("FindClose"); const Win32_DWORD GENERIC_WRITE = 0x40000000; const Win32_DWORD OPEN_EXISTING = 3; -const Win32_DWORD FILE_ATTRIBUTE_NORMAL = 0x00000080; +const Win32_DWORD FILE_ATTRIBUTE_READONLY = 0x01; +const Win32_DWORD FILE_ATTRIBUTE_HIDDEN = 0x02; +const Win32_DWORD FILE_ATTRIBUTE_SYSTEM = 0x04; +const Win32_DWORD FILE_ATTRIBUTE_DIRECTORY = 0x10; +const Win32_DWORD FILE_ATTRIBUTE_ARCHIVE = 0x20; +const Win32_DWORD FILE_ATTRIBUTE_DEVICE = 0x40; +const Win32_DWORD FILE_ATTRIBUTE_NORMAL = 0x80; +const Win32_DWORD FILE_ATTRIBUTE_TEMPORARY = 0x100; +const Win32_DWORD FILE_ATTRIBUTE_SPARSE_FILE = 0x200; +const Win32_DWORD FILE_ATTRIBUTE_REPARSE_POINT = 0x400; +const Win32_DWORD FILE_ATTRIBUTE_COMPRESSED = 0x800; +const Win32_DWORD FILE_ATTRIBUTE_OFFLINE = 0x1000; +const Win32_DWORD FILE_ATTRIBUTE_NOT_CONTENT_INDEXED = 0x2000; +const Win32_DWORD FILE_ATTRIBUTE_ENCRYPTED = 0x4000; +const Win32_DWORD FILE_ATTRIBUTE_INTEGRITY_STREAM = 0x8000; +const Win32_DWORD FILE_ATTRIBUTE_VIRTUAL = 0x10000; +const Win32_DWORD FILE_ATTRIBUTE_NO_SCRUB_DATA = 0x20000; +const Win32_DWORD FILE_ATTRIBUTE_EA = 0x40000; +const Win32_DWORD FILE_ATTRIBUTE_PINNED = 0x80000; +const Win32_DWORD FILE_ATTRIBUTE_UNPINNED = 0x100000; +const Win32_DWORD FILE_ATTRIBUTE_RECALL_ON_OPEN = 0x40000; +const Win32_DWORD FILE_ATTRIBUTE_RECALL_ON_DATA_ACCESS = 0x400000; extern fn Win32_HANDLE createFileA( Win32_LPCSTR lpFileName, diff --git a/resources/examples/ls.c3 b/resources/examples/ls.c3 new file mode 100644 index 000000000..4167894f5 --- /dev/null +++ b/resources/examples/ls.c3 @@ -0,0 +1,10 @@ +import std::io; + +fn void main() +{ + Path path = path::getcwd()!!; + foreach (i, p : path::ls(path)!!) + { + io::printfn("%02d %s", i, p.as_str()); + } +} \ No newline at end of file