@REM Copyright (c) 2000-2009 Nokia Corporation and/or its subsidiary(-ies).
@REM All rights reserved.
@REM This component and the accompanying materials are made available
@REM under the terms of "Eclipse Public License v1.0"
@REM which accompanies this distribution, and is available
@REM at the URL "http://www.eclipse.org/legal/epl-v10.html".
@REM
@REM Initial Contributors:
@REM Nokia Corporation - initial contribution.
@REM
@REM Contributors:
@REM
@goto invoke
#!perl
use FindBin; # for FindBin::Bin
use Getopt::Long;
use Cwd;
$_ = cwd;
tr/\//\\/;
my $Pwd = $_;
my $PerlLibPath; # fully qualified pathname of the directory containing our Perl modules
# establish the path to the Perl binaries
BEGIN {
require 5.005_03; # check user has a version of perl that will cope
# establish the path to the Perl libraries: currently the same directory as this script
$PerlLibPath = $FindBin::Bin; # X:/epoc32/tools
$PerlLibPath =~ s/\//\\/g; # X:\epoc32\tools
$PerlLibPath .= "\\";
}
use lib $PerlLibPath;
use Defutl;
use Genutl;
my %opts = ();
my $result = GetOptions(\%opts,
"srcpath:s",
"defpath:s",
"name:s",
"version:s",
"alignstack",
"help",
);
Usage() if(!$result || $opts{'help'} || @ARGV < 1);
my $srcPath = $opts{"srcpath"} || $Pwd;
my $defPath = $opts{"defpath"} || $srcPath;
my $outputName = $opts{"name"} || "shim";
my %Version;
if ($opts{version}) {
%Version = &Genutl_StringToVersion($opts{version}) or die "Bad version number\n";
} else {
$Version{major} = 0;
$Version{minor} = 0;
}
my $infile = pop @ARGV;
my @DefData;
eval { &Def_ReadFileL(\@DefData, $infile); } ;
die $@ if $@;
sub WriteFunction($$$) {
my ($ordinal, $branchTarget, $comment) = @_;
my $fnName = "export_at_ordinal_$ordinal";
if ($branchTarget =~ /^\"(.*)\"$/) {
$branchTarget = $1;
}
if ($comment =~ /(null)/) {
$comment = $branchTarget;
}
print CPP <<FUNCTION_DEFINITION;
EXPORT_C __NAKED__ int $fnName()
//
// $comment
//
{
asm("B $branchTarget ");
}
FUNCTION_DEFINITION
}
sub WriteFunctionAligned($$$) {
my ($ordinal, $branchTarget, $comment) = @_;
my $fnName = "export_at_ordinal_$ordinal";
if ($branchTarget =~ /^\"(.*)\"$/) {
$branchTarget = $1;
}
if ($comment =~ /(null)/) {
$comment = $branchTarget;
}
print CPP <<FUNCTION_DEFINITION2;
EXPORT_C __NAKED__ int $fnName()
//
// $comment
//
{
asm("stmfd sp!, {r4,lr} ");
asm("mov r4, sp ");
asm("bic sp, sp, #4 ");
asm("bl $branchTarget ");
asm("mov sp, r4 ");
asm("ldmfd sp!, {r4,pc} ");
}
FUNCTION_DEFINITION2
}
sub WriteCppHeader($) {
my ($filename) = @_;
print CPP <<FILE_HEADER;
//
// $filename - generated by GENSHIMSRC.BAT
//
#include <e32def.h>
#include <e32const.h>
#include <cpudefs.h>
FILE_HEADER
}
sub WriteExport($$$) {
my ($ordinal, $export, $comment) = @_;
if ($comment =~ /(null)/) {
$comment = $export;
}
printf DEF "\t${export}=export_at_ordinal_${ordinal}__Fv \@ $ordinal NONAME \; $comment\n";
}
my $cppFile = "$srcPath\\$outputName\.cia";
die "ERROR: Couldn't open $cppFile\n" unless open CPP, ">$cppFile";
my $vstring = &Genutl_VersionToFileAugment(%Version);
my $defFile = "$defPath\\${outputName}$vstring\.def";
die "ERROR: Couldn't open $defFile\n" unless open DEF, ">$defFile";
WriteCppHeader(uc "${outputName}.cia");
printf DEF "EXPORTS\n";
foreach my $defData (@DefData){
my $ord = $$defData{Ordinal};
if ($ord) {
my $name = $$defData{Name};
my $comment = $$defData{Comment};
if ($opts{alignstack}) {
WriteFunctionAligned($ord, $name, $comment);
} else {
WriteFunction($ord, $name, $comment);
}
WriteExport($ord, $name, $comment);
}
}
close CPP;
close DEF;
#####################################################################
sub Usage
{
print <<EOT;
genshimsrc
Generate source for a shim DLL and its associated deffile from a supplied deffile
Usage:
genshimsrc [options] deffile
Where:
[deffile] The source deffile
Options:
--srcpath the path for the output source file (defaults to CWD)
--defpath the path for the output DEF file (defaults to srcpath)
--name the name to use for the output files (defaults to shim)
--version the version to use for the output DEF file (defaults to 0.0)
--alignstack use shims which align the stack to an 8 byte boundary
EOT
exit 1;
}
1;
__END__
# Tell emacs that this is a perl script even 'though it has a .bat extension
# Local Variables:
# mode:perl
# tab-width:4
# End:
:invoke
@perl -x -S genshimsrc.bat %1 %2 %3 %4 %5 %6 %7 %8 %9