imgtools/buildrom/tools/datadriveimage.pm
changeset 606 30b30f9da0b7
parent 0 044383f39525
child 607 378360dbbdba
--- a/imgtools/buildrom/tools/datadriveimage.pm	Fri Jun 25 20:58:33 2010 +0800
+++ b/imgtools/buildrom/tools/datadriveimage.pm	Tue Jun 29 14:52:54 2010 +0800
@@ -1,727 +1,742 @@
-#
-# Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies).
-# All rights reserved.
-# This component and the accompanying materials are made available
-# under the terms of the License "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: 
-# This package contains fuctions specific to data drive image generation
-#
-
-
-package datadriveimage;
-
-require Exporter;
-@ISA=qw(Exporter);
-@EXPORT=qw(
-			createDirectory 
-			deleteDirectory 
-			checkInArray 
-			setPath 
-			locateStubsisfiles 
-			copyFilesToFolders 
-			checkForSisFile 
-			copyNonSisFiles
-			invokeInterpretsis
-			invokeReadImage
-			compareArrays
-			dumpDatadriveObydata
-			TraverseDir
-			writeDataToFile
-			generate_datadriveheader
-			checkForWhiteSpace
-			reportError
-);
-
-use strict;
-use File::Path;		# Module to provide functions to remove or create directories in a convenient way.
-use File::Copy;		# Module to provide functions to copy file(s) from source to destination.
-
-use Pathutl;
-use Cwd;			# Module to provide functions for determining the pathname of the current working directory.
-
-# This fuction is used primiarly to check for whitespace in the location for "zdrive" / "datadrive" folder creation,
-# specified by the user, if yes then it returns one, else zero
-sub checkForWhiteSpace
-{
-	my ($dirLoc,$dirName) = @_;
-	if( $dirLoc =~ m/ / )
-	{
-		print "* Warning: $dirLoc contains whitespace, hence $dirName will be created in default location \n";
-		return 1;
-	}
-	else
-	{
-		return 0;
-	}
-}
-
-
-# This function reports the appropriate meassage supplied to it
-# and does a exit if and only if keepgoing option is disabled.
-sub reportError
-{
-	my( $message,$keepgoingOpt ) = @_;
-	# print the specified meassage.
-	print STDERR "$message \n";
-	# bail out, if keepgoing option is not set.
-	exit(1) if (!$keepgoingOpt);
-}
-
-# generate header for final datadrive oby file.
-sub generate_datadriveheader
-{
-	my ($idx,$datadriveimage) = @_;
-	my $header;
-	$header =  "dataimagename=$$datadriveimage[$idx]{name}.img\n";
-	$header .= "dataimagefilesystem=$$datadriveimage[$idx]{fstype}\n";
-
-	# check whether the size of the image has been mentioned
-	if(defined($$datadriveimage[$idx]{size}))
-	{
-		$header .= "dataimagesize=$$datadriveimage[$idx]{size}\n\n";
-	}
-	return $header;
-}
-
-# Create the specified directory by making use of mkpath function 
-# from File::Path module.
-sub createDirectory
-{
-	my($dir) = @_;
-	if( !-d $dir )
-	{
-		mkpath($dir);
-		if (! -e $dir) 
-		{
-			print ("ERROR: Couldn't create $dir\n");
-		}
-	}
-}
-
-# check if the given file is a reg file or ctl file or a txt file
-# if it is any of these files then return true else false.
-# This check is need since these three files or not valid not valid e32 file 
-# and hence needs to be placed as an data file inside the image.
-sub checkRegCtlFiles
-{
-	my ($fileName) = @_;
-
-	# check whether the file has "reg","ctl" or "txt" extension.
-	if( $fileName =~/\.(reg|ctl|txt)$/i )
-	{
-		return 1;		
-	}
-	else
-	{
-		return 0;
-	}
-}
-
-# delete the given directory by making use of rmtree function 
-# from File::Path module.
-sub deleteDirectory
-{
-	my($dir,$verboseOpt) = @_;
-	# check whether the directory exists.
-	if( -d $dir )
-	{
-		print("found $dir directory \n") if($verboseOpt);
-		if(rmtree($dir))
-		{
-			print("$dir directory deleted \n") if($verboseOpt);
-			return 0;
-		}
-		else
-		{
-			print("$dir directory could'nt be deleted \n") if($verboseOpt);
-			return 1;
-		}
-	}
-}
-
-# check for processed data drive image index.
-# if there is a match return one else return zero.
-# this check is done in order to ensure data drive image index is not repeated.
-sub checkInArray
-{
-	my($array, $value) = @_;
-	foreach my $aLine(@$array)
-	{
-		if( $aLine eq $value )
-		{
-			return 0;
-		}
-	}
-	return 1;
-}
-
-# set the path for the given directory.
-sub setPath
-{
-	my($dirName) = @_;
-	# get the working directory.
-	my $curWorkingDir = getcwd;
-	# substitute slash with double backward slash.
-	$curWorkingDir =~ s/\//\\/g;
- 	#if $curWorkingDir already has trailing '\', don't include it again 
- 	if( $curWorkingDir =~ /\\$/)
- 	{
- 		return $curWorkingDir.$dirName;
- 	}
- 	else
- 	{
- 		return $curWorkingDir."\\".$dirName;
- 	}
-}
-
-# create directory and copy respective file on to that directory.
-# is there is a problem while copying files from source to destination
-# then bail out if and only if keep going option is disabled.
-sub copyFilesToFolders
-{
-	my ($source,$dest,$dir,$verboseOpt) = @_;
-	$source =~ s/\"//g; # remove double quotes from the string. 
-	my $destFileName = "";	# name of the destination file.
-	$dest =~ s/\"//g;	# remove double quotes from the string. 
-	my $destDirectory = $dest;
-	# strip the last substring to get destination file 
-	if ($dest=~/.*\\(\S+)/) 
-	{
-		$destFileName = $1;
-	}
-	else
-	{
-		$destFileName = $dest;
-	}
-	#get the destination directory along with full path
-	#when "[" and "]" appear in the file name we need add "\" before "[" or "]"
-	#like this: [filename].exe translate to \[filename\].exe 
-	if($destFileName =~ /\[|\]/)
-	{
-		my $tempFileName = $destFileName;
-		$tempFileName =~ s/(\[|\])/\\$1/g;
-		$destDirectory =~ s/$tempFileName//;
-	}
-	else
-	{	
-		$destDirectory =~ s/$destFileName//;
-	}
-	my $destfile = $dir."\\".$dest;
-	my $createdir = $dir."\\".$destDirectory ;
-
-	# create the specified directory.
-	&createDirectory($createdir);
-	if (!copy($source,$destfile))
-	{
-		warn "warning : $source file could not found \n";
-		return 0;
-	}
-	else
-	{
-		print "$source copied to $destfile\n" if($verboseOpt);
-		return $destfile;
-	}
-}
-
-# Make a check for sisfile keyword by reading the specified iby/oby file,
-# if sisfile keyword is found then push the respective image on to the respective array 
-# and return true.
-sub checkForSisFile 
-{
-	my($obyfile,$sisFileArray,$sisFilePrestent) = @_;
-	# open the oby file in read only mode. 
-	open (DATA, "< $obyfile") or die("* Can't open $obyfile\n");
-	while  (my $line =<DATA>)
-	{
-		if($line =~ /^\s*sisfile\s*=\s*(\S+)/i )
-		{
-			# found a sis file.
-			$$sisFilePrestent = 1;
-			# push sis file on to stack.
-			push(@$sisFileArray,$1);
-			next;
-		}
-	}
-	close(DATA);
-	return $$sisFilePrestent;
-}
-
-# Make a check for zdriveimagename keyword by reading the specified iby/oby file,
-# if zdriveimagename keyword is found then push the respective image on to the respective array 
-# and return true.
-sub checkForZDriveImageKeyword 
-{
-	#$ZDriveImageFilePresent
-	my($obyfile,$ZDriveImageKeywordArray,$ImageFilePresent) = @_;
-	# open the oby file in read only mode. 
-	open (DATA, "< $obyfile") or die("* Can't open $obyfile\n");
-	while  (my $line =<DATA>)
-	{
-		if($line =~ /^\s*zdriveimagename\s*=\s*(\S+)/i )
-		{
-			# found a Z Drive Image file.
-			$$ImageFilePresent = 1;
-			# push sis file on to stack.
-			push(@$ZDriveImageKeywordArray,$1);
-			next;
-		}
-	}
-	close(DATA);
-	return $$ImageFilePresent;
-}
-
-# copy all non-sis file(s) on to prototype data drive folder 
-# which are mentioned under input data drive iby/oby file.
-sub copyNonSisFiles
-{
-	my($dir,$obyfile,$nonsisFileArray,$renameArray,$aliasArray,$hideArray,$verboseOpt,$keepgoingOpt) = @_;
-	open (OBEY ,$obyfile) or die($obyfile."\n");
-	while(my $line =<OBEY>) 
-	{
-		if( $line =~ /^(file|data)\s*=\s*(\S+)\s+(\S+)/i )
-		{
-			my $keyWord=$1;
-			my $source=$2;
-			my $dest=$3;
-
-			if( $source !~ /(\S+):(\S+)/ )
-			{ 
-				$source = Path_Drive().$2;
-			}
-			my $var = &copyFilesToFolders( $source,$dest,$dir,$verboseOpt);
-			if($var)
-			{
-				$var = $keyWord."=".$var;
-				$line =~ s/^(\S+)=(\S+)/$var/;
-				push(@$nonsisFileArray,$line);
-			}
-			else
-			{
-				exit(1)if(!$keepgoingOpt);
-			}
-		}
-		elsif($line =~ /^rename\s+(\S+)\s+(\S+)/i)
-		{
-			my $oldFile = $dir.$1;	# existing-file
-			my $newFile = $dir.$2;	# destination-file
-			print"found rename keyword\nrenaming $oldFile to $newFile\n" if ($verboseOpt);
-			if ( rename($oldFile, $newFile) )
-			{
-				# push the line on to the stack.
-				push(@$renameArray,$1."\t".$2."\n");
-			}
-			else
-			{
-				&datadriveimage::reportError("* Warning : can't rename $oldFile to $newFile: $!",$keepgoingOpt);
-			}
-		}
-		elsif($line =~ /^alias\s+(\S+)\s+(\S+)/i)
-		{
-			my $exFile = $dir.$1;	# existing-file
-			my $destFile = $dir.$2;	# destination-file
-			print"found alias keyword\n" if ($verboseOpt);
-			if(!copy($exFile,$destFile))
-			{
-				&datadriveimage::reportError("* warning : couldnt create alias of $1 to $2 ",$keepgoingOpt);
-			}
-			else
-			{
-				# push the line on to the stack.
-				push(@$aliasArray,$1."\t".$2."\n");
-			}
-		}
-		elsif($line =~ /^hide\s+(\S+)/i)
-		{
-			print"found hide keyword\n" if ($verboseOpt);
-			print "$1 is marked as hidden, hence will not be part of the image\n" if($verboseOpt);
-			if( unlink($dir.$1) )
-			{
-				# push the line on to the stack.
-				push(@$hideArray,$1);
-			}
-			else 
-			{ 
-				&datadriveimage::reportError("* Warning : Can't delete $1: $! ",$keepgoingOpt);
-			}
-		}
-	}
-	close(OBEY);
-}
-
-# invoke the INTERPRETSIS tool with appropriate parameters.
-sub invokeInterpretsis
-{
-	my($sisFileArray,$dataDrivePath,$verboseOpt,$zDrivePath,$parafile,$keepgoingOpt,$interpretsisOptList) = @_;
-	my $sisfile = ""; 
-	# default system drive letter is specified since interpretsis doesnt allow overloading of options unless default 
-	# options are specified.
-	my $basicOption = "-d C: ";	# default system drive letter
-	my $command = "interpretsis ";
-	my $vOption = "-w info" if ($verboseOpt);
-
-	# do a check if the path has a white space.
-	if( $dataDrivePath =~ m/ /)
-	{
-		$dataDrivePath = '"'.$dataDrivePath.'"';
-	}
-
-	# find out size of the array
-	my $sisarraysize = scalar(@$sisFileArray);
-	for( my $i=0; $i<$sisarraysize; $i++ )
-	{
-		if($sisfile ne "")
-		{
-			$sisfile = pop(@$sisFileArray).",".$sisfile;
-		}
-		else
-		{
-			$sisfile = pop(@$sisFileArray);
-		}
-	}
-
-	# check whether the directory exists or not 
-	if( -d $zDrivePath )
-	{ 
-		# do a check if the path has a white space.
-		if( $zDrivePath =~ m/ /)
-		{
-			$zDrivePath = '"'.$zDrivePath.'"';
-		}
-		$basicOption .= "-z $zDrivePath "; 
-	}
-
-	$basicOption .= "-c $dataDrivePath -s $sisfile $vOption";
-
-	# if parameter file is specified then invoke the INTERPRETSIS
-	# with the specified parameter file with "-p" option.
-	if( defined($parafile) )
-	{ 
-		# do a check if the path has a white space.
-		if( $parafile =~ m/ /)
-		{
-			$parafile = '"'.$parafile.'"';
-		}
-		$command .= "-p $parafile "; 
-	}
-	# else invoke the INTERPRETSIS with default parameter file with "-p" option. 
-	else
-	{
-		# Truncate and open the parameter file for writing..
-		open( OPTDATA, "> parameterfile.txt" )  or die "can't open parameterfile.txt";
-		print OPTDATA $basicOption."\n";
-		close( OPTDATA );
-		$command .= "-p parameterfile.txt ";
-	}
-
-	if( $interpretsisOptList )
-	{
-		# find out size of the array
-		my $arraysize = scalar( @$interpretsisOptList );
-		for( my $i = 0; $i < $arraysize; $i++ )
-		{
-			$command .= $$interpretsisOptList[$i]." ";
-		}
-	}
-
-	print "* Executing $command\n" if ( $verboseOpt );
-	system ( $command );
-
-	if ($? != 0)
-	{
-		&datadriveimage::reportError("* ERROR: INTERPRETSIS failed",$keepgoingOpt);
-	}
-}
-
-# invoke the READIMAGE tool with appropriate parameters.
-sub invokeReadImage
-{
-	my($imageName,$loc,$verboseOpt,$logFile,$keepgoingOpt) = @_;
-	my $command = "readimage ";
-	# check if log file has been supplied.
-	if(defined($logFile))
-	{
-		if( $logFile =~ m/ /)
-		{
-			$logFile = '"'.$logFile.'"';
-		}
-		$command .= "-l $logFile ";
-	}
-	
-	# do a check if the path has a white space.
-	if( $loc =~ m/ /)
-	{
-		$loc = '"'.$loc.'"';
-	}
-	$command .= "-z ".$loc." ".$imageName;
-	print "* Executing $command\n" if ($verboseOpt);
-	system ($command);
-	if ($? != 0)
-	{
-		&datadriveimage::reportError("* ERROR: READIMAGE failed to read the image",$keepgoingOpt);
-		return 0;
-	}
-	return 1;
-}
-
-# Each line from the OBY file is read and if any of the line contains "rename"/ "alias" keyword
-# then that corresponding line source and line destination is obtained and is passed to this function as one of the parameters.
-# This fuction compares given array with non-sis file(s) array, when an given line destination matches with the destination of an
-# element in the rename array/alias array(array holding list of file(s) that are renamed / made alias) then,
-# that respective element is removed from the rename array and a further check is made to see whether the given
-# line source matches with the destination of an element in the rename array/alias array.If a match is found then
-# a keyword check is done,if the keyword is "rename" then corresponding element's source and destination file is replaced
-# with given line destination file and if the keyword is "alias" then a new element will be added to non sis file array
-# with line destination file as the source and destination file.
-sub compareArrays
-{
-	my ( $firstarray,$nonsisArray,$linesource,$linedest,$linekeyword ) = @_;
-	# count of array element(s).
-	my $firstArrayCount = 0;
-	# source file.
-	my $linesourceFile;
-	# destination file.
-	my $linedestFile;
-	# get source file.
-
-	# strip first occurrence of back slash
-	$linesource =~ s/\\//; 
-
-	# get source file.
-	if ($linesource =~ /.*\\(\S+)/ ) 
-	{
-		$linesourceFile = $1;
-	}
-	# get destination file.
-	if ($linedest =~ /.*\\(\S+)/ )
-	{
-		$linedestFile = $1;
-	}
-	# iterate trough all
-	foreach my $firstarrayEntry (@$firstarray) 
-	{
-		if( $firstarrayEntry =~ /(\S+)\s+(\S+)/ )
-		{
-			my $firstarrayEntrydest = $2;
-
-			if( $linedest eq $firstarrayEntrydest )
-			{
-				# remove the specified element from the array.
-				splice(@$firstarray,$firstArrayCount,1);
-				# initialize the nonsisFileListCount to zero.
-				my $nonsisFileListCount = 0;
-				foreach my $nonsisEntry ( @$nonsisArray )
-				{
-					if( $nonsisEntry =~ /^(\S+)=(\S+)\s+(\S+)/ )
-					{
-						my $nonsisEntryDest = $3;
-						# remove double quotes.
-						$nonsisEntryDest =~ s/\"//g;
-						my $nonsisEntryDestFile;
-						if ($nonsisEntryDest =~ /.*\\(\S+)/ ) 
-						{ 
-							$nonsisEntryDestFile = $1;
-						}
-						if( $nonsisEntryDest eq $linesource )
-						{
-							if($linekeyword eq "rename")
-							{
-								# remove the specified element from the array.
-								splice(@$nonsisArray,$nonsisFileListCount,1);
-								$nonsisEntry =~ s/$nonsisEntryDestFile/$linedestFile/g;
-								push(@$nonsisArray,$nonsisEntry);
-							}
-							elsif($linekeyword eq "alias")
-							{
-								my $newLine = $nonsisEntry;
-								$newLine =~ s/$nonsisEntryDestFile/$linedestFile/g;
-								push(@$nonsisArray,$newLine);
-							}
-						}
-					 }
-					$nonsisFileListCount++;
-				 }#end of loop foreach my $newLine ( @nonsisArray )
-			}
-			$firstArrayCount++;
-		}#end of loop foreach my $newLine ( @firstarray) 
-	}
-}
-
-# Traverse the entire directory and log the folder contents on to a file.
-sub dumpDatadriveObydata
-{
-	#assign a temporary name and extension to the new oby file.
-	my $newobyfile = "temp.$$";
-	my ($datadir,$oldobyfile,$size,$nonsisFileArray,$renameArray,$aliasArray,
-		$hideArray,$sisobyArray,$datadriveArray,$keepgoingOpt,$verboseOpt) = @_;
-	# get the working directory.
-	my $curWorkingDir = getcwd;
-	# traverse the updated data drive directory structure.
-	&TraverseDir($datadir,"",$sisobyArray,$datadir);
-	# change the directrory to the Working directory.
-	chdir($curWorkingDir);
-	# copy non-sis file(s) on to prototype data drive folder.
-	copyNonSisFiles($datadir,$oldobyfile,$nonsisFileArray,$renameArray,$aliasArray,$hideArray,$verboseOpt,$keepgoingOpt);
-	#open the oby file in read-only mode. 
-	open (OLDDATA, "< $oldobyfile") or die("* Can't open $oldobyfile\n");
-	# Truncate and open the new oby file for writing..
-	open(NEWDATA, "> $newobyfile")  or die "can't open $newobyfile";
-	while  (my $line =<OLDDATA>)
-	{
-		if( $line =~ /^hide\s+(\S+)/i)
-		{
-			my $lineToSearch = $1; 
-			my $hideListCount = 0;
-			foreach my $newLine ( @$hideArray ) 
-			{
-				if( $newLine eq $lineToSearch )
-				{
-					splice(@$hideArray,$hideListCount,1);
-					my $nonsisFileListCount = 0;
-					foreach my $newLine ( @$nonsisFileArray )
-					{
-						if( $newLine =~ /^(\S+)=(\S+)\s+(\S+)/ )
-						{
-							my $newLineKeyword = $1;
-							my $newLinesource = $2;
-							my $newLinedest = $3;
-							$newLinedest =~ s/\"//g;
-							$newLinedest = "\\".$newLinedest;
-							if( $newLinedest eq $lineToSearch )
-							{
-								# remove the specified element from the array.
-								splice(@$nonsisFileArray,$nonsisFileListCount,1);
-							}
-						}
-						# increment the non sis file list count.
-						$nonsisFileListCount++;
-					}
-				}
-				# increment the  hide file list count.
-				$hideListCount++;
-			}
-		}
-		elsif( $line =~ /^rename\s+(\S+)\s+(\S+)/i) 
-		{ 
-			my $linesource = $1 ;
-			my $linedest = $2;
-			my $linekeyword = "rename";
-			&compareArrays($renameArray,$nonsisFileArray,$linesource,$linedest,$linekeyword);
-		}
-		elsif( $line =~ /^alias\s+(\S+)\s+(\S+)/i )
-		{
-			my $linesource = $1 ;
-			my $linedest = $2;
-			my $linekeyword = "alias";
-			&compareArrays($aliasArray,$nonsisFileArray,$linesource,$linedest,$linekeyword);
-		}
-		elsif(	$line =~ /^(file|data)\s*=\s*/i || $line =~ /^\s*(zdriveimagename|sisfile)\s*=\s*/i )
-		{
-			# skip to next line. 
-			next;
-		}
-		else
-		{ 
-			# push it on to the array.
-			unshift(@$datadriveArray,$line); 
-		}
-		next;
-	}
-	# close the old oby files.
-	close(OLDDATA)or die "can't close $oldobyfile";
-	#write the array contents on to the file
-	print"* Updating $oldobyfile - final OBY file\n";
-	&writeDataToFile( $datadriveArray );
-	&writeDataToFile( $sisobyArray );
-	&writeDataToFile( $nonsisFileArray );
-	# close the new oby file.
-	close(NEWDATA)or die "can't close $newobyfile";
-	#rename the file.
-	rename( $newobyfile, $oldobyfile )or die "can't rename $newobyfile to $oldobyfile: $!";
-}
-
-
-# Traverse the entire given directory 
-# push all the folder contents on to an array.
-sub  TraverseDir
-{
-	my($dir,$folderList,$sisFileContent,$rootdir) = @_;
-	#check the specified directory
-	chdir($dir) || die "Cannot chdir to $dir\n";
-	local(*DIR);
-	opendir(DIR, ".");#open current directory.
-	my $sourcedir;
-	my $destdir;
-	while (my $entry=readdir(DIR)) 
-	{
-		#skip, parent directory and current directory.
-		next if ($entry eq "." || $entry eq "..");
-		#check if it is a file 
-		if( -f $entry )
-		{
-			my $sourcedir = $rootdir."\\".$folderList.$entry;
-			my $destdir	= "$folderList".$entry;
-			my $sisSource;
-			my $sisdestination;
-			if(&checkRegCtlFiles($entry))
-			{
-				# check for any whitespace
-				if($sourcedir =~ m/ /)
-				{
-					# if yes, then append double quotes
-					$sisSource = "data="."\"".$sourcedir."\"";
-				}
-				else
-				{
-					# else dont append any double quotes for destination
-					$sisSource = "data=".$sourcedir;
-				}
-				# push the line on to the array.
-				push(@$sisFileContent,$sisSource."\t".'"'.$destdir.'"');
-			}
-			else
-			{
-				# check for any white space
-				if($sourcedir =~ m/ /)
-				{
-					# if yes, then append double quotes
-					$sisSource = "file="."\"".$sourcedir."\"";
-				}
-				else
-				{
-					# else dont append any double quotes for destination
-					$sisSource = "file=".$sourcedir;
-				}
-				# push the line on to the array.
-				push(@$sisFileContent,$sisSource."\t".'"'.$destdir.'"');
-			}
-		}
-		#else it's a directory
-		else
-		{
-			&TraverseDir($entry,$folderList.$entry."\\",$sisFileContent,$rootdir);
-		}
-	}
-	closedir(DIR);
-	chdir("..");
-}
-
-# write the data in to oby file by accessing appropriate array.
-sub writeDataToFile
-{
-	my ($array) = @_; 
-	#get the array size.
-	my $arraySize = scalar(@$array);
-	for(my $i=0; $i<$arraySize ; $i++ )
-	{
-		#pop out the element to the respective obey file.
-		 print NEWDATA pop(@$array)."\n";
-	}
-}
\ No newline at end of file
+#
+# Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of the License "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: 
+# This package contains fuctions specific to data drive image generation
+#
+
+
+package datadriveimage;
+
+require Exporter;
+@ISA=qw(Exporter);
+@EXPORT=qw(
+			createDirectory 
+			deleteDirectory 
+			checkInArray 
+			setPath 
+			locateStubsisfiles 
+			copyFilesToFolders 
+			checkForSisFile 
+			copyNonSisFiles
+			invokeInterpretsis
+			invokeReadImage
+			compareArrays
+			dumpDatadriveObydata
+			TraverseDir
+			writeDataToFile
+			generate_datadriveheader
+			checkForWhiteSpace
+			reportError
+);
+
+use strict;
+use File::Path;		# Module to provide functions to remove or create directories in a convenient way.
+use File::Copy;		# Module to provide functions to copy file(s) from source to destination.
+
+use Cwd;			# Module to provide functions for determining the pathname of the current working directory.
+
+use romutl;
+use romosvariant;
+
+# This fuction is used primiarly to check for whitespace in the location for "zdrive" / "datadrive" folder creation,
+# specified by the user, if yes then it returns one, else zero
+sub checkForWhiteSpace
+{
+	my ($dirLoc,$dirName) = @_;
+	if( $dirLoc =~ m/ / )
+	{
+		print "* Warning: $dirLoc contains whitespace, hence $dirName will be created in default location \n";
+		return 1;
+	}
+	else
+	{
+		return 0;
+	}
+}
+
+
+# This function reports the appropriate meassage supplied to it
+# and does a exit if and only if keepgoing option is disabled.
+sub reportError
+{
+	my( $message,$keepgoingOpt ) = @_;
+	# print the specified meassage.
+	print STDERR "$message \n";
+	# bail out, if keepgoing option is not set.
+	exit(1) if (!$keepgoingOpt);
+}
+
+# generate header for final datadrive oby file.
+sub generate_datadriveheader
+{
+	my ($idx,$datadriveimage) = @_;
+	my $header;
+	$header =  "dataimagename=$$datadriveimage[$idx]{name}.img\n";
+	$header .= "dataimagefilesystem=$$datadriveimage[$idx]{fstype}\n";
+
+	# check whether the size of the image has been mentioned
+	if(defined($$datadriveimage[$idx]{size}))
+	{
+		$header .= "dataimagesize=$$datadriveimage[$idx]{size}\n\n";
+	}
+	return $header;
+}
+
+# Create the specified directory by making use of mkpath function 
+# from File::Path module.
+sub createDirectory
+{
+	my($dir) = @_;
+	if( !-d $dir )
+	{
+		mkpath($dir);
+		if (! -e $dir) 
+		{
+			print ("ERROR: Couldn't create $dir\n");
+		}
+	}
+}
+
+# check if the given file is a reg file or ctl file or a txt file
+# if it is any of these files then return true else false.
+# This check is need since these three files or not valid not valid e32 file 
+# and hence needs to be placed as an data file inside the image.
+sub checkRegCtlFiles
+{
+	my ($fileName) = @_;
+
+	# check whether the file has "reg","ctl" or "txt" extension.
+	if( $fileName =~/\.(reg|ctl|txt)$/i )
+	{
+		return 1;		
+	}
+	else
+	{
+		return 0;
+	}
+}
+
+# delete the given directory by making use of rmtree function 
+# from File::Path module.
+sub deleteDirectory
+{
+	my($dir,$verboseOpt) = @_;
+	# check whether the directory exists.
+	if( -d $dir )
+	{
+		print("found $dir directory \n") if($verboseOpt);
+		if(rmtree($dir))
+		{
+			print("$dir directory deleted \n") if($verboseOpt);
+			return 0;
+		}
+		else
+		{
+			print("$dir directory could'nt be deleted \n") if($verboseOpt);
+			return 1;
+		}
+	}
+}
+
+# check for processed data drive image index.
+# if there is a match return one else return zero.
+# this check is done in order to ensure data drive image index is not repeated.
+sub checkInArray
+{
+	my($array, $value) = @_;
+	foreach my $aLine(@$array)
+	{
+		if( $aLine eq $value )
+		{
+			return 0;
+		}
+	}
+	return 1;
+}
+
+# set the path for the given directory.
+sub setPath
+{
+	my($dirName) = @_;
+	# get the working directory.
+	my $curWorkingDir = getcwd;
+	# substitute slash with double backward slash.
+	$curWorkingDir =~ s/\\/\//g;
+ 	#if $curWorkingDir already has trailing '\', don't include it again 
+ 	if( $curWorkingDir =~ /\/$/)
+ 	{
+ 		return $curWorkingDir.$dirName;
+ 	}
+ 	else
+ 	{
+ 		return $curWorkingDir."\/".$dirName;
+ 	}
+}
+
+# create directory and copy respective file on to that directory.
+# is there is a problem while copying files from source to destination
+# then bail out if and only if keep going option is disabled.
+sub copyFilesToFolders
+{
+	my ($source,$dest,$dir,$verboseOpt) = @_;
+	$source =~ s/\"//g; # remove double quotes from the string. 
+	my $destFileName = "";	# name of the destination file.
+	$dest =~ s/\"//g;	# remove double quotes from the string. 
+	my $destDirectory = $dest;
+	# strip the last substring to get destination file 
+	if ($dest=~/.*[\/\\](\S+)/) 
+	{
+		$destFileName = $1;
+	}
+	else
+	{
+		$destFileName = $dest;
+	}
+	#get the destination directory along with full path
+	#when "[" and "]" appear in the file name we need add "\" before "[" or "]"
+	#like this: [filename].exe translate to \[filename\].exe 
+	if($destFileName =~ /\[|\]/)
+	{
+		my $tempFileName = $destFileName;
+		$tempFileName =~ s/(\[|\])/\\$1/g;
+		$destDirectory =~ s/$tempFileName//;
+	}
+	else
+	{	
+		$destDirectory =~ s/$destFileName//;
+	}
+	my $destfile = $dir."\/".$dest;
+	my $createdir = $dir."\/".$destDirectory ;
+
+	# create the specified directory.
+	&createDirectory($createdir);
+	if (!copy($source,$destfile))
+	{
+		warn "warning : $source file could not found \n";
+		return 0;
+	}
+	else
+	{
+		print "$source copied to $destfile\n" if($verboseOpt);
+		return "\"".$destfile."\"";
+	}
+}
+
+# Make a check for sisfile keyword by reading the specified iby/oby file,
+# if sisfile keyword is found then push the respective image on to the respective array 
+# and return true.
+sub checkForSisFile 
+{
+	my($obyfile,$sisFileArray,$sisFilePrestent) = @_;
+	# open the oby file in read only mode. 
+	open (DATA, "< $obyfile") or die("* Can't open $obyfile\n");
+	while  (my $line =<DATA>)
+	{
+		if($line =~ /^\s*sisfile\s*=\s*(\S+)/i )
+		{
+			# found a sis file.
+			$$sisFilePrestent = 1;
+			# push sis file on to stack.
+			push(@$sisFileArray,$1);
+			next;
+		}
+	}
+	close(DATA);
+	return $$sisFilePrestent;
+}
+
+# Make a check for zdriveimagename keyword by reading the specified iby/oby file,
+# if zdriveimagename keyword is found then push the respective image on to the respective array 
+# and return true.
+sub checkForZDriveImageKeyword 
+{
+	#$ZDriveImageFilePresent
+	my($obyfile,$ZDriveImageKeywordArray,$ImageFilePresent) = @_;
+	# open the oby file in read only mode. 
+	open (DATA, "< $obyfile") or die("* Can't open $obyfile\n");
+	while  (my $line =<DATA>)
+	{
+		if($line =~ /^\s*zdriveimagename\s*=\s*(\S+)/i )
+		{
+			# found a Z Drive Image file.
+			$$ImageFilePresent = 1;
+			# push sis file on to stack.
+			push(@$ZDriveImageKeywordArray,$1);
+			next;
+		}
+	}
+	close(DATA);
+	return $$ImageFilePresent;
+}
+
+# copy all non-sis file(s) on to prototype data drive folder 
+# which are mentioned under input data drive iby/oby file.
+sub copyNonSisFiles
+{
+	my($dir,$obyfile,$nonsisFileArray,$renameArray,$aliasArray,$hideArray,$verboseOpt,$keepgoingOpt) = @_;
+	open (OBEY ,$obyfile) or die($obyfile."\n");
+	while(my $line =<OBEY>) 
+	{
+		if( $line =~ /^(file|data)\s*=\s*(\"[^"]+\")\s+(\"[^"]+\")/i || 
+				$line =~ /^(file|data)\s*=\s*(\"[^"]+\")\s+(\S+)/i || 
+				$line =~ /^(file|data)\s*=\s*(\S+)\s+(\"[^"]+\")/i || 
+				$line =~ /^(file|data)\s*=\s*(\S+)\s+(\S+)/i )
+		{
+			my $keyWord=$1;
+			my $source=$2;
+			my $dest=$3;
+
+			if( $source !~ /(\S+):([^"]+)/ )
+			{ 
+				$source = get_drive().$2;
+			}
+			my $var = &copyFilesToFolders( $source,$dest,$dir,$verboseOpt);
+			if($var)
+			{
+				$line = $keyWord."=".$var."\t".$dest."\n";
+				push(@$nonsisFileArray,$line);
+			}
+			else
+			{
+				exit(1)if(!$keepgoingOpt);
+			}
+		}
+		elsif($line =~ /^rename\s+(\S+)\s+(\S+)/i)
+		{
+			my $oldFile = $dir.$1;	# existing-file
+			my $newFile = $dir.$2;	# destination-file
+			print"found rename keyword\nrenaming $oldFile to $newFile\n" if ($verboseOpt);
+			if ( rename($oldFile, $newFile) )
+			{
+				# push the line on to the stack.
+				push(@$renameArray,$1."\t".$2."\n");
+			}
+			else
+			{
+				&datadriveimage::reportError("* Warning : can't rename $oldFile to $newFile: $!",$keepgoingOpt);
+			}
+		}
+		elsif($line =~ /^alias\s+(\S+)\s+(\S+)/i)
+		{
+			my $exFile = $dir.$1;	# existing-file
+			my $destFile = $dir.$2;	# destination-file
+			print"found alias keyword\n" if ($verboseOpt);
+			if(!copy($exFile,$destFile))
+			{
+				&datadriveimage::reportError("* warning : couldnt create alias of $1 to $2 ",$keepgoingOpt);
+			}
+			else
+			{
+				# push the line on to the stack.
+				push(@$aliasArray,$1."\t".$2."\n");
+			}
+		}
+		elsif($line =~ /^hide\s+(\S+)/i)
+		{
+			print"found hide keyword\n" if ($verboseOpt);
+			print "$1 is marked as hidden, hence will not be part of the image\n" if($verboseOpt);
+			if( unlink($dir.$1) )
+			{
+				# push the line on to the stack.
+				push(@$hideArray,$1);
+			}
+			else 
+			{ 
+				&datadriveimage::reportError("* Warning : Can't delete $1: $! ",$keepgoingOpt);
+			}
+		}
+	}
+	close(OBEY);
+}
+
+# invoke the INTERPRETSIS tool with appropriate parameters.
+sub invokeInterpretsis
+{
+	my($sisFileArray,$dataDrivePath,$verboseOpt,$zDrivePath,$parafile,$keepgoingOpt,$interpretsisOptList) = @_;
+	my $sisfile = ""; 
+	# default system drive letter is specified since interpretsis doesnt allow overloading of options unless default 
+	# options are specified.
+	my $basicOption = "-d C: ";	# default system drive letter
+	my $command = "interpretsis ";
+	my $vOption = "-w info" if ($verboseOpt);
+	
+	is_existinpath("interpretsis", romutl::DIE_NOT_FOUND);
+
+	# do a check if the path has a white space.
+	if( $dataDrivePath =~ m/ /)
+	{
+		$dataDrivePath = '"'.$dataDrivePath.'"';
+	}
+
+	# find out size of the array
+	my $sisarraysize = scalar(@$sisFileArray);
+	for( my $i=0; $i<$sisarraysize; $i++ )
+	{
+		if($sisfile ne "")
+		{
+			$sisfile = pop(@$sisFileArray).",".$sisfile;
+		}
+		else
+		{
+			$sisfile = pop(@$sisFileArray);
+		}
+	}
+
+	# check whether the directory exists or not 
+	if( -d $zDrivePath )
+	{ 
+		# do a check if the path has a white space.
+		if( $zDrivePath =~ m/ /)
+		{
+			$zDrivePath = '"'.$zDrivePath.'"';
+		}
+		$basicOption .= "-z $zDrivePath "; 
+	}
+
+	$basicOption .= "-c $dataDrivePath -s $sisfile $vOption";
+
+	# if parameter file is specified then invoke the INTERPRETSIS
+	# with the specified parameter file with "-p" option.
+	if( defined($parafile) )
+	{ 
+		# do a check if the path has a white space.
+		if( $parafile =~ m/ /)
+		{
+			$parafile = '"'.$parafile.'"';
+		}
+		$command .= "-p $parafile "; 
+	}
+	# else invoke the INTERPRETSIS with default parameter file with "-p" option. 
+	else
+	{
+		# Truncate and open the parameter file for writing..
+		open( OPTDATA, "> parameterfile.txt" )  or die "can't open parameterfile.txt";
+		print OPTDATA $basicOption."\n";
+		close( OPTDATA );
+		$command .= "-p parameterfile.txt ";
+	}
+
+	if( $interpretsisOptList )
+	{
+		# find out size of the array
+		my $arraysize = scalar( @$interpretsisOptList );
+		for( my $i = 0; $i < $arraysize; $i++ )
+		{
+			$command .= $$interpretsisOptList[$i]." ";
+		}
+	}
+	
+	print "* Executing $command\n" if ( $verboseOpt );
+	system ( $command );
+
+	if ($? != 0)
+	{
+		&datadriveimage::reportError("* ERROR: INTERPRETSIS failed",$keepgoingOpt);
+	}
+}
+
+# invoke the READIMAGE tool with appropriate parameters.
+sub invokeReadImage
+{
+	my($imageName,$loc,$verboseOpt,$logFile,$keepgoingOpt) = @_;
+	my $command = "readimage ";
+	
+	is_existinpath("readimage", romutl::DIE_NOT_FOUND);
+	
+	# check if log file has been supplied.
+	if(defined($logFile))
+	{
+		if( $logFile =~ m/ /)
+		{
+			$logFile = '"'.$logFile.'"';
+		}
+		$command .= "-l $logFile ";
+	}
+	
+	# do a check if the path has a white space.
+	if( $loc =~ m/ /)
+	{
+		$loc = '"'.$loc.'"';
+	}
+	$command .= "-z ".$loc." ".$imageName;
+	print "* Executing $command\n" if ($verboseOpt);
+	system ($command);
+	if ($? != 0)
+	{
+		&datadriveimage::reportError("* ERROR: READIMAGE failed to read the image",$keepgoingOpt);
+		return 0;
+	}
+	return 1;
+}
+
+# Each line from the OBY file is read and if any of the line contains "rename"/ "alias" keyword
+# then that corresponding line source and line destination is obtained and is passed to this function as one of the parameters.
+# This fuction compares given array with non-sis file(s) array, when an given line destination matches with the destination of an
+# element in the rename array/alias array(array holding list of file(s) that are renamed / made alias) then,
+# that respective element is removed from the rename array and a further check is made to see whether the given
+# line source matches with the destination of an element in the rename array/alias array.If a match is found then
+# a keyword check is done,if the keyword is "rename" then corresponding element's source and destination file is replaced
+# with given line destination file and if the keyword is "alias" then a new element will be added to non sis file array
+# with line destination file as the source and destination file.
+sub compareArrays
+{
+	my ( $firstarray,$nonsisArray,$linesource,$linedest,$linekeyword ) = @_;
+	# count of array element(s).
+	my $firstArrayCount = 0;
+	# source file.
+	my $linesourceFile;
+	# destination file.
+	my $linedestFile;
+	# get source file.
+
+	# strip first occurrence of back slash
+	$linesource =~ s/[\/\\]//; 
+
+	# get source file.
+	if ($linesource =~ /.*[\/\\](\S+)/ ) 
+	{
+		$linesourceFile = $1;
+	}
+	# get destination file.
+	if ($linedest =~ /.*[\/\\](\S+)/ )
+	{
+		$linedestFile = $1;
+	}
+	# iterate trough all
+	foreach my $firstarrayEntry (@$firstarray) 
+	{
+		if( $firstarrayEntry =~ /(\S+)\s+(\S+)/ )
+		{
+			my $firstarrayEntrydest = $2;
+
+			if( $linedest eq $firstarrayEntrydest )
+			{
+				# remove the specified element from the array.
+				splice(@$firstarray,$firstArrayCount,1);
+				# initialize the nonsisFileListCount to zero.
+				my $nonsisFileListCount = 0;
+				foreach my $nonsisEntry ( @$nonsisArray )
+				{
+					if( $nonsisEntry =~ /^(\S+)=(\S+)\s+(\S+)/ )
+					{
+						my $nonsisEntryDest = $3;
+						# remove double quotes.
+						$nonsisEntryDest =~ s/\"//g;
+						my $nonsisEntryDestFile;
+						if ($nonsisEntryDest =~ /.*[\/\\](\S+)/ ) 
+						{ 
+							$nonsisEntryDestFile = $1;
+						}
+						if( $nonsisEntryDest eq $linesource )
+						{
+							if($linekeyword eq "rename")
+							{
+								# remove the specified element from the array.
+								splice(@$nonsisArray,$nonsisFileListCount,1);
+								$nonsisEntry =~ s/$nonsisEntryDestFile/$linedestFile/g;
+								push(@$nonsisArray,$nonsisEntry);
+							}
+							elsif($linekeyword eq "alias")
+							{
+								my $newLine = $nonsisEntry;
+								$newLine =~ s/$nonsisEntryDestFile/$linedestFile/g;
+								push(@$nonsisArray,$newLine);
+							}
+						}
+					 }
+					$nonsisFileListCount++;
+				 }#end of loop foreach my $newLine ( @nonsisArray )
+			}
+			$firstArrayCount++;
+		}#end of loop foreach my $newLine ( @firstarray) 
+	}
+}
+
+# Traverse the entire directory and log the folder contents on to a file.
+sub dumpDatadriveObydata
+{
+	#assign a temporary name and extension to the new oby file.
+	my $newobyfile = "temp.$$";
+	my ($datadir,$oldobyfile,$size,$nonsisFileArray,$renameArray,$aliasArray,
+		$hideArray,$sisobyArray,$datadriveArray,$keepgoingOpt,$verboseOpt) = @_;
+	# get the working directory.
+	my $curWorkingDir = getcwd;
+	# traverse the updated data drive directory structure.
+	&TraverseDir($datadir,"",$sisobyArray,$datadir);
+	# change the directrory to the Working directory.
+	chdir($curWorkingDir);
+	# copy non-sis file(s) on to prototype data drive folder.
+	copyNonSisFiles($datadir,$oldobyfile,$nonsisFileArray,$renameArray,$aliasArray,$hideArray,$verboseOpt,$keepgoingOpt);
+	#open the oby file in read-only mode. 
+	open (OLDDATA, "< $oldobyfile") or die("* Can't open $oldobyfile\n");
+	# Truncate and open the new oby file for writing..
+	open(NEWDATA, "> $newobyfile")  or die "can't open $newobyfile";
+	while  (my $line =<OLDDATA>)
+	{
+		if( $line =~ /^hide\s+(\S+)/i)
+		{
+			my $lineToSearch = $1; 
+			my $hideListCount = 0;
+			foreach my $newLine ( @$hideArray ) 
+			{
+				if( $newLine eq $lineToSearch )
+				{
+					splice(@$hideArray,$hideListCount,1);
+					my $nonsisFileListCount = 0;
+					foreach my $newLine ( @$nonsisFileArray )
+					{
+						if( $newLine =~ /^(\S+)=(\S+)\s+(\S+)/ )
+						{
+							my $newLineKeyword = $1;
+							my $newLinesource = $2;
+							my $newLinedest = $3;
+							$newLinedest =~ s/\"//g;
+							$newLinedest = "\/".$newLinedest;
+							if( $newLinedest eq $lineToSearch )
+							{
+								# remove the specified element from the array.
+								splice(@$nonsisFileArray,$nonsisFileListCount,1);
+							}
+						}
+						# increment the non sis file list count.
+						$nonsisFileListCount++;
+					}
+				}
+				# increment the  hide file list count.
+				$hideListCount++;
+			}
+		}
+		elsif( $line =~ /^rename\s+(\S+)\s+(\S+)/i) 
+		{ 
+			my $linesource = $1 ;
+			my $linedest = $2;
+			my $linekeyword = "rename";
+			&compareArrays($renameArray,$nonsisFileArray,$linesource,$linedest,$linekeyword);
+		}
+		elsif( $line =~ /^alias\s+(\S+)\s+(\S+)/i )
+		{
+			my $linesource = $1 ;
+			my $linedest = $2;
+			my $linekeyword = "alias";
+			&compareArrays($aliasArray,$nonsisFileArray,$linesource,$linedest,$linekeyword);
+		}
+		elsif(	$line =~ /^(file|data)\s*=\s*/i || $line =~ /^\s*(zdriveimagename|sisfile)\s*=\s*/i )
+		{
+			# skip to next line. 
+			next;
+		}
+		else
+		{ 
+			# push it on to the array.
+			unshift(@$datadriveArray,$line); 
+		}
+		next;
+	}
+	# close the old oby files.
+	close(OLDDATA)or die "can't close $oldobyfile";
+	#write the array contents on to the file
+	print"* Updating $oldobyfile - final OBY file\n";
+	&writeDataToFile( $datadriveArray );
+	&writeDataToFile( $sisobyArray );
+	&writeDataToFile( $nonsisFileArray );
+	# close the new oby file.
+	close(NEWDATA)or die "can't close $newobyfile";
+	#rename the file.
+	rename( $newobyfile, $oldobyfile )or die "can't rename $newobyfile to $oldobyfile: $!";
+}
+
+
+# Traverse the entire given directory 
+# push all the folder contents on to an array.
+sub  TraverseDir
+{
+	my($dir,$folderList,$sisFileContent,$rootdir) = @_;
+	#check the specified directory
+	chdir($dir) || die "Cannot chdir to $dir\n";
+	local(*DIR);
+	opendir(DIR, ".");#open current directory.
+	my $sourcedir;
+	my $destdir;
+	while (my $entry=readdir(DIR)) 
+	{
+		#skip, parent directory and current directory.
+		next if ($entry eq "." || $entry eq "..");
+		#check if it is a file 
+		if( -f $entry )
+		{
+			my $sourcedir = $rootdir."\/".$folderList.$entry;
+			my $destdir	= "$folderList".$entry;
+			my $sisSource;
+			my $sisdestination;
+			if(&checkRegCtlFiles($entry))
+			{
+				# check for any whitespace
+				if($sourcedir =~ m/ /)
+				{
+					# if yes, then append double quotes
+					$sisSource = "data="."\"".$sourcedir."\"";
+				}
+				else
+				{
+					# else dont append any double quotes for destination
+					$sisSource = "data=".$sourcedir;
+				}
+				# push the line on to the array.
+				push(@$sisFileContent,$sisSource."\t".'"'.$destdir.'"');
+			}
+			else
+			{
+				# check for any white space
+				if($sourcedir =~ m/ /)
+				{
+					# if yes, then append double quotes
+					$sisSource = "file="."\"".$sourcedir."\"";
+				}
+				else
+				{
+					# else dont append any double quotes for destination
+					$sisSource = "file=".$sourcedir;
+				}
+				# push the line on to the array.
+				push(@$sisFileContent,$sisSource."\t".'"'.$destdir.'"');
+			}
+		}
+		#else it's a directory
+		else
+		{
+			&TraverseDir($entry,$folderList.$entry."\/",$sisFileContent,$rootdir);
+		}
+	}
+	closedir(DIR);
+	chdir("..");
+}
+
+# write the data in to oby file by accessing appropriate array.
+sub writeDataToFile
+{
+	my ($array) = @_; 
+	#get the array size.
+	my $arraySize = scalar(@$array);
+	for(my $i=0; $i<$arraySize ; $i++ )
+	{
+		#pop out the element to the respective obey file.
+		my $line=pop(@$array);
+		if (&is_windows){
+			$line =~ s-\/-\\-g;
+		}else{
+			$line =~ s-\\-\/-g;
+		}
+		print NEWDATA $line."\n";
+	}
+}