diff --git a/core/flags/constants.odin b/core/flags/constants.odin index 68ac711c1..dc2663e2a 100644 --- a/core/flags/constants.odin +++ b/core/flags/constants.odin @@ -28,7 +28,7 @@ TAG_USAGE :: "usage" UNDOCUMENTED_FLAG :: "" -INTERNAL_VARIADIC_FLAG :: "varg" +INTERNAL_OVERFLOW_FLAG :: #config(ODIN_CORE_FLAGS_OVERFLOW_FLAG, "overflow") RESERVED_HELP_FLAG :: "help" RESERVED_HELP_FLAG_SHORT :: "h" diff --git a/core/flags/doc.odin b/core/flags/doc.odin index 0763c01a7..440acd52c 100644 --- a/core/flags/doc.odin +++ b/core/flags/doc.odin @@ -22,10 +22,14 @@ The format is similar to the Odin binary's way of handling compiler flags. Unhandled Arguments: -All unhandled positional arguments are placed into the `varg` field on a +All unhandled positional arguments are placed into the `overflow` field on a struct, if it exists. In UNIX-style parsing, the existence of a `--` on the command line will also pass all arguments afterwards into this field. +If desired, the name of the field may be changed from `overflow` to any string +by setting the `ODIN_CORE_FLAGS_OVERFLOW_FLAG` compile-time config option with +`-define:ODIN_CORE_FLAGS_OVERFLOW_FLAG=`. + Struct Tags: diff --git a/core/flags/errors.odin b/core/flags/errors.odin index 6e48f6ccf..3d34a95d3 100644 --- a/core/flags/errors.odin +++ b/core/flags/errors.odin @@ -4,7 +4,7 @@ import "core:os" Parse_Error_Reason :: enum { None, - // An extra positional argument was given, and there is no `varg` field. + // An extra positional argument was given, and there is no `overflow` field. Extra_Positional, // The underlying type does not support the string value it is being set to. Bad_Value, diff --git a/core/flags/example/example.odin b/core/flags/example/example.odin index 1988eb3ee..a3af44790 100644 --- a/core/flags/example/example.odin +++ b/core/flags/example/example.odin @@ -114,7 +114,7 @@ main :: proc() { verbose: bool `usage:"Show verbose output."`, debug: bool `args:"hidden" usage:"print debug info"`, - varg: [dynamic]string `usage:"Any extra arguments go here."`, + overflow: [dynamic]string `usage:"Any extra arguments go here."`, } opt: Options diff --git a/core/flags/internal_assignment.odin b/core/flags/internal_assignment.odin index 3543dba37..5999dbf2d 100644 --- a/core/flags/internal_assignment.odin +++ b/core/flags/internal_assignment.odin @@ -33,9 +33,9 @@ push_positional :: #force_no_inline proc (model: ^$T, parser: ^Parser, arg: stri field, index, has_pos_assigned := get_field_by_pos(model, pos) if !has_pos_assigned { - when intrinsics.type_has_field(T, INTERNAL_VARIADIC_FLAG) { + when intrinsics.type_has_field(T, INTERNAL_OVERFLOW_FLAG) { // Add it to the fallback array. - field = reflect.struct_field_by_name(T, INTERNAL_VARIADIC_FLAG) + field = reflect.struct_field_by_name(T, INTERNAL_OVERFLOW_FLAG) } else { return Parse_Error { .Extra_Positional, diff --git a/core/flags/internal_parsing.odin b/core/flags/internal_parsing.odin index 4e49f45b0..6d544e5af 100644 --- a/core/flags/internal_parsing.odin +++ b/core/flags/internal_parsing.odin @@ -95,7 +95,7 @@ parse_one_unix_arg :: proc(model: ^$T, parser: ^Parser, arg: string) -> ( // `--`, and only `--`. // Everything from now on will be treated as an argument. future_args = max(int) - current_flag = INTERNAL_VARIADIC_FLAG + current_flag = INTERNAL_OVERFLOW_FLAG return } } diff --git a/core/flags/internal_validation.odin b/core/flags/internal_validation.odin index b68df8cb5..cd903c3e5 100644 --- a/core/flags/internal_validation.odin +++ b/core/flags/internal_validation.odin @@ -80,7 +80,7 @@ validate_structure :: proc(model_type: $T, style: Parsing_Style, loc := #caller_ fmt.assertf(!reflect.is_boolean(field.type), "%T.%s is a required boolean. This is disallowed.", model_type, field.name, loc = loc) - fmt.assertf(field.name != INTERNAL_VARIADIC_FLAG, "%T.%s is defined as required. This is disallowed.", + fmt.assertf(field.name != INTERNAL_OVERFLOW_FLAG, "%T.%s is defined as required. This is disallowed.", model_type, field.name, loc = loc) if len(requirement) > 0 { @@ -113,7 +113,7 @@ validate_structure :: proc(model_type: $T, style: Parsing_Style, loc := #caller_ if length, is_manifold := get_struct_subtag(args_tag, SUBTAG_MANIFOLD); is_manifold { fmt.assertf(!has_pos, "%T.%s has both `%s` and `%s` defined. This is disallowed.\n\tSuggestion: Use a dynamic array field named `%s` to accept unspecified positional arguments.", - model_type, field.name, SUBTAG_POS, SUBTAG_MANIFOLD, INTERNAL_VARIADIC_FLAG, loc = loc) + model_type, field.name, SUBTAG_POS, SUBTAG_MANIFOLD, INTERNAL_OVERFLOW_FLAG, loc = loc) if value, parse_ok := strconv.parse_u64_of_base(length, 10); parse_ok { fmt.assertf(value > 0, diff --git a/core/flags/usage.odin b/core/flags/usage.odin index 92cf21cdb..a44baec81 100644 --- a/core/flags/usage.odin +++ b/core/flags/usage.odin @@ -38,10 +38,10 @@ write_usage :: proc(out: io.Writer, data_type: typeid, program: string = "", sty // POSITIONAL+REQUIRED, POSITIONAL, REQUIRED, NON_REQUIRED+NON_POSITIONAL, ... // sort_flags :: proc(i, j: Flag) -> slice.Ordering { - // `varg` goes to the end. - if i.name == INTERNAL_VARIADIC_FLAG { + // `overflow` goes to the end. + if i.name == INTERNAL_OVERFLOW_FLAG { return .Greater - } else if j.name == INTERNAL_VARIADIC_FLAG { + } else if j.name == INTERNAL_OVERFLOW_FLAG { return .Less } @@ -147,7 +147,7 @@ write_usage :: proc(out: io.Writer, data_type: typeid, program: string = "", sty case runtime.Type_Info_Dynamic_Array: requirement_spec := describe_array_requirements(flag) - if flag.is_manifold || flag.name == INTERNAL_VARIADIC_FLAG { + if flag.is_manifold || flag.name == INTERNAL_OVERFLOW_FLAG { if flag.manifold_length == 0 { flag.type_description = fmt.tprintf("<%v, ...>%s", specific_type_info.elem.id, @@ -177,7 +177,7 @@ write_usage :: proc(out: io.Writer, data_type: typeid, program: string = "", sty } } - if flag.name == INTERNAL_VARIADIC_FLAG { + if flag.name == INTERNAL_OVERFLOW_FLAG { flag.full_length = len(flag.type_description) } else if flag.is_boolean { flag.full_length = len(flag_prefix) + len(flag.name) + len(flag.type_description) @@ -201,13 +201,13 @@ write_usage :: proc(out: io.Writer, data_type: typeid, program: string = "", sty strings.write_string(&builder, program) for flag in visible_flags { - if keep_it_short && !(flag.is_required || flag.is_positional || flag.name == INTERNAL_VARIADIC_FLAG) { + if keep_it_short && !(flag.is_required || flag.is_positional || flag.name == INTERNAL_OVERFLOW_FLAG) { continue } strings.write_byte(&builder, ' ') - if flag.name == INTERNAL_VARIADIC_FLAG { + if flag.name == INTERNAL_OVERFLOW_FLAG { strings.write_string(&builder, "...") continue } @@ -252,7 +252,7 @@ write_usage :: proc(out: io.Writer, data_type: typeid, program: string = "", sty strings.write_byte(&builder, '\t') - if flag.name == INTERNAL_VARIADIC_FLAG { + if flag.name == INTERNAL_OVERFLOW_FLAG { strings.write_string(&builder, flag.type_description) } else { strings.write_string(&builder, flag_prefix) diff --git a/tests/core/flags/test_core_flags.odin b/tests/core/flags/test_core_flags.odin index dd2074144..0527d85c5 100644 --- a/tests/core/flags/test_core_flags.odin +++ b/tests/core/flags/test_core_flags.odin @@ -454,44 +454,44 @@ test_arrays :: proc(t: ^testing.T) { @(test) test_varargs :: proc(t: ^testing.T) { S :: struct { - varg: [dynamic]string, + overflow: [dynamic]string, } s: S args := [?]string { "abc", "foo", "bar" } result := flags.parse(&s, args[:]) - defer delete(s.varg) + defer delete(s.overflow) testing.expect_value(t, result, nil) - testing.expect_value(t, len(s.varg), 3) + testing.expect_value(t, len(s.overflow), 3) - if len(s.varg) < 3 { + if len(s.overflow) < 3 { return } - testing.expect_value(t, s.varg[0], "abc") - testing.expect_value(t, s.varg[1], "foo") - testing.expect_value(t, s.varg[2], "bar") + testing.expect_value(t, s.overflow[0], "abc") + testing.expect_value(t, s.overflow[1], "foo") + testing.expect_value(t, s.overflow[2], "bar") } @(test) test_mixed_varargs :: proc(t: ^testing.T) { S :: struct { input: string `args:"pos=0"`, - varg: [dynamic]string, + overflow: [dynamic]string, } s: S args := [?]string { "abc", "foo", "bar" } result := flags.parse(&s, args[:]) - defer delete(s.varg) + defer delete(s.overflow) testing.expect_value(t, result, nil) - testing.expect_value(t, len(s.varg), 2) + testing.expect_value(t, len(s.overflow), 2) - if len(s.varg) < 2 { + if len(s.overflow) < 2 { return } testing.expect_value(t, s.input, "abc") - testing.expect_value(t, s.varg[0], "foo") - testing.expect_value(t, s.varg[1], "bar") + testing.expect_value(t, s.overflow[0], "foo") + testing.expect_value(t, s.overflow[1], "bar") } @(test) @@ -718,23 +718,23 @@ test_tags_required_limit_max :: proc(t: ^testing.T) { test_tags_pos_out_of_order :: proc(t: ^testing.T) { S :: struct { a: int `args:"pos=2"`, - varg: [dynamic]int, + overflow: [dynamic]int, } s: S args := [?]string { "1", "2", "3", "4" } result := flags.parse(&s, args[:]) - defer delete(s.varg) + defer delete(s.overflow) testing.expect_value(t, result, nil) - testing.expect_value(t, len(s.varg), 3) + testing.expect_value(t, len(s.overflow), 3) - if len(s.varg) < 3 { + if len(s.overflow) < 3 { return } testing.expect_value(t, s.a, 3) - testing.expect_value(t, s.varg[0], 1) - testing.expect_value(t, s.varg[1], 2) - testing.expect_value(t, s.varg[2], 4) + testing.expect_value(t, s.overflow[0], 1) + testing.expect_value(t, s.overflow[1], 2) + testing.expect_value(t, s.overflow[2], 4) } @(test) @@ -899,7 +899,7 @@ test_pos_nonoverlap :: proc(t: ^testing.T) { @(test) test_pos_many_args :: proc(t: ^testing.T) { S :: struct { - varg: [dynamic]int, + overflow: [dynamic]int, a: int `args:"pos=0,required"`, b: int `args:"pos=64,required"`, c: int `args:"pos=66,required"`, @@ -908,7 +908,7 @@ test_pos_many_args :: proc(t: ^testing.T) { s: S args: [dynamic]string - defer delete(s.varg) + defer delete(s.overflow) for i in 0 ..< 130 { append(&args, fmt.aprintf("%i", 1 + i)) } defer { @@ -922,14 +922,14 @@ test_pos_many_args :: proc(t: ^testing.T) { testing.expect_value(t, result, nil) testing.expect_value(t, s.a, 1) - for i in 1 ..< 63 { testing.expect_value(t, s.varg[i], 2 + i) } + for i in 1 ..< 63 { testing.expect_value(t, s.overflow[i], 2 + i) } testing.expect_value(t, s.b, 65) - testing.expect_value(t, s.varg[63], 66) + testing.expect_value(t, s.overflow[63], 66) testing.expect_value(t, s.c, 67) - testing.expect_value(t, s.varg[64], 68) - testing.expect_value(t, s.varg[65], 69) - testing.expect_value(t, s.varg[66], 70) - for i in 67 ..< 126 { testing.expect_value(t, s.varg[i], 4 + i) } + testing.expect_value(t, s.overflow[64], 68) + testing.expect_value(t, s.overflow[65], 69) + testing.expect_value(t, s.overflow[66], 70) + for i in 67 ..< 126 { testing.expect_value(t, s.overflow[i], 4 + i) } testing.expect_value(t, s.d, 130) } @@ -1135,7 +1135,7 @@ test_unix_positional :: proc(t: ^testing.T) { @(test) test_unix_positional_with_manifold :: proc(t: ^testing.T) { S :: struct { - varg: [dynamic]int, + overflow: [dynamic]int, v: [dynamic]int `args:"manifold"`, } s: S @@ -1144,18 +1144,18 @@ test_unix_positional_with_manifold :: proc(t: ^testing.T) { result := flags.parse(&s, args[:], .Unix) defer { - delete(s.varg) + delete(s.overflow) delete(s.v) } testing.expect_value(t, result, nil) - testing.expect_value(t, len(s.varg), 1) + testing.expect_value(t, len(s.overflow), 1) testing.expect_value(t, len(s.v), 2) } @(test) test_unix_double_dash_varargs :: proc(t: ^testing.T) { S :: struct { - varg: [dynamic]string, + overflow: [dynamic]string, i: int, } s: S @@ -1164,19 +1164,19 @@ test_unix_double_dash_varargs :: proc(t: ^testing.T) { result := flags.parse(&s, args[:], .Unix) defer { - delete(s.varg) + delete(s.overflow) } testing.expect_value(t, result, nil) - testing.expect_value(t, len(s.varg), 3) + testing.expect_value(t, len(s.overflow), 3) testing.expect_value(t, s.i, 3) - if len(s.varg) != 3 { + if len(s.overflow) != 3 { return } - testing.expect_value(t, s.varg[0], "hellope") - testing.expect_value(t, s.varg[1], "-i") - testing.expect_value(t, s.varg[2], "5") + testing.expect_value(t, s.overflow[0], "hellope") + testing.expect_value(t, s.overflow[1], "-i") + testing.expect_value(t, s.overflow[2], "5") } @(test) @@ -1200,17 +1200,17 @@ test_unix_no_value :: proc(t: ^testing.T) { @(test) test_if_dynamic_cstrings_get_freed :: proc(t: ^testing.T) { S :: struct { - varg: [dynamic]cstring, + overflow: [dynamic]cstring, } s: S args := [?]string { "Hellope", "world!" } result := flags.parse(&s, args[:]) defer { - for v in s.varg { + for v in s.overflow { delete(v) } - delete(s.varg) + delete(s.overflow) } testing.expect_value(t, result, nil) } @@ -1428,7 +1428,7 @@ very nicely. debug: bool `args:"hidden" usage:"print debug info"`, verbose: bool, - varg: [dynamic]string, + overflow: [dynamic]string, } builder := strings.builder_make() @@ -1441,7 +1441,7 @@ very nicely. @(test) test_usage_write_unix :: proc(t: ^testing.T) { Expected_Output :: `Usage: - varg required-number [number] [name] --bars --bots --foos --gadgets --manifold-flag --widgets [--array] [--count] [--greek] [--verbose] ... + overflow required-number [number] [name] --bars --bots --foos --gadgets --manifold-flag --widgets [--array] [--count] [--greek] [--verbose] ... Flags: --required-number , required | some number --number | some other number @@ -1493,12 +1493,12 @@ very nicely. debug: bool `args:"hidden" usage:"print debug info"`, verbose: bool, - varg: [dynamic]string, + overflow: [dynamic]string, } builder := strings.builder_make() defer strings.builder_destroy(&builder) writer := strings.to_stream(&builder) - flags.write_usage(writer, S, "varg", .Unix) + flags.write_usage(writer, S, "overflow", .Unix) testing.expect_value(t, strings.to_string(builder), Expected_Output) }