Dir listing with looping

This commit is contained in:
Riyyi
2026-08-02 13:33:10 +02:00
parent 856befd876
commit b38caa7ff8
2 changed files with 42 additions and 33 deletions
+41 -32
View File
@@ -13,12 +13,46 @@ DirectoryEntry :: struct #all_or_none {
// -----------------------------------------
list_dir_by_path :: proc(path: string) -> [dynamic]DirectoryEntry {
list_dir_recursive :: proc(f: ^os.File) -> [dynamic]DirectoryEntry {
path := os.name(f)
return list_dir_recursive_by_path_impl(path)
}
list_dir_recursive_by_path :: proc(path: string) -> [dynamic]DirectoryEntry {
return list_dir_recursive_by_path_impl(path)
}
@(private)
list_dir_recursive_by_path_impl :: proc(
path: string,
) -> [dynamic]DirectoryEntry {
if !os.is_dir(path) {
fmt.eprintln("error: path is not a directory:", path)
os.exit(1)
}
result := [dynamic]DirectoryEntry{}
queue := [dynamic]string{}
append(&queue, path)
for len(queue) > 0 {
list_dir_queue(&queue, &result)
}
shrink(&result, len(result)) // shrink to fit
return result
}
@(private)
list_dir_queue :: proc(
queue: ^[dynamic]string,
result: ^[dynamic]DirectoryEntry,
) {
assert(len(queue) > 0, "queue must not be empty")
path := pop(queue)
f, open_err := os.open(path, {.Read})
if open_err != nil {
fmt.eprintln("error: open failed:", open_err)
@@ -26,25 +60,6 @@ list_dir_by_path :: proc(path: string) -> [dynamic]DirectoryEntry {
}
defer os.close(f)
result := [dynamic]DirectoryEntry{}
list_dir_impl(f, &result)
return result
}
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)
}
result := [dynamic]DirectoryEntry{}
list_dir_impl(f, &result)
return result
}
@(private)
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)
@@ -53,7 +68,7 @@ list_dir_impl :: proc(f: ^os.File, builder: ^[dynamic]DirectoryEntry) {
defer delete(entries)
// Reserve space for new entries
reserve(builder, cap(builder) + len(entries))
reserve(result, cap(result) + len(entries))
working_dir, wd_err := os.get_working_directory(context.allocator)
if wd_err != nil {
@@ -64,6 +79,10 @@ list_dir_impl :: proc(f: ^os.File, builder: ^[dynamic]DirectoryEntry) {
for entry, i in entries {
if entry.type == os.File_Type.Directory {
append(queue, entry.fullpath)
}
if entry.type == os.File_Type.Regular {
relpath, rel_err := strings.replace(
entry.fullpath,
@@ -73,19 +92,9 @@ list_dir_impl :: proc(f: ^os.File, builder: ^[dynamic]DirectoryEntry) {
context.allocator,
)
append(
builder,
result,
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
}
}
}
+1 -1
View File
@@ -19,6 +19,6 @@ main :: proc() {
fmt.println("size:", asset.size)
fmt.println("data:", asset.data)
entries := file.list_dir_by_path("./src")
entries := file.list_dir_recursive_by_path("./src")
fmt.println("entries:", entries)
}