/src/lib/io/internal/unixish_path_name.e

http://github.com/tybor/Liberty · Specman e · 247 lines · 193 code · 24 blank · 30 comment · 18 complexity · dbf0d12eb7782feb0823664d4ad9cf38 MD5 · raw file

  1. -- This file is part of a Liberty Eiffel library.
  2. -- See the full copyright at the end.
  3. --
  4. deferred class UNIXISH_PATH_NAME
  5. -- A PATH_NAME that is more or less built after the same model as traditional unix path names.
  6. inherit PATH_NAME
  7. feature {ANY} -- Access
  8. last: STRING
  9. deferred
  10. ensure then
  11. not Result.has(directory_separator)
  12. end
  13. extension: STRING
  14. deferred
  15. ensure then
  16. is_extension: not Result.is_empty implies Result.first = extension_separator
  17. is_minimal: Result.occurrences(extension_separator) <= 1
  18. not Result.has(directory_separator)
  19. end
  20. is_valid_file_name (elem: STRING): BOOLEAN
  21. do
  22. Result := not elem.has(directory_separator)
  23. ensure then
  24. Result implies not elem.has(directory_separator)
  25. end
  26. is_valid_directory: BOOLEAN True
  27. is_valid_file: BOOLEAN
  28. local
  29. lst: like last
  30. do
  31. lst := last
  32. Result := not (last.is_empty or else last.is_equal(this_directory) or else last.is_equal(up_directory))
  33. end
  34. is_separator (ch: CHARACTER): BOOLEAN
  35. -- Is `ch' a possible path separator?
  36. do
  37. Result := ch = directory_separator
  38. ensure
  39. (ch = directory_separator) implies Result
  40. end
  41. feature {ANY} -- Operations
  42. go_up
  43. local
  44. lst: like last
  45. do
  46. from
  47. until
  48. path.count <= 1 or else not is_separator(path.last)
  49. loop
  50. path.remove_last
  51. end
  52. if is_empty then
  53. if not is_absolute then
  54. add_last(up_directory)
  55. end
  56. else
  57. lst := last
  58. if lst.is_equal(this_directory) then
  59. remove_last
  60. add_last(up_directory)
  61. elseif lst.is_equal(up_directory) then
  62. add_last(up_directory)
  63. else
  64. remove_last
  65. end
  66. end
  67. end
  68. join_to (other: PATH_JOINER)
  69. local
  70. p: INTEGER; element: STRING
  71. do
  72. p := start_join_to (other)
  73. if p <= path.upper then
  74. element := once "a_file_name"
  75. from
  76. p := scan_element(p, element)
  77. until
  78. p > path.upper
  79. loop
  80. join_directory_to(other, element)
  81. p := scan_element(p, element)
  82. end
  83. if not element.is_empty then
  84. if is_separator(path.last) then
  85. join_directory_to(other, element)
  86. else
  87. join_element_to(other, element)
  88. end
  89. end
  90. other.end_join
  91. end
  92. end
  93. short_name: STRING
  94. local
  95. i: INTEGER
  96. do
  97. Result := once ""
  98. Result.copy(path)
  99. if path.count > 1 or path.first /= directory_separator then
  100. if Result.last = directory_separator then
  101. Result.remove_last
  102. end
  103. i := Result.last_index_of(directory_separator)
  104. if i >= 0 then
  105. Result.shrink(i + 1, Result.count)
  106. end
  107. end
  108. end
  109. feature {ANY} -- Constants
  110. extension_separator: CHARACTER
  111. -- Character used to separate filenames from extensions
  112. deferred
  113. end
  114. directory_separator: CHARACTER
  115. -- Character used to separate directories
  116. -- This character is forbidden in filenames
  117. deferred
  118. end
  119. up_directory: STRING
  120. deferred
  121. end
  122. this_directory: STRING
  123. deferred
  124. end
  125. feature {PATH_JOINER}
  126. join_element (element: STRING)
  127. do
  128. if not is_empty and then last.is_equal(this_directory) then
  129. remove_last
  130. end
  131. if not path.is_empty and then not is_separator(path.last) then
  132. path.extend(directory_separator)
  133. end
  134. path.append(element)
  135. end
  136. join_extension (an_extension: STRING)
  137. do
  138. path.extend(extension_separator)
  139. path.append(an_extension)
  140. end
  141. join_error: BOOLEAN False
  142. feature {}
  143. path: STRING
  144. start_join_to (other: PATH_JOINER): INTEGER
  145. require
  146. other /= Void
  147. deferred
  148. ensure
  149. Result.in_range(path.lower, path.upper + 1)
  150. end
  151. scan_element (p: INTEGER; element: STRING): INTEGER
  152. require
  153. path.valid_index(p)
  154. element /= Void
  155. do
  156. element.clear_count
  157. from
  158. Result := p
  159. until
  160. Result > path.upper or else not is_separator(path.item(Result))
  161. loop
  162. Result := Result + 1
  163. end
  164. from
  165. until
  166. Result > path.upper or else is_separator(path.item(Result))
  167. loop
  168. element.add_last(path.item(Result))
  169. Result := Result + 1
  170. end
  171. ensure
  172. Result.in_range(p + 1, path.upper + 1)
  173. path.substring(p, Result - 1).has_suffix(element)
  174. end
  175. join_directory_to (other: PATH_JOINER; element: STRING)
  176. require
  177. other /= Void
  178. not element.is_empty
  179. do
  180. if element.is_equal(up_directory) then
  181. other.join_up
  182. elseif element.is_equal(this_directory) then
  183. else
  184. -- *** TODO: handle extensions
  185. other.join_directory(element)
  186. end
  187. end
  188. join_element_to (other: PATH_JOINER; element: STRING)
  189. require
  190. other /= Void
  191. not element.is_empty
  192. do
  193. if element.is_equal(up_directory) then
  194. other.join_up
  195. elseif element.is_equal(this_directory) then
  196. else
  197. -- *** TODO: handle extensions
  198. other.join_element(element)
  199. end
  200. end
  201. invariant
  202. path /= Void
  203. end -- class UNIXISH_PATH_NAME
  204. --
  205. -- Copyright (C) 2009-2017: by all the people cited in the AUTHORS file.
  206. --
  207. -- Permission is hereby granted, free of charge, to any person obtaining a copy
  208. -- of this software and associated documentation files (the "Software"), to deal
  209. -- in the Software without restriction, including without limitation the rights
  210. -- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  211. -- copies of the Software, and to permit persons to whom the Software is
  212. -- furnished to do so, subject to the following conditions:
  213. --
  214. -- The above copyright notice and this permission notice shall be included in
  215. -- all copies or substantial portions of the Software.
  216. --
  217. -- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  218. -- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  219. -- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  220. -- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  221. -- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  222. -- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  223. -- THE SOFTWARE.