Dir listing with recursion

This commit is contained in:
Riyyi
2026-08-02 13:00:35 +02:00
parent 3b0b1a2387
commit 3992c80e6b
2 changed files with 40 additions and 20 deletions
+39 -19
View File
@@ -14,18 +14,18 @@ import "core:strings"
Asset :: struct #all_or_none { Asset :: struct #all_or_none {
relpath: string, relpath: string,
size: i64, size: i64,
data: []u8, data: []u8,
} }
DirectoryEntry :: struct #all_or_none { DirectoryEntry :: struct #all_or_none {
relpath: string, 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) { if !os.is_dir(path) {
fmt.eprintln("error: path is not a directory:", path) fmt.eprintln("error: path is not a directory:", path)
os.exit(1) os.exit(1)
@@ -38,21 +38,25 @@ list_dir_by_path :: proc(path: string) -> []DirectoryEntry {
} }
defer os.close(f) 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) path := os.name(f)
if !os.is_dir(path) { if !os.is_dir(path) {
fmt.eprintln("error: path is not a directory:", path) fmt.eprintln("error: path is not a directory:", path)
os.exit(1) os.exit(1)
} }
return list_dir_impl(f) result := [dynamic]DirectoryEntry{}
list_dir_impl(f, &result)
return result
} }
@(private) @(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) entries, read_err := os.read_all_directory(f, context.allocator)
if read_err != nil { if read_err != nil {
fmt.eprintln("error: read directory failed:", read_err) fmt.eprintln("error: read directory failed:", read_err)
@@ -60,6 +64,9 @@ list_dir_impl :: proc(f: ^os.File) -> []DirectoryEntry {
} }
defer delete(entries) defer delete(entries)
// Reserve space for new entries
reserve(builder, cap(builder) + len(entries))
working_dir, wd_err := os.get_working_directory(context.allocator) working_dir, wd_err := os.get_working_directory(context.allocator)
if wd_err != nil { if wd_err != nil {
fmt.eprintln("error: get working directory failed:", wd_err) 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) defer delete(working_dir)
result := make([]DirectoryEntry, len(entries))
for entry, i in 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 { read_by_path :: proc(path: string) -> []u8 {
+1 -1
View File
@@ -19,6 +19,6 @@ main :: proc() {
fmt.println("size:", asset.size) fmt.println("size:", asset.size)
fmt.println("data:", asset.data) fmt.println("data:", asset.data)
entries := file.list_dir_by_path("./build") entries := file.list_dir_by_path("./src")
fmt.println("entries:", entries) fmt.println("entries:", entries)
} }