diff --git a/src/cli/cli.odin b/src/cli/cli.odin index 86f811a..8e2d1f7 100644 --- a/src/cli/cli.odin +++ b/src/cli/cli.odin @@ -3,6 +3,7 @@ package cli import "core:flags" import "core:fmt" import "core:os" +import "core:strings" Options :: struct { verbose: bool `args:"name=verbose" usage:"Enable verbose output"`, @@ -13,7 +14,7 @@ Options :: struct { // overflow: [dynamic]string, } -parse :: proc() -> Options { +parse :: proc(working_dir: string) -> Options { opts: Options err := flags.parse(&opts, os.args[1:], .Unix) @@ -23,16 +24,48 @@ parse :: proc() -> Options { os.exit(1) } - if opts.compression > 12 { - err := flags.Validation_Error { - message = fmt.tprintf( - `Invalid compression "%d". Compression higher than allowed maximum.`, - opts.compression, - ), - } - flags.print_errors(typeid_of(Options), err, os.args[0], .Unix) - os.exit(1) - } + verify(opts, working_dir) return opts } + +@(private) +verify :: proc(opts: Options, working_dir: string) { + if opts.compression > 12 { + throw_error( + `Invalid compression "%d". Compression higher than allowed maximum.`, + opts.compression, + ) + } + + input_path := os.name(opts.input) + if !os.is_dir(input_path) { + throw_error(`Invalid input "%v". Should be a directory`, input_path) + } + + if opts.output != nil { + output_path := os.name(opts.output) + if !os.is_dir(output_path) { + throw_error( + `Invalid output "%v". Should be a directory`, + output_path, + ) + } + } + + if !strings.has_prefix(input_path, working_dir) { + throw_error( + `Invalid input "%v". Should be a subdirectory of the working directory.`, + input_path, + ) + } +} + +@(private) +throw_error :: proc(fmt_str: string, args: ..any) { + err := flags.Validation_Error { + message = fmt.tprintf(fmt_str, ..args), + } + flags.print_errors(typeid_of(Options), err, os.args[0], .Unix) + os.exit(1) +} diff --git a/src/file/file.odin b/src/file/file.odin index c1b5dc6..6858b52 100644 --- a/src/file/file.odin +++ b/src/file/file.odin @@ -1,7 +1,28 @@ package file +import "core:fmt" +import "core:os" + // TODO: // - list files in directory // - get relative path // - read file contents // - write file contents + +working_dir: string + +store_working_dir :: proc(allocator := context.allocator) { + wd, err := os.get_working_directory(allocator) + if err != nil { + fmt.eprintln("error: get working directory failed:", err) + os.exit(1) + } + working_dir = wd +} + +remove_working_dir :: proc() { + if working_dir != "" { + delete(working_dir) + working_dir = "" + } +} diff --git a/src/file/list_dir.odin b/src/file/list_dir.odin index be676d3..bee1539 100644 --- a/src/file/list_dir.odin +++ b/src/file/list_dir.odin @@ -34,20 +34,13 @@ list_dir_recursive_by_path :: proc( @(private) list_dir_recursive_by_path_impl :: proc( path: string, - allocator: runtime.Allocator + allocator: runtime.Allocator, ) -> [dynamic]DirectoryEntry { if !os.is_dir(path) { fmt.eprintln("error: path is not a directory:", path) os.exit(1) } - working_dir, wd_err := os.get_working_directory(allocator) - if wd_err != nil { - fmt.eprintln("error: get working directory failed:", wd_err) - os.exit(1) - } - defer delete(working_dir, allocator) - result := make([dynamic]DirectoryEntry, allocator) queue := make([dynamic]string, 0, 1, allocator) // reserve 1 slot diff --git a/src/main.odin b/src/main.odin index 4086c10..2818f1f 100644 --- a/src/main.odin +++ b/src/main.odin @@ -8,7 +8,10 @@ import "src:file" VERSION :: #config(VERSION, "dev") main :: proc() { - opts := cli.parse() + file.store_working_dir() + defer file.remove_working_dir() + + opts := cli.parse(file.working_dir) fmt.println("verbose:", opts.verbose) fmt.println("compression:", opts.compression)