tizen beta release
[framework/web/webkit-efl.git] / Source / WebCore / bindings / scripts / generate-bindings.pl
1 #!/usr/bin/perl -w
2 #
3 # Copyright (C) 2005 Apple Computer, Inc.
4 # Copyright (C) 2006 Anders Carlsson <andersca@mac.com>
5
6 # This file is part of WebKit
7
8 # This library is free software; you can redistribute it and/or
9 # modify it under the terms of the GNU Library General Public
10 # License as published by the Free Software Foundation; either
11 # version 2 of the License, or (at your option) any later version.
12
13 # This library is distributed in the hope that it will be useful,
14 # but WITHOUT ANY WARRANTY; without even the implied warranty of
15 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16 # Library General Public License for more details.
17
18 # You should have received a copy of the GNU Library General Public License
19 # along with this library; see the file COPYING.LIB.  If not, write to
20 # the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
21 # Boston, MA 02110-1301, USA.
22
23
24 # This script is a temporary hack. 
25 # Files are generated in the source directory, when they really should go
26 # to the DerivedSources directory.
27 # This should also eventually be a build rule driven off of .idl files
28 # however a build rule only solution is blocked by several radars:
29 # <rdar://problems/4251781&4251785>
30
31 use strict;
32
33 use File::Path;
34 use File::Basename;
35 use Getopt::Long;
36 use Cwd;
37
38 use IDLParser;
39 use CodeGenerator;
40
41 my @idlDirectories;
42 my $outputDirectory;
43 my $outputHeadersDirectory;
44 my $generator;
45 my $defines;
46 my $filename;
47 my $prefix;
48 my $preprocessor;
49 my $writeDependencies;
50 my $verbose;
51 my $supplementalDependencyFile;
52
53 GetOptions('include=s@' => \@idlDirectories,
54            'outputDir=s' => \$outputDirectory,
55            'outputHeadersDir=s' => \$outputHeadersDirectory,
56            'generator=s' => \$generator,
57            'defines=s' => \$defines,
58            'filename=s' => \$filename,
59            'prefix=s' => \$prefix,
60            'preprocessor=s' => \$preprocessor,
61            'verbose' => \$verbose,
62            'write-dependencies' => \$writeDependencies,
63            'supplementalDependencyFile=s' => \$supplementalDependencyFile);
64
65 my $targetIdlFile = $ARGV[0];
66
67 die('Must specify input file.') unless defined($targetIdlFile);
68 die('Must specify generator') unless defined($generator);
69 die('Must specify output directory.') unless defined($outputDirectory);
70
71 if (!$outputHeadersDirectory) {
72     $outputHeadersDirectory = $outputDirectory;
73 }
74 $targetIdlFile = Cwd::realpath($targetIdlFile);
75 if ($verbose) {
76     print "$generator: $targetIdlFile\n";
77 }
78 my $targetInterfaceName = fileparse(basename($targetIdlFile), ".idl");
79
80 my $idlFound = 0;
81 my @supplementedIdlFiles;
82 if ($supplementalDependencyFile) {
83     # The format of a supplemental dependency file:
84     #
85     # DOMWindow.idl P.idl Q.idl R.idl
86     # Document.idl S.idl
87     # Event.idl
88     # ...
89     #
90     # The above indicates that DOMWindow.idl is supplemented by P.idl, Q.idl and R.idl,
91     # Document.idl is supplemented by S.idl, and Event.idl is supplemented by no IDLs.
92     # The IDL that supplements another IDL (e.g. P.idl) never appears in the dependency file.
93     open FH, "< $supplementalDependencyFile" or die "Cannot open $supplementalDependencyFile\n";
94     while (my $line = <FH>) {
95         my ($idlFile, @followingIdlFiles) = split(/\s+/, $line);
96         if ($idlFile and $idlFile eq $targetIdlFile) {
97             $idlFound = 1;
98             @supplementedIdlFiles = @followingIdlFiles;
99         }
100     }
101     close FH;
102
103     if (!$idlFound) {
104         if ($verbose) {
105             print "$targetIdlFile is supplementing another IDL file, and thus .h and .cpp for $targetIdlFile are not generated.\n";
106         }
107         exit 0;
108     }
109 }
110
111 # Parse the target IDL file.
112 my $targetParser = IDLParser->new(!$verbose);
113 my $targetDocument = $targetParser->Parse($targetIdlFile, $defines, $preprocessor);
114
115 foreach my $idlFile (@supplementedIdlFiles) {
116     next if $idlFile eq $targetIdlFile;
117
118     my $interfaceName = fileparse(basename($idlFile), ".idl");
119     my $parser = IDLParser->new(!$verbose);
120     my $document = $parser->Parse($idlFile, $defines, $preprocessor);
121
122     foreach my $dataNode (@{$document->classes}) {
123         if ($dataNode->extendedAttributes->{"Supplemental"} and $dataNode->extendedAttributes->{"Supplemental"} eq $targetInterfaceName) {
124             my $targetDataNode;
125             foreach my $class (@{$targetDocument->classes}) {
126                 if ($class->name eq $targetInterfaceName) {
127                     $targetDataNode = $class;
128                     last;
129                 }
130             }
131             die "Not found an interface ${targetInterfaceName} in ${targetInterfaceName}.idl." unless defined $targetDataNode;
132
133             foreach my $attribute (@{$dataNode->attributes}) {
134                 # Record that this attribute is implemented by $interfaceName.
135                 $attribute->signature->extendedAttributes->{"ImplementedBy"} = $interfaceName;
136
137                 # Add interface-wide extended attributes to each attribute.
138                 foreach my $extendedAttributeName (keys %{$dataNode->extendedAttributes}) {
139                     next if ($extendedAttributeName eq "Supplemental");
140                     $attribute->signature->extendedAttributes->{$extendedAttributeName} = $dataNode->extendedAttributes->{$extendedAttributeName};
141                 }
142                 push(@{$targetDataNode->attributes}, $attribute);
143             }
144         }
145     }
146 }
147
148 # Generate desired output for the target IDL file.
149 my $codeGen = CodeGenerator->new(\@idlDirectories, $generator, $outputDirectory, $outputHeadersDirectory, 0, $preprocessor, $writeDependencies, $verbose);
150 $codeGen->ProcessDocument($targetDocument, $defines);