recls-ruby 2.11.0 → 2.11.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (43) hide show
  1. checksums.yaml +5 -5
  2. data/LICENSE +27 -24
  3. data/README.md +242 -1
  4. data/examples/find_files_and_directories.md +33 -30
  5. data/examples/find_files_and_directories.recursive.md +255 -254
  6. data/examples/show_hidden_files.md +4 -1
  7. data/examples/show_hidden_files.rb +1 -1
  8. data/examples/show_readonly_files.md +4 -1
  9. data/examples/show_readonly_files.rb +1 -1
  10. data/lib/recls/api.rb +76 -73
  11. data/lib/recls/combine_paths_1.rb +26 -23
  12. data/lib/recls/combine_paths_2plus.rb +32 -29
  13. data/lib/recls/entry.rb +277 -273
  14. data/lib/recls/file_search.rb +194 -193
  15. data/lib/recls/flags.rb +47 -45
  16. data/lib/recls/foreach.rb +105 -98
  17. data/lib/recls/obsolete.rb +80 -79
  18. data/lib/recls/recls.rb +16 -15
  19. data/lib/recls/stat.rb +137 -134
  20. data/lib/recls/util.rb +95 -92
  21. data/lib/recls/version.rb +18 -17
  22. data/lib/recls/ximpl/os.rb +45 -43
  23. data/lib/recls/ximpl/unix.rb +38 -35
  24. data/lib/recls/ximpl/util.rb +597 -596
  25. data/lib/recls/ximpl/windows.rb +139 -136
  26. data/lib/recls.rb +10 -9
  27. data/test/scratch/test_display_parts.rb +33 -33
  28. data/test/scratch/test_entry.rb +6 -6
  29. data/test/scratch/test_files_and_directories.rb +8 -8
  30. data/test/scratch/test_foreach.rb +10 -10
  31. data/test/scratch/test_module_function.rb +33 -33
  32. data/test/scratch/test_pattern_arrays.rb +5 -5
  33. data/test/scratch/test_show_dev_and_ino.rb +1 -1
  34. data/test/scratch/test_show_hidden.rb +3 -3
  35. data/test/unit/tc_recls_entries.rb +31 -31
  36. data/test/unit/tc_recls_entry.rb +19 -19
  37. data/test/unit/tc_recls_file_search.rb +32 -32
  38. data/test/unit/tc_recls_module.rb +25 -25
  39. data/test/unit/tc_recls_util.rb +161 -161
  40. data/test/unit/tc_recls_ximpl_util.rb +676 -676
  41. data/test/unit/test_all_separately.sh +1 -1
  42. data/test/unit/ts_all.rb +4 -4
  43. metadata +6 -6
@@ -1,13 +1,14 @@
1
- # ######################################################################### #
2
- # File: recls/ximpl/util.rb
1
+ # ######################################################################## #
2
+ # File: recls/ximpl/util.rb
3
3
  #
4
- # Purpose: Internal implementation constructs for the recls library.
4
+ # Purpose: Internal implementation constructs for the recls library.
5
5
  #
6
- # Created: 24th July 2012
7
- # Updated: 14th April 2019
6
+ # Created: 24th July 2012
7
+ # Updated: 20th April 2024
8
8
  #
9
- # Author: Matthew Wilson
9
+ # Author: Matthew Wilson
10
10
  #
11
+ # Copyright (c) 2019-2024, Matthew Wilson and Synesis Information Systems
11
12
  # Copyright (c) 2012-2019, Matthew Wilson and Synesis Software
12
13
  # All rights reserved.
13
14
  #
@@ -33,7 +34,7 @@
33
34
  # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
34
35
  # POSSIBILITY OF SUCH DAMAGE.
35
36
  #
36
- # ######################################################################### #
37
+ # ######################################################################## #
37
38
 
38
39
 
39
40
  require 'recls/ximpl/os'
@@ -41,6 +42,7 @@ require 'recls/flags'
41
42
 
42
43
  require 'pathname'
43
44
 
45
+
44
46
  =begin
45
47
  =end
46
48
 
@@ -48,832 +50,831 @@ module Recls # :nodoc:
48
50
 
49
51
  # :stopdoc:
50
52
 
51
- module Ximpl # :nodoc: all
53
+ module Ximpl # :nodoc: all
52
54
 
53
- module Util # :nodoc: all
55
+ module Util # :nodoc: all
54
56
 
55
- # @!visibility private
56
- def self.is_path_name_separator(c) # :nodoc:
57
+ # @!visibility private
58
+ def self.is_path_name_separator(c) # :nodoc:
57
59
 
58
- return true if ?/ == c
60
+ return true if ?/ == c
59
61
 
60
- if Recls::Ximpl::OS::OS_IS_WINDOWS
62
+ if Recls::Ximpl::OS::OS_IS_WINDOWS
61
63
 
62
- return true if ?\\ == c
63
- end
64
+ return true if ?\\ == c
65
+ end
64
66
 
65
- return false
66
- end
67
+ return false
68
+ end
67
69
 
68
- # Indicates whether a trailing slash is on the given path
69
- #
70
- # dependencies: none
71
- #
72
- # @!visibility private
73
- def self.has_trailing_slash(p) # :nodoc:
70
+ # Indicates whether a trailing slash is on the given path
71
+ #
72
+ # dependencies: none
73
+ #
74
+ # @!visibility private
75
+ def self.has_trailing_slash(p) # :nodoc:
74
76
 
75
- return p if p.nil? or p.empty?
77
+ return p if p.nil? or p.empty?
76
78
 
77
- return self.is_path_name_separator(p[-1])
78
- end
79
+ return self.is_path_name_separator(p[-1])
80
+ end
79
81
 
80
- # returns the trailing slash, or nil if none present
81
- #
82
- # dependencies: none
83
- #
84
- # @!visibility private
85
- def self.get_trailing_slash(p, args = {}) # :nodoc:
82
+ # returns the trailing slash, or nil if none present
83
+ #
84
+ # dependencies: none
85
+ #
86
+ # @!visibility private
87
+ def self.get_trailing_slash(p, args = {}) # :nodoc:
86
88
 
87
- return nil if p.nil?
88
- return nil if p.empty?
89
+ return nil if p.nil?
90
+ return nil if p.empty?
89
91
 
