path_unix.odin 1.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. //+build linux, darwin, freebsd, openbsd, netbsd
  2. package filepath
  3. when ODIN_OS == .Darwin {
  4. foreign import libc "system:System.framework"
  5. } else {
  6. foreign import libc "system:c"
  7. }
  8. import "base:runtime"
  9. import "core:strings"
  10. SEPARATOR :: '/'
  11. SEPARATOR_STRING :: `/`
  12. LIST_SEPARATOR :: ':'
  13. is_reserved_name :: proc(path: string) -> bool {
  14. return false
  15. }
  16. is_abs :: proc(path: string) -> bool {
  17. return strings.has_prefix(path, "/")
  18. }
  19. abs :: proc(path: string, allocator := context.allocator) -> (string, bool) {
  20. rel := path
  21. if rel == "" {
  22. rel = "."
  23. }
  24. rel_cstr := strings.clone_to_cstring(rel, context.temp_allocator)
  25. path_ptr := realpath(rel_cstr, nil)
  26. if path_ptr == nil {
  27. return "", __error()^ == 0
  28. }
  29. defer _unix_free(rawptr(path_ptr))
  30. path_str := strings.clone(string(path_ptr), allocator)
  31. return path_str, true
  32. }
  33. join :: proc(elems: []string, allocator := context.allocator) -> (joined: string, err: runtime.Allocator_Error) #optional_allocator_error {
  34. for e, i in elems {
  35. if e != "" {
  36. runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD(ignore = context.temp_allocator == allocator)
  37. p := strings.join(elems[i:], SEPARATOR_STRING, context.temp_allocator) or_return
  38. return clean(p, allocator)
  39. }
  40. }
  41. return "", nil
  42. }
  43. @(private)
  44. foreign libc {
  45. realpath :: proc(path: cstring, resolved_path: [^]byte = nil) -> cstring ---
  46. @(link_name="free") _unix_free :: proc(ptr: rawptr) ---
  47. }
  48. when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD {
  49. @(private)
  50. foreign libc {
  51. @(link_name="__error") __error :: proc() -> ^i32 ---
  52. }
  53. } else when ODIN_OS == .OpenBSD || ODIN_OS == .NetBSD {
  54. @(private)
  55. foreign libc {
  56. @(link_name="__errno") __error :: proc() -> ^i32 ---
  57. }
  58. } else {
  59. @(private)
  60. foreign libc {
  61. @(link_name="__errno_location") __error :: proc() -> ^i32 ---
  62. }
  63. }