Browse Source

Improve `_error_string` for Linux

gingerBill 1 year ago
parent
commit
3d992e2704
3 changed files with 167 additions and 24 deletions
  1. 165 21
      core/os/errors.odin
  2. 2 2
      core/os/os2/errors_linux.odin
  3. 0 1
      core/os/os_windows.odin

+ 165 - 21
core/os/errors.odin

@@ -47,6 +47,8 @@ Error :: union #shared_nil {
 
 
 ERROR_NONE :: Error{}
 ERROR_NONE :: Error{}
 
 
+ERROR_EOF :: io.Error.EOF
+
 @(require_results)
 @(require_results)
 is_platform_error :: proc "contextless" (ferr: Error) -> (err: i32, ok: bool) {
 is_platform_error :: proc "contextless" (ferr: Error) -> (err: i32, ok: bool) {
 	v := ferr.(Platform_Error) or_else {}
 	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)
 @(require_results, private)
 _error_string :: proc "contextless" (e: Platform_Error) -> string where intrinsics.type_is_enum(Platform_Error) {
 _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 {
 	if e == nil {
 		return ""
 		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 "<unknown platform error>"
 	return "<unknown platform error>"
 }
 }

+ 2 - 2
core/os/os2/errors_linux.odin

@@ -4,8 +4,8 @@ package os2
 import "core:sys/linux"
 import "core:sys/linux"
 
 
 @(rodata)
 @(rodata)
-_errno_strings : [linux.Error]string = {
-	.NONE            = "Success",
+_errno_strings := [linux.Error]string{
+	.NONE            = "",
 	.EPERM           = "Operation not permitted",
 	.EPERM           = "Operation not permitted",
 	.ENOENT          = "No such file or directory",
 	.ENOENT          = "No such file or directory",
 	.ESRCH           = "No such process",
 	.ESRCH           = "No such process",

+ 0 - 1
core/os/os_windows.odin

@@ -35,7 +35,6 @@ ERROR_INVALID_HANDLE      :: _Platform_Error(6)
 ERROR_NOT_ENOUGH_MEMORY   :: _Platform_Error(8)
 ERROR_NOT_ENOUGH_MEMORY   :: _Platform_Error(8)
 ERROR_NO_MORE_FILES       :: _Platform_Error(18)
 ERROR_NO_MORE_FILES       :: _Platform_Error(18)
 ERROR_HANDLE_EOF          :: _Platform_Error(38)
 ERROR_HANDLE_EOF          :: _Platform_Error(38)
-ERROR_EOF                 :: General_Error.EOF
 ERROR_NETNAME_DELETED     :: _Platform_Error(64)
 ERROR_NETNAME_DELETED     :: _Platform_Error(64)
 ERROR_FILE_EXISTS         :: _Platform_Error(80)
 ERROR_FILE_EXISTS         :: _Platform_Error(80)
 ERROR_INVALID_PARAMETER   :: _Platform_Error(87)
 ERROR_INVALID_PARAMETER   :: _Platform_Error(87)