90
- return self.is_path_name_separator(p[-1]) ? p[-1] : nil
91
- end
92
+ return self.is_path_name_separator(p[-1]) ? p[-1] : nil
93
+ end
92
94
 
93
- # appends trailing slash to a path if not already
94
- # present
95
- #
96
- # dependencies: none
97
- #
98
- # @!visibility private
99
- def self.append_trailing_slash(p, slash = nil) # :nodoc:
95
+ # appends trailing slash to a path if not already
96
+ # present
97
+ #
98
+ # dependencies: none
99
+ #
100
+ # @!visibility private
101
+ def self.append_trailing_slash(p, slash = nil) # :nodoc:
100
102
 
101
- return p if not p or p.empty?
103
+ return p if not p or p.empty?
102
104
 
103
- return p if self.is_path_name_separator(p[-1])
105
+ return p if self.is_path_name_separator(p[-1])
104
106
 
105
- slash = '/' if not slash
107
+ slash = '/' if not slash
106
108
 
107
- "#{p}#{slash}"
108
- end
109
+ "#{p}#{slash}"
110
+ end
109
111
 
110
- # trims trailing slash from a path, unless it is the
111
- # root
112
- #
113
- # dependencies: none
114
- #
115
- # @!visibility private
116
- def self.trim_trailing_slash(p) # :nodoc:
112
+ # trims trailing slash from a path, unless it is the
113
+ # root
114
+ #
115
+ # dependencies: none
116
+ #
117
+ # @!visibility private
118
+ def self.trim_trailing_slash(p) # :nodoc:
117
119
 
118
- return p if not p or p.empty?
120
+ return p if not p or p.empty?
119
121
 
120
- p = p[0 ... -1] if self.is_path_name_separator(p[-1])
122
+ p = p[0 ... -1] if self.is_path_name_separator(p[-1])
121
123
 
122
- return p
123
- end
124
+ return p
125
+ end
124
126
 
125
- # From path p, returns a tuple containing either:
126
- #
127
- # [ nil, p ] if p does not contain a Windows root, or
128
- #
129
- # [ wroot, remainder ] if p does contain a Windows root, or
130
- #
131
- # [ nil, nil ] if p is nil
132
- #
133
- # dependencies: none
134
- #
135
- # @!visibility private
136
- def self.get_windows_root(p) # :nodoc:
127
+ # From path p, returns a tuple containing either:
128
+ #
129
+ # [ nil, p ] if p does not contain a Windows root, or
130
+ #
131
+ # [ wroot, remainder ] if p does contain a Windows root, or
132
+ #
133
+ # [ nil, nil ] if p is nil
134
+ #
135
+ # dependencies: none
136
+ #
137
+ # @!visibility private
138
+ def self.get_windows_root(p) # :nodoc:
137
139
 
138
- return [ nil, nil ] if not p
140
+ return [ nil, nil ] if not p
139
141
 
140
- if Recls::Ximpl::OS::OS_IS_WINDOWS
142
+ if Recls::Ximpl::OS::OS_IS_WINDOWS
141
143
 
142
- # Windows local drive (e.g. 'H:')
143
- #
144
- # NOTE: this works for both rooted and unrooted paths
145
- if p =~ /^([a-zA-Z]:)/
144
+ # Windows local drive (e.g. 'H:')
145
+ #
146
+ # NOTE: this works for both rooted and unrooted paths
147
+ if p =~ /^([a-zA-Z]:)/
146
148
 
