glob.odin 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  1. package posix
  2. import "core:c"
  3. when ODIN_OS == .Darwin {
  4. foreign import lib "system:System.framework"
  5. } else {
  6. foreign import lib "system:c"
  7. }
  8. // glob.h - pathname pattern-matching types
  9. foreign lib {
  10. /*
  11. The glob() function is a pathname generator that shall implement the rules defined in
  12. [[ XCU Pattern Matching Notation; https://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_13 ]],
  13. with optional support for rule 3 in XCU [[ Patterns Used for Filename Expansion; https://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_13_03 ]].
  14. [[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/glob.html ]]
  15. */
  16. @(link_name=LGLOB)
  17. glob :: proc(
  18. pattern: cstring,
  19. flags: Glob_Flags,
  20. errfunc: proc "c" (epath: cstring, eerrno: Errno) -> b32 = nil, // Return `true` to abort the glob().
  21. pglob: ^glob_t,
  22. ) -> Glob_Result ---
  23. /*
  24. Free the glob results.
  25. [[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/glob.html ]]
  26. */
  27. @(link_name=LGLOBFREE)
  28. globfree :: proc(^glob_t) ---
  29. }
  30. Glob_Flag_Bits :: enum c.int {
  31. // Append pathnames generated to the ones from a previous call to glob().
  32. APPEND = log2(GLOB_APPEND),
  33. // Make use of pglob->gl_offs. If this flag is set, pglob->gl_offs is used to specify how many null pointers to add to the beginning of pglob->gl_pathv.
  34. // In other words, pglob->gl_pathv shall point to pglob->gl_offs null pointers, followed by pglob->gl_pathc pathname pointers, followed by a null pointer.
  35. DOOFFS = log2(GLOB_DOOFFS),
  36. // Cause glob() to return when it encounters a directory that it cannot open or read. Ordinarily,
  37. // glob() continues to find matches.
  38. ERR = log2(GLOB_ERR),
  39. // Each pathname that is a directory that matches pattern shall have a <slash> appended.
  40. MARK = log2(GLOB_MARK),
  41. // Supports rule 3 in [[ XCU Patterns Used for Filename Expansion; https://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_13_03 ]].
  42. // If pattern does not match any pathname, then glob() shall return a list consisting of only pattern,
  43. // and the number of matched pathnames is 1.
  44. NOCHECK = log2(GLOB_NOCHECK),
  45. // Disable backslash escaping.
  46. NOESCAPE = log2(GLOB_NOESCAPE),
  47. // Ordinarily, glob() sorts the matching pathnames according to the current setting of the
  48. // LC_COLLATE category; see XBD LC_COLLATE. When this flag is used,
  49. // the order of pathnames returned is unspecified.
  50. NOSORT = log2(GLOB_NOSORT),
  51. }
  52. Glob_Flags :: bit_set[Glob_Flag_Bits; c.int]
  53. Glob_Result :: enum c.int {
  54. SUCCESS = 0,
  55. ABORTED = GLOB_ABORTED,
  56. NOMATCH = GLOB_NOMATCH,
  57. NOSPACE = GLOB_NOSPACE,
  58. }
  59. when ODIN_OS == .NetBSD {
  60. @(private) LGLOB :: "__glob30"
  61. @(private) LGLOBFREE :: "__globfree30"
  62. } else {
  63. @(private) LGLOB :: "glob" + INODE_SUFFIX
  64. @(private) LGLOBFREE :: "globfree"
  65. }
  66. when ODIN_OS == .Darwin {
  67. glob_t :: struct {
  68. gl_pathc: c.size_t, /* [PSX] count of paths matched by pattern */
  69. gl_matchc: c.int, /* count of paths matching pattern */
  70. gl_offs: c.size_t, /* [PSX] slots to reserve at the beginning of gl_pathv */
  71. gl_flags: Glob_Flags, /* copy of flags parameter to glob */
  72. gl_pathv: [^]cstring `fmt:"v,gl_pathc"`, /* [PSX] pointer to list of matched pathnames */
  73. // Non-standard alternate file system access functions:
  74. using _: struct #raw_union {
  75. gl_errfunc: proc "c" (cstring, c.int) -> c.int,
  76. gl_errblk: proc "c" (cstring, c.int) -> c.int,
  77. },
  78. gl_closedir: proc "c" (dirp: DIR),
  79. gl_readdir: proc "c" (dirp: DIR) -> ^dirent,
  80. gl_opendir: proc "c" (path: cstring) -> DIR,
  81. gl_lstat: proc "c" (path: cstring, buf: ^stat_t) -> result,
  82. gl_stat: proc "c" (path: cstring, buf: ^stat_t) -> result,
  83. }
  84. GLOB_APPEND :: 0x0001
  85. GLOB_DOOFFS :: 0x0002
  86. GLOB_ERR :: 0x0004
  87. GLOB_MARK :: 0x0008
  88. GLOB_NOCHECK :: 0x0010
  89. GLOB_NOESCAPE :: 0x2000
  90. GLOB_NOSORT :: 0x0020
  91. GLOB_ABORTED :: -2
  92. GLOB_NOMATCH :: -3
  93. GLOB_NOSPACE :: -1
  94. } else when ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD {
  95. glob_t :: struct {
  96. gl_pathc: c.size_t, /* [PSX] count of paths matched by pattern */
  97. gl_matchc: c.size_t, /* count of paths matching pattern */
  98. gl_offs: c.size_t, /* [PSX] slots to reserve at the beginning of gl_pathv */
  99. gl_flags: Glob_Flags, /* copy of flags parameter to glob */
  100. gl_pathv: [^]cstring `fmt:"v,gl_pathc"`, /* [PSX] pointer to list of matched pathnames */
  101. // Non-standard alternate file system access functions:
  102. gl_errfunc: proc "c" (cstring, c.int) -> c.int,
  103. gl_closedir: proc "c" (dirp: DIR),
  104. gl_readdir: proc "c" (dirp: DIR) -> ^dirent,
  105. gl_opendir: proc "c" (path: cstring) -> DIR,
  106. gl_lstat: proc "c" (path: cstring, buf: ^stat_t) -> result,
  107. gl_stat: proc "c" (path: cstring, buf: ^stat_t) -> result,
  108. }
  109. GLOB_APPEND :: 0x0001
  110. GLOB_DOOFFS :: 0x0002
  111. GLOB_ERR :: 0x0004
  112. GLOB_MARK :: 0x0008
  113. GLOB_NOCHECK :: 0x0010
  114. GLOB_NOESCAPE :: 0x2000 when ODIN_OS == .FreeBSD else 0x0100
  115. GLOB_NOSORT :: 0x0020
  116. GLOB_ABORTED :: -2
  117. GLOB_NOMATCH :: -3
  118. GLOB_NOSPACE :: -1
  119. } else when ODIN_OS == .OpenBSD {
  120. glob_t :: struct {
  121. gl_pathc: c.size_t, /* [PSX] count of paths matched by pattern */
  122. gl_matchc: c.size_t, /* count of paths matching pattern */
  123. gl_offs: c.size_t, /* [PSX] slots to reserve at the beginning of gl_pathv */
  124. gl_flags: Glob_Flags, /* copy of flags parameter to glob */
  125. gl_pathv: [^]cstring `fmt:"v,gl_pathc"`, /* [PSX] pointer to list of matched pathnames */
  126. gl_statv: [^]stat_t,
  127. // Non-standard alternate file system access functions:
  128. gl_errfunc: proc "c" (cstring, c.int) -> c.int,
  129. gl_closedir: proc "c" (dirp: DIR),
  130. gl_readdir: proc "c" (dirp: DIR) -> ^dirent,
  131. gl_opendir: proc "c" (path: cstring) -> DIR,
  132. gl_lstat: proc "c" (path: cstring, buf: ^stat_t) -> result,
  133. gl_stat: proc "c" (path: cstring, buf: ^stat_t) -> result,
  134. }
  135. GLOB_APPEND :: 0x0001
  136. GLOB_DOOFFS :: 0x0002
  137. GLOB_ERR :: 0x0004
  138. GLOB_MARK :: 0x0008
  139. GLOB_NOCHECK :: 0x0010
  140. GLOB_NOESCAPE :: 0x1000
  141. GLOB_NOSORT :: 0x0020
  142. GLOB_ABORTED :: -2
  143. GLOB_NOMATCH :: -3
  144. GLOB_NOSPACE :: -1
  145. } else {
  146. #panic("posix is unimplemented for the current target")
  147. }