imgtools/buildrom/tools/spitool.pm
changeset 590 360bd6b35136
parent 0 044383f39525
--- a/imgtools/buildrom/tools/spitool.pm	Wed Jun 16 16:51:40 2010 +0300
+++ b/imgtools/buildrom/tools/spitool.pm	Wed Jun 23 16:56:47 2010 +0800
@@ -1,478 +1,478 @@
-#
-# Copyright (c) 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: 
-#
-
-package spitool;
-
-use strict;
-use Exporter;
-use vars qw($VERSION @ISA @EXPORT @EXPORT_OK);
-
-$VERSION     = 1.00;
-@ISA         = qw(Exporter);
-@EXPORT      = ();
-@EXPORT_OK   = qw(createSpi);
-
-sub binarize { #converts decimal number to 4 byte litte endian format
-	my $value = shift;
-	my $remainder;
-	my $returnValue;
-	for(my $i=0;$i<4;$i++) {
-		$remainder=$value % 256;
-		$returnValue.=chr($remainder);
-		$value = ($value-$remainder)/256;
-	}
-	return $returnValue;
-}
-
-sub convertUidFromText { #converts UID from hexadeciaml text value to decimal value, passes decimal value unchanged, returns -1 if invalid UID
-	my $value = shift;
-	if($value =~ /^0x([\da-fA-F]{1,8})$/i) {
-		return hex $1;
-	} elsif ($value =~ /^\d*$/) {
-		return $value;
-	} else {
-		return -1;
-	}
-}
-
-sub bin2hex { #converts 4 byte little endian value to 0x... hex text value
-	my $value=shift;
-	my $byte;
-	my $quotient;
-	my $remainder;
-	my $hexValue="";
-	for(my $i=0;$i<4;$i++) {
-		$byte=ord(substr($value,$i,1));
-		$remainder=$byte%16;
-		$quotient=($byte-$remainder)/16;
-		if($remainder>9) {
-			$remainder= chr($remainder+55);
-		}
-		if($quotient>9) {
-			$quotient= chr($quotient+55);
-		}		
-		$hexValue=$quotient . $remainder . $hexValue;
-	}
-	return "0x" . $hexValue;
-}
-
-sub uidcrc { #returns decimal UID checksum value for the three inputs
-	my $output = `uidcrc $_[0] $_[1] $_[2]`;
-	if($output =~ /([^ ]*)$/i) {
-		$output =$1;
-		chomp $output;
-		return hex($output);
-	}	
-}
-
-sub printZeroes { #prints as many hexadecimal zeroes to OUTPUTFILE as specified by input
-	my $numberOfZeroes=shift;
-	for(my $i=0;$i<$numberOfZeroes;$i++) {
-		print OUTPUTFILE chr(0);
-	}
-}
-
-sub bytes2dec { #calculates decimal value from inputted 4 byte little endian value 
-	my $bytes=shift;
-	my @byteArray;
-	for(my $i=0;$i<length $bytes;$i++) {
-		$byteArray[$i]=ord(substr($bytes,$i,1));
-	}
-	my $decValue;
-	for(my $i=0;$i<scalar @byteArray;$i++) {
-		$decValue+=($byteArray[$i]*(2**($i*8)));
-	}
-	return $decValue;
-}
-
-sub print_usage
-	{
-#........1.........2.........3.........4.........5.........6.........7.....
-	print <<USAGE_EOF;
-
-Usage:
-  spitool.pl [options] files directories   
-
-Create an SPI file by concatenating the files and contents of directories,
-based on the options passed. 
-
-The available options are:
-
--tSPIFileName       -- SPIFileName is the name the produced SPI file will 
-                       have (i.e. ecom-0-0.spi). If not specified, the name 
-                       will be ecom-0-0.spi by default
--dTargetDir         -- TargetDir is the directory where the SPI file should
-                       be created, ending with a \
--iExisting          -- Existing is address and name of existing SPI file to
-                       concatenate specified files to 
--uid<x>=<y>         -- <x> has value 1, 2 or 3, <y> is an UID value in
-                       decimal or 0x... hexadecimal
--existinguid<x>=<y> -- <x> has value 1, 2 or 3, <y> is an UID value in 
-                       decimal or 0x... hexadecimal
--existinguidcrc=<x> -- <x> is an UID value in decimal or 0x.. hexadecimal
--hide<ResourceFileNames> -- <ResourceFileNames> is the list of the resource files
-			    that are to be hidden in the SPI file separated by
-			    space or comma.
-  
-If an existing SPI file is specified with the -i option then this file is
-used as a base and other data files are added to the end of this file,
-otherwise a new SPI file is created. In either case the produced SPI file
-is placed in the directory specified by the -d option and given the name 
-specified with the -t option.
-
-Files which are to be concatenated into the SPI file should be specified
-on the command line by either specifying the file's name (and location), or
-by including a directory name, in which case all files from that directory
-will be included.
-
-The -uid options can be used to filter files for inclusion in the SPI file.
-This option can be included multiple times, so a list of UID1 values can be
-built up, and the same for UID2 and UID3 values. Each file on the command
-line is compared with this list, and if any of its UID values match a
-relevant value in the UID lists then that file will be included in the SPI
-file. If the file does not match any values it will be excluded.
-
-The -existinguid options allow the UID values that an existing SPI file
-should have to be specified. This will allow the possibility of checking
-that the correct type of files are being concatenated together.
-
-The -hide option can be used to mark a resource file as hidden in the SPI file.
-To mark a resource file as a hidden entry in the SPI file, the resource data 
-length will be written as 0.
-
-USAGE_EOF
-	}
-
-sub createSpi 
-	{
-	my @resourceFiles=();
-	my @hideresourceFiles=();
-	my $spiFileName;
-	my $targetDirectory;
-	my $existingSpiFileName;
-	my @uid;
-	my @uidLengths = (0, 0, 0, 0);
-	my @uid1;
-	my @uid2;
-	my @uid3;
-	my @existingUid = (-1,-1,-1,-1);
-	my $uidNumber;
-	my $defaultSpiFileName = "ecom-0-0.spi";
-	my $defaultTargetDirectory = "$ENV{EPOCROOT}epoc32\\tools\\";
-	my @defaultUid = (-1,-1,-1,-1);
-	
-##########################################################################################
-# Reading arguments phase
-##########################################################################################
-
-	foreach my $arg (@_) {
-		if ($arg =~ /^-t(.*)/i) { # set target SPI file
-			$spiFileName = $1;
-			next;
-			}
-		if ($arg =~ /^-d(.*)/i) { # set target ouput directory
-			my $tempDirectory=$1;
-			if((-d $tempDirectory) ) {
-				$targetDirectory = $tempDirectory;
-				next;
-				}
-				else
-				{
-				 print "Output directory \'",$tempDirectory,"\' does not exist.\n";
-				 exit(1);
-				 }				
-			}
-		if ($arg =~ /^-i(.*)/i) { # existing SPI file to use as a base
-			my $tempFileName = $1;
-			if((-e $tempFileName) && (!(-d $tempFileName))) {
-				$existingSpiFileName = $tempFileName;
-				next;
-				}
-			}
-		if ($arg =~ /^-uid([1-3])\=(.*)/i) {
-			$uid[$1-1][$uidLengths[$1-1]++] = $2;
-			next;
-			}
-		if($arg=~/^-existinguidcrc\=(.*)/i) {
-			$existingUid[3]=$1;
-			next;
-			}
-		if ($arg =~ /^-existinguid([1-3])\=(.*)/i) {
-			$existingUid[$1-1]=$2;
-			next;
-			}
-		if ($arg =~ /^-hide(.*)/i) { # Collect the files to be hidden
-			my $line = $1;
-			$line =~ s/,/ /g;
-			my @files = split(' ' , $line);
-			foreach my $file (@files)
-			{
-				push @hideresourceFiles, $file;
-			}
-			next;
-			}
-		if (-d $arg) {
-			if(($arg =~ m-^.:-) && ($arg =~ m-\\$-)) {
-				unless(opendir(DIRECTORY, $arg)) { print "Exiting: $arg"; exit; }
-				while (my $file=readdir(DIRECTORY)) {
-					my $newfile = $arg.$file;
-					if(!(-d $newfile)) {
-						push @resourceFiles, $newfile;
-					}
-				}
-				close(DIRECTORY);
-				next;
-				}
-			}
-		if ((-e $arg) && (!(-d $arg))) {
-			push @resourceFiles, $arg;
-			next;
-			}
-		if ($arg eq "-h") {
-			print_usage;
-			exit(1);
-		}	
-		print "Unknown command: $arg\n";
-	}
-
-#####################################################################################
-# UID phase
-#####################################################################################
-		
-	if(!(defined $spiFileName)) { #use default file name if none passed on command line
-		$spiFileName = $defaultSpiFileName;
-	}
-	if(!(defined $targetDirectory)) { #use default target dir if none passed on command line
-		$targetDirectory = $defaultTargetDirectory;
-	}
-	for(my $i=0;$i<3;$i++) { #if default UIDs specified then added to UID match lists
-		if($defaultUid[$i]>=0) {
-			$uid[$i][$uidLengths[$i]++] = $defaultUid[$i];
-		}
-	}
-	for(my $i=0;$i<3;$i++) { #makes sure UIDs are valid UIDs
-		my @tempUidArray;
-		my $iterator=0;
-		while(defined $uid[$i][$iterator]) {
-			my $convertedUid=convertUidFromText($uid[$i][$iterator]);
-			if ($convertedUid != -1) {
-				push @tempUidArray, binarize($convertedUid);
-			} else {
-				print "Invalid UID: $uid[$i][$iterator]\n";
-			}
-			$iterator++;
-		}
-		for(my $j=0;$i<scalar @tempUidArray;$j++) {
-			$uid[$i][$j]=$tempUidArray[$j];
-		}
-		for(my $j=scalar@tempUidArray;defined $uid[$i][$j];$j++) {
-			undef $uid[$i][$j];
-		}
-	}
-#####################################################################################
-# Phase to split up resource names
-#####################################################################################
-
-	my @resourceFilePaths;
-	my @resourceFileNames;
-	my @resourceExtensions;
-	my @filestobehidden;
-
-# To mark the resource files as hidden in the SPI file by writing the data length as zero
-	foreach my $file (@hideresourceFiles)
-	{
-		my $matchfound =0;
-		my $i=0;
-		for(;$i<scalar @resourceFiles && !$matchfound;$i++)
-		{
-			if (lc($file) eq lc($resourceFiles[$i]))
-			{
-				$filestobehidden[$i] = 1;
-				$matchfound =1;
-			}
-		}
-		if (!$matchfound)
-		{
-# Those files that are to be hidden in the SPI file but not existing in the SPI
-			if (! -e $file)
-			{
-				print "Warning: Hiding non-existent file $file\n";
-			}
-			push @resourceFiles,$file;
-			$filestobehidden[$i] = 1;
-		}
-	}
-	
-	for(my $i=0;$i<scalar @resourceFiles;$i++) {
-		if($resourceFiles[$i]=~m|\\|) {
-			if($resourceFiles[$i]=~m|(.*)\\([^\\]*)$|) {
-				$resourceFilePaths[$i]=$1;
-				$resourceFileNames[$i]=$2;
-			}
-			if($resourceFileNames[$i]=~m|(.*)\.([^\.]*)|) {
-				$resourceFileNames[$i]= $1;
-				$resourceExtensions[$i]=$2;
-			}
-		} else {
-			$resourceFilePaths[$i]="";
-			if($resourceFiles[$i]=~m|(.*)\.([^\.]*)|) {
-				$resourceFileNames[$i]= $1;
-				$resourceExtensions[$i]=$2;
-			}
-		}
-	}
-	
-	my %uid2values; #hash to hold UID2 values for each type of SPI file
-	$uid2values{"ecom"} = 270556204;
-
-##########################################################
-# Existing file stage
-##########################################################
-
-	my @spiUid = (270556203, 0, 0); #holds spi values (including CRC value)
-	foreach my $key (keys(%uid2values)) { #searches through SPI types to match UID2 value
-		if($spiFileName =~/^$key/) {
-			$spiUid[1]=$uid2values{$key};
-		}
-	}
-	$spiUid[3] = uidcrc($spiUid[0], $spiUid[1], $spiUid[2]);
-	my $total=0; #used to keep track of position in SPI file
-	my $buffer;
-	my $spifile=File::Spec->catpath( "", $targetDirectory, $spiFileName );
- 	open OUTPUTFILE, ">$spifile" or die $!;
-	binmode (OUTPUTFILE);
-	if($existingSpiFileName) {
-		open EXISTINGFILE, "$existingSpiFileName" or die $!;
-		binmode (EXISTINGFILE);
-
-		my @fileNameLengths;
-		my @fileLengths;
-		my @fileNames;
-		my @fileContents;
-
-		read(EXISTINGFILE,$buffer,4);
-		read(EXISTINGFILE,$buffer,4);
-		if(bytes2dec($buffer)!=$spiUid[1]) {
-			print "Incompatible SPI files.\n";
-		}
-		read(EXISTINGFILE,$buffer,24);
-		$total=32;
-		my $existingSpiFileSize = (stat(EXISTINGFILE))[7];
-		while($total<$existingSpiFileSize) { #loop to store information from files which are not being replaced
-			read(EXISTINGFILE,$buffer,4);
-			push @fileNameLengths, bytes2dec($buffer);
-			read(EXISTINGFILE,$buffer,4);
-			push @fileLengths, bytes2dec($buffer);
-			read(EXISTINGFILE,$buffer,$fileNameLengths[$#fileNameLengths]);
-			push @fileNames, $buffer;
-			$total=$total+8+$fileNameLengths[$#fileNameLengths]+$fileLengths[$#fileLengths];
-			my $padding = (4-(($fileNameLengths[$#fileNameLengths]+$fileLengths[$#fileLengths])%4))%4;
-			read(EXISTINGFILE,$buffer,$fileLengths[$#fileLengths]+$padding);
-			push @fileContents, $buffer;
-			$total += (4-($total%4))%4;			
-		}
-		close EXISTINGFILE;	
-		#next part prints to OUTPUTFILE the header and files which are not being replaced
-		print OUTPUTFILE binarize($spiUid[0]) . binarize($spiUid[1]) . binarize($spiUid[2]) . binarize($spiUid[3]);
-		printZeroes(16);
-		$total=32;
-		for(my $i=0; $i<scalar @fileNames; $i++) {
-			my $flag=1;
-			for(my $j=0; $j<scalar @resourceFileNames && $flag==1; $j++) {
-				if($fileNames[$i] eq $resourceFileNames[$j]) {
-					$flag=0;
-				}
-			}
-			if($flag) {
-				print OUTPUTFILE binarize($fileNameLengths[$i]) . binarize($fileLengths[$i]) . $fileNames[$i] . $fileContents[$i];
-				$total=$total+8+length($fileNames[$i])+length($fileContents[$i]);
-			}
-		}
-	} else { #prints header for target SPI file if there is no existing SPI file
-		print OUTPUTFILE binarize($spiUid[0]) . binarize($spiUid[1]) . binarize($spiUid[2]) . binarize($spiUid[3]);
-		printZeroes(16);
-		$total=32;
-	}
-
-####################################################################
-# Appending new data files to the SPI file
-####################################################################
-
-	my $resourceFileSize;
-	my $resourceFileSizeInBinary;
-	my $resourceFileNameSize;
-	my $resourceFileNameSizeInBinary;
-	for(my $i=0; $i<scalar @resourceExtensions;$i++) {
-# To mark the resource files as hidden in the SPI file by writing the data length as zero
-	   if ($filestobehidden[$i] == 1)
-	   {
-		$resourceFileNameSize = length($resourceFileNames[$i]);
-		$resourceFileNameSizeInBinary = binarize($resourceFileNameSize);
-		$resourceFileSize = 0;
-		$resourceFileSizeInBinary = binarize($resourceFileSize);
-		print OUTPUTFILE $resourceFileNameSizeInBinary . $resourceFileSizeInBinary . $resourceFileNames[$i];
-		$total+=$resourceFileNameSize;
-		my $padding = (4-(($resourceFileSize + $resourceFileNameSize)%4))%4;
-		printZeroes($padding);
-		$total+=$padding;
-	   }
-	   else
-	   {
-		open RESOURCEFILE, "<$resourceFiles[$i]";
-		binmode(RESOURCEFILE);
-		my @fileUid; #stores UIDs from particular data file
-		my $fileUid1;
-		my $fileUid2;
-		my $fileUid3;
-		read(RESOURCEFILE,$fileUid[0],4);
-		read(RESOURCEFILE,$fileUid[1],4);
-		read(RESOURCEFILE,$fileUid[2],4);
-		my $uidFlag=0; #changes to 1 if a UID value in data file matches a specified UID value
-		my $uidExists=1; #changes to 1 if there are specified UIDs to match to
-		for(my $j=0;$j<3 && (!$uidFlag);$j++) {
-			my $k=0;
-			while(defined $uid[$j][$k] && (!$uidFlag)) {
-				$uidExists=0;
-				if($uid[$j][$k] eq bin2hex($fileUid[$j])) {
-					$uidFlag=1;
-				}
-				$k++;
-			}
-		}	
-		if(($uidFlag) || ($uidExists)) { #if suitable UIDs writes data file to SPI file
-			$resourceFileSize = (stat(RESOURCEFILE))[7];
-			$resourceFileNameSize = length($resourceFileNames[$i]);
-			$resourceFileNameSizeInBinary = binarize($resourceFileNameSize);
-			$resourceFileSizeInBinary = binarize($resourceFileSize);
-			print OUTPUTFILE $resourceFileNameSizeInBinary . $resourceFileSizeInBinary . $resourceFileNames[$i];
-			print OUTPUTFILE "$fileUid[0]$fileUid[1]$fileUid[2]";
-			while(read(RESOURCEFILE,$buffer,1)) {
-				print OUTPUTFILE $buffer;
-			}
-			$total+=$resourceFileSize;
-			$total+=8;
-			$total+=$resourceFileNameSize;
-			my $padding = (4-(($resourceFileSize + $resourceFileNameSize)%4))%4;
-			printZeroes($padding);
-			$total+=$padding;
-		}
-	   }
-	}
-	print "Created $spiFileName\n";
-}
-
-
-1;
+#
+# Copyright (c) 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: 
+#
+
+package spitool;
+
+use strict;
+use Exporter;
+use vars qw($VERSION @ISA @EXPORT @EXPORT_OK);
+use romutl;
+
+$VERSION     = 1.00;
+@ISA         = qw(Exporter);
+@EXPORT      = ();
+@EXPORT_OK   = qw(createSpi);
+
+sub binarize { #converts decimal number to 4 byte litte endian format
+	my $value = shift;
+	my $remainder;
+	my $returnValue;
+	for(my $i=0;$i<4;$i++) {
+		$remainder=$value % 256;
+		$returnValue.=chr($remainder);
+		$value = ($value-$remainder)/256;
+	}
+	return $returnValue;
+}
+
+sub convertUidFromText { #converts UID from hexadeciaml text value to decimal value, passes decimal value unchanged, returns -1 if invalid UID
+	my $value = shift;
+	if($value =~ /^0x([\da-fA-F]{1,8})$/i) {
+		return hex $1;
+	} elsif ($value =~ /^\d*$/) {
+		return $value;
+	} else {
+		return -1;
+	}
+}
+
+sub bin2hex { #converts 4 byte little endian value to 0x... hex text value
+	my $value=shift;
+	my $byte;
+	my $quotient;
+	my $remainder;
+	my $hexValue="";
+	for(my $i=0;$i<4;$i++) {
+		$byte=ord(substr($value,$i,1));
+		$remainder=$byte%16;
+		$quotient=($byte-$remainder)/16;
+		if($remainder>9) {
+			$remainder= chr($remainder+55);
+		}
+		if($quotient>9) {
+			$quotient= chr($quotient+55);
+		}		
+		$hexValue=$quotient . $remainder . $hexValue;
+	}
+	return "0x" . $hexValue;
+}
+
+sub uidcrc { #returns decimal UID checksum value for the three inputs
+	my $output = `uidcrc $_[0] $_[1] $_[2]`;
+	if($output =~ /([^ ]*)$/i) {
+		$output =$1;
+		chomp $output;
+		return hex($output);
+	}	
+}
+
+sub printZeroes { #prints as many hexadecimal zeroes to OUTPUTFILE as specified by input
+	my $numberOfZeroes=shift;
+	for(my $i=0;$i<$numberOfZeroes;$i++) {
+		print OUTPUTFILE chr(0);
+	}
+}
+
+sub bytes2dec { #calculates decimal value from inputted 4 byte little endian value 
+	my $bytes=shift;
+	my @byteArray;
+	for(my $i=0;$i<length $bytes;$i++) {
+		$byteArray[$i]=ord(substr($bytes,$i,1));
+	}
+	my $decValue;
+	for(my $i=0;$i<scalar @byteArray;$i++) {
+		$decValue+=($byteArray[$i]*(2**($i*8)));
+	}
+	return $decValue;
+}
+
+sub print_usage
+	{
+#........1.........2.........3.........4.........5.........6.........7.....
+	print <<USAGE_EOF;
+
+Usage:
+  spitool.pl [options] files directories   
+
+Create an SPI file by concatenating the files and contents of directories,
+based on the options passed. 
+
+The available options are:
+
+-tSPIFileName       -- SPIFileName is the name the produced SPI file will 
+                       have (i.e. ecom-0-0.spi). If not specified, the name 
+                       will be ecom-0-0.spi by default
+-dTargetDir         -- TargetDir is the directory where the SPI file should
+                       be created, ending with a \
+-iExisting          -- Existing is address and name of existing SPI file to
+                       concatenate specified files to 
+-uid<x>=<y>         -- <x> has value 1, 2 or 3, <y> is an UID value in
+                       decimal or 0x... hexadecimal
+-existinguid<x>=<y> -- <x> has value 1, 2 or 3, <y> is an UID value in 
+                       decimal or 0x... hexadecimal
+-existinguidcrc=<x> -- <x> is an UID value in decimal or 0x.. hexadecimal
+-hide<ResourceFileNames> -- <ResourceFileNames> is the list of the resource files
+			    that are to be hidden in the SPI file separated by
+			    space or comma.
+  
+If an existing SPI file is specified with the -i option then this file is
+used as a base and other data files are added to the end of this file,
+otherwise a new SPI file is created. In either case the produced SPI file
+is placed in the directory specified by the -d option and given the name 
+specified with the -t option.
+
+Files which are to be concatenated into the SPI file should be specified
+on the command line by either specifying the file's name (and location), or
+by including a directory name, in which case all files from that directory
+will be included.
+
+The -uid options can be used to filter files for inclusion in the SPI file.
+This option can be included multiple times, so a list of UID1 values can be
+built up, and the same for UID2 and UID3 values. Each file on the command
+line is compared with this list, and if any of its UID values match a
+relevant value in the UID lists then that file will be included in the SPI
+file. If the file does not match any values it will be excluded.
+
+The -existinguid options allow the UID values that an existing SPI file
+should have to be specified. This will allow the possibility of checking
+that the correct type of files are being concatenated together.
+
+The -hide option can be used to mark a resource file as hidden in the SPI file.
+To mark a resource file as a hidden entry in the SPI file, the resource data 
+length will be written as 0.
+
+USAGE_EOF
+	}
+
+sub createSpi 
+	{
+	my @resourceFiles=();
+	my @hideresourceFiles=();
+	my $spiFileName;
+	my $targetDirectory;
+	my $existingSpiFileName;
+	my @uid;
+	my @uidLengths = (0, 0, 0, 0);
+	my @uid1;
+	my @uid2;
+	my @uid3;
+	my @existingUid = (-1,-1,-1,-1);
+	my $uidNumber;
+	my $defaultSpiFileName = "ecom-0-0.spi";
+	my $defaultTargetDirectory = &get_epocroot."epoc32\/tools\/";
+	my @defaultUid = (-1,-1,-1,-1);
+	
+##########################################################################################
+# Reading arguments phase
+##########################################################################################
+
+	foreach my $arg (@_) {
+		if ($arg =~ /^-t(.*)/i) { # set target SPI file
+			$spiFileName = $1;
+			next;
+			}
+		if ($arg =~ /^-d(.*)/i) { # set target ouput directory
+			my $tempDirectory=$1;
+			if((-d $tempDirectory) ) {
+				$targetDirectory = $tempDirectory;
+				next;
+				}
+				else
+				{
+				 print "Output directory \'",$tempDirectory,"\' does not exist.\n";
+				 exit(1);
+				 }				
+			}
+		if ($arg =~ /^-i(.*)/i) { # existing SPI file to use as a base
+			my $tempFileName = $1;
+			if((-e $tempFileName) && (!(-d $tempFileName))) {
+				$existingSpiFileName = $tempFileName;
+				next;
+				}
+			}
+		if ($arg =~ /^-uid([1-3])\=(.*)/i) {
+			$uid[$1-1][$uidLengths[$1-1]++] = $2;
+			next;
+			}
+		if($arg=~/^-existinguidcrc\=(.*)/i) {
+			$existingUid[3]=$1;
+			next;
+			}
+		if ($arg =~ /^-existinguid([1-3])\=(.*)/i) {
+			$existingUid[$1-1]=$2;
+			next;
+			}
+		if ($arg =~ /^-hide(.*)/i) { # Collect the files to be hidden
+			my $line = $1;
+			$line =~ s/,/ /g;
+			my @files = split(' ' , $line);
+			foreach my $file (@files)
+			{
+				push @hideresourceFiles, $file;
+			}
+			next;
+			}
+		if (-d $arg) {
+			if(($arg =~ m-^.:-) && ($arg =~ m-[\\\/]$-)) {
+				unless(opendir(DIRECTORY, $arg)) { print "Exiting: $arg"; exit; }
+				while (my $file=readdir(DIRECTORY)) {
+					my $newfile = $arg.$file;
+					if(!(-d $newfile)) {
+						push @resourceFiles, $newfile;
+					}
+				}
+				close(DIRECTORY);
+				next;
+				}
+			}
+		if ((-e $arg) && (!(-d $arg))) {
+			push @resourceFiles, $arg;
+			next;
+			}
+		if ($arg eq "-h") {
+			print_usage;
+			exit(1);
+		}	
+		print "Unknown command: $arg\n";
+	}
+
+#####################################################################################
+# UID phase
+#####################################################################################
+		
+	if(!(defined $spiFileName)) { #use default file name if none passed on command line
+		$spiFileName = $defaultSpiFileName;
+	}
+	if(!(defined $targetDirectory)) { #use default target dir if none passed on command line
+		$targetDirectory = $defaultTargetDirectory;
+	}
+	for(my $i=0;$i<3;$i++) { #if default UIDs specified then added to UID match lists
+		if($defaultUid[$i]>=0) {
+			$uid[$i][$uidLengths[$i]++] = $defaultUid[$i];
+		}
+	}
+	for(my $i=0;$i<3;$i++) { #makes sure UIDs are valid UIDs
+		my @tempUidArray;
+		my $iterator=0;
+		while(defined $uid[$i][$iterator]) {
+			my $convertedUid=convertUidFromText($uid[$i][$iterator]);
+			if ($convertedUid != -1) {
+				push @tempUidArray, binarize($convertedUid);
+			} else {
+				print "Invalid UID: $uid[$i][$iterator]\n";
+			}
+			$iterator++;
+		}
+		for(my $j=0;$i<scalar @tempUidArray;$j++) {
+			$uid[$i][$j]=$tempUidArray[$j];
+		}
+		for(my $j=scalar@tempUidArray;defined $uid[$i][$j];$j++) {
+			undef $uid[$i][$j];
+		}
+	}
+#####################################################################################
+# Phase to split up resource names
+#####################################################################################
+
+	my @resourceFilePaths;
+	my @resourceFileNames;
+	my @resourceExtensions;
+	my @filestobehidden;
+
+# To mark the resource files as hidden in the SPI file by writing the data length as zero
+	foreach my $file (@hideresourceFiles)
+	{
+		my $matchfound =0;
+		my $i=0;
+		for(;$i<scalar @resourceFiles && !$matchfound;$i++)
+		{
+			if (lc($file) eq lc($resourceFiles[$i]))
+			{
+				$filestobehidden[$i] = 1;
+				$matchfound =1;
+			}
+		}
+		if (!$matchfound)
+		{
+# Those files that are to be hidden in the SPI file but not existing in the SPI
+			if (! -e $file)
+			{
+				print "Warning: Hiding non-existent file $file\n";
+			}
+			push @resourceFiles,$file;
+			$filestobehidden[$i] = 1;
+		}
+	}
+	
+	for(my $i=0;$i<scalar @resourceFiles;$i++) {
+		if($resourceFiles[$i]=~m|\/|) {
+			if($resourceFiles[$i]=~m|(.*)\/([^\/]*)$|) {
+				$resourceFilePaths[$i]=$1;
+				$resourceFileNames[$i]=$2;
+			}
+			if($resourceFileNames[$i]=~m|(.*)\.([^\.]*)|) {
+				$resourceFileNames[$i]= $1;
+				$resourceExtensions[$i]=$2;
+			}
+		} else {
+			$resourceFilePaths[$i]="";
+			if($resourceFiles[$i]=~m|(.*)\.([^\.]*)|) {
+				$resourceFileNames[$i]= $1;
+				$resourceExtensions[$i]=$2;
+			}
+		}
+	}
+	my %uid2values; #hash to hold UID2 values for each type of SPI file
+	$uid2values{"ecom"} = 270556204;
+
+##########################################################
+# Existing file stage
+##########################################################
+
+	my @spiUid = (270556203, 0, 0); #holds spi values (including CRC value)
+	foreach my $key (keys(%uid2values)) { #searches through SPI types to match UID2 value
+		if($spiFileName =~/^$key/) {
+			$spiUid[1]=$uid2values{$key};
+		}
+	}
+	$spiUid[3] = uidcrc($spiUid[0], $spiUid[1], $spiUid[2]);
+	my $total=0; #used to keep track of position in SPI file
+	my $buffer;
+	my $spifile=File::Spec->catpath( "", $targetDirectory, $spiFileName );
+ 	open OUTPUTFILE, ">$spifile" or die $!;
+	binmode (OUTPUTFILE);
+	if($existingSpiFileName) {
+		open EXISTINGFILE, "$existingSpiFileName" or die $!;
+		binmode (EXISTINGFILE);
+
+		my @fileNameLengths;
+		my @fileLengths;
+		my @fileNames;
+		my @fileContents;
+
+		read(EXISTINGFILE,$buffer,4);
+		read(EXISTINGFILE,$buffer,4);
+		if(bytes2dec($buffer)!=$spiUid[1]) {
+			print "Incompatible SPI files.\n";
+		}
+		read(EXISTINGFILE,$buffer,24);
+		$total=32;
+		my $existingSpiFileSize = (stat(EXISTINGFILE))[7];
+		while($total<$existingSpiFileSize) { #loop to store information from files which are not being replaced
+			read(EXISTINGFILE,$buffer,4);
+			push @fileNameLengths, bytes2dec($buffer);
+			read(EXISTINGFILE,$buffer,4);
+			push @fileLengths, bytes2dec($buffer);
+			read(EXISTINGFILE,$buffer,$fileNameLengths[$#fileNameLengths]);
+			push @fileNames, $buffer;
+			$total=$total+8+$fileNameLengths[$#fileNameLengths]+$fileLengths[$#fileLengths];
+			my $padding = (4-(($fileNameLengths[$#fileNameLengths]+$fileLengths[$#fileLengths])%4))%4;
+			read(EXISTINGFILE,$buffer,$fileLengths[$#fileLengths]+$padding);
+			push @fileContents, $buffer;
+			$total += (4-($total%4))%4;			
+		}
+		close EXISTINGFILE;	
+		#next part prints to OUTPUTFILE the header and files which are not being replaced
+		print OUTPUTFILE binarize($spiUid[0]) . binarize($spiUid[1]) . binarize($spiUid[2]) . binarize($spiUid[3]);
+		printZeroes(16);
+		$total=32;
+		for(my $i=0; $i<scalar @fileNames; $i++) {
+			my $flag=1;
+			for(my $j=0; $j<scalar @resourceFileNames && $flag==1; $j++) {
+				if($fileNames[$i] eq $resourceFileNames[$j]) {
+					$flag=0;
+				}
+			}
+			if($flag) {
+				print OUTPUTFILE binarize($fileNameLengths[$i]) . binarize($fileLengths[$i]) . $fileNames[$i] . $fileContents[$i];
+				$total=$total+8+length($fileNames[$i])+length($fileContents[$i]);
+			}
+		}
+	} else { #prints header for target SPI file if there is no existing SPI file
+		print OUTPUTFILE binarize($spiUid[0]) . binarize($spiUid[1]) . binarize($spiUid[2]) . binarize($spiUid[3]);
+		printZeroes(16);
+		$total=32;
+	}
+
+####################################################################
+# Appending new data files to the SPI file
+####################################################################
+
+	my $resourceFileSize;
+	my $resourceFileSizeInBinary;
+	my $resourceFileNameSize;
+	my $resourceFileNameSizeInBinary;
+	for(my $i=0; $i<scalar @resourceExtensions;$i++) {
+# To mark the resource files as hidden in the SPI file by writing the data length as zero
+	   if ($filestobehidden[$i] == 1)
+	   {
+		$resourceFileNameSize = length($resourceFileNames[$i]);
+		$resourceFileNameSizeInBinary = binarize($resourceFileNameSize);
+		$resourceFileSize = 0;
+		$resourceFileSizeInBinary = binarize($resourceFileSize);
+		print OUTPUTFILE $resourceFileNameSizeInBinary . $resourceFileSizeInBinary . $resourceFileNames[$i];
+		$total+=$resourceFileNameSize;
+		my $padding = (4-(($resourceFileSize + $resourceFileNameSize)%4))%4;
+		printZeroes($padding);
+		$total+=$padding;
+	   }
+	   else
+	   {
+		open RESOURCEFILE, "<$resourceFiles[$i]";
+		binmode(RESOURCEFILE);
+		my @fileUid; #stores UIDs from particular data file
+		my $fileUid1;
+		my $fileUid2;
+		my $fileUid3;
+		read(RESOURCEFILE,$fileUid[0],4);
+		read(RESOURCEFILE,$fileUid[1],4);
+		read(RESOURCEFILE,$fileUid[2],4);
+		my $uidFlag=0; #changes to 1 if a UID value in data file matches a specified UID value
+		my $uidExists=1; #changes to 1 if there are specified UIDs to match to
+		for(my $j=0;$j<3 && (!$uidFlag);$j++) {
+			my $k=0;
+			while(defined $uid[$j][$k] && (!$uidFlag)) {
+				$uidExists=0;
+				if($uid[$j][$k] eq bin2hex($fileUid[$j])) {
+					$uidFlag=1;
+				}
+				$k++;
+			}
+		}	
+		if(($uidFlag) || ($uidExists)) { #if suitable UIDs writes data file to SPI file
+			$resourceFileSize = (stat(RESOURCEFILE))[7];
+			$resourceFileNameSize = length($resourceFileNames[$i]);
+			$resourceFileNameSizeInBinary = binarize($resourceFileNameSize);
+			$resourceFileSizeInBinary = binarize($resourceFileSize);
+			print OUTPUTFILE $resourceFileNameSizeInBinary . $resourceFileSizeInBinary . $resourceFileNames[$i];
+			print OUTPUTFILE "$fileUid[0]$fileUid[1]$fileUid[2]";
+			while(read(RESOURCEFILE,$buffer,1)) {
+				print OUTPUTFILE $buffer;
+			}
+			$total+=$resourceFileSize;
+			$total+=8;
+			$total+=$resourceFileNameSize;
+			my $padding = (4-(($resourceFileSize + $resourceFileNameSize)%4))%4;
+			printZeroes($padding);
+			$total+=$padding;
+		}
+	   }
+	}
+	print "Created $spiFileName\n";
+}
+
+
+1;