Module: Recls::Ximpl

Defined in:
lib/recls/ximpl/os.rb,
lib/recls/ximpl/unix.rb,
lib/recls/ximpl/util.rb,
lib/recls/ximpl/windows.rb

Overview

:nodoc: all

Defined Under Namespace

Modules: OS, Util Classes: FileStat

Class Method Summary collapse

Class Method Details

.absolute_path(path, refdir = nil) ⇒ Object

determines the absolute path of a given path



492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
# File 'lib/recls/ximpl/util.rb', line 492

def self.absolute_path(path, refdir = nil)

	case path
	when ::NilClass

		return nil
	when ::String

		path	=	File.expand_path(path) if '~' == path[0]
	when ::Recls::Entry

		return path.path
	else

		raise TypeError, "parameter path ('#{path}') is of type #{path.class} must be an instance of #{::String} or Recls::Entry"
	end

	return '' if path.empty?

	dummy1, f2_directory, dummy2, dummy3, dummy4, dummy5, dummy6 = Util.split_path(path)

	# suppress unused warnings
	dummy1 = dummy1
	dummy2 = dummy2
	dummy3 = dummy3
	dummy4 = dummy4
	dummy5 = dummy5
	dummy6 = dummy6

	if f2_directory =~ /^[\\\/]/

		return path
	end

	cwd = refdir ? refdir : Dir.getwd

	trailing_slash = Util.get_trailing_slash(path)

	if '.' == path

		return Util.trim_trailing_slash cwd
	elsif 2 == path.size and trailing_slash

		return Util.append_trailing_slash(cwd, path[1..1])
	end

	cwd = Util.append_trailing_slash(cwd)

	path = "#{cwd}#{path}"

	path = canonicalise_path path

	if trailing_slash

		path = Util.append_trailing_slash path, trailing_slash
	else

		path = Util.trim_trailing_slash path
	end

	path
end

.absolute_path?(path) ⇒ Boolean



458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
# File 'lib/recls/ximpl/util.rb', line 458

def self.absolute_path?(path)

	case path
	when nil

		return nil
	when ::String

		return nil if path.empty?

		path	=	File.expand_path(path) if '~' == path[0]
	when ::Recls::Entry

		return path
	else

		raise TypeError, "parameter path ('#{path}') is of type #{path.class} must be nil or an instance of #{::String} or #{::Recls::Entry}"
	end

	f1_windows_root, f2_directory, dummy1, dummy2, dummy3, dummy4, dummy5 = Util.split_path(path)

	dummy1 = dummy2 = dummy3 = dummy4 = dummy5 = nil

	unless f1_windows_root

		return nil unless f2_directory

		return nil unless Util.is_path_name_separator(f2_directory[0])
	end

	Recls::Ximpl.stat_prep(path, nil, Recls::DETAILS_LATER)
end

.basename(path) ⇒ Object

obtains the basename of a path, e.g. the basename of

abc/def/ghi.jkl

or (on Windows)

C:\abc\def\ghi.jkl

is

ghi.jkl


563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
# File 'lib/recls/ximpl/util.rb', line 563

def self.basename(path)

	return nil if not path

	# NOTE: we don't implement in terms of split_path
	# because all but the UNC case work with just
	# detecting the last (back)slash

	if Recls::Ximpl::OS::OS_IS_WINDOWS

		wr, rem = Util.get_windows_root(path)

		# suppress unused warning
		wr = wr

		if not rem

			return ''
		else

			path = rem
		end
	end

	if not path.is_a? String

		path = path.to_s
	end

	if path =~ /^.*[\/\\](.*)/

		$1
	else

		path
	end
end

.canonicalise_path(path) ⇒ Object

Canonicalises a path

Note: contains a trailing slash if, in the context of the given path, the last element of the canonicalised path is a directory unequivocally



432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
# File 'lib/recls/ximpl/util.rb', line 432

def self.canonicalise_path(path)

	return nil if not path
	return '' if path.empty?

	path	=	File.expand_path(path) if '~' == path[0].to_s

	f1_windows_root, f2_directory, f3_basename, dummy1, dummy2, directory_parts, dummy3 = Util.split_path(path)

	# suppress unused warnings
	dummy1 = dummy1
	dummy2 = dummy2
	dummy3 = dummy3

	if not f2_directory

		canonicalised_directory = nil
	else

		canonicalised_directory, consume_basename = Util.canonicalise_parts(directory_parts, f3_basename)
		f3_basename = nil if consume_basename
	end

	return "#{f1_windows_root}#{canonicalised_directory}#{f3_basename}"
end

.combine_paths(paths, options) ⇒ Object



743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
# File 'lib/recls/ximpl/util.rb', line 743

