From 3d992e2704511b77cb6c1187652c0952ea8d38f6 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Sun, 4 Aug 2024 13:25:35 +0100 Subject: Improve `_error_string` for Linux --- core/os/errors.odin | 186 +++++++++++++++++++++++++++++++++++++----- core/os/os2/errors_linux.odin | 4 +- core/os/os_windows.odin | 1 - 3 files changed, 167 insertions(+), 24 deletions(-) diff --git a/core/os/errors.odin b/core/os/errors.odin index 347f314d3..c7fd12dfb 100644 --- a/core/os/errors.odin +++ b/core/os/errors.odin @@ -47,6 +47,8 @@ Error :: union #shared_nil { ERROR_NONE :: Error{} +ERROR_EOF :: io.Error.EOF + @(require_results) is_platform_error :: proc "contextless" (ferr: Error) -> (err: i32, ok: bool) { v := ferr.(Platform_Error) or_else {} @@ -128,32 +130,174 @@ print_error :: proc(f: Handle, ferr: Error, msg: string) -> (n: int, err: Error) @(require_results, private) _error_string :: proc "contextless" (e: Platform_Error) -> string where intrinsics.type_is_enum(Platform_Error) { - @(require_results) - binary_search :: proc "contextless" (array: $A/[]$T, key: T) -> (index: int, found: bool) #no_bounds_check { - n := len(array) - left, right := 0, n - for left < right { - mid := int(uint(left+right) >> 1) - if array[mid] < key { - left = mid+1 - } else { - // equal or greater - right = mid - } - } - return left, left < n && array[left] == key - } - - if e == nil { return "" } - err := runtime.Type_Info_Enum_Value(e) + when ODIN_OS != .Linux { + @(require_results) + binary_search :: proc "contextless" (array: $A/[]$T, key: T) -> (index: int, found: bool) #no_bounds_check { + n := len(array) + left, right := 0, n + for left < right { + mid := int(uint(left+right) >> 1) + if array[mid] < key { + left = mid+1 + } else { + // equal or greater + right = mid + } + } + return left, left < n && array[left] == key + } + + err := runtime.Type_Info_Enum_Value(e) - ti := &runtime.type_info_base(type_info_of(Platform_Error)).variant.(runtime.Type_Info_Enum) - if idx, ok := binary_search(ti.values, err); ok { - return ti.names[idx] + ti := &runtime.type_info_base(type_info_of(Platform_Error)).variant.(runtime.Type_Info_Enum) + if idx, ok := binary_search(ti.values, err); ok { + return ti.names[idx] + } + } else { + @(rodata, static) + pe_strings := [Platform_Error]string{ + .NONE = "", + .EPERM = "Operation not permitted", + .ENOENT = "No such file or directory", + .ESRCH = "No such process", + .EINTR = "Interrupted system call", + .EIO = "Input/output error", + .ENXIO = "No such device or address", + .E2BIG = "Argument list too long", + .ENOEXEC = "Exec format error", + .EBADF = "Bad file descriptor", + .ECHILD = "No child processes", + .EAGAIN = "Resource temporarily unavailable", + .ENOMEM = "Cannot allocate memory", + .EACCES = "Permission denied", + .EFAULT = "Bad address", + .ENOTBLK = "Block device required", + .EBUSY = "Device or resource busy", + .EEXIST = "File exists", + .EXDEV = "Invalid cross-device link", + .ENODEV = "No such device", + .ENOTDIR = "Not a directory", + .EISDIR = "Is a directory", + .EINVAL = "Invalid argument", + .ENFILE = "Too many open files in system", + .EMFILE = "Too many open files", + .ENOTTY = "Inappropriate ioctl for device", + .ETXTBSY = "Text file busy", + .EFBIG = "File too large", + .ENOSPC = "No space left on device", + .ESPIPE = "Illegal seek", + .EROFS = "Read-only file system", + .EMLINK = "Too many links", + .EPIPE = "Broken pipe", + .EDOM = "Numerical argument out of domain", + .ERANGE = "Numerical result out of range", + .EDEADLK = "Resource deadlock avoided", + .ENAMETOOLONG = "File name too long", + .ENOLCK = "No locks available", + .ENOSYS = "Function not implemented", + .ENOTEMPTY = "Directory not empty", + .ELOOP = "Too many levels of symbolic links", + .EUNKNOWN_41 = "Unknown Error (41)", + .ENOMSG = "No message of desired type", + .EIDRM = "Identifier removed", + .ECHRNG = "Channel number out of range", + .EL2NSYNC = "Level 2 not synchronized", + .EL3HLT = "Level 3 halted", + .EL3RST = "Level 3 reset", + .ELNRNG = "Link number out of range", + .EUNATCH = "Protocol driver not attached", + .ENOCSI = "No CSI structure available", + .EL2HLT = "Level 2 halted", + .EBADE = "Invalid exchange", + .EBADR = "Invalid request descriptor", + .EXFULL = "Exchange full", + .ENOANO = "No anode", + .EBADRQC = "Invalid request code", + .EBADSLT = "Invalid slot", + .EUNKNOWN_58 = "Unknown Error (58)", + .EBFONT = "Bad font file format", + .ENOSTR = "Device not a stream", + .ENODATA = "No data available", + .ETIME = "Timer expired", + .ENOSR = "Out of streams resources", + .ENONET = "Machine is not on the network", + .ENOPKG = "Package not installed", + .EREMOTE = "Object is remote", + .ENOLINK = "Link has been severed", + .EADV = "Advertise error", + .ESRMNT = "Srmount error", + .ECOMM = "Communication error on send", + .EPROTO = "Protocol error", + .EMULTIHOP = "Multihop attempted", + .EDOTDOT = "RFS specific error", + .EBADMSG = "Bad message", + .EOVERFLOW = "Value too large for defined data type", + .ENOTUNIQ = "Name not unique on network", + .EBADFD = "File descriptor in bad state", + .EREMCHG = "Remote address changed", + .ELIBACC = "Can not access a needed shared library", + .ELIBBAD = "Accessing a corrupted shared library", + .ELIBSCN = ".lib section in a.out corrupted", + .ELIBMAX = "Attempting to link in too many shared libraries", + .ELIBEXEC = "Cannot exec a shared library directly", + .EILSEQ = "Invalid or incomplete multibyte or wide character", + .ERESTART = "Interrupted system call should be restarted", + .ESTRPIPE = "Streams pipe error", + .EUSERS = "Too many users", + .ENOTSOCK = "Socket operation on non-socket", + .EDESTADDRREQ = "Destination address required", + .EMSGSIZE = "Message too long", + .EPROTOTYPE = "Protocol wrong type for socket", + .ENOPROTOOPT = "Protocol not available", + .EPROTONOSUPPORT = "Protocol not supported", + .ESOCKTNOSUPPORT = "Socket type not supported", + .EOPNOTSUPP = "Operation not supported", + .EPFNOSUPPORT = "Protocol family not supported", + .EAFNOSUPPORT = "Address family not supported by protocol", + .EADDRINUSE = "Address already in use", + .EADDRNOTAVAIL = "Cannot assign requested address", + .ENETDOWN = "Network is down", + .ENETUNREACH = "Network is unreachable", + .ENETRESET = "Network dropped connection on reset", + .ECONNABORTED = "Software caused connection abort", + .ECONNRESET = "Connection reset by peer", + .ENOBUFS = "No buffer space available", + .EISCONN = "Transport endpoint is already connected", + .ENOTCONN = "Transport endpoint is not connected", + .ESHUTDOWN = "Cannot send after transport endpoint shutdown", + .ETOOMANYREFS = "Too many references: cannot splice", + .ETIMEDOUT = "Connection timed out", + .ECONNREFUSED = "Connection refused", + .EHOSTDOWN = "Host is down", + .EHOSTUNREACH = "No route to host", + .EALREADY = "Operation already in progress", + .EINPROGRESS = "Operation now in progress", + .ESTALE = "Stale file handle", + .EUCLEAN = "Structure needs cleaning", + .ENOTNAM = "Not a XENIX named type file", + .ENAVAIL = "No XENIX semaphores available", + .EISNAM = "Is a named type file", + .EREMOTEIO = "Remote I/O error", + .EDQUOT = "Disk quota exceeded", + .ENOMEDIUM = "No medium found", + .EMEDIUMTYPE = "Wrong medium type", + .ECANCELED = "Operation canceled", + .ENOKEY = "Required key not available", + .EKEYEXPIRED = "Key has expired", + .EKEYREVOKED = "Key has been revoked", + .EKEYREJECTED = "Key was rejected by service", + .EOWNERDEAD = "Owner died", + .ENOTRECOVERABLE = "State not recoverable", + .ERFKILL = "Operation not possible due to RF-kill", + .EHWPOISON = "Memory page has hardware error", + } + if Platform_Error.NONE <= e && e <= max(Platform_Error) { + return pe_strings[e] + } } return "" } diff --git a/core/os/os2/errors_linux.odin b/core/os/os2/errors_linux.odin index e4191d9aa..28c93cfae 100644 --- a/core/os/os2/errors_linux.odin +++ b/core/os/os2/errors_linux.odin @@ -4,8 +4,8 @@ package os2 import "core:sys/linux" @(rodata) -_errno_strings : [linux.Error]string = { - .NONE = "Success", +_errno_strings := [linux.Error]string{ + .NONE = "", .EPERM = "Operation not permitted", .ENOENT = "No such file or directory", .ESRCH = "No such process", diff --git a/core/os/os_windows.odin b/core/os/os_windows.odin index af5b485a6..d331bcfc8 100644 --- a/core/os/os_windows.odin +++ b/core/os/os_windows.odin @@ -35,7 +35,6 @@ ERROR_INVALID_HANDLE :: _Platform_Error(6) ERROR_NOT_ENOUGH_MEMORY :: _Platform_Error(8) ERROR_NO_MORE_FILES :: _Platform_Error(18) ERROR_HANDLE_EOF :: _Platform_Error(38) -ERROR_EOF :: General_Error.EOF ERROR_NETNAME_DELETED :: _Platform_Error(64) ERROR_FILE_EXISTS :: _Platform_Error(80) ERROR_INVALID_PARAMETER :: _Platform_Error(87) -- cgit v1.2.3