diff options
| -rw-r--r-- | core/flags/errors.odin | 6 | ||||
| -rw-r--r-- | core/flags/example/example.odin | 8 | ||||
| -rw-r--r-- | core/flags/internal_rtti.odin | 56 | ||||
| -rw-r--r-- | core/flags/internal_validation.odin | 26 | ||||
| -rw-r--r-- | core/flags/util.odin | 12 | ||||
| -rw-r--r-- | core/time/timezone/tz_unix.odin | 7 | ||||
| -rw-r--r-- | tests/core/flags/test_core_flags.odin | 10 | ||||
| -rw-r--r-- | tests/core/path/filepath/test_core_filepath.odin | 12 |
8 files changed, 71 insertions, 66 deletions
diff --git a/core/flags/errors.odin b/core/flags/errors.odin index e9b2e18c8..d0caa1427 100644 --- a/core/flags/errors.odin +++ b/core/flags/errors.odin @@ -2,7 +2,7 @@ package flags import "base:runtime" import "core:net" -import "core:os" +import os "core:os/os2" Parse_Error_Reason :: enum { None, @@ -37,8 +37,8 @@ Unified_Parse_Error_Reason :: union #shared_nil { Open_File_Error :: struct { filename: string, errno: os.Error, - mode: int, - perms: int, + flags: os.File_Flags, + perms: os.Permissions, } // Raised during parsing. diff --git a/core/flags/example/example.odin b/core/flags/example/example.odin index a3af44790..6e74c7dcc 100644 --- a/core/flags/example/example.odin +++ b/core/flags/example/example.odin @@ -4,7 +4,7 @@ import "base:runtime" import "core:flags" import "core:fmt" import "core:net" -import "core:os" +import os "core:os/os2" import "core:time/datetime" @@ -76,8 +76,8 @@ 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."`, + file: ^os.File `args:"pos=0,required,file=r" usage:"Input file."`, + output: ^os.File `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."`, @@ -126,7 +126,7 @@ main :: proc() { fmt.printfln("%#v", opt) - if opt.output != 0 { + if opt.output != nil { os.write_string(opt.output, "Hellope!\n") } } diff --git a/core/flags/internal_rtti.odin b/core/flags/internal_rtti.odin index b3880afa0..07481a89b 100644 --- a/core/flags/internal_rtti.odin +++ b/core/flags/internal_rtti.odin @@ -6,7 +6,7 @@ import "base:runtime" import "core:fmt" import "core:mem" import "core:net" -import "core:os" +@(require) import os "core:os/os2" import "core:reflect" import "core:strconv" import "core:strings" @@ -209,7 +209,7 @@ parse_and_set_pointer_by_base_type :: proc(ptr: rawptr, str: string, type_info: parse_and_set_pointer_by_named_type :: proc(ptr: rawptr, str: string, data_type: typeid, arg_tag: string, out_error: ^Error) { // Core types currently supported: // - // - os.Handle + // - ^os.File // - time.Time // - datetime.DateTime // - net.Host_Or_Endpoint @@ -217,47 +217,44 @@ parse_and_set_pointer_by_named_type :: proc(ptr: rawptr, str: string, data_type: GENERIC_RFC_3339_ERROR :: "Invalid RFC 3339 string. Try this format: `yyyy-mm-ddThh:mm:ssZ`, for example `2024-02-29T16:30:00Z`." out_error^ = nil - - if data_type == os.Handle { + if data_type == ^os.File { // NOTE: `os` is hopefully available everywhere, even if it might panic on some calls. - wants_read := false - wants_write := false - mode: int + flags: os.File_Flags if file, ok := get_struct_subtag(arg_tag, SUBTAG_FILE); ok { for i in 0..<len(file) { #no_bounds_check switch file[i] { - case 'r': wants_read = true - case 'w': wants_write = true - case 'c': mode |= os.O_CREATE - case 'a': mode |= os.O_APPEND - case 't': mode |= os.O_TRUNC + case 'r': flags |= {.Read} + case 'w': flags |= {.Write} + case 'c': flags |= {.Create} + case 'a': flags |= {.Append} + case 't': flags |= {.Trunc} } } } // Sane default. // owner/group/other: r--r--r-- - perms: int = 0o444 - - if wants_read && wants_write { - mode |= os.O_RDWR - perms |= 0o200 - } else if wants_write { - mode |= os.O_WRONLY - perms |= 0o200 + octal_perms: int = 0o444 + + if flags >= {.Read, .Write} { + octal_perms |= 0o200 + } else if .Write in flags { + octal_perms |= 0o200 } else { - mode |= os.O_RDONLY + flags |= {.Read} } if permstr, ok := get_struct_subtag(arg_tag, SUBTAG_PERMS); ok { if value, parse_ok := strconv.parse_u64_of_base(permstr, 8); parse_ok { - perms = int(value) + octal_perms = int(value) } } - handle, errno := os.open(str, mode, perms) - if errno != nil { + perms := os.perm(octal_perms) + + f, error := os.open(str, flags, perms) + if error != nil { // NOTE(Feoramund): os.Error is system-dependent, and there's // currently no good way to translate them all into strings. // @@ -267,14 +264,14 @@ parse_and_set_pointer_by_named_type :: proc(ptr: rawptr, str: string, data_type: // it up. out_error^ = Open_File_Error { str, - errno, - mode, + error, + flags, perms, } return } - (^os.Handle)(ptr)^ = handle + (^^os.File)(ptr)^ = f return } @@ -475,6 +472,11 @@ parse_and_set_pointer_by_type :: proc(ptr: rawptr, str: string, type_info: ^runt } case: + if type_info.id == ^os.File { + parse_and_set_pointer_by_named_type(ptr, str, type_info.id, arg_tag, &error) + return + } + if !parse_and_set_pointer_by_base_type(ptr, str, type_info) { return Parse_Error { // The caller will add more details. diff --git a/core/flags/internal_validation.odin b/core/flags/internal_validation.odin index cd903c3e5..dc19f3084 100644 --- a/core/flags/internal_validation.odin +++ b/core/flags/internal_validation.odin @@ -1,14 +1,14 @@ #+private package flags -@require import "base:runtime" -@require import "core:container/bit_array" -@require import "core:fmt" -@require import "core:mem" -@require import "core:os" -@require import "core:reflect" -@require import "core:strconv" -@require import "core:strings" +@require import "base:runtime" +@require import "core:container/bit_array" +@require import "core:fmt" +@require import "core:mem" +@require import os "core:os/os2" +@require import "core:reflect" +@require import "core:strconv" +@require import "core:strings" // This proc is used to assert that `T` meets the expectations of the library. @(optimization_mode="favor_size", disabled=ODIN_DISABLE_ASSERT) @@ -138,20 +138,20 @@ validate_structure :: proc(model_type: $T, style: Parsing_Style, loc := #caller_ allowed_to_define_file_perms: bool = --- #partial switch specific_type_info in field.type.variant { case runtime.Type_Info_Map: - allowed_to_define_file_perms = specific_type_info.value.id == os.Handle + allowed_to_define_file_perms = specific_type_info.value.id == ^os.File case runtime.Type_Info_Dynamic_Array: - allowed_to_define_file_perms = specific_type_info.elem.id == os.Handle + allowed_to_define_file_perms = specific_type_info.elem.id == ^os.File case: - allowed_to_define_file_perms = field.type.id == os.Handle + allowed_to_define_file_perms = field.type.id == ^os.File } if _, has_file := get_struct_subtag(args_tag, SUBTAG_FILE); has_file { - fmt.assertf(allowed_to_define_file_perms, "%T.%s has `%s` defined, but it is not nor does it contain an `os.Handle` type.", + fmt.assertf(allowed_to_define_file_perms, "%T.%s has `%s` defined, but it is not nor does it contain an `^os.File` type.", model_type, field.name, SUBTAG_FILE, loc = loc) } if _, has_perms := get_struct_subtag(args_tag, SUBTAG_PERMS); has_perms { - fmt.assertf(allowed_to_define_file_perms, "%T.%s has `%s` defined, but it is not nor does it contain an `os.Handle` type.", + fmt.assertf(allowed_to_define_file_perms, "%T.%s has `%s` defined, but it is not nor does it contain an `^os.File` type.", model_type, field.name, SUBTAG_PERMS, loc = loc) } diff --git a/core/flags/util.odin b/core/flags/util.odin index ce7e2e36c..20e40cab5 100644 --- a/core/flags/util.odin +++ b/core/flags/util.odin @@ -1,7 +1,7 @@ package flags import "core:fmt" -@require import "core:os" +@require import os "core:os/os2" @require import "core:path/filepath" import "core:strings" @@ -38,7 +38,7 @@ parse_or_exit :: proc( error := parse(model, args, style, true, true, allocator, loc) if error != nil { - stderr := os.stream_from_handle(os.stderr) + stderr := os.to_stream(os.stderr) if len(args) == 0 { // No arguments entered, and there was an error; show the usage, @@ -65,18 +65,18 @@ Inputs: */ @(optimization_mode="favor_size") print_errors :: proc(data_type: typeid, error: Error, program: string, style: Parsing_Style = .Odin) { - stderr := os.stream_from_handle(os.stderr) - stdout := os.stream_from_handle(os.stdout) + stderr := os.to_stream(os.stderr) + stdout := os.to_stream(os.stdout) switch specific_error in error { case Parse_Error: fmt.wprintfln(stderr, "[%T.%v] %s", specific_error, specific_error.reason, specific_error.message) case Open_File_Error: - fmt.wprintfln(stderr, "[%T#%i] Unable to open file with perms 0o%o in mode 0x%x: %s", + fmt.wprintfln(stderr, "[%T#%i] Unable to open file with perms 0o%o and flags %v: %s", specific_error, specific_error.errno, specific_error.perms, - specific_error.mode, + specific_error.flags, specific_error.filename) case Validation_Error: fmt.wprintfln(stderr, "[%T] %s", specific_error, specific_error.message) diff --git a/core/time/timezone/tz_unix.odin b/core/time/timezone/tz_unix.odin index 6bab440d9..32590f177 100644 --- a/core/time/timezone/tz_unix.odin +++ b/core/time/timezone/tz_unix.odin @@ -5,6 +5,7 @@ package timezone import os "core:os/os2" import "core:strings" import "core:time/datetime" +import "core:path/filepath" local_tz_name :: proc(allocator := context.allocator) -> (name: string, success: bool) { local_str, ok := os.lookup_env("TZ", allocator) @@ -88,7 +89,8 @@ _region_load :: proc(_reg_str: string, allocator := context.allocator) -> (out_r defer if tzdir_ok { delete(tzdir_str, allocator) } if tzdir_ok { - region_path := filepath.join({tzdir_str, reg_str}, allocator) + region_path, err := filepath.join({tzdir_str, reg_str}, allocator) + if err != nil { return nil, false } defer delete(region_path, allocator) if tz_reg, ok := load_tzif_file(region_path, reg_str, allocator); ok { @@ -98,7 +100,8 @@ _region_load :: proc(_reg_str: string, allocator := context.allocator) -> (out_r db_paths := []string{"/usr/share/zoneinfo", "/share/zoneinfo", "/etc/zoneinfo"} for db_path in db_paths { - region_path := filepath.join({db_path, reg_str}, allocator) + region_path, err := filepath.join({db_path, reg_str}, allocator) + if err != nil { return nil, false} defer delete(region_path, allocator) if tz_reg, ok := load_tzif_file(region_path, reg_str, allocator); ok { diff --git a/tests/core/flags/test_core_flags.odin b/tests/core/flags/test_core_flags.odin index 0cfcf8e75..1aee7f69c 100644 --- a/tests/core/flags/test_core_flags.odin +++ b/tests/core/flags/test_core_flags.odin @@ -7,7 +7,7 @@ import "core:fmt" @require import "core:log" import "core:math" @require import "core:net" -import "core:os" +import os "core:os/os2" import "core:strings" import "core:testing" import "core:time/datetime" @@ -1249,7 +1249,7 @@ test_os_handle :: proc(t: ^testing.T) { test_data := "Hellope!" W :: struct { - outf: os.Handle `args:"file=cw"`, + outf: ^os.File `args:"file=cw"`, } w: W @@ -1263,7 +1263,7 @@ test_os_handle :: proc(t: ^testing.T) { os.write_string(w.outf, test_data) R :: struct { - inf: os.Handle `args:"file=r"`, + inf: ^os.File `args:"file=r"`, } r: R @@ -1274,8 +1274,8 @@ test_os_handle :: proc(t: ^testing.T) { return } defer os.close(r.inf) - data, read_ok := os.read_entire_file_from_handle(r.inf, context.temp_allocator) - testing.expect_value(t, read_ok, true) + data, read_err := os.read_entire_file(r.inf, context.temp_allocator) + testing.expect_value(t, read_err, nil) file_contents_equal := 0 == bytes.compare(transmute([]u8)test_data, data) testing.expectf(t, file_contents_equal, "expected file contents to be the same, got %v", data) } diff --git a/tests/core/path/filepath/test_core_filepath.odin b/tests/core/path/filepath/test_core_filepath.odin index f0137f69b..a0de7e831 100644 --- a/tests/core/path/filepath/test_core_filepath.odin +++ b/tests/core/path/filepath/test_core_filepath.odin @@ -33,7 +33,7 @@ test_split_list_windows :: proc(t: ^testing.T) { for d, i in data { assert(i == d.i, fmt.tprintf("wrong data index: i %d != d.i %d\n", i, d.i)) - r := filepath.split_list(d.v) + r, _ := filepath.split_list(d.v, context.allocator) defer delete_split(r) testing.expect(t, len(r) == len(d.e), fmt.tprintf("i:%d %s(%s) len(r) %d != len(d.e) %d", i, #procedure, d.v, len(r), len(d.e))) if len(r) == len(d.e) { @@ -45,13 +45,13 @@ test_split_list_windows :: proc(t: ^testing.T) { { v := "" - r := filepath.split_list(v) + r, _ := filepath.split_list(v, context.allocator) defer delete_split(r) testing.expect(t, r == nil, fmt.tprintf("%s(%s) -> %v != nil", #procedure, v, r)) } { v := "a" - r := filepath.split_list(v) + r, _ := filepath.split_list(v, context.allocator) defer delete_split(r) testing.expect(t, len(r) == 1, fmt.tprintf("%s(%s) len(r) %d != 1", #procedure, v, len(r))) if len(r) == 1 { @@ -77,7 +77,7 @@ test_split_list_unix :: proc(t: ^testing.T) { } for d in data { - r := filepath.split_list(d.v) + r, _ := filepath.split_list(d.v, context.allocator) defer delete_split(r) testing.expectf(t, len(r) == len(d.e), "%s len(r) %d != len(d.e) %d", d.v, len(r), len(d.e)) if len(r) == len(d.e) { @@ -89,12 +89,12 @@ test_split_list_unix :: proc(t: ^testing.T) { { v := "" - r := filepath.split_list(v) + r, _ := filepath.split_list(v, context.allocator) testing.expectf(t, r == nil, "'%s' -> '%v' != nil", v, r) } { v := "a" - r := filepath.split_list(v) + r, _ := filepath.split_list(v, context.allocator) defer delete_split(r) testing.expectf(t, len(r) == 1, "'%s' len(r) %d != 1", v, len(r)) if len(r) == 1 { |