sbsv1/abld/genutil/pathutl.pm
changeset 40 68f68128601f
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sbsv1/abld/genutil/pathutl.pm	Thu Nov 25 13:59:07 2010 +0000
@@ -0,0 +1,384 @@
+# Copyright (c) 1997-2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+# General Path and File Utility Functions for use with Makmake
+# Distinguish paths from filepaths by assuming paths end with "\"
+# therefore ensure this is the case for all paths coming into programs using this module
+# 
+#
+
+package Pathutl;
+
+require Exporter;
+@ISA=qw(Exporter);
+
+@EXPORT=qw(
+	Path_SetVerbose Path_Drive Path_WorkPath Path_RltToWork Path_AbsToWork
+	Path_DelFiles Path_Split Path_Dirs Path_StepDirs Path_Strip 
+	Path_MakePathL Path_UpToRoot Path_MakeRlt Path_MakeAbs Path_Chop
+	Path_MakeEAbs Path_Quote Path_MakeRltToBase Path_Norm Path_PrefixWithDrive Path_PrefixWithDriveAndQuote
+);
+
+use Cwd;
+use File::Path;                # for mkpath
+
+my %Mode=(
+	Verbose=>0
+);
+my $Drive;
+my $WorkPath;
+my @WorkPathList;
+
+sub Path_SetVerbose () {
+	$Mode{Verbose}=1;
+}
+
+sub Path_Drive () {
+# return the current drive - programs shouldn't change directory if using this module
+	$Drive;
+}
+
+sub Path_WorkPath () {
+# return the current working directory - programs shouldn't change directory if using this module
+	$WorkPath;
+}
+
+sub helper_MakeRlt ($@) {
+# helper function for computing relative path(s) given a base path
+	my ($BaseRef,@List)=@_;
+	foreach my $p (@List) {
+		my $filename=&Path_Split('File',$p);
+		my @plist=&Path_Dirs($p);
+		my $upcount=scalar @{$BaseRef};
+		foreach (@{$BaseRef}) {
+			if (uc $_ ne uc $plist[0]) {
+				last;
+			}
+			$upcount -= 1;
+			shift @plist;
+		}
+		$p="";
+		while ($upcount-->0) {
+			$p .= "..\\";
+		}
+		foreach (@plist) {
+			$p .= "$_\\";
+		}
+		$p=".\\" if ($p eq "");		# ensure a well-formed result if path == work
+		$p .= $filename;
+	}
+	return wantarray ? @List : $List[0];	
+}
+
+sub Path_RltToWork (@) {
+# make a path or list of paths relative to the current working directory
+	my @List=@_;
+	@List=&helper_MakeRlt(\@WorkPathList,@List);
+	return wantarray ? @List : $List[0];
+}
+
+sub Path_MakeRltToBase ($@) {	#args: $_[0] Base $_[1]... list of (Abs FilePath/Path)
+# make a path, or list of paths, relative to a particular directory specified by the first
+# path passed into the function
+	return undef unless $_[0]=~m-(|\\$)-o;	# allow for null value passed in
+	my ($Base,@List)=@_;
+	my @BasePathList=&Path_Dirs($Base);
+	@List=&helper_MakeRlt(\@BasePathList,@List);
+	return wantarray ? @List : $List[0];	
+}
+
+sub Path_AbsToWork (@) {
+# make a path or list of paths relative to the current working directory absolute
+	my @List=@_;
+	@List=&Path_MakeAbs($WorkPath,@List);
+	return wantarray ? @List : $List[0];	
+}
+
+sub Path_DelFiles (@) {
+# delete a list of files
+	my @List=@_;
+	my $File;
+	foreach $File (@List) {
+		if (unlink $File) {
+			if ($Mode{Verbose}) {
+				print "Deleted File: \"$File\"\n";
+			}
+			next;
+		}
+		if ($Mode{Verbose}) {
+			print "Not Found: \"$File\"\n";
+		}
+	}
+}
+
+sub Path_Split ($$) {	#args: $_[0] 'Path' or 'Base' or 'Ext' $_[1] Abs/Rel FilePath/Path
+# return the section of a file path required - Path, Base, Ext or File
+	my ($Sect,$P)=@_;
+
+	return '' if !$P;
+	
+	$Sect= ucfirst lc $Sect;
+	if ($Sect eq 'Path') {
+		if ($P=~/^(.*\\)/o) {
+			return $1;
+		}
+		return '';
+	}
+	if ($Sect eq 'Base') {
+		if ($P=~/\\?([^\\]*?)(\.[^\\\.]*)?$/o) {
+			return $1;
+		}
+		return '';
+	}
+	if ($Sect eq 'Ext') {
+		if ($P=~/(\.[^\\\.]*)$/o) {
+			return $1;
+		}
+		return '';
+	}
+	if ($Sect eq 'File') {
+		if ($P=~/([^\\]*)$/o) {
+			return $1;
+		}
+		return '';
+	}
+	undef;
+}
+
+sub Path_Dirs ($) {	#args: $_[0] Abs FilePath/Path
+# return an ordered list of individual directories that make up a path
+	return undef unless $_[0]=~m-^\\-o;
+	my $P=&Path_Split('Path',$_[0]);
+	return undef unless $P=~s-^(.*)\\$-$1-o;
+	$P=~s-^\\(.*)-$1-o;
+	split /\\/,$P;
+}
+
+sub Path_StepDirs ($) { #args: $_[0] Abs FilePath/Path
+# return an ordered list of paths - starting with the directory in the root directory from the
+# path passed into the function, each subsequent path contains the next directory from the path
+# passed into the function, and the last path is the same as the path passed into the function
+	return undef unless $_[0]=~m-^\\-o;
+	my $P=$_[0];
+	my @Dirs=&Path_Dirs($P);
+	my @StepDirs;
+	my $dir;
+	my $stepDir="\\";
+	foreach $dir (@Dirs) {
+		$stepDir.="$dir\\";
+		push @StepDirs, $stepDir;
+	}
+	@StepDirs;
+}
+
+sub Path_Strip ($) {	#args: $_[0] Abs FilePath/Path
+# Remove excess occurrences of '..' and '.' from a path
+	return undef unless $_[0]=~m-^\\-o;
+	my $P=$_[0];
+	while ($P=~s-\\\.\\-\\-go) { }
+	while ($P=~s-\\(?!\.{2}\\)[^\\]*\\\.{2}(?=\\)--go) { }
+	$P;
+}
+
+sub Path_MakePathL (@) {	#args: @_ list of Abs FilePath/Path
+# make a directory or list of directories
+	my @Paths=@_;
+	my $P;
+	foreach $P (@Paths) { 
+		return undef unless $P=~m-^\\-o;
+		$P=&Path_Split('Path',$P);
+		$P=&Path_Strip($P);
+		$P=~m-(.*)\\-o;
+		if (-d $1) {
+			if ($Mode{'Verbose'}) {
+				print "Existing Path: \"$P\"\n";
+			}
+			next;
+		}
+		mkpath[$P];
+		if ($Mode{'Verbose'}) {
+			print "Created Path: \"$P\"\n";
+		}
+	}
+	return wantarray ? @Paths : $Paths[0];
+}
+
+sub Path_UpToRoot ($) {	#args: $_[0] Abs FilePath/Path
+# return the path that will lead from the directory the path passed into the function
+# specifies back up to the root directory
+	return undef unless $_[0]=~m-^\\-o;
+	my $Path=$_[0];
+	my $UpP;
+	while ($Path=~m-\\-go) {
+		$UpP.="..\\";
+	}
+	undef $Path;
+	$UpP=~s-^(.*)\.\.\\-$1-o;
+	$UpP=".\\" unless $UpP;
+}
+
+sub Path_MakeRlt ($@) {	#args: $_[0] Start UpPath $_[1]... list of (Abs FilePath/Path)
+# make a path, or list of paths, relative to a particular directory specified by the first
+# path passed into the function which leads upwards from a particular directory
+	return undef unless $_[0]=~m-(|\\$)-o;	# allow for null value passed in
+	my ($UpPath,@List)=@_;
+	my $p;
+	foreach $p (@List) {
+		return undef unless $p=~m-^\\-o;
+		$p=~s-^\\(.*)$-$1-o;
+		$p=$UpPath.$p;
+	}
+	return wantarray ? @List : $List[0];	
+}
+
+sub Path_MakeAbs ($@) {	#args: $_[0] Start Abs FilePath/Path $_[1]... list of (Abs/Rel FilePath/Path)
+# make a path, or list of paths, absolute given the directory specified by the first path
+# passed into the function which the other paths passed into the function are assumed to be
+# relative to
+	return undef unless $_[0]=~m-^\\-o;
+	my ($Path,@List)=@_;
+	my $BasePath=&Path_Split("Path",$Path);
+	undef $Path;
+	my $p;
+	foreach $p (@List) {
+		if ($p=~m-^\.{2}-o) {
+			$p=&Path_Strip($BasePath.$p);
+			next;
+		}
+		if ($p=~m-^[^\.\\]-o) {
+			$p=&Path_Strip($BasePath.$p);
+			next;
+		}
+		if ($p=~m-^\\-o) {
+			$p=&Path_Strip($p);
+			next;
+		}
+		if ($p=~m-^\.\\(.*)$-o) {
+			$p=&Path_Strip($BasePath.$1);
+			next;
+		}
+		return undef;
+	}
+	return wantarray ? @List : $List[0];
+}
+
+sub Path_MakeEAbs ($@) {	#args: $_[0] Start EPOCPath Abs FilePath/Path $_[1]... list of (Abs/Rel FilePath/Path)
+# Variant of MakAbs which also maps "+\\" to "${EPOCPath}"
+	return undef unless $_[0]=~m-^\\-o;
+	my ($EPOCPath,$Path,@List)=@_;
+	my $BasePath=&Path_Split("Path",$Path);
+	undef $Path;
+	my $p;
+	foreach $p (@List) {
+		if ($p=~m-^\\epoc32\\(.*)$-io) {	# change - special case for existing \\epoc32 references
+			$p=$EPOCPath.$1;
+			next;
+		}
+		if ($p=~m-^\s*\+\\(.*)$-o) {
+			$p=$EPOCPath.$1;
+			next;
+		}
+		if ($p=~m-^\.{2}-o) {
+			$p=&Path_Strip($BasePath.$p);
+			next;
+		}
+		if ($p=~m-^[^\.\\]-o) {
+			$p=$BasePath.$p;
+			next;
+		}
+		if ($p=~m-^\\-o) {
+			next;
+		}
+		if ($p=~m-^\.\\(.*)$-o) {
+			$p=&Path_Strip($BasePath.$1);
+			next;
+		}
+		return undef;
+	}
+	return wantarray ? @List : $List[0];
+}
+
+sub Path_Chop (@) {
+# remove the terminating backslash from a path, or list of paths, if there is one
+	my @List=@_;
+	my $Path;
+	foreach $Path (@List) {
+		$Path=~s-^(.*)\\$-$1-o;
+	}
+	return wantarray ? @List : $List[0];
+}
+
+sub Path_Quote ($) {
+# Quote name for use in GNU makefiles
+	my @List=@_;
+	my $Path;
+	foreach $Path (@List) {
+		$Path=~s- -\\ -go if (defined($Path));
+	}
+	return wantarray ? @List : $List[0];
+}
+
+sub Path_Norm ($) {
+# Normalise source specified paths for processing
+	my ($Path) = @_;
+	$Path =~ s/\//\\/g;
+	return $Path;
+}
+
+sub Path_PrefixWithDrive ($) {
+# Take a path, or list of paths, and prefix with drive based on CWD.
+# Relative paths are just returned.
+	my @List=@_;
+	my $Path;
+	my $Drive=$1 if (cwd =~ /^(.:)/); 
+
+	foreach $Path (@List) {
+		next if ($Path !~ /^\\/);
+		$Path=$Drive.$Path;
+	}
+	
+	return wantarray ? @List : $List[0];
+}
+
+sub Path_PrefixWithDriveAndQuote ($) {
+# Take a path, or list of paths, and prefix with drive based on CWD.
+# Relative paths are just quoted.
+	my @List=@_;
+	my $Path;
+	my $Drive=$1 if (cwd =~ /^(.:)/); 
+
+	foreach $Path (@List) {
+		next if ($Path !~ /^\\/);
+		$Path=$Drive.$Path;
+	}
+
+	foreach $Path (@List) {
+		$Path="\"".$Path."\"";
+	}
+	
+	return wantarray ? @List : $List[0];
+}
+
+
+
+BEGIN {
+# get the current working directory
+	$WorkPath=cwd;
+	$WorkPath=~s-/-\\-go; # separator from Perl 5.005_02+ is forward slash
+	$WorkPath=~s/^(.:)//o;    # remove drive letter
+	$Drive=$1;
+	$WorkPath=~s-^(.*[^\\])$-$1\\-o;        # ensure workpath ends with a backslash
+	@WorkPathList=&Path_Dirs($WorkPath);
+}
+
+1;