diff --git a/myflag/flag.odin b/myflag/flag.odin deleted file mode 100644 index e11f684..0000000 --- a/myflag/flag.odin +++ /dev/null @@ -1,162 +0,0 @@ -#+vet explicit-allocators -package myflag - -import "base:runtime" -import "core:fmt" -import "core:os" -import "core:strconv" -import "core:strings" - -FORCE_HELP_ON_EMPTY_ARGS := false - -Flag_Value_Ptr :: union { - ^bool, - ^int, - ^string, - ^f32, - ^f64, -} - -Flag :: struct { - name: string, - value: Flag_Value_Ptr, - usage: string, - parsed: bool, // sck: flag to check if it has been parsed -} - -all_flags: [dynamic]Flag -flag_allocator: runtime.Allocator - -// sck: Used to create a customer allocator -init_custom_allocator :: proc(allocator: runtime.Allocator) { - destroy() // sck: make sure to destory the old allocations - - flag_allocator = allocator - all_flags = make([dynamic]Flag, flag_allocator) -} - -destroy :: proc() { - delete(all_flags) - all_flags = {} // sck: needed? -} - -print_flags :: proc() { - for f in all_flags { - fmt.printfln("%s: %v: %s", f.name, f.value, f.usage) - } -} - -print_usage :: proc() { - fmt.println("\tUsage: ") - for f in all_flags { - switch v in f.value { - case ^bool: - fmt.printfln("\t-%s:\n\t\t%s (default: %v)\n", f.name, f.usage, v^) - case ^int: - fmt.printfln("\t-%s:\n\t\t%s (default: %d)\n", f.name, f.usage, v^) - case ^string: - fmt.printfln("\t-%s:\n\t\t%s (default: %s)\n", f.name, f.usage, v^) - case ^f32: - fmt.printfln("\t-%s:\n\t\t%s (default: %f)\n", f.name, f.usage, v^) - case ^f64: - fmt.printfln("\t-%s:\n\t\t%s (default: %f)\n", f.name, f.usage, v^) - } - } - os.exit(0) -} - -BoolVar :: proc(ptr: ^bool, name: string, default: bool, usage: string) { - ptr^ = default - append(&all_flags, Flag{name = name, value = ptr, usage = usage}) -} - -IntVar :: proc(ptr: ^int, name: string, default: int, usage: string) { - ptr^ = default - append(&all_flags, Flag{name = name, value = ptr, usage = usage}) -} - -StringVar :: proc(ptr: ^string, name: string, default: string, usage: string) { - ptr^ = default - append(&all_flags, Flag{name = name, value = ptr, usage = usage}) -} - -Float32Var :: proc(ptr: ^f32, name: string, default: f32, usage: string) { - ptr^ = default - append(&all_flags, Flag{name = name, value = ptr, usage = usage}) -} - -Float64Var :: proc(ptr: ^f64, name: string, default: f64, usage: string) { - ptr^ = default - append(&all_flags, Flag{name = name, value = ptr, usage = usage}) -} - -parse_flags :: proc() { - if len(os.args) < 2 && FORCE_HELP_ON_EMPTY_ARGS {print_usage()} - - for &a in os.args { - if a == "-help" || a == "--help" {print_usage()} - if a == os.args[0] {continue} - - for &f in all_flags { - if f.parsed {continue} - a = strings.trim_prefix(a, "-") - - name := a - value: string - - split := strings.index_any(a, "=") - if split >= 0 { - name = a[:split] - value = a[split + 1:] - } else { - name = a - } - - if name == f.name && !f.parsed { - f.parsed = true - switch &v in f.value { - case ^bool: - if value == "" {break} - parsed, ok := strconv.parse_bool(value) - if !ok { - fmt.fprintfln(os.stderr, "[ERROR] Failed to parse flag %s: got %T, wanted bool", f.name, value) - os.exit(1) - } - v^ = parsed - - case ^int: - if value == "" {break} - parsed, ok := strconv.parse_int(value) - if !ok { - fmt.fprintfln(os.stderr, "[ERROR] Failed to parse flag %s: got %T, wanted int", f.name, value) - os.exit(1) - } - v^ = parsed - - case ^string: - if value == "" {break} - // TODO: validate string? - v^ = value - - case ^f32: - if value == "" {break} - parsed, ok := strconv.parse_f32(value) - if !ok { - fmt.fprintfln(os.stderr, "[ERROR] Failed to parse flag %s: got %T, wanted f32", f.name, value) - os.exit(1) - } - v^ = parsed - - case ^f64: - if value == "" {break} - parsed, ok := strconv.parse_f64(value) - if !ok { - fmt.fprintfln(os.stderr, "[ERROR] Failed to parse flag %s: got %T, wanted f64", f.name, value) - os.exit(1) - } - v^ = parsed - } - } - } - } -}