# Copyright (c) 1999-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:
#
#!perl
use strict;
use File::Copy;
use File::Path;
use File::stat;
use Getopt::Long;
use Cwd;
use FindBin;
if ($^O =~ /MSWin32/)
{
require Win32::Mutex;
require Win32::File;
}
$::emulatorCfg = 'emulator.cfg';
$::targetCfg = 'target.cfg';
GetOptions (
'command=s' => \$::command,
'platform=s' => \$::platform,
'variant=s' => \$::variant,
'targetcfg=s' => \$::targetCfg,
'emulatorcfg=s' => \$::emulatorCfg,
'sourceDir=s' => \$::sourceDir,
'platsec!' => \$::platsec);
#
# Constants.
#
my $epocRoot = GetEpocRoot();
my $EpocWinsStore = 'c:\defaultcommdb';
my $emptyDatabase = 'empty.txt';
my $emulatorstore = $epocRoot . 'epoc32/winscw/c/defaultcommdb';
my $release = $epocRoot . 'epoc32/release/';
my $winscedUREL = $release . 'wins/urel/ced.exe';
my $winscwcedUREL = $release . 'winscw/urel/ced.exe';
my $winscedUDEB = $release . 'wins/udeb/ced.exe';
my $winscwcedUDEB = $release . 'winscw/udeb/ced.exe';
# Linux static copies
my $bindir = $FindBin::Bin.'/../bin/';
my @bincopies=(
# plat var source destination
['emulator', 'both', $bindir.'commsdb.dat', $emulatorstore.'/commsdb.dat'],
['emulator', 'udeb', $bindir.'cccccc00.cre', $epocRoot.'epoc32/release/winscw/udeb/z/private/10202be9/cccccc00.cre'],
['emulator', 'urel', $bindir.'cccccc00.cre', $epocRoot.'epoc32/release/winscw/urel/z/private/10202be9/cccccc00.cre'],
['target', 'both', $bindir.'cccccc00.cre', $epocRoot.'epoc32/data/z/private/10202be9/cccccc00.cre']
);
#
# Main.
#
unless ($::command and $::platform and $::variant and (scalar(@ARGV) == 0))
{
die "CreateCommdbs Error: Invalid arguments\n";
}
my $platType;
if ($::platform =~ /^(wins|wincw)/i)
{
$platType = 'emulator';
}
else
{
$platType = 'target';
}
#
# Check OS, and perform copies of key binaries from source if dynamic generation in unsupported
#
if (!($^O =~ /MSWin32/))
{
foreach my $bincopy (@bincopies)
{
my ($copyplat, $copyvar, $source, $destination) = @$bincopy;
if (($copyplat eq $platType) and (($copyvar eq lc($::variant)) or ($copyvar eq "both")))
{
if (($::command eq "build") and not (-e $destination))
{
# Existing files are considered to be current
print ("Warning: createcommdbs.pl: \'$destination\' generated by a copy from source as building is not supported on this platform.\n");
print ("Copy \'$source\' to \'$destination\'\n");
CopyFile($source, $destination);
}
elsif (($::command eq "clean") and (-e $destination))
{
unlink ($destination)
}
elsif ($::command eq "releasables")
{
print ("$destination\n");
}
}
}
exit;
}
my $cccccc00Root;
my $cccccc00NameCre;
my $cccccc00Nametxt;
$cccccc00Root = "/private/10202be9/";
$cccccc00NameCre = "cccccc00.cre";
$cccccc00Nametxt = "cccccc00.txt";
my $data =
{
target =>
{
sourceCfg => "$::sourceDir/$::targetCfg",
cedCfg => "$EpocWinsStore\\$::targetCfg",
emptyDb => "$::sourceDir/$emptyDatabase",
destinationCdb => $emulatorstore . '/CommsDb.dat',
},
emulator =>
{
sourceCfg => "$::sourceDir\\$::emulatorCfg",
cedCfg => "$EpocWinsStore\\$::emulatorCfg",
emptyDb => "$::sourceDir\\$emptyDatabase",
destinationCdb => $emulatorstore . '/CommsDb.dat',
}
};
my $ced;
my $cedPlatfrom;
my $cedVariant;
my $emulatorstore;
my $CopiedCfg;
my $CedLog;
my $winsCdb;
my $CdbEmpty;
my $romCdb;
my $attrib;
my $cdbIn;
my $cdbOut;
my $cdbDatPath;
my $cdbDatFile;
my $cdbDatExt;
my $zDrive;
my $zDriveCre;
#
# Establish location of ced.exe
#
if ($platType =~ 'emulator')
{
$cedPlatfrom = $::platform;
$cedVariant = $::variant;
}
elsif (($platType =~ 'target') && (-e $winscwcedUREL))
{
$cedPlatfrom = 'WINSCW';
$cedVariant = 'UREL';
}
elsif (($platType =~ 'target') && (-e $winscwcedUDEB))
{
$cedPlatfrom = 'WINSCW';
$cedVariant = 'UDEB';
}
elsif (($platType =~ 'target') && (-e $winscedUREL))
{
$cedPlatfrom = 'WINS';
$cedVariant = 'UREL';
}
elsif (($platType =~ 'target') && (-e $winscedUDEB))
{
$cedPlatfrom = 'WINS';
$cedVariant = 'UDEB';
}
$cdbIn = '/c/defaultcommdb/';
$cdbOut = '/c/defaultcommdb/';
$CopiedCfg = $epocRoot . 'epoc32/' . $cedPlatfrom . $cdbIn . $platType . '.cfg';
$CedLog = $CopiedCfg . '.log';
if ($ENV{DEFAULTCOMMSDATDATAFILE})
{
($cdbDatPath, $cdbDatFile, $cdbDatExt) = SplitFileName($ENV{DEFAULTCOMMSDATDATAFILE});
}
else
{
$cdbDatPath = $epocRoot. 'epoc32/' . $cedPlatfrom . $cdbOut;
$cdbDatFile = 'CommsDb';
$cdbDatExt = '.dat';
}
$zDrive = $release . $cedPlatfrom . '/' . $cedVariant . '/z';
$zDriveCre = $zDrive . $cccccc00Root . $cccccc00NameCre;
$CdbEmpty = $zDrive . $cccccc00Root . $cccccc00Nametxt;
if ($::command eq 'build')
{
$ced = $release . $cedPlatfrom . '/' . $cedVariant . '/ced.exe';
$emulatorstore = $epocRoot . 'epoc32/' . $cedPlatfrom . $cdbIn;
$winsCdb = $epocRoot . 'epoc32/' . $cedPlatfrom . '/c' . $cccccc00Root . "persists/" . $cccccc00NameCre;
$romCdb = $epocRoot . 'epoc32/' . 'data/z' . $cccccc00Root . $cccccc00NameCre;
if ($platType =~ 'emulator')
{
$CopiedCfg = $emulatorstore . 'emulator.cfg';
}
else
{
$CopiedCfg = $emulatorstore . 'target.cfg';
}
PreBuild();
}
elsif ($::command eq 'clean')
{
Clean();
}
elsif ($::command eq 'releasables')
{
Releasables();
}
#
# Subs.
#
sub PreBuild
{
if ($^O =~ /MSWin32/)
{
# We cannot have more than one instance of this script's activites running at the same time on Windows, so
# we safeguarded everything with a Windows mutex. Mutex name needs to be unique for every build,
# so we add the current working directory and EPOCROOT to the mutex name
my $drive = Win32::GetCwd();
$drive =~ s/^(\D:).*/$1/;
my $mutexname = $drive.lc($ENV{'EPOCROOT'});
$mutexname =~ s/[:\\\/]+/_/g;
my $mutex = Win32::Mutex->new(1,"CEDMUTEX_".$mutexname);
die "Unable to create mutex, createcommdbs.pl not run" if not $mutex;
if ($mutex->wait())
{
Build();
$mutex->release();
}
else
{
die "Unable to access mutex, createcommdbs.pl not run";
}
}
else
{
Build();
}
}
sub Build
{
print("\n**Constructing $::platform $::variant database**\n");
print("**$winsCdb\n\n");
# delete old log file if it exists
DeleteFile($CedLog);
#Check for empty cenrep initialisation .txt file and store if missing
if (!(-e $CdbEmpty))
{
print("\nCopying $data->{$platType}->{emptyDb} to $CdbEmpty\n");
CopyFile($data->{$platType}->{emptyDb}, $CdbEmpty);
print("Remove ReadOnly attribute! from $CdbEmpty \n\n");
if ($^O =~ /MSWin32/)
{
no strict; # Not nice this, but avoids compilation errors on Linux
Win32::File::SetAttributes($CdbEmpty, NORMAL) || die $!;
}
}
# Ensure CFG file exists
if (-e $data->{$platType}->{sourceCfg})
{
print("Copying $data->{$platType}->{sourceCfg} ... \n");
CopyIfYounger($data->{$platType}->{sourceCfg}, $CopiedCfg);
print("copied successfully to $CopiedCfg\n\n");
# Ensure replacement file is more up-to-date than existing file
if (FileIsYounger($CopiedCfg, $data->{$platType}->{destinationCdb}))
{
print("$CopiedCfg newer than $data->{$platType}->{destinationCdb}\n");
RunCed();
if ($@)
{
die $@;
}
print("\n");
}
else
{
print("$data->{$platType}->{sourceCfg} older than $data->{$platType}->{destinationCdb}\n");
print("Construction aborted.\n");
}
}
else
{
print("CreateCommdbs Error: $data->{$platType}->{sourceCfg} does not exist, construction aborted.\n");
}
print("Deleting $CopiedCfg\n");
DeleteFile($CopiedCfg);
}
sub Clean
{
print("$data->{$platType}->{destinationCdb}\n");
DeleteFile($data->{$platType}->{destinationCdb});
print("Deleting $CopiedCfg\n");
DeleteFile($CopiedCfg);
print("Deleting $CedLog\n");
DeleteFile($CedLog);
print("Deleting $cdbDatPath$cdbDatFile$cdbDatExt\n");
DeleteFile("$cdbDatPath$cdbDatFile$cdbDatExt");
}
sub Releasables
{
print("$data->{$platType}->{destinationCdb}\n");
print("$CdbEmpty\n");
}
sub RunCed
{
print("sub RunCed\n");
print("Running $ced -Mconsole -dJustInTime=0 -dtextshell -- -i $data->{$platType}->{cedCfg} -d -o $data->{$platType}->{cedCfg}.log\n");
system ("$ced -Mconsole -dJustInTime=0 -dtextshell -- -i $data->{$platType}->{cedCfg} -d -o $data->{$platType}->{cedCfg}.log");
CheckCedLog("$CopiedCfg.log");
CheckEpocLog();
#copy to output location
print("Copy $winsCdb to $data->{$platType}->{destinationCdb}\n");
CopyFile($winsCdb, $data->{$platType}->{destinationCdb});
#copy to z drive
print("Copy $winsCdb to $zDriveCre\n");
CopyFile($winsCdb, $zDriveCre);
#print("Copy $winsCdb to $romCdb\n");
#CopyFile($winsCdb, $romCdb);
}
sub CheckCedLog
{
print("sub CheckCedLog\n");
my $log = shift;
open (LOG, $log) or die "CreateCommdbs Error: Couldn't open \"$log\" for reading: $!\n";
my @log = reverse <LOG>;
close (LOG);
unless ($log[0] eq "SUCCESS\n")
{
die "CreateCommdbs Error: CED failed to generate commdb, see \"$log\" for details\n";
}
}
sub CheckEpocLog
{
print("sub CheckEpocLog\n");
my $log = $ENV{'TEMP'}."\\epocwind.out";
unless (open (LOG, $log))
{
print "CreateCommdbs Error: Couldn't open \"$log\" for reading: $!\n";
return;
}
foreach my $line (<LOG>)
{
if ($line =~ m/ced\.exe.+panic/i)
{
print "CreateCommdbs Error: CED panic detected, see \"$log\" for details\n";
}
}
close(LOG);
}
sub CopyFile
{
my $file1 = shift;
my $file2 = shift;
(my $path) = SplitFileName($file2);
unless (-e $path)
{
mkpath ($path) or die "CreateCommdbs Error: Couldn't make path \"$path\": $!\n";
}
if (-e $file2 and not -w $file2)
{
system "attrib -r $file2";
}
copy ($file1, $file2) or die "CreateCommdbs Error: Couldn't copy \"$file1\" to \"$file2\": $!\n";
}
sub MoveFile
{
my $file1 = shift;
my $file2 = shift;
(my $path) = SplitFileName($file2);
unless (-e $path)
{
mkpath ($path) or die "CreateCommdbs Error: Couldn't make path \"$path\": $!\n";
}
move ($file1, $file2) or die "CreateCommdbs Error: Couldn't move \"$file1\" to \"$file2\": $!\n";
}
sub DeleteFile
{
my $file = shift;
if (-e $file)
{
unlink ($file) or die "CreateCommdbs Error: Couldn't delete \"$file\": $!\n";
}
}
sub SplitFileName
{
my $fileName = shift;
my $path = '';
my $base = '';
my $ext = '';
if ($fileName =~ /^(.*\/)/)
{
$path = $1;
}
if ($fileName =~ /\/?([^\/]*?)(\.[^\/\.]*)?$/)
{
$base = $1;
}
if ($fileName =~ /(\.[^\/\.]*)$/o)
{
$ext = $1;
}
die unless ($fileName eq "$path$base$ext");
return ($path, $base, $ext);
}
sub CopyIfYounger
{
my $from = shift;
my $to = shift;
unless (-e $from)
{
die "Error: \"$from\" not found\n";
}
if (FileIsYounger($from, $to))
{
CopyFile($from, $to);
}
}
sub FileIsYounger
{
my $file1 = shift;
my $file2 = shift;
return (FileModifiedTime($file1) > FileModifiedTime($file2));
}
sub FileModifiedTime
{
my $file = shift;
if (-e $file)
{
my $st = stat($file) or return 0;
return $st->mtime;
}
return 0;
}
sub RenameFile
{
my $file1 = shift;
my $file2 = shift;
rename ($file1, $file2) or die "installCommdb Error: Couldn't rename \"$file1\" to \"$file2\": $!\n";
}
sub GetEpocRoot
{
my $path = $ENV{EPOCROOT};
# replace to forward slashes
$path =~ s/\\/\//g;
# append trailing slash if one isn't already present
if($path =~ m/.*\/$/)
{
return $path;
}
else
{
return $path."\/";
}
}