From f69f817bd5f5ed96586bc6be21191e2a455caf57 Mon Sep 17 00:00:00 2001 From: Riyyi Date: Mon, 17 Aug 2026 17:48:30 +0200 Subject: [PATCH] Improve building of relative path --- src/file/file.odin | 16 +++++++++------- src/file/list_dir.odin | 35 +++++++++++++++++------------------ 2 files changed, 26 insertions(+), 25 deletions(-) diff --git a/src/file/file.odin b/src/file/file.odin index 58224e4..a54ba1f 100644 --- a/src/file/file.odin +++ b/src/file/file.odin @@ -13,16 +13,18 @@ Error :: union #shared_nil { } File_Error :: enum u8 { - None = 0, - Not_A_Directory = 1, - Unimplemented = 127, - Okay = None, + None = 0, + Not_A_Directory = 1, + Not_Under_Working_Directory = 2, + Unimplemented = 127, + Okay = None, } file_error_strings := #sparse[File_Error]string { // enumerated array - .None = "", - .Not_A_Directory = "path is not a directory", - .Unimplemented = "feature is unimplemented", + .None = "", + .Not_A_Directory = "path is not a directory", + .Not_Under_Working_Directory = "path is not a subdirectory of the working directory", + .Unimplemented = "feature is unimplemented", } // ----------------------------------------- diff --git a/src/file/list_dir.odin b/src/file/list_dir.odin index c8d91e8..7b96dde 100644 --- a/src/file/list_dir.odin +++ b/src/file/list_dir.odin @@ -3,6 +3,7 @@ package file import "base:runtime" import "core:fmt" import "core:os" +import "core:path/filepath" import "core:strings" // ----------------------------------------- @@ -23,9 +24,9 @@ list_dir_recursive :: proc( entries: [dynamic]File_Entry, err: Error, ) { - path := os.name(f) + full_path := os.name(f) result := list_dir_recursive_by_path_impl( - path, + full_path, working_dir, allocator, ) or_return @@ -41,8 +42,9 @@ list_dir_recursive_by_path :: proc( entries: [dynamic]File_Entry, err: Error, ) { + full_path := filepath.abs(path) or_return result := list_dir_recursive_by_path_impl( - path, + full_path, working_dir, allocator, ) or_return @@ -111,25 +113,22 @@ list_dir_queue :: proc( append(queue, strings.clone(entry.fullpath, queue^.allocator)) case os.File_Type.Regular: { - relpath_dirty, was_allocation := strings.replace( - entry.fullpath, - working_dir, - ".", - 1, - result^.allocator, - ) - // Remove unneeded references to the current or parent directory (./). - relpath := os.clean_path( - relpath_dirty, - result^.allocator, - ) or_return + rel := entry.fullpath[:] + if !strings.has_prefix(rel, working_dir) || + !os.is_path_separator(rel[len(working_dir)]) { + fmt.eprintf( + "fullpath not a subdirectory of working dir\n {}\n {}\n", + working_dir, + entry.fullpath, + ) + return .Not_Under_Working_Directory + } + rel = rel[len(working_dir) + 1:] + relpath := strings.clone(rel, result^.allocator) or_return append( result, File_Entry{relpath = relpath, size = entry.size}, ) - if was_allocation { - delete(relpath_dirty, result^.allocator) - } } case: // skip other types }