aboutsummaryrefslogtreecommitdiff
path: root/core/flags/example/example.odin
diff options
context:
space:
mode:
authorFeoramund <161657516+Feoramund@users.noreply.github.com>2024-06-06 18:35:43 -0400
committerFeoramund <161657516+Feoramund@users.noreply.github.com>2024-06-07 13:16:13 -0400
commitedb685f04be9aef407dc8abac7bb76fb51184f9f (patch)
tree63f48c951de7a9d751895a3cd72194e241bd38c0 /core/flags/example/example.odin
parent08612423b9afffb7499d8db2c69715df1627bd50 (diff)
Add package `core:flags`
Diffstat (limited to 'core/flags/example/example.odin')
-rw-r--r--core/flags/example/example.odin132
1 files changed, 132 insertions, 0 deletions
diff --git a/core/flags/example/example.odin b/core/flags/example/example.odin
new file mode 100644
index 000000000..b1d7b58d6
--- /dev/null
+++ b/core/flags/example/example.odin
@@ -0,0 +1,132 @@
+package core_flags_example
+
+import "base:runtime"
+import "core:flags"
+import "core:fmt"
+import "core:net"
+import "core:os"
+import "core:time/datetime"
+
+
+Fixed_Point1_1 :: struct {
+ integer: u8,
+ fractional: u8,
+}
+
+Optimization_Level :: enum {
+ Slow,
+ Fast,
+ Warp_Speed,
+ Ludicrous_Speed,
+}
+
+// It's simple but powerful.
+my_custom_type_setter :: proc(
+ data: rawptr,
+ data_type: typeid,
+ unparsed_value: string,
+ args_tag: string,
+) -> (
+ error: string,
+ handled: bool,
+ alloc_error: runtime.Allocator_Error,
+) {
+ if data_type == Fixed_Point1_1 {
+ handled = true
+ ptr := cast(^Fixed_Point1_1)data
+
+ // precision := flags.get_subtag(args_tag, "precision")
+
+ if len(unparsed_value) == 3 {
+ ptr.integer = unparsed_value[0] - '0'
+ ptr.fractional = unparsed_value[2] - '0'
+ } else {
+ error = "Incorrect format. Must be in the form of `i.f`."
+ }
+
+ // Perform sanity checking here in the type parsing phase.
+ //
+ // The validation phase is flag-specific.
+ if !(0 <= ptr.integer && ptr.integer < 10) || !(0 <= ptr.fractional && ptr.fractional < 10) {
+ error = "Incorrect format. Must be between `0.0` and `9.9`."
+ }
+ }
+
+ return
+}
+
+my_custom_flag_checker :: proc(
+ model: rawptr,
+ name: string,
+ value: any,
+ args_tag: string,
+) -> (error: string) {
+ if name == "iterations" {
+ v := value.(int)
+ if !(1 <= v && v < 5) {
+ error = "Iterations only supports 1 ..< 5."
+ }
+ }
+
+ return
+}
+
+Distinct_Int :: distinct int
+
+main :: proc() {
+ Options :: struct {
+
+ file: os.Handle `args:"pos=0,required,file=r" usage:"Input file."`,
+ output: os.Handle `args:"pos=1,file=cw" usage:"Output file."`,
+
+ hub: net.Host_Or_Endpoint `usage:"Internet address to contact for updates."`,
+ schedule: datetime.DateTime `usage:"Launch tasks at this time."`,
+
+ opt: Optimization_Level `usage:"Optimization level."`,
+ todo: [dynamic]string `usage:"Todo items."`,
+
+ accuracy: Fixed_Point1_1 `args:"required" usage:"Lenience in FLOP calculations."`,
+ iterations: int `usage:"Run this many times."`,
+
+ // Note how the parser will transform this flag's name into `special-int`.
+ special_int: Distinct_Int `args:"indistinct" usage:"Able to set distinct types."`,
+
+ quat: quaternion256,
+
+ bits: bit_set[0..<8],
+
+ // Many different requirement styles:
+
+ // gadgets: [dynamic]string `args:"required=1" usage:"gadgets"`,
+ // widgets: [dynamic]string `args:"required=<3" usage:"widgets"`,
+ // foos: [dynamic]string `args:"required=2<4"`,
+ // bars: [dynamic]string `args:"required=3<4"`,
+ // bots: [dynamic]string `args:"required"`,
+
+ // (Maps) Only available in Odin style:
+
+ // assignments: map[string]u8 `args:"name=assign" usage:"Number of jobs per worker."`,
+
+ // (Variadic) Only available in UNIX style:
+
+ // bots: [dynamic]string `args:"variadic=2,required"`,
+
+ verbose: bool `usage:"Show verbose output."`,
+ debug: bool `args:"hidden" usage:"print debug info"`,
+
+ varg: [dynamic]string `usage:"Any extra arguments go here."`,
+ }
+
+ opt: Options
+ style : flags.Parsing_Style = .Odin
+
+ flags.register_type_setter(my_custom_type_setter)
+ flags.register_flag_checker(my_custom_flag_checker)
+ flags.parse_or_exit(&opt, os.args, style)
+
+ fmt.printfln("%#v", opt)
+
+ if opt.output != 0 {
+ os.write_string(opt.output, "Hellope!\n")
+ }
+}