147
- return [ $1, $' ]
148
- end
149
+ return [ $1, $' ]
150
+ end
149
151
 
150
- # UNC network drive
151
- #
152
- # NOTE: there are several permutations ...
153
- if p =~ /^(\\\\[^\\\/:*?<>|]+\\[^\\\/:*?<>|]+)([\\\/].*)$/
152
+ # UNC network drive
153
+ #
154
+ # NOTE: there are several permutations ...
155
+ if p =~ /^(\\\\[^\\\/:*?<>|]+\\[^\\\/:*?<>|]+)([\\\/].*)$/
154
156
 
155
- # \\server\share{\{... rest of path}}
156
- return [ $1, $2 ]
157
- end
158
- if p =~ /^(\\\\[^\\\/:*?<>|]+\\[^\\\/:*?<>|]+)$/
157
+ # \\server\share{\{... rest of path}}
158
+ return [ $1, $2 ]
159
+ end
160
+ if p =~ /^(\\\\[^\\\/:*?<>|]+\\[^\\\/:*?<>|]+)$/
159
161
 
160
- # \\server\share
161
- return [ $1, nil ]
162
- end
163
- if p =~ /^(\\\\[^\\\/:*?<>|]+\\)$/
164
-
165
- # \\server\
166
- return [ $1, nil ]
167
- end
168
- if p =~ /^(\\\\[^\\\/:*?<>|]+)$/
169
-
170
- # \\server
171
- return [ $1, nil ]
172
- end
173
- end
174
-
175
- return [ nil, p ]
176
- end
177
-
178
- # obtains the parts from a path, including any Windows root and
179
- # the file basename
180
- #
181
- # @!visibility private
182
- def self.path_parts(path) # :nodoc:
183
-
184
- return nil if path.nil?
185
- return [] if path.empty?
186
-
187
- parts = []
188
-
189
- wr, rem = self.get_windows_root(path)
190
-
191
- parts << wr if wr
192
-
193
- until rem.nil? || rem.empty?
194
-
195
- if rem =~ /^([^\\\/]*[\\\/])/
196
-
197
- parts << $1
198
- rem = $'
199
- else
162
+ # \\server\share
163
+ return [ $1, nil ]
164
+ end
165
+ if p =~ /^(\\\\[^\\\/:*?<>|]+\\)$/
166
+
167
+ # \\server\
168
+ return [ $1, nil ]
169
+ end
170
+ if p =~ /^(\\\\[^\\\/:*?<>|]+)$/
171
+
172
+ # \\server
173
+ return [ $1, nil ]
174
+ end
175
+ end
176
+
177
+ return [ nil, p ]
178
+ end
179
+
180
+ # obtains the parts from a path, including any Windows root and
181
+ # the file basename
182
+ #
183
+ # @!visibility private
184
+ def self.path_parts(path) # :nodoc:
185
+
186
+ return nil if path.nil?
187
+ return [] if path.empty?
188
+
189
+ parts = []
190
+
191
+ wr, rem = self.get_windows_root(path)
192
+
193
+ parts << wr if wr
194
+
195
+ until rem.nil? || rem.empty?
196
+
197
+ if rem =~ /^([^\\\/]*[\\\/])/
198
+
199
+ parts << $1
200
+ rem = $'
201
+ else
200
202
 
201
- parts << rem
202
- rem = ''
203
- end
204
- end
205
-
206
- parts
207
- end
208
-
209
- # Returns a tuple consisting of the following
210
- # elements (or nil, for any element that is not)
211
- # present
212
- #
213
- # f1. Windows root, or nil
214
- # f2. directory, or nil
215
- # f3. basename, or nil
216
- # f4. basename-minus-extension, or nil
217
- # f5. extension, or nil
218
- # f6. array of directory path parts, which may be empty (not nil)
219
- # f7. array of all path parts, which may be empty (not nil)
220
- #
221
- # dependencies: Util.path_parts, Util.get_windows_root
222
- #
223
- # @!visibility private
224
- def self.split_path(p) # :nodoc:
203
+ parts << rem
204
+ rem = ''
205
+ end
206
+ end
207
+
208
+ parts
209
+ end
210
+
211
+ # Returns a tuple consisting of the following
212
+ # elements (or nil, for any element that is not)
213
+ # present
214
+ #
215
+ # f1. Windows root, or nil
216
+ # f2. directory, or nil
217
+ # f3. basename, or nil
218
+ # f4. basename-minus-extension, or nil
219
+ # f5. extension, or nil
220
+ # f6. array of directory path parts, which may be empty (not nil)
221
+ # f7. array of all path parts, which may be empty (not nil)
222
+ #
223
+ # dependencies: Util.path_parts, Util.get_windows_root
224
+ #
225
+ # @!visibility private
226
+ def self.split_path(p) # :nodoc:
225
227
 
226
- f1_windows_root, remainder = self.get_windows_root p
227
- f1_windows_root = nil if not f1_windows_root or f1_windows_root.empty?
228
- remainder = nil if not remainder or remainder.empty?
228
+ f1_windows_root, remainder = self.get_windows_root p
229
+ f1_windows_root = nil if not f1_windows_root or f1_windows_root.empty?
230
+ remainder = nil if not remainder or remainder.empty?
229
231
 
230
- if not remainder or remainder.empty?
232
+ if not remainder or remainder.empty?
231
233
 
232
- f2_directory = nil
233
- f3_basename = nil
234
- f4_nameonly = nil
235
- f5_extension = nil
236
- else
234
+ f2_directory = nil
235
+ f3_basename = nil
236
+ f4_nameonly = nil
237
+ f5_extension = nil
238
+ else
237
239
 
238
- if remainder =~ /^(.*[\\\/])([^\\\/]*)$/
240
+ if remainder =~ /^(.*[\\\/])([^\\\/]*)$/
239
241
 
240
- f2_directory = $1
241
- f3_basename = $2
242
- else
242
+ f2_directory = $1
243
+ f3_basename = $2
244
+ else
243
245
 
244
- f2_directory = nil
245
- f3_basename = remainder
246
- f4_nameonly = nil
247
- f5_extension = nil
248
- end
246
+ f2_directory = nil
247
+ f3_basename = remainder
248
+ f4_nameonly = nil
249
+ f5_extension = nil
250
+ end
249
251
 
250
- f2_directory = nil if not f2_directory or f2_directory.empty?
251
- f3_basename = nil if not f3_basename or f3_basename.empty?
252
+ f2_directory = nil if not f2_directory or f2_directory.empty?
253
+ f3_basename = nil if not f3_basename or f3_basename.empty?
252
254
 
253
- if f3_basename
255
+ if f3_basename
254
256
 
255
- # special case: treat '.' and '..' as file-name only
256
- if '.' == f3_basename or '..' == f3_basename
257
+ # special case: treat '.' and '..' as file-name only
258
+ if '.' == f3_basename or '..' == f3_basename
257
259
 
258
- f4_nameonly = f3_basename
259
- f5_extension = nil
260
- elsif f3_basename =~ /^(.*)(\.[^.]*)$/
260
+ f4_nameonly = f3_basename
261
+ f5_extension = nil
262
+ elsif f3_basename =~ /^(.*)(\.[^.]*)$/
261
263
 
262
- f4_nameonly = $1
263
- f5_extension = $2
264
- else
264
+ f4_nameonly = $1
265
+ f5_extension = $2
266
+ else
265
267
 
266
- f4_nameonly = f3_basename
267
- f5_extension = nil
268
- end
269
- else
268
+ f4_nameonly = f3_basename
269
+ f5_extension = nil
270
+ end
271
+ else
270
272
 
271
- f4_nameonly = nil
272
- f5_extension = nil
273
- end
274
- end
273
+ f4_nameonly = nil
274
+ f5_extension = nil
275
+ end
276
+ end
275
277
 
276
- f4_nameonly = nil if not f4_nameonly or f4_nameonly.empty?
277
- f5_extension = nil if not f5_extension or f5_extension.empty?
278
- f6_directory_parts = self.path_parts(f2_directory)
279
- f7_path_parts = self.path_parts(p)
278
+ f4_nameonly = nil if not f4_nameonly or f4_nameonly.empty?
279
+ f5_extension = nil if not f5_extension or f5_extension.empty?
280
+ f6_directory_parts = self.path_parts(f2_directory)
281
+ f7_path_parts = self.path_parts(p)
280
282
 
281
- return [ f1_windows_root, f2_directory, f3_basename, f4_nameonly, f5_extension, f6_directory_parts, f7_path_parts ]
282
- end
283
+ return [ f1_windows_root, f2_directory, f3_basename, f4_nameonly, f5_extension, f6_directory_parts, f7_path_parts ]
284
+ end
283
285
 
284
- # Returns a tuple consisting of:
285
- #
286
- # f1. The canonicalised array of parts
287
- # f2. A boolean indicating whether to 'consume' the basename
288
- #
289
- # dependencies: OS.is_root_dir_, OS.get_number_of_dots_dir_,
290
- #
291
- # @!visibility private
292
- def self.canonicalise_parts(parts, basename = nil) # :nodoc:
286
+ # Returns a tuple consisting of:
287
+ #
288
+ # f1. The canonicalised array of parts
289
+ # f2. A boolean indicating whether to 'consume' the basename
290
+ #
291
+ # dependencies: OS.is_root_dir_, OS.get_number_of_dots_dir_,
292
+ #
293
+ # @!visibility private
294
+ def self.canonicalise_parts(parts, basename = nil) # :nodoc:
293
295
 
294
- newParts = []
296
+ newParts = []
295
297
 
296
- lastSingleDots = nil
298
+ lastSingleDots = nil
297
299
 
298
- path_is_rooted = nil
300
+ path_is_rooted = nil
299
301
 
300
- index = -1
301
- parts.each do |part|
302
+ index = -1
303
+ parts.each do |part|
302
304
 
303
- index += 1
305
+ index += 1
304
306
 
305
- next if not part
306
- next if part.empty?
307
+ next if not part
308
+ next if part.empty?
307
309
 
308
- if path_is_rooted.nil?
310
+ if path_is_rooted.nil?
309
311
 
310
- path_is_rooted = self.is_path_name_separator(part[0])
311
- end
312
+ path_is_rooted = self.is_path_name_separator(part[0])
313
+ end
312
314
 
313
- if ?. == part[0]
315
+ if ?. == part[0]
314
316
 
315
- if self.is_path_name_separator(part[1])
317
+ if self.is_path_name_separator(part[1])
316
318
 
317
- # single dots, so ...
319
+ # single dots, so ...
318
320
 
319
- # ... remember the last instance, and ...
320
- lastSingleDots = part
321
+ # ... remember the last instance, and ...
322
+ lastSingleDots = part
321
323
 
322
- # ... skip to leave this out of the result
323
- next
324
- elsif ?. == part[1]
324
+ # ... skip to leave this out of the result
325
+ next
326
+ elsif ?. == part[1]
325
327
 
326
- if self.is_path_name_separator(part[2])
328
+ if self.is_path_name_separator(part[2])
327
329
 
328
- # double dots, so ...
329
- # ... skip this and pop prior from the new list iff:
330
- #
331
- # 1. there is a prior elements in the new list (size > 1); AND
332
- # 2. the last element in the new list is not the root directory; AND
333
- # 3. the last element in the list is not a dots directory
334
- if not newParts.empty? # 1.
330
+ # double dots, so ...
331
+ # ... skip this and pop prior from the new list iff:
332
+ #
333
+ # 1. there is a prior elements in the new list (size > 1); AND
334
+ # 2. the last element in the new list is not the root directory; AND
335
+ # 3. the last element in the list is not a dots directory
336
+ if not newParts.empty? # 1.
335
337
 
336
- priorPart = newParts[-1]
337
- if 1 == newParts.size and OS.is_root_dir_(priorPart)
338
+ priorPart = newParts[-1]
339
+ if 1 == newParts.size and OS.is_root_dir_(priorPart)
338
340
 
339
- # 2.
340
- next
341
- else
341
+ # 2.
342
+ next
343
+ else
342
344
 
343
- dirtype = OS.get_number_of_dots_dir_(priorPart)
344
- if 0 == dirtype # 3.
345
+ dirtype = OS.get_number_of_dots_dir_(priorPart)
346
+ if 0 == dirtype # 3.
345
347
 
346
- if newParts.pop
348
+ if newParts.pop
347
349
 
348
- next
349
- end
350
- end
351
- end
352
- end
353
- else
350
+ next
351
+ end
352
+ end
353
+ end
354
+ end
355
+ else
354
356
 
355
- # it's a ..X part
356
- end
357
- else
357
+ # it's a ..X part
358
+ end
359
+ else
358
360
 
359
- # it's a .X part
360
- end
361
- else
361
+ # it's a .X part
362
+ end
363
+ else
362
364
 
363
- # it's a non-dots part
364
- end
365
+ # it's a non-dots part
366
+ end
365
367
 
366
- newParts << part
367
- end
368
+ newParts << part
369
+ end
368
370
 
369
- consume_basename = false
371
+ consume_basename = false
370
372
 
371
- if basename
373
+ if basename
372
374
 
373
- if ?. == basename[0]
375
+ if ?. == basename[0]
374
376
 
375
- if 1 == basename.size
377
+ if 1 == basename.size
376
378
 
377
- # single dots
378
- if newParts.empty?
379
+ # single dots
380
+ if newParts.empty?
379
381
 
380
- lastSingleDots = false
381
- else
382
+ lastSingleDots = false
383
+ else
382
384
 
383
- consume_basename = true
384
- end
385
- elsif ?. == basename[1] and 2 == basename.size
385
+ consume_basename = true
386
+ end
387
+ elsif ?. == basename[1] and 2 == basename.size
386
388
 
387
- # double dots, so ...
388
- #
389
- # ... pop unless we already have some outstanding double dots
390
- if newParts.empty?
389
+ # double dots, so ...
390
+ #
391
+ # ... pop unless we already have some outstanding double dots
392
+ if newParts.empty?
391
393
 
392
- newParts << '..'
393
- consume_basename = true
394
- elsif 1 == newParts.size && 1 == newParts[0].size && Util.is_path_name_separator(newParts[0][0])
394
+ newParts << '..'
395
+ consume_basename = true
396
+ elsif 1 == newParts.size && 1 == newParts[0].size && Util.is_path_name_separator(newParts[0][0])
395
397
 
396
- consume_basename = true
397
- else
398
+ consume_basename = true
399
+ else
398
400
 
399
- if 2 != OS.get_number_of_dots_dir_(newParts[-1])
401
+ if 2 != OS.get_number_of_dots_dir_(newParts[-1])
400
402
 
401
- newParts.pop
402
- consume_basename = true
403
- end
404
- end
405
- end
406
- end
407
- end
403
+ newParts.pop
404
+ consume_basename = true
405
+ end
406
+ end
407
+ end
408
+ end
409
+ end
408
410
 
409
- # push lastSingleDots (which may contain a trailing slash) if
410
- # exists and newParts is empty
411
- newParts << lastSingleDots if lastSingleDots and newParts.empty?
411
+ # push lastSingleDots (which may contain a trailing slash) if
412
+ # exists and newParts is empty
413
+ newParts << lastSingleDots if lastSingleDots and newParts.empty?
412
414
 
413
- if not newParts.empty?
415
+ if not newParts.empty?
414
416
 
415
- if 2 == OS.get_number_of_dots_dir_(newParts[-1])
417
+ if 2 == OS.get_number_of_dots_dir_(newParts[-1])
416
418
 
417
- # the last element is the double-dots directory, but
418
- # need to determine whether to ensure/remote a
419
- # trailing slash
420
- if basename and not basename.empty?
419
+ # the last element is the double-dots directory, but
420
+ # need to determine whether to ensure/remote a
421
+ # trailing slash
422
+ if basename and not basename.empty?
421
423
 
422
- if not consume_basename
424
+ if not consume_basename
423
425
 
424
- # leave as is
425
- else
426
+ # leave as is
427
+ else
426
428
 
427
- #
428
- newParts[-1] = '..'
429
- end
430
- end
431
- end
432
- else
429
+ newParts[-1] = '..'
430
+ end
431
+ end
432
+ end
433
+ else
433
434
 
434
- # handle case where all (double)-dots have eliminated
435
- # all regular directories
436
- if not basename or basename.empty? or consume_basename
435
+ # handle case where all (double)-dots have eliminated
436
+ # all regular directories
437
+ if not basename or basename.empty? or consume_basename
437
438
 
438
- newParts << '.'
439
- end
440
- end
439
+ newParts << '.'
440
+ end
441
+ end
441
442
 
442
- [ newParts.join(''), consume_basename ]
443
- end
444
- end # module Util
443
+ [ newParts.join(''), consume_basename ]
444
+ end
445
+ end # module Util
445
446
 
446
- # Canonicalises a path
447
- #
448
- # Note: contains a trailing slash if, in the context of the given
449
- # path, the last element of the canonicalised path is a directory
450
- # unequivocally
451
- #
452
- # @!visibility private
453
- def self.canonicalise_path(path) # :nodoc:
447
+ # Canonicalises a path
448
+ #
449
+ # Note: contains a trailing slash if, in the context of the given
450
+ # path, the last element of the canonicalised path is a directory
451
+ # unequivocally
452
+ #
453
+ # @!visibility private
454
+ def self.canonicalise_path(path) # :nodoc:
454
455
 
455
- return nil if not path
456
- return '' if path.empty?
456
+ return nil if not path
457
+ return '' if path.empty?
457
458
 
458
- path = File.expand_path(path) if '~' == path[0].to_s
459
+ path = File.expand_path(path) if '~' == path[0].to_s
459
460
 
460
- f1_windows_root, f2_directory, f3_basename, dummy1, dummy2, directory_parts, dummy3 = Util.split_path(path)
461
+ f1_windows_root, f2_directory, f3_basename, dummy1, dummy2, directory_parts, dummy3 = Util.split_path(path)
461
462
 
462
- # suppress unused warnings
463
- dummy1 = dummy1
464
- dummy2 = dummy2
465
- dummy3 = dummy3
463
+ # suppress unused warnings
464
+ dummy1 = dummy1
465
+ dummy2 = dummy2
466
+ dummy3 = dummy3
466
467
 
467
- if not f2_directory
468
+ if not f2_directory
468
469
 
469
- canonicalised_directory = nil
470
- else
470
+ canonicalised_directory = nil
471
+ else
471
472
 
472
- canonicalised_directory, consume_basename = Util.canonicalise_parts(directory_parts, f3_basename)
473
- f3_basename = nil if consume_basename
474
- end
473
+ canonicalised_directory, consume_basename = Util.canonicalise_parts(directory_parts, f3_basename)
474
+ f3_basename = nil if consume_basename
475
+ end
475
476
 
476
- return "#{f1_windows_root}#{canonicalised_directory}#{f3_basename}"
477
- end
477
+ return "#{f1_windows_root}#{canonicalised_directory}#{f3_basename}"
478
+ end
478
479
 
479
- # @!visibility private
480
- def self.absolute_path?(path) # :nodoc:
480
+ # @!visibility private
481
+ def self.absolute_path?(path) # :nodoc:
481
482
 
482
- case path
483
- when nil
483
+ case path
484
+ when nil
484
485
 
485
- return nil
486
- when ::String
486
+ return nil
487
+ when ::String
487
488
 
488
- return nil if path.empty?
489
+ return nil if path.empty?
489
490
 
490
- path = File.expand_path(path) if '~' == path[0]
491
- when ::Recls::Entry
491
+ path = File.expand_path(path) if '~' == path[0]
492
+ when ::Recls::Entry
492
493
 
493
- return path
494
- else
494
+ return path
495
+ else
495
496
 
496
- raise TypeError, "parameter path ('#{path}') is of type #{path.class} must be nil or an instance of #{::String} or #{::Recls::Entry}"
497
- end
497
+ raise TypeError, "parameter path ('#{path}') is of type #{path.class} must be nil or an instance of #{::String} or #{::Recls::Entry}"
498
+ end
498
499
 
499
- f1_windows_root, f2_directory, dummy1, dummy2, dummy3, dummy4, dummy5 = Util.split_path(path)
500
+ f1_windows_root, f2_directory, dummy1, dummy2, dummy3, dummy4, dummy5 = Util.split_path(path)
500
501
 
501
- dummy1 = dummy2 = dummy3 = dummy4 = dummy5 = nil
502
+ dummy1 = dummy2 = dummy3 = dummy4 = dummy5 = nil
502
503
 
503
- unless f1_windows_root
504
+ unless f1_windows_root
504
505
 
505
- return nil unless f2_directory
506
+ return nil unless f2_directory
506
507
 
507
- return nil unless Util.is_path_name_separator(f2_directory[0])
508
- end
508
+ return nil unless Util.is_path_name_separator(f2_directory[0])
509
+ end
509
510
 
510
- Recls::Ximpl.stat_prep(path, nil, Recls::DETAILS_LATER)
511
- end
511
+ Recls::Ximpl.stat_prep(path, nil, Recls::DETAILS_LATER)
512
+ end
512
513
 
513
- # determines the absolute path of a given path
514
- #
515
- # @!visibility private
516
- def self.absolute_path(path, refdir = nil) # :nodoc:
514
+ # determines the absolute path of a given path
515
+ #
516
+ # @!visibility private
517
+ def self.absolute_path(path, refdir = nil) # :nodoc:
517
518
 
518
- case path
519
- when ::NilClass
519
+ case path
520
+ when ::NilClass
520
521
 
521
- return nil
522
- when ::String
522
+ return nil
523
+ when ::String
523
524
 
524
- path = File.expand_path(path) if '~' == path[0]
525
- when ::Recls::Entry
525
+ path = File.expand_path(path) if '~' == path[0]
526
+ when ::Recls::Entry
526
527
 
527
- return path.path
528
- else
528
+ return path.path
529
+ else
529
530
 
530
- raise TypeError, "parameter path ('#{path}') is of type #{path.class} must be an instance of #{::String} or Recls::Entry"
531
- end
531
+ raise TypeError, "parameter path ('#{path}') is of type #{path.class} must be an instance of #{::String} or Recls::Entry"
532
+ end
532
533
 
533
- return '' if path.empty?
534
+ return '' if path.empty?
534
535
 
535
- dummy1, f2_directory, dummy2, dummy3, dummy4, dummy5, dummy6 = Util.split_path(path)
536
+ dummy1, f2_directory, dummy2, dummy3, dummy4, dummy5, dummy6 = Util.split_path(path)
536
537
 
537
- # suppress unused warnings
538
- dummy1 = dummy1
539
- dummy2 = dummy2
540
- dummy3 = dummy3
541
- dummy4 = dummy4
542
- dummy5 = dummy5
543
- dummy6 = dummy6
538
+ # suppress unused warnings
539
+ dummy1 = dummy1
540
+ dummy2 = dummy2
541
+ dummy3 = dummy3
542
+ dummy4 = dummy4
543
+ dummy5 = dummy5
544
+ dummy6 = dummy6
544
545
 
545
- if f2_directory =~ /^[\\\/]/
546
+ if f2_directory =~ /^[\\\/]/
546
547
 
547
- return path
548
- end
548
+ return path
549
+ end
549
550
 
550
- cwd = refdir ? refdir : Dir.getwd
551
+ cwd = refdir ? refdir : Dir.getwd
551
552
 
552
- trailing_slash = Util.get_trailing_slash(path)
553
+ trailing_slash = Util.get_trailing_slash(path)
553
554
 
554
- if '.' == path
555
+ if '.' == path
555
556
 
556
- return Util.trim_trailing_slash cwd
557
- elsif 2 == path.size and trailing_slash
557
+ return Util.trim_trailing_slash cwd
558
+ elsif 2 == path.size and trailing_slash
558
559
 
559
- return Util.append_trailing_slash(cwd, path[1..1])
560
- end
560
+ return Util.append_trailing_slash(cwd, path[1..1])
561
+ end
561
562
 
562
- cwd = Util.append_trailing_slash(cwd)
563
+ cwd = Util.append_trailing_slash(cwd)
563
564
 
564
- path = "#{cwd}#{path}"
565
+ path = "#{cwd}#{path}"
565
566
 
566
- path = canonicalise_path path
567
+ path = canonicalise_path path
567
568
 
568
- if trailing_slash
569
+ if trailing_slash
569
570
 
570
- path = Util.append_trailing_slash path, trailing_slash
571
- else
571
+ path = Util.append_trailing_slash path, trailing_slash
572
+ else
572
573
 
573
- path = Util.trim_trailing_slash path
574
- end
574
+ path = Util.trim_trailing_slash path
575
+ end
575
576
 
576
- path
577
- end
577
+ path
578
+ end
578
579
 
579
- # obtains the basename of a path, e.g.
580
- # the basename of
581
- # abc/def/ghi.jkl
582
- # or (on Windows)
583
- # C:\abc\def\ghi.jkl
584
- # is
585
- # ghi.jkl
586
- #
587
- # @!visibility private
588
- def self.basename(path) # :nodoc:
580
+ # obtains the basename of a path, e.g.
581
+ # the basename of
582
+ # abc/def/ghi.jkl
583
+ # or (on Windows)
584
+ # C:\abc\def\ghi.jkl
585
+ # is
586
+ # ghi.jkl
587
+ #
588
+ # @!visibility private
589
+ def self.basename(path) # :nodoc:
589
590
 
590
- return nil if not path
591
+ return nil if not path
591
592
 
592
- # NOTE: we don't implement in terms of split_path
593
- # because all but the UNC case work with just
594
- # detecting the last (back)slash
593
+ # NOTE: we don't implement in terms of split_path
594
+ # because all but the UNC case work with just
595
+ # detecting the last (back)slash
595
596
 
596
- if Recls::Ximpl::OS::OS_IS_WINDOWS
597
+ if Recls::Ximpl::OS::OS_IS_WINDOWS
597
598
 
598
- wr, rem = Util.get_windows_root(path)
599
+ wr, rem = Util.get_windows_root(path)
599
600
 
600
- # suppress unused warning
601
- wr = wr
601
+ # suppress unused warning
602
+ wr = wr
602
603
 
603
- if not rem
604
+ if not rem
604
605
 
605
- return ''
606
- else
606
+ return ''
607
+ else
607
608
 
608
- path = rem
609
- end
610
- end
609
+ path = rem
610
+ end
611
+ end
611
612
 
612
- if not path.is_a? String
613
+ if not path.is_a? String
613
614
 
614
- path = path.to_s
615
- end
615
+ path = path.to_s
616
+ end
616
617
 
617
- if path =~ /^.*[\/\\](.*)/
618
+ if path =~ /^.*[\/\\](.*)/
618
619
 
619
- $1
620
- else
620
+ $1
621
+ else
621
622
 
622
- path
623
- end
624
- end
623
+ path
624
+ end
625
+ end
625
626
 
626
- # obtains the file extension of a basename, e.g.
627
- # the file_ext of
628
- # ghi.jkl
629
- # is
630
- # .jkl
631
- #
632
- # @!visibility private
633
- def self.file_ext(path) # :nodoc:
627
+ # obtains the file extension of a basename, e.g.
628
+ # the file_ext of
629
+ # ghi.jkl
630
+ # is
631
+ # .jkl
632
+ #
633
+ # @!visibility private
634
+ def self.file_ext(path) # :nodoc:
634
635
 
635
- return nil if not path
636
+ return nil if not path
636
637
 
637
- use_split_path = false
638
+ use_split_path = false
638
639
 
639
- if Recls::Ximpl::OS::OS_IS_WINDOWS
640
+ if Recls::Ximpl::OS::OS_IS_WINDOWS
640
641
 
641
- if path.include? ?\\
642
+ if path.include? ?\\
642
643
 
643
- use_split_path = true
644
- end
645
- end
644
+ use_split_path = true
645
+ end
646
+ end
646
647
 
647
- if path.include? ?/
648
+ if path.include? ?/
648
649
 
649
- use_split_path = true
650
- end
650
+ use_split_path = true
651
+ end
651
652
 
652
- if use_split_path
653
+ if use_split_path
653
654
 
654
- ext = Util.split_path(path)[4]
655
- else
655
+ ext = Util.split_path(path)[4]
656
+ else
656
657
 
657
- if path =~ /^.*(\.[^.]*)$/
658
+ if path =~ /^.*(\.[^.]*)$/
658
659
 
659
- ext = $1
660
- else
660
+ ext = $1
661
+ else
661
662
 
662
- ext = nil
663
- end
664
- end
663
+ ext = nil
664
+ end
665
+ end
665
666
 
666
- return ext ? ext : ''
667
- end
667
+ return ext ? ext : ''
668
+ end
668
669
 
669
- # obtains the directory from the directory path
670
- #
671
- # @!visibility private
672
- def self.directory_from_directory_path(directory_path) # :nodoc:
670
+ # obtains the directory from the directory path
671
+ #
672
+ # @!visibility private
673
+ def self.directory_from_directory_path(directory_path) # :nodoc:
673
674
 
674
- wr, rem = Util.get_windows_root(directory_path)
675
+ wr, rem = Util.get_windows_root(directory_path)
675
676
 
676
- # suppress unused warning
677
- wr = wr
677
+ # suppress unused warning
678
+ wr = wr
678
679
 
679
- rem
680
- end
680
+ rem
681
+ end
681
682
 
682
- # obtains the directory parts from a directory
683
- #
684
- # @!visibility private
685
- def self.directory_parts_from_directory(directory) # :nodoc:
683
+ # obtains the directory parts from a directory
684
+ #
685
+ # @!visibility private
686
+ def self.directory_parts_from_directory(directory) # :nodoc:
686
687
 
687
- return nil if not directory
688
+ return nil if not directory
688
689
 
689
- directory_parts = []
690
+ directory_parts = []
690
691
 
691
- until directory.empty?
692
+ until directory.empty?
692
693
 
693
- if directory =~ /^([^\\\/]*[\\\/])/
694
+ if directory =~ /^([^\\\/]*[\\\/])/
694
695
 
695
- directory_parts << $1
696
- directory = $'
697
- else
696
+ directory_parts << $1
697
+ directory = $'
698
+ else
698
699
 
699
- directory_parts << directory
700
- directory = ''
701
- end
702
- end
700
+ directory_parts << directory
701
+ directory = ''
702
+ end
703
+ end
703
704
 
704
- directory_parts
705
- end
705
+ directory_parts
706
+ end
706
707
 
707
- # obtains the relative path of a given path and
708
- # a reference directory
709
- #
710
- # @!visibility private
711
- def self.derive_relative_path(origin, path) # :nodoc:
708
+ # obtains the relative path of a given path and
709
+ # a reference directory
710
+ #
711
+ # @!visibility private
712
+ def self.derive_relative_path(origin, path) # :nodoc:
712
713
 
713
- return nil if path.nil?
714
- return nil if path.empty?
715
- return path if origin.nil?
716
- return path if origin.empty?
714
+ return nil if path.nil?
715
+ return nil if path.empty?
716
+ return path if origin.nil?
717
+ return path if origin.empty?
717
718
 
718
- path = self.canonicalise_path path
719
- origin = self.canonicalise_path origin
719
+ path = self.canonicalise_path path
720
+ origin = self.canonicalise_path origin
720
721
 
721
- path = self.absolute_path path
722
- origin = self.absolute_path origin
722
+ path = self.absolute_path path
723
+ origin = self.absolute_path origin
723
724
 
724
- return path if /^\.[\\\/]*$/ =~ origin
725
+ return path if /^\.[\\\/]*$/ =~ origin
725
726
 
726
- path_splits = Util.split_path(path)
727
- origin_splits = Util.split_path(origin)
727
+ path_splits = Util.split_path(path)
728
+ origin_splits = Util.split_path(origin)
728
729
 
729
- # if different windows root, then cannot provide relative
730
+ # if different windows root, then cannot provide relative
730
731
 
731
- if path_splits[0] and origin_splits[0]
732
+ if path_splits[0] and origin_splits[0]
732
733
 
733
- return path if path_splits[0] != origin_splits[0]
734
- end
734
+ return path if path_splits[0] != origin_splits[0]
735
+ end
735
736
 
736
- trailing_slash = Util.get_trailing_slash(path)
737
+ trailing_slash = Util.get_trailing_slash(path)
737
738
 
738
- path_parts = path_splits[6]
739
- origin_parts = origin_splits[6]
739
+ path_parts = path_splits[6]
740
+ origin_parts = origin_splits[6]
740
741
 
741
- loop do
742
+ loop do
742
743
 
743
- break if path_parts.empty?
744
- break if origin_parts.empty?
744
+ break if path_parts.empty?
745
+ break if origin_parts.empty?
745
746
 
746
- path_part = path_parts[0]
747
- origin_part = origin_parts[0]
747
+ path_part = path_parts[0]
748
+ origin_part = origin_parts[0]
748
749
 
749
- if 1 == path_parts.size || 1 == origin_parts.size
750
+ if 1 == path_parts.size || 1 == origin_parts.size
750
751
 
751
- path_part = Util.append_trailing_slash(path_part)
752
- origin_part = Util.append_trailing_slash(origin_part)
753
- end
752
+ path_part = Util.append_trailing_slash(path_part)
753
+ origin_part = Util.append_trailing_slash(origin_part)
754
+ end
754
755
 
755
- if path_part == origin_part
756
+ if path_part == origin_part
756
757
 
757
- path_parts.shift
758
- origin_parts.shift
759
- else
758
+ path_parts.shift
759
+ origin_parts.shift
760
+ else
760
761
 
761
- break
762
- end
763
- end
762
+ break
763
+ end
764
+ end
764
765
 
765
- return ".#{trailing_slash}" if path_parts.empty? and origin_parts.empty?
766
+ return ".#{trailing_slash}" if path_parts.empty? and origin_parts.empty?
766
767
 
767
- # at this point, all reference parts should be converted into '..'
768
+ # at this point, all reference parts should be converted into '..'
768
769
 
769
- return origin_parts.map { |rp| '..' }.join('/') if path_parts.empty?
770
+ return origin_parts.map { |rp| '..' }.join('/') if path_parts.empty?
770
771
 
771
- return '../' * origin_parts.size + path_parts.join('')
772
- end
772
+ return '../' * origin_parts.size + path_parts.join('')
773
+ end
773
774
 
774
- # @!visibility private
775
- def self.combine_paths(paths, options) # :nodoc:
775
+ # @!visibility private
776
+ def self.combine_paths(paths, options) # :nodoc:
776
777
 
777
- paths = [ paths ] unless ::Array === paths
778
- abs_ix = 0
778
+ paths = [ paths ] unless ::Array === paths
779
+ abs_ix = 0
779
780
 
780
- paths = paths.map { |path| '~' == path[0].to_s ? File.expand_path(path) : path }
781
+ paths = paths.map { |path| '~' == path[0].to_s ? File.expand_path(path) : path }
781
782
 
782
- paths.each_with_index do |path, index|
783
+ paths.each_with_index do |path, index|
783
784
 
784
- dummy1, f2_directory, dummy2, dummy3, dummy4, dummy5, dummy6 = Util.split_path(path)
785
+ dummy1, f2_directory, dummy2, dummy3, dummy4, dummy5, dummy6 = Util.split_path(path)
785
786
 
786
- # suppress unused warnings
787
- dummy1 = dummy1
788
- dummy2 = dummy2
789
- dummy3 = dummy3
790
- dummy4 = dummy4
791
- dummy5 = dummy5
792
- dummy6 = dummy6
787
+ # suppress unused warnings
788
+ dummy1 = dummy1
789
+ dummy2 = dummy2
790
+ dummy3 = dummy3
791
+ dummy4 = dummy4
792
+ dummy5 = dummy5
793
+ dummy6 = dummy6
793
794
 
794
- if f2_directory && Util.is_path_name_separator(f2_directory[0])
795
+ if f2_directory && Util.is_path_name_separator(f2_directory[0])
795
796
 
796
- abs_ix = index
797
- end
798
- end
797
+ abs_ix = index
798
+ end
799
+ end
799
800
 
800
- paths = paths[abs_ix..-1]
801
+ paths = paths[abs_ix..-1]
801
802
 
802
- r = File.join(*paths)
803
+ r = File.join(*paths)
803
804
 
804
- cap = options[:canonicalise] || options[:canonicalize]
805
+ cap = options[:canonicalise] || options[:canonicalize]
805
806
 
806
- if cap
807
+ if cap
807
808
 
808
- r = Recls.canonicalise_path r
809
- else
809
+ r = Recls.canonicalise_path r
810
+ else
810
811
 
811
- clp = options[:clean] || options[:clean_path]
812
+ clp = options[:clean] || options[:clean_path]
812
813
 
813
- if clp
814
+ if clp
814
815
 
815
- r = Pathname.new(r).cleanpath.to_s
816
- end
817
- end
816
+ r = Pathname.new(r).cleanpath.to_s
817
+ end
818
+ end
818
819
 
819
- r
820
- end
820
+ r
821
+ end
821
822
 
822
823
 
823
- # Elicits the contents of the given directory, or, if the flag
824
- # STOP_ON_ACCESS_FAILURE is specified throws an exception if the
825
- # directory does not exist
826
- #
827
- # Some known conditions:
828
- #
829
- # * (Mac OSX) /dev/fd/<N> - some of these stat() as directories but
830
- # Dir.new fails with ENOTDIR
831
- #
832
- # @!visibility private
833
- def self.dir_entries_maybe(dir, flags) # :nodoc:
824
+ # Elicits the contents of the given directory, or, if the flag
825
+ # STOP_ON_ACCESS_FAILURE is specified throws an exception if the
826
+ # directory does not exist
827
+ #
828
+ # Some known conditions:
829
+ #
830
+ # * (Mac OSX) /dev/fd/<N> - some of these stat() as directories but
831
+ # Dir.new fails with ENOTDIR
832
+ #
833
+ # @!visibility private
834
+ def self.dir_entries_maybe(dir, flags) # :nodoc:
834
835
 
835
- begin
836
+ begin
836
837
 
837
- Dir.new(dir).to_a
838
+ Dir.new(dir).to_a
838
839
 
839
- rescue SystemCallError => x
840
+ rescue SystemCallError => x
840
841
 
841
- $stderr.puts "exception (#{x.class}): #{x}" if $DEBUG
842
+ $stderr.puts "exception (#{x.class}): #{x}" if $DEBUG
842
843
 
843
- if(0 != (STOP_ON_ACCESS_FAILURE & flags))
844
+ if(0 != (STOP_ON_ACCESS_FAILURE & flags))
844
845
 
845
- raise
846
- end
846
+ raise
847
+ end
847
848
 
848
- return []
849
- end
850
- end
849
+ return []
850
+ end
851
+ end
851
852
 
852
- # @!visibility private
853
- def self.stat_prep(path, search_root, flags) # :nodoc:
853
+ # @!visibility private
854
+ def self.stat_prep(path, search_root, flags) # :nodoc:
854
855
 
855
- begin
856
+ begin
856
857
 
857
- Recls::Entry.new(path, Recls::Ximpl::FileStat.stat(path), search_root, flags)
858
- rescue Errno::ENOENT, Errno::ENXIO => x
858
+ Recls::Entry.new(path, Recls::Ximpl::FileStat.stat(path), search_root, flags)
859
+ rescue Errno::ENOENT, Errno::ENXIO => x
859
860
 
860
- x = x # suppress warning
861
+ x = x # suppress warning
861
862
 
862
- if 0 != (flags & Recls::DETAILS_LATER)
863
+ if 0 != (flags & Recls::DETAILS_LATER)
863
864
 
864
- Recls::Entry.new(path, nil, search_root, flags)
865
- else
865
+ Recls::Entry.new(path, nil, search_root, flags)
866
+ else
866
867
 
867
- nil
868
- end
869
- end
870
- end
871
- end # module Ximpl
868
+ nil
869
+ end
870
+ end
871
+ end
872
+ end # module Ximpl
872
873
 
873
874
  # :startdoc:
874
875
 
875
876
  end # module Recls
876
877
 
877
- # ############################## end of file ############################# #
878
878
 
879
+ # ############################## end of file ############################# #
879
880