PageRenderTime 23ms CodeModel.GetById 12ms app.highlight 5ms RepoModel.GetById 1ms app.codeStats 1ms

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