summaryrefslogtreecommitdiffstats
path: root/WebCore/bindings/scripts/IDLParser.pm
diff options
context:
space:
mode:
authorUpstream <upstream-import@none>1970-01-12 13:46:40 +0000
committerUpstream <upstream-import@none>1970-01-12 13:46:40 +0000
commitd8543bb6618c17b12da906afa77d216f58cf4058 (patch)
treec58dc05ed86825bd0ef8d305d58c8205106b540f /WebCore/bindings/scripts/IDLParser.pm
downloadexternal_webkit-d8543bb6618c17b12da906afa77d216f58cf4058.zip
external_webkit-d8543bb6618c17b12da906afa77d216f58cf4058.tar.gz
external_webkit-d8543bb6618c17b12da906afa77d216f58cf4058.tar.bz2
external/webkit r30707
Diffstat (limited to 'WebCore/bindings/scripts/IDLParser.pm')
-rw-r--r--WebCore/bindings/scripts/IDLParser.pm416
1 files changed, 416 insertions, 0 deletions
diff --git a/WebCore/bindings/scripts/IDLParser.pm b/WebCore/bindings/scripts/IDLParser.pm
new file mode 100644
index 0000000..de7cf9c
--- /dev/null
+++ b/WebCore/bindings/scripts/IDLParser.pm
@@ -0,0 +1,416 @@
+#
+# KDOM IDL parser
+#
+# Copyright (C) 2005 Nikolas Zimmermann <wildfox@kde.org>
+#
+# This file is part of the KDE project
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Library General Public
+# License as published by the Free Software Foundation; either
+# version 2 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Library General Public License for more details.
+#
+# You should have received a copy of the GNU Library General Public License
+# aint with this library; see the file COPYING.LIB. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+# Boston, MA 02110-1301, USA.
+#
+
+package IDLParser;
+
+use IPC::Open2;
+use IDLStructure;
+
+use constant MODE_UNDEF => 0; # Default mode.
+
+use constant MODE_MODULE => 10; # 'module' section
+use constant MODE_INTERFACE => 11; # 'interface' section
+use constant MODE_EXCEPTION => 12; # 'exception' section
+use constant MODE_ALIAS => 13; # 'alias' section
+
+# Helper variables
+my @temporaryContent = "";
+
+my $parseMode = MODE_UNDEF;
+my $preservedParseMode = MODE_UNDEF;
+
+my $beQuiet; # Should not display anything on STDOUT?
+my $document = 0; # Will hold the resulting 'idlDocument'
+
+# Default Constructor
+sub new
+{
+ my $object = shift;
+ my $reference = { };
+
+ $document = 0;
+ $beQuiet = shift;
+
+ bless($reference, $object);
+ return $reference;
+}
+
+# Returns the parsed 'idlDocument'
+sub Parse
+{
+ my $object = shift;
+ my $fileName = shift;
+ my $defines = shift;
+ my $preprocessor = shift;
+
+ if (!$preprocessor) {
+ $preprocessor = "/usr/bin/gcc -E -P -x c++";
+ }
+
+ if (!$defines) {
+ $defines = "";
+ }
+
+ print " | *** Starting to parse $fileName...\n |\n" unless $beQuiet;
+
+ open2(\*PP_OUT, \*PP_IN, split(' ', $preprocessor), (map { "-D$_" } split(' ', $defines)), $fileName);
+ close PP_IN;
+ my @documentContent = <PP_OUT>;
+ close PP_OUT;
+
+ my $dataAvailable = 0;
+
+ # Simple IDL Parser (tm)
+ foreach (@documentContent) {
+ my $newParseMode = $object->DetermineParseMode($_);
+
+ if ($newParseMode ne MODE_UNDEF) {
+ if ($dataAvailable eq 0) {
+ $dataAvailable = 1; # Start node building...
+ } else {
+ $object->ProcessSection();
+ }
+ }
+
+ # Update detected data stream mode...
+ if ($newParseMode ne MODE_UNDEF) {
+ $parseMode = $newParseMode;
+ }
+
+ push(@temporaryContent, $_);
+ }
+
+ # Check if there is anything remaining to parse...
+ if (($parseMode ne MODE_UNDEF) and ($#temporaryContent > 0)) {
+ $object->ProcessSection();
+ }
+
+ print " | *** Finished parsing!\n" unless $beQuiet;
+
+ $document->fileName($fileName);
+
+ return $document;
+}
+
+sub ParseModule
+{
+ my $object = shift;
+ my $dataNode = shift;
+
+ print " |- Trying to parse module...\n" unless $beQuiet;
+
+ my $data = join("", @temporaryContent);
+ $data =~ /$IDLStructure::moduleSelector/;
+
+ my $moduleName = (defined($1) ? $1 : die("Parsing error!\nSource:\n$data\n)"));
+ $dataNode->module($moduleName);
+
+ print " |----> Module; NAME \"$moduleName\"\n |-\n |\n" unless $beQuiet;
+}
+
+sub dumpExtendedAttributes
+{
+ my $padStr = shift;
+ my $attrs = shift;
+
+ if (!%{$attrs}) {
+ return "";
+ }
+
+ my @temp;
+ while (($name, $value) = each(%{$attrs})) {
+ push(@temp, "$name=$value");
+ }
+
+ return $padStr . "[" . join(", ", @temp) . "]";
+}
+
+sub parseExtendedAttributes
+{
+ my $str = shift;
+ $str =~ s/\[\s*(.*?)\s*\]/$1/g;
+
+ my %attrs = ();
+
+ foreach my $value (split(/\s*,\s*/, $str)) {
+ ($name,$value) = split(/\s*=\s*/, $value, 2);
+
+ # Attributes with no value are set to be true
+ $value = 1 unless defined $value;
+ $attrs{$name} = $value;
+ }
+
+ return \%attrs;
+}
+
+sub ParseInterface
+{
+ my $object = shift;
+ my $dataNode = shift;
+ my $sectionName = shift;
+
+ my $data = join("", @temporaryContent);
+
+ # Look for end-of-interface mark
+ $data =~ /};/g;
+ $data = substr($data, index($data, $sectionName), pos($data) - length($data));
+
+ $data =~ s/[\n\r]/ /g;
+
+ # Beginning of the regexp parsing magic
+ if ($sectionName eq "exception") {
+ print " |- Trying to parse exception...\n" unless $beQuiet;
+
+ my $exceptionName = "";
+ my $exceptionData = "";
+ my $exceptionDataName = "";
+ my $exceptionDataType = "";
+
+ # Match identifier of the exception, and enclosed data...
+ $data =~ /$IDLStructure::exceptionSelector/;
+ $exceptionName = (defined($1) ? $1 : die("Parsing error!\nSource:\n$data\n)"));
+ $exceptionData = (defined($2) ? $2 : die("Parsing error!\nSource:\n$data\n)"));
+
+ ('' =~ /^/); # Reset variables needed for regexp matching
+
+ # ... parse enclosed data (get. name & type)
+ $exceptionData =~ /$IDLStructure::exceptionSubSelector/;
+ $exceptionDataType = (defined($1) ? $1 : die("Parsing error!\nSource:\n$data\n)"));
+ $exceptionDataName = (defined($2) ? $2 : die("Parsing error!\nSource:\n$data\n)"));
+
+ # Fill in domClass datastructure
+ $dataNode->name($exceptionName);
+
+ my $newDataNode = new domAttribute();
+ $newDataNode->type("readonly attribute");
+ $newDataNode->signature(new domSignature());
+
+ $newDataNode->signature->name($exceptionDataName);
+ $newDataNode->signature->type($exceptionDataType);
+
+ my $arrayRef = $dataNode->attributes;
+ push(@$arrayRef, $newDataNode);
+
+ print " |----> Exception; NAME \"$exceptionName\" DATA TYPE \"$exceptionDataType\" DATA NAME \"$exceptionDataName\"\n |-\n |\n" unless $beQuiet;
+ } elsif ($sectionName eq "interface") {
+ print " |- Trying to parse interface...\n" unless $beQuiet;
+
+ my $interfaceName = "";
+ my $interfaceData = "";
+
+ # Match identifier of the interface, and enclosed data...
+ $data =~ /$IDLStructure::interfaceSelector/;
+
+ $interfaceExtendedAttributes = (defined($1) ? $1 : " "); chop($interfaceExtendedAttributes);
+ $interfaceName = (defined($2) ? $2 : die("Parsing error!\nSource:\n$data\n)"));
+ $interfaceBase = (defined($3) ? $3 : "");
+ $interfaceData = (defined($4) ? $4 : die("Parsing error!\nSource:\n$data\n)"));
+
+ # Fill in known parts of the domClass datastructure now...
+ $dataNode->name($interfaceName);
+ $dataNode->extendedAttributes(parseExtendedAttributes($interfaceExtendedAttributes));
+
+ # Inheritance detection
+ my @interfaceParents = split(/,/, $interfaceBase);
+ foreach(@interfaceParents) {
+ my $line = $_;
+ $line =~ s/\s*//g;
+
+ my $arrayRef = $dataNode->parents;
+ push(@$arrayRef, $line);
+ }
+
+ $interfaceData =~ s/[\n\r]/ /g;
+ my @interfaceMethods = split(/;/, $interfaceData);
+
+ foreach my $line (@interfaceMethods) {
+ if ($line =~ /attribute/) {
+ $line =~ /$IDLStructure::interfaceAttributeSelector/;
+
+ my $attributeType = (defined($1) ? $1 : die("Parsing error!\nSource:\n$line\n)"));
+ my $attributeExtendedAttributes = (defined($2) ? $2 : " "); chop($attributeExtendedAttributes);
+
+ my $attributeDataType = (defined($3) ? $3 : die("Parsing error!\nSource:\n$line\n)"));
+ my $attributeDataName = (defined($4) ? $4 : die("Parsing error!\nSource:\n$line\n)"));
+
+ ('' =~ /^/); # Reset variables needed for regexp matching
+
+ $line =~ /$IDLStructure::getterRaisesSelector/;
+ my $getterException = (defined($1) ? $1 : "");
+
+ $line =~ /$IDLStructure::setterRaisesSelector/;
+ my $setterException = (defined($1) ? $1 : "");
+
+ my $newDataNode = new domAttribute();
+ $newDataNode->type($attributeType);
+ $newDataNode->signature(new domSignature());
+
+ $newDataNode->signature->name($attributeDataName);
+ $newDataNode->signature->type($attributeDataType);
+ $newDataNode->signature->extendedAttributes(parseExtendedAttributes($attributeExtendedAttributes));
+
+ my $arrayRef = $dataNode->attributes;
+ push(@$arrayRef, $newDataNode);
+
+ print " | |> Attribute; TYPE \"$attributeType\" DATA NAME \"$attributeDataName\" DATA TYPE \"$attributeDataType\" GET EXCEPTION? \"$getterException\" SET EXCEPTION? \"$setterException\"" .
+ dumpExtendedAttributes("\n | ", $newDataNode->signature->extendedAttributes) . "\n" unless $beQuiet;
+
+ $getterException =~ s/\s+//g;
+ $setterException =~ s/\s+//g;
+ @{$newDataNode->getterExceptions} = split(/,/, $getterException);
+ @{$newDataNode->setterExceptions} = split(/,/, $setterException);
+ } elsif (($line !~ s/^\s*$//g) and ($line !~ /^\s*const/)) {
+ $line =~ /$IDLStructure::interfaceMethodSelector/ or die "Parsing error!\nSource:\n$line\n)";
+
+ my $methodExtendedAttributes = (defined($1) ? $1 : " "); chop($methodExtendedAttributes);
+ my $methodType = (defined($2) ? $2 : die("Parsing error!\nSource:\n$line\n)"));
+ my $methodName = (defined($3) ? $3 : die("Parsing error!\nSource:\n$line\n)"));
+ my $methodSignature = (defined($4) ? $4 : die("Parsing error!\nSource:\n$line\n)"));
+
+ ('' =~ /^/); # Reset variables needed for regexp matching
+
+ $line =~ /$IDLStructure::raisesSelector/;
+ my $methodException = (defined($1) ? $1 : "");
+
+ my $newDataNode = new domFunction();
+
+ $newDataNode->signature(new domSignature());
+ $newDataNode->signature->name($methodName);
+ $newDataNode->signature->type($methodType);
+ $newDataNode->signature->extendedAttributes(parseExtendedAttributes($methodExtendedAttributes));
+
+ print " | |- Method; TYPE \"$methodType\" NAME \"$methodName\" EXCEPTION? \"$methodException\"" .
+ dumpExtendedAttributes("\n | ", $newDataNode->signature->extendedAttributes) . "\n" unless $beQuiet;
+
+ $methodException =~ s/\s+//g;
+ @{$newDataNode->raisesExceptions} = split(/,/, $methodException);
+
+ my @params = split(/,/, $methodSignature);
+ foreach(@params) {
+ my $line = $_;
+
+ $line =~ /$IDLStructure::interfaceParameterSelector/;
+ my $paramExtendedAttributes = (defined($1) ? $1 : " "); chop($paramExtendedAttributes);
+ my $paramType = (defined($2) ? $2 : die("Parsing error!\nSource:\n$line\n)"));
+ my $paramName = (defined($3) ? $3 : die("Parsing error!\nSource:\n$line\n)"));
+
+ my $paramDataNode = new domSignature();
+ $paramDataNode->name($paramName);
+ $paramDataNode->type($paramType);
+ $paramDataNode->extendedAttributes(parseExtendedAttributes($paramExtendedAttributes));
+
+ my $arrayRef = $newDataNode->parameters;
+ push(@$arrayRef, $paramDataNode);
+
+ print " | |> Param; TYPE \"$paramType\" NAME \"$paramName\"" .
+ dumpExtendedAttributes("\n | ", $paramDataNode->extendedAttributes) . "\n" unless $beQuiet;
+ }
+
+ my $arrayRef = $dataNode->functions;
+ push(@$arrayRef, $newDataNode);
+ } elsif ($line =~ /^\s*const/) {
+ $line =~ /$IDLStructure::constantSelector/;
+ my $constType = (defined($1) ? $1 : die("Parsing error!\nSource:\n$line\n)"));
+ my $constName = (defined($2) ? $2 : die("Parsing error!\nSource:\n$line\n)"));
+ my $constValue = (defined($3) ? $3 : die("Parsing error!\nSource:\n$line\n)"));
+
+ my $newDataNode = new domConstant();
+ $newDataNode->name($constName);
+ $newDataNode->type($constType);
+ $newDataNode->value($constValue);
+
+ my $arrayRef = $dataNode->constants;
+ push(@$arrayRef, $newDataNode);
+
+ print " | |> Constant; TYPE \"$constType\" NAME \"$constName\" VALUE \"$constValue\"\n" unless $beQuiet;
+ }
+ }
+
+ print " |----> Interface; NAME \"$interfaceName\"" .
+ dumpExtendedAttributes("\n | ", $dataNode->extendedAttributes) . "\n |-\n |\n" unless $beQuiet;
+ }
+}
+
+# Internal helper
+sub DetermineParseMode
+{
+ my $object = shift;
+ my $line = shift;
+
+ my $mode = MODE_UNDEF;
+ if ($_ =~ /module/) {
+ $mode = MODE_MODULE;
+ } elsif ($_ =~ /interface/) {
+ $mode = MODE_INTERFACE;
+ } elsif ($_ =~ /exception/) {
+ $mode = MODE_EXCEPTION;
+ } elsif ($_ =~ /alias/) {
+ $mode = MODE_ALIAS;
+ }
+
+ return $mode;
+}
+
+# Internal helper
+sub ProcessSection
+{
+ my $object = shift;
+
+ if ($parseMode eq MODE_MODULE) {
+ die ("Two modules in one file! Fatal error!\n") if ($document ne 0);
+ $document = new idlDocument();
+ $object->ParseModule($document);
+ } elsif ($parseMode eq MODE_INTERFACE) {
+ my $node = new domClass();
+ $object->ParseInterface($node, "interface");
+
+ die ("No module specified! Fatal Error!\n") if ($document eq 0);
+ my $arrayRef = $document->classes;
+ push(@$arrayRef, $node);
+ } elsif($parseMode eq MODE_EXCEPTION) {
+ my $node = new domClass();
+ $object->ParseInterface($node, "exception");
+
+ die ("No module specified! Fatal Error!\n") if ($document eq 0);
+ my $arrayRef = $document->classes;
+ push(@$arrayRef, $node);
+ } elsif($parseMode eq MODE_ALIAS) {
+ print " |- Trying to parse alias...\n" unless $beQuiet;
+
+ my $line = join("", @temporaryContent);
+ $line =~ /$IDLStructure::aliasSelector/;
+
+ my $interfaceName = (defined($1) ? $1 : die("Parsing error!\nSource:\n$line\n)"));
+ my $wrapperName = (defined($2) ? $2 : die("Parsing error!\nSource:\n$line\n)"));
+
+ print " |----> Alias; INTERFACE \"$interfaceName\" WRAPPER \"$wrapperName\"\n |-\n |\n" unless $beQuiet;
+
+ # FIXME: Check if alias is already in aliases
+ my $aliases = $document->aliases;
+ $aliases->{$interfaceName} = $wrapperName;
+ }
+
+ @temporaryContent = "";
+}
+
+1;