From 3992c80e6b83242ecea647e005b055fabd130c0a Mon Sep 17 00:00:00 2001 From: Riyyi Date: Sun, 2 Aug 2026 13:00:35 +0200 Subject: [PATCH] Dir listing with recursion --- src/file/file.odin | 58 +++++++++++++++++++++++++++++++--------------- src/main.odin | 2 +- 2 files changed, 40 insertions(+), 20 deletions(-) diff --git a/src/file/file.odin b/src/file/file.odin index 0263d47..ac6d5aa 100644 --- a/src/file/file.odin +++ b/src/file/file.odin @@ -14,18 +14,18 @@ import "core:strings" Asset :: struct #all_or_none { relpath: string, - size: i64, - data: []u8, + size: i64, + data: []u8, } DirectoryEntry :: struct #all_or_none { relpath: string, - size: i64, + size: i64, } // ----------------------------------------- -list_dir_by_path :: proc(path: string) -> []DirectoryEntry { +list_dir_by_path :: proc(path: string) -> [dynamic]DirectoryEntry { if !os.is_dir(path) { fmt.eprintln("error: path is not a directory:", path) os.exit(1) @@ -38,21 +38,25 @@ list_dir_by_path :: proc(path: string) -> []DirectoryEntry { } defer os.close(f) - return list_dir_impl(f) + result := [dynamic]DirectoryEntry{} + list_dir_impl(f, &result) + return result } -list_dir :: proc(f: ^os.File) -> []DirectoryEntry { +list_dir :: proc(f: ^os.File) -> [dynamic]DirectoryEntry { path := os.name(f) if !os.is_dir(path) { fmt.eprintln("error: path is not a directory:", path) os.exit(1) } - return list_dir_impl(f) + result := [dynamic]DirectoryEntry{} + list_dir_impl(f, &result) + return result } @(private) -list_dir_impl :: proc(f: ^os.File) -> []DirectoryEntry { +list_dir_impl :: proc(f: ^os.File, builder: ^[dynamic]DirectoryEntry) { entries, read_err := os.read_all_directory(f, context.allocator) if read_err != nil { fmt.eprintln("error: read directory failed:", read_err) @@ -60,6 +64,9 @@ list_dir_impl :: proc(f: ^os.File) -> []DirectoryEntry { } defer delete(entries) + // Reserve space for new entries + reserve(builder, cap(builder) + len(entries)) + working_dir, wd_err := os.get_working_directory(context.allocator) if wd_err != nil { fmt.eprintln("error: get working directory failed:", wd_err) @@ -67,19 +74,32 @@ list_dir_impl :: proc(f: ^os.File) -> []DirectoryEntry { } defer delete(working_dir) - result := make([]DirectoryEntry, len(entries)) for entry, i in entries { - relpath, rel_err := strings.replace( - entry.fullpath, - working_dir, - ".", - 1, - context.allocator, - ) - result[i] = DirectoryEntry{relpath = relpath, size = entry.size} - } - return result + if entry.type == os.File_Type.Regular { + relpath, rel_err := strings.replace( + entry.fullpath, + working_dir, + ".", + 1, + context.allocator, + ) + append( + builder, + DirectoryEntry{relpath = relpath, size = entry.size}, + ) + } + + if entry.type == os.File_Type.Directory { + dir, dir_err := os.open(entry.fullpath, {.Read}) + if dir_err != nil { + fmt.eprintln("error: open directory failed:", dir_err) + os.exit(1) + } + defer os.close(dir) + list_dir_impl(dir, builder) // recurse into directory + } + } } read_by_path :: proc(path: string) -> []u8 { diff --git a/src/main.odin b/src/main.odin index 94c5f5f..c51d5b9 100644 --- a/src/main.odin +++ b/src/main.odin @@ -19,6 +19,6 @@ main :: proc() { fmt.println("size:", asset.size) fmt.println("data:", asset.data) - entries := file.list_dir_by_path("./build") + entries := file.list_dir_by_path("./src") fmt.println("entries:", entries) }