From fbfadf99d039f033c03cbdf8932bfa4ee4f7e079 Mon Sep 17 00:00:00 2001 From: RoBaertschi Date: Thu, 19 Jun 2025 17:33:48 +0200 Subject: [PATCH] store(ini): added support for all integers --- store/ini.odin | 45 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/store/ini.odin b/store/ini.odin index df683dc..b38cc08 100644 --- a/store/ini.odin +++ b/store/ini.odin @@ -147,6 +147,13 @@ ini_unmarshal :: proc(data: string, v: ^$T, allocator := context.allocator) -> I } ini_parse_and_set_pointer_by_base_type :: proc(ptr: rawptr, str: string, type_info: ^runtime.Type_Info, allocator := context.allocator) -> bool { + bounded_int :: proc(value, min, max: i128) -> (result: i128, ok: bool) { + return value, min <= value && value <= max + } + + bounded_uint :: proc(value, max: u128) -> (result: u128, ok: bool) { + return value, value <= max + } #partial switch type_info_variant in type_info.variant { case runtime.Type_Info_Boolean: value := strconv.parse_bool(str) or_return @@ -157,6 +164,29 @@ ini_parse_and_set_pointer_by_base_type :: proc(ptr: rawptr, str: string, type_in case b32: (cast(^b32) ptr)^ = b32(value) case b64: (cast(^b64) ptr)^ = b64(value) } + case runtime.Type_Info_Integer: + if type_info_variant.signed { + value := strconv.parse_i128(str) or_return + switch type_info.id { + case int: (cast( ^int)ptr)^ = cast( int) bounded_int(value, cast(i128)min( int), cast(i128)max( int)) or_return + case i8: (cast( ^i8)ptr)^ = cast( i8) bounded_int(value, cast(i128)min( i8), cast(i128)max( i8)) or_return + case i16: (cast( ^i16)ptr)^ = cast( i16) bounded_int(value, cast(i128)min( i16), cast(i128)max( i16)) or_return + case i32: (cast( ^i32)ptr)^ = cast( i32) bounded_int(value, cast(i128)min( i32), cast(i128)max( i32)) or_return + case i64: (cast( ^i64)ptr)^ = cast( i64) bounded_int(value, cast(i128)min( i64), cast(i128)max( i64)) or_return + case i128: (cast(^i128)ptr)^ = bounded_int(value, min(i128), max(i128)) or_return + } + } else { + value := strconv.parse_u128(str) or_return + switch type_info.id { + case uint: (cast( ^uint)ptr)^ = cast( uint) bounded_uint(value, cast(u128)max( uint)) or_return + case u8: (cast( ^u8)ptr)^ = cast( u8) bounded_uint(value, cast(u128)max( u8)) or_return + case u16: (cast( ^u16)ptr)^ = cast( u16) bounded_uint(value, cast(u128)max( u16)) or_return + case u32: (cast( ^u32)ptr)^ = cast( u32) bounded_uint(value, cast(u128)max( u32)) or_return + case u64: (cast( ^u64)ptr)^ = cast( u64) bounded_uint(value, cast(u128)max( u64)) or_return + case u128: (cast( ^u128)ptr)^ = bounded_uint(value, max( u128)) or_return + case uintptr: (cast(^uintptr)ptr)^ = cast(uintptr) bounded_uint(value, cast(u128)max(uintptr)) or_return + } + } case runtime.Type_Info_String: if type_info_variant.is_cstring { cstr_ptr := cast(^cstring)ptr @@ -210,6 +240,21 @@ ini_parse_and_set_pointer_by_base_type_success :: proc(t: ^te.T) { te.expectf(t, val == expected, "expected value of type %T to be %v, but got %v", expected, expected, val) } + test_with_type_info(t, i8, "-3", -3) + test_with_type_info(t, i16, "-3", -3) + test_with_type_info(t, i32, "-3", -3) + test_with_type_info(t, i64, "-3", -3) + test_with_type_info(t, i128, "-3", -3) + test_with_type_info(t, int, "-3", -3) + + test_with_type_info(t, u8, "3", 3) + test_with_type_info(t, u16, "3", 3) + test_with_type_info(t, u32, "3", 3) + test_with_type_info(t, u64, "3", 3) + test_with_type_info(t, u128, "3", 3) + test_with_type_info(t, uint, "3", 3) + test_with_type_info(t, uintptr, "3", 3) + test_with_type_info(t, bool, "true", true) test_with_type_info(t, b8, "true", true) test_with_type_info(t, b16, "true", true)