Try to map to General_Error where possible

This commit is contained in:
gingerBill
2024-08-04 11:44:45 +01:00
parent 28666414bc
commit def2e2e271
8 changed files with 103 additions and 7 deletions

View File

@@ -3,6 +3,7 @@ package os
import "core:strings"
@(require_results)
read_dir :: proc(fd: Handle, n: int, allocator := context.allocator) -> (fi: []File_Info, err: Errno) {
dirp := _fdopendir(fd) or_return
defer _closedir(dirp)

View File

@@ -4,6 +4,7 @@ import win32 "core:sys/windows"
import "core:strings"
import "base:runtime"
@(require_results)
read_dir :: proc(fd: Handle, n: int, allocator := context.allocator) -> (fi: []File_Info, err: Errno) {
find_data_to_file_info :: proc(base_path: string, d: ^win32.WIN32_FIND_DATAW) -> (fi: File_Info) {
// Ignore "." and ".."

View File

@@ -7,6 +7,7 @@ import "base:runtime"
// If the variable is found in the environment the value (which can be empty) is returned and the boolean is true
// Otherwise the returned value will be empty and the boolean will be false
// NOTE: the value will be allocated with the supplied allocator
@(require_results)
lookup_env :: proc(key: string, allocator := context.allocator) -> (value: string, found: bool) {
if key == "" {
return
@@ -33,6 +34,7 @@ lookup_env :: proc(key: string, allocator := context.allocator) -> (value: strin
// It returns the value, which will be empty if the variable is not present
// To distinguish between an empty value and an unset value, use lookup_env
// NOTE: the value will be allocated with the supplied allocator
@(require_results)
get_env :: proc(key: string, allocator := context.allocator) -> (value: string) {
value, _ = lookup_env(key, allocator)
return
@@ -60,6 +62,7 @@ unset_env :: proc(key: string) -> Errno {
// environ returns a copy of strings representing the environment, in the form "key=value"
// NOTE: the slice of strings and the strings with be allocated using the supplied allocator
@(require_results)
environ :: proc(allocator := context.allocator) -> []string {
envs := ([^]win32.WCHAR)(win32.GetEnvironmentStringsW())
if envs == nil {

View File

@@ -11,7 +11,7 @@ is_path_separator :: proc(c: byte) -> bool {
open :: proc(path: string, mode: int = O_RDONLY, perm: int = 0) -> (Handle, Errno) {
if len(path) == 0 {
return INVALID_HANDLE, ERROR_FILE_NOT_FOUND
return INVALID_HANDLE, General_Error.Not_Exist
}
access: u32
@@ -55,8 +55,7 @@ open :: proc(path: string, mode: int = O_RDONLY, perm: int = 0) -> (Handle, Errn
return handle, nil
}
err := get_last_error()
return INVALID_HANDLE, err
return INVALID_HANDLE, get_last_error()
}
close :: proc(fd: Handle) -> Errno {

View File

@@ -19,17 +19,51 @@ Platform_Error :: _Platform_Error
#assert(size_of(Platform_Error) <= 4)
#assert(intrinsics.type_has_nil(Platform_Error))
General_Error :: enum u32 {
None,
Permission_Denied,
Exist,
Not_Exist,
Closed,
Timeout,
Broken_Pipe,
// Indicates that an attempt to retrieve a file's size was made, but the
// file doesn't have a size.
No_Size,
Invalid_File,
Invalid_Dir,
Invalid_Path,
Invalid_Callback,
Pattern_Has_Separator,
Unsupported,
}
Errno :: Error // alias for legacy use
Error :: union #shared_nil {
General_Error,
io.Error,
runtime.Allocator_Error,
Platform_Error,
}
#assert(size_of(Error) <= 8)
#assert(size_of(Error) == 8)
ERROR_NONE :: Error{}
@(require_results)
is_platform_error :: proc(ferr: Error) -> (err: i32, ok: bool) {
v := ferr.(Platform_Error) or_else {}
return i32(v), i32(v) != 0
}
write_string :: proc(fd: Handle, str: string) -> (int, Errno) {
return write(fd, transmute([]byte)str)
}

View File

@@ -42,13 +42,14 @@ Error :: union #shared_nil {
ERROR_NONE :: Error{}
@(require_results)
is_platform_error :: proc(ferr: Error) -> (err: i32, ok: bool) {
v := ferr.(Platform_Error) or_else {}
return i32(v), i32(v) != 0
}
@(require_results)
error_string :: proc(ferr: Error) -> string {
if ferr == nil {
return ""

View File

@@ -521,7 +521,18 @@ _get_errno :: proc(res: int) -> Errno {
// get errno from libc
get_last_error :: proc "contextless" () -> Error {
return Platform_Error(__errno_location()^)
err := Platform_Error(__errno_location()^)
#partial switch err {
case .NONE:
return nil
case .EPERM:
return .Permission_Denied
case .EEXIST:
return .Exist
case .ENOENT:
return .Not_Exist
}
return err
}
personality :: proc(persona: u64) -> (Errno) {

View File

@@ -64,7 +64,53 @@ ERROR_NEGATIVE_OFFSET :: _Platform_Error(1<<29 + 2)
args := _alloc_command_line_arguments()
get_last_error :: proc "contextless" () -> Error {
return Platform_Error(win32.GetLastError())
err := win32.GetLastError()
if err == 0 {
return nil
}
switch err {
case win32.ERROR_ACCESS_DENIED, win32.ERROR_SHARING_VIOLATION:
return .Permission_Denied
case win32.ERROR_FILE_EXISTS, win32.ERROR_ALREADY_EXISTS:
return .Exist
case win32.ERROR_FILE_NOT_FOUND, win32.ERROR_PATH_NOT_FOUND:
return .Not_Exist
case win32.ERROR_NO_DATA:
return .Closed
case win32.ERROR_TIMEOUT, win32.WAIT_TIMEOUT:
return .Timeout
case win32.ERROR_NOT_SUPPORTED:
return .Unsupported
case win32.ERROR_HANDLE_EOF:
return .EOF
case win32.ERROR_INVALID_HANDLE:
return .Invalid_File
case
win32.ERROR_BAD_ARGUMENTS,
win32.ERROR_INVALID_PARAMETER,
win32.ERROR_NOT_ENOUGH_MEMORY,
win32.ERROR_NO_MORE_FILES,
win32.ERROR_LOCK_VIOLATION,
win32.ERROR_BROKEN_PIPE,
win32.ERROR_CALL_NOT_IMPLEMENTED,
win32.ERROR_INSUFFICIENT_BUFFER,
win32.ERROR_INVALID_NAME,
win32.ERROR_LOCK_FAILED,
win32.ERROR_ENVVAR_NOT_FOUND,
win32.ERROR_OPERATION_ABORTED,
win32.ERROR_IO_PENDING,
win32.ERROR_NO_UNICODE_TRANSLATION:
// fallthrough
}
return Platform_Error(err)
}