recls-ruby 2.11.0.3 → 2.12.0

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