errors.odin 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. package os2
  2. import "core:io"
  3. import "base:runtime"
  4. General_Error :: enum u32 {
  5. None,
  6. Permission_Denied,
  7. Exist,
  8. Not_Exist,
  9. Closed,
  10. Timeout,
  11. Broken_Pipe,
  12. // Indicates that an attempt to retrieve a file's size was made, but the
  13. // file doesn't have a size.
  14. No_Size,
  15. Invalid_File,
  16. Invalid_Dir,
  17. Invalid_Path,
  18. Invalid_Callback,
  19. Invalid_Command,
  20. Pattern_Has_Separator,
  21. Unsupported,
  22. }
  23. Platform_Error :: _Platform_Error
  24. Error :: union #shared_nil {
  25. General_Error,
  26. io.Error,
  27. runtime.Allocator_Error,
  28. Platform_Error,
  29. }
  30. #assert(size_of(Error) == size_of(u64))
  31. ERROR_NONE :: Error{}
  32. @(require_results)
  33. is_platform_error :: proc(ferr: Error) -> (err: i32, ok: bool) {
  34. v := ferr.(Platform_Error) or_else {}
  35. return i32(v), i32(v) != 0
  36. }
  37. @(require_results)
  38. error_string :: proc(ferr: Error) -> string {
  39. if ferr == nil {
  40. return ""
  41. }
  42. switch e in ferr {
  43. case General_Error:
  44. switch e {
  45. case .None: return ""
  46. case .Permission_Denied: return "permission denied"
  47. case .Exist: return "file already exists"
  48. case .Not_Exist: return "file does not exist"
  49. case .Closed: return "file already closed"
  50. case .Timeout: return "i/o timeout"
  51. case .Broken_Pipe: return "Broken pipe"
  52. case .No_Size: return "file has no definite size"
  53. case .Invalid_File: return "invalid file"
  54. case .Invalid_Dir: return "invalid directory"
  55. case .Invalid_Path: return "invalid path"
  56. case .Invalid_Callback: return "invalid callback"
  57. case .Invalid_Command: return "invalid command"
  58. case .Unsupported: return "unsupported"
  59. case .Pattern_Has_Separator: return "pattern has separator"
  60. }
  61. case io.Error:
  62. switch e {
  63. case .None: return ""
  64. case .EOF: return "eof"
  65. case .Unexpected_EOF: return "unexpected eof"
  66. case .Short_Write: return "short write"
  67. case .Invalid_Write: return "invalid write result"
  68. case .Short_Buffer: return "short buffer"
  69. case .No_Progress: return "multiple read calls return no data or error"
  70. case .Invalid_Whence: return "invalid whence"
  71. case .Invalid_Offset: return "invalid offset"
  72. case .Invalid_Unread: return "invalid unread"
  73. case .Negative_Read: return "negative read"
  74. case .Negative_Write: return "negative write"
  75. case .Negative_Count: return "negative count"
  76. case .Buffer_Full: return "buffer full"
  77. case .Unknown, .Empty: //
  78. }
  79. case runtime.Allocator_Error:
  80. switch e {
  81. case .None: return ""
  82. case .Out_Of_Memory: return "out of memory"
  83. case .Invalid_Pointer: return "invalid allocator pointer"
  84. case .Invalid_Argument: return "invalid allocator argument"
  85. case .Mode_Not_Implemented: return "allocator mode not implemented"
  86. }
  87. case Platform_Error:
  88. return _error_string(i32(e))
  89. }
  90. return "unknown error"
  91. }
  92. print_error :: proc(f: ^File, ferr: Error, msg: string) {
  93. TEMP_ALLOCATOR_GUARD()
  94. err_str := error_string(ferr)
  95. // msg + ": " + err_str + '\n'
  96. length := len(msg) + 2 + len(err_str) + 1
  97. buf := make([]u8, length, temp_allocator())
  98. copy(buf, msg)
  99. buf[len(msg)] = ':'
  100. buf[len(msg) + 1] = ' '
  101. copy(buf[len(msg) + 2:], err_str)
  102. buf[length - 1] = '\n'
  103. write(f, buf)
  104. }