def self.combine_paths(paths, options)

	paths	=	[ paths ] unless ::Array === paths
	abs_ix	=	0

	paths	=	paths.map { |path| '~' == path[0].to_s ? File.expand_path(path) : path }

	paths.each_with_index do |path, index|

		dummy1, f2_directory, dummy2, dummy3, dummy4, dummy5, dummy6 = Util.split_path(path)

		# suppress unused warnings
		dummy1 = dummy1
		dummy2 = dummy2
		dummy3 = dummy3
		dummy4 = dummy4
		dummy5 = dummy5
		dummy6 = dummy6

		if f2_directory && Util.is_path_name_separator(f2_directory[0])

			abs_ix = index
		end
	end

	paths	=	paths[abs_ix..-1]

	r		=	File.join(*paths)

	cap	=	options[:canonicalise] || options[:canonicalize]

	if cap

		r = Recls.canonicalise_path r
	else

		clp	=	options[:clean] || options[:clean_path]

		if clp

			r = Pathname.new(r).cleanpath.to_s
		end
	end

	r
end

.derive_relative_path(origin, path) ⇒ Object

obtains the relative path of a given path and a reference directory



679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
# File 'lib/recls/ximpl/util.rb', line 679

def self.derive_relative_path(origin, path)

	return nil if path.nil?
	return nil if path.empty?
	return path if origin.nil?
	return path if origin.empty?

	path			=	self.canonicalise_path path
	origin			=	self.canonicalise_path origin

	path			=	self.absolute_path path
	origin			=	self.absolute_path origin

	return path if /^\.[\\\/]*$/ =~ origin

	path_splits		=	Util.split_path(path)
	origin_splits	=	Util.split_path(origin)

	# if different windows root, then cannot provide relative

	if path_splits[0] and origin_splits[0]

		return path if path_splits[0] != origin_splits[0]
	end

	trailing_slash	=	Util.get_trailing_slash(path)

	path_parts		=	path_splits[6]
	origin_parts	=	origin_splits[6]

	loop do

		break if path_parts.empty?
		break if origin_parts.empty?

		path_part	=	path_parts[0]
		origin_part	=	origin_parts[0]

		if 1 == path_parts.size || 1 == origin_parts.size

			path_part	=	Util.append_trailing_slash(path_part)
			origin_part	=	Util.append_trailing_slash(origin_part)
		end

		if path_part == origin_part

			path_parts.shift
			origin_parts.shift
		else

			break
		end
	end

	return ".#{trailing_slash}" if path_parts.empty? and origin_parts.empty?

	# at this point, all reference parts should be converted into '..'

	return origin_parts.map { |rp| '..' }.join('/') if path_parts.empty?

	return '../' * origin_parts.size + path_parts.join('')
end

.dir_entries_maybe(dir, flags) ⇒ Object

Elicits the contents of the given directory, or, if the flag STOP_ON_ACCESS_FAILURE is specified throws an exception if the directory does not exist

Some known conditions:

  • (Mac OSX) /dev/fd/<N> - some of these stat() as directories but

    Dir.new fails with ENOTDIR
    


800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
# File 'lib/recls/ximpl/util.rb', line 800

def self.dir_entries_maybe(dir, flags)

	begin

		Dir.new(dir).to_a

	rescue SystemCallError => x

		$stderr.puts "exception (#{x.class}): #{x}" if $DEBUG

		if(0 != (STOP_ON_ACCESS_FAILURE & flags))

			raise
		end

		return []
	end
end

.directory_from_directory_path(directory_path) ⇒ Object

obtains the directory from the directory path



644
645
646
647
648
649
650
651
652
# File 'lib/recls/ximpl/util.rb', line 644

def self.directory_from_directory_path(directory_path)

	wr, rem =  Util.get_windows_root(directory_path)

	# suppress unused warning
	wr = wr

	rem
end

.directory_parts_from_directory(directory) ⇒ Object

obtains the directory parts from a directory



655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
# File 'lib/recls/ximpl/util.rb', line 655

def self.directory_parts_from_directory(directory)

	return nil if not directory

	directory_parts = []

	until directory.empty?

		if directory =~ /^([^\\\/]*[\\\/])/

			directory_parts << $1
			directory = $'
		else

			directory_parts << directory
			directory = ''
		end
	end

	directory_parts
end

.file_ext(path) ⇒ Object

obtains the file extension of a basename, e.g. the file_ext of

ghi.jkl

is

.jkl


606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
# File 'lib/recls/ximpl/util.rb', line 606

def self.file_ext(path)

	return nil if not path

	use_split_path = false

	if Recls::Ximpl::OS::OS_IS_WINDOWS

		if path.include? ?\\

			use_split_path = true
		end
	end

	if path.include? ?/

		use_split_path = true
	end

	if use_split_path

		ext = Util.split_path(path)[4]
	else

		if path =~ /^.*(\.[^.]*)$/

			ext = $1
		else

			ext = nil
		end
	end

	return ext ? ext : ''
end

.stat_prep(path, search_root, flags) ⇒ Object



819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
# File 'lib/recls/ximpl/util.rb', line 819

def self.stat_prep(path, search_root, flags)

	begin

		Recls::Entry.new(path, Recls::Ximpl::FileStat.stat(path), search_root, flags)
	rescue Errno::ENOENT, Errno::ENXIO => x

		x = x # suppress warning

		if 0 != (flags & Recls::DETAILS_LATER)

			Recls::Entry.new(path, nil, search_root, flags)
		else

			nil
		end
	end
end