Home | History | Annotate | Download | only in scripts
      1 #!/usr/bin/perl -w
      2 
      3 # Copyright (C) 2005, 2006, 2007, 2009 Apple Inc. All rights reserved.
      4 # Copyright (C) 2009, Julien Chaffraix <jchaffraix (at] webkit.org>
      5 # Copyright (C) 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
      6 # Copyright (C) 2011 Ericsson AB. All rights reserved.
      7 #
      8 # Redistribution and use in source and binary forms, with or without
      9 # modification, are permitted provided that the following conditions
     10 # are met:
     11 #
     12 # 1.  Redistributions of source code must retain the above copyright
     13 #     notice, this list of conditions and the following disclaimer.
     14 # 2.  Redistributions in binary form must reproduce the above copyright
     15 #     notice, this list of conditions and the following disclaimer in the
     16 #     documentation and/or other materials provided with the distribution.
     17 # 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
     18 #     its contributors may be used to endorse or promote products derived
     19 #     from this software without specific prior written permission.
     20 #
     21 # THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
     22 # EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
     23 # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
     24 # DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
     25 # DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
     26 # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
     27 # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
     28 # ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     29 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     30 # THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     31 
     32 use strict;
     33 
     34 use StaticString;
     35 use Config;
     36 use Getopt::Long;
     37 use File::Path;
     38 use File::Spec;
     39 use IO::File;
     40 use InFilesParser;
     41 
     42 sub readTags($$);
     43 sub readAttrs($$);
     44 
     45 my $printFactory = 0;
     46 my $fontNamesIn = "";
     47 my $resourceTypesIn = "";
     48 my $tagsFile = "";
     49 my $attrsFile = "";
     50 my $outputDir = ".";
     51 my %parsedTags = ();
     52 my %parsedAttrs = ();
     53 my %enabledTags = ();
     54 my %enabledAttrs = ();
     55 my %allTags = ();
     56 my %allAttrs = ();
     57 my %allStrings = ();
     58 my %parameters = ();
     59 my $extraDefines = 0;
     60 my $initDefaults = 1;
     61 my %extensionAttrs = ();
     62 
     63 require Config;
     64 
     65 my $gccLocation = "";
     66 if ($ENV{CC}) {
     67     $gccLocation = $ENV{CC};
     68 } elsif (($Config::Config{'osname'}) =~ /solaris/i) {
     69     $gccLocation = "/usr/sfw/bin/gcc";
     70 } else {
     71     $gccLocation = "/usr/bin/gcc";
     72 }
     73 my $preprocessor = $gccLocation . " -E -x c++";
     74 
     75 GetOptions(
     76     'tags=s' => \$tagsFile,
     77     'attrs=s' => \$attrsFile,
     78     'factory' => \$printFactory,
     79     'outputDir=s' => \$outputDir,
     80     'extraDefines=s' => \$extraDefines,
     81     'preprocessor=s' => \$preprocessor,
     82     'fonts=s' => \$fontNamesIn,
     83     'resourceTypes=s' => \$resourceTypesIn
     84 );
     85 
     86 mkpath($outputDir);
     87 
     88 if (length($fontNamesIn)) {
     89     my $familyNamesFileBase = "FontFamily";
     90     my $familyNamesPrefix = "CSS";
     91     createGenericNamesFile($fontNamesIn, $familyNamesFileBase, $familyNamesPrefix);
     92 }
     93 
     94 if (length($resourceTypesIn)) {
     95     my $baseName = "FetchInitiatorType";
     96     my $basePrefix = "Loader_Cache";
     97     createGenericNamesFile($resourceTypesIn, $baseName, $basePrefix);
     98 }
     99 
    100 die "You must specify at least one of --tags <file> or --attrs <file>" unless (length($tagsFile) || length($attrsFile));
    101 
    102 if (length($tagsFile)) {
    103     %allTags = %{readTags($tagsFile, 0)};
    104     %enabledTags = %{readTags($tagsFile, 1)};
    105     namesToStrings(\%allTags, \%allStrings);
    106 }
    107 
    108 if (length($attrsFile)) {
    109     %allAttrs = %{readAttrs($attrsFile, 0)};
    110     %enabledAttrs = %{readAttrs($attrsFile, 1)};
    111     namesToStrings(\%allAttrs, \%allStrings);
    112 }
    113 
    114 die "You must specify a namespace (e.g. SVG) for <namespace>Names.h" unless $parameters{namespace};
    115 die "You must specify a namespaceURI (e.g. http://www.w3.org/2000/svg)" unless $parameters{namespaceURI};
    116 
    117 $parameters{namespacePrefix} = $parameters{namespace} unless $parameters{namespacePrefix};
    118 $parameters{fallbackJSInterfaceName} = $parameters{fallbackInterfaceName} unless $parameters{fallbackJSInterfaceName};
    119 
    120 my $namesBasePath = "$outputDir/$parameters{namespace}Names";
    121 my $factoryBasePath = "$outputDir/$parameters{namespace}ElementFactory";
    122 my $wrapperFactoryFileName = "$parameters{namespace}ElementWrapperFactory";
    123 
    124 printNamesHeaderFile("$namesBasePath.h");
    125 printNamesCppFile("$namesBasePath.cpp");
    126 
    127 if ($printFactory) {
    128     printFactoryCppFile("$factoryBasePath.cpp");
    129     printFactoryHeaderFile("$factoryBasePath.h");
    130 }
    131 
    132 printWrapperFactoryCppFile($outputDir, $wrapperFactoryFileName);
    133 printWrapperFactoryHeaderFile($outputDir, $wrapperFactoryFileName);
    134 
    135 ### Hash initialization
    136 
    137 sub defaultTagPropertyHash
    138 {
    139     return (
    140         'constructorNeedsCreatedByParser' => 0,
    141         'constructorNeedsFormElement' => 0,
    142         'noConstructor' => 0,
    143         'interfaceName' => defaultInterfaceName($_[0]),
    144         # By default, the JSInterfaceName is the same as the interfaceName.
    145         'JSInterfaceName' => defaultInterfaceName($_[0]),
    146         'mapToTagName' => '',
    147         'wrapperOnlyIfMediaIsAvailable' => 0,
    148         'conditional' => 0,
    149         'contextConditional' => 0,
    150         'runtimeConditional' => 0
    151     );
    152 }
    153 
    154 sub defaultParametersHash
    155 {
    156     return (
    157         'namespace' => '',
    158         'namespacePrefix' => '',
    159         'namespaceURI' => '',
    160         'guardFactoryWith' => '',
    161         'tagsNullNamespace' => 0,
    162         'attrsNullNamespace' => 0,
    163         'fallbackInterfaceName' => '',
    164         'fallbackJSInterfaceName' => ''
    165     );
    166 }
    167 
    168 sub defaultInterfaceName
    169 {
    170     die "No namespace found" if !$parameters{namespace};
    171     return $parameters{namespace} . upperCaseName($_[0]) . "Element"
    172 }
    173 
    174 ### Parsing handlers
    175 
    176 sub valueForName
    177 {
    178     my $name = shift;
    179     my $value = $extensionAttrs{$name};
    180 
    181     if (!$value) {
    182         $value = $name;
    183         $value =~ s/_/-/g;
    184     }
    185 
    186     return $value;
    187 }
    188 
    189 sub namesToStrings
    190 {
    191     my $namesRef = shift;
    192     my $stringsRef = shift;
    193 
    194     my %names = %$namesRef;
    195 
    196     for my $name (keys %names) {
    197         $stringsRef->{$name} = valueForName($name);
    198     }
    199 }
    200 
    201 sub tagsHandler
    202 {
    203     my ($tag, $property, $value) = @_;
    204 
    205     $tag =~ s/-/_/g;
    206 
    207     # Initialize default property values.
    208     $parsedTags{$tag} = { defaultTagPropertyHash($tag) } if !defined($parsedTags{$tag});
    209 
    210     if ($property) {
    211         die "Unknown property $property for tag $tag\n" if !defined($parsedTags{$tag}{$property});
    212 
    213         # The code relies on JSInterfaceName deriving from interfaceName to check for custom JSInterfaceName.
    214         # So override JSInterfaceName if it was not already set.
    215         $parsedTags{$tag}{JSInterfaceName} = $value if $property eq "interfaceName" && $parsedTags{$tag}{JSInterfaceName} eq $parsedTags{$tag}{interfaceName};
    216 
    217         $parsedTags{$tag}{$property} = $value;
    218     }
    219 }
    220 
    221 sub attrsHandler
    222 {
    223     my ($attr, $property, $value) = @_;
    224     # Translate HTML5 extension attributes of the form 'x-webkit-feature' to 'webkitfeature'.
    225     # We don't just check for the 'x-' prefix because there are attributes such as x-height
    226     # which should follow the default path below.
    227     if ($attr =~ m/^x-webkit-(.*)/) {
    228         my $newAttr = "webkit$1";
    229         $extensionAttrs{$newAttr} = $attr;
    230         $attr = $newAttr;
    231     }
    232     $attr =~ s/-/_/g;
    233 
    234     # Initialize default properties' values.
    235     $parsedAttrs{$attr} = {} if !defined($parsedAttrs{$attr});
    236 
    237     if ($property) {
    238         die "Unknown property $property for attribute $attr\n" if !defined($parsedAttrs{$attr}{$property});
    239         $parsedAttrs{$attr}{$property} = $value;
    240     }
    241 }
    242 
    243 sub parametersHandler
    244 {
    245     my ($parameter, $value) = @_;
    246 
    247     # Initialize default properties' values.
    248     %parameters = defaultParametersHash() if (!(keys %parameters) && $initDefaults);
    249 
    250     # If the input is an array, we want the strings to have the same value as the key.
    251     if ( $value eq 1) {
    252         $value = $parameter;
    253     }
    254 
    255     die "Unknown parameter $parameter for tags/attrs\n" if (!defined($parameters{$parameter}) && $initDefaults);
    256     $parameters{$parameter} = $value;
    257 }
    258 
    259 ## Support routines
    260 
    261 sub preprocessorCommand()
    262 {
    263     return $preprocessor if $extraDefines eq 0;
    264     return $preprocessor . " -D" . join(" -D", split(" ", $extraDefines));
    265 }
    266 
    267 sub readNames($$$$)
    268 {
    269     my ($namesFile, $hashToFillRef, $handler, $usePreprocessor) = @_;
    270 
    271     my $names = new IO::File;
    272     if ($usePreprocessor) {
    273         open($names, preprocessorCommand() . " " . $namesFile . "|") or die "Failed to open file: $namesFile";
    274     } else {
    275         open($names, $namesFile) or die "Failed to open file: $namesFile";
    276     }
    277 
    278     my $InParser = InFilesParser->new();
    279     $InParser->parse($names, \&parametersHandler, $handler);
    280 
    281     close($names);
    282     die "Failed to read names from file: $namesFile" if (keys %{$hashToFillRef} == 0);
    283     return $hashToFillRef;
    284 }
    285 
    286 sub readAttrs($$)
    287 {
    288     my ($namesFile, $usePreprocessor) = @_;
    289     %parsedAttrs = ();
    290     return readNames($namesFile, \%parsedAttrs, \&attrsHandler, $usePreprocessor);
    291 }
    292 
    293 sub readTags($$)
    294 {
    295     my ($namesFile, $usePreprocessor) = @_;
    296     %parsedTags = ();
    297     return readNames($namesFile, \%parsedTags, \&tagsHandler, $usePreprocessor);
    298 }
    299 
    300 sub printMacros
    301 {
    302     my ($F, $macro, $suffix, $namesRef) = @_;
    303     my %names = %$namesRef;
    304 
    305     for my $name (sort keys %names) {
    306         print F "$macro $name","$suffix;\n";
    307     }
    308 }
    309 
    310 sub usesDefaultWrapper
    311 {
    312     my $tagName = shift;
    313     return $tagName eq $parameters{namespace} . "Element";
    314 }
    315 
    316 # Build a direct mapping from the tags to the Element to create.
    317 sub buildConstructorMap
    318 {
    319     my %tagConstructorMap = ();
    320     for my $tagName (keys %enabledTags) {
    321         my $interfaceName = $enabledTags{$tagName}{interfaceName};
    322 
    323         if ($enabledTags{$tagName}{mapToTagName}) {
    324             die "Cannot handle multiple mapToTagName for $tagName\n" if $enabledTags{$enabledTags{$tagName}{mapToTagName}}{mapToTagName};
    325             $interfaceName = $enabledTags{ $enabledTags{$tagName}{mapToTagName} }{interfaceName};
    326         }
    327 
    328         # Chop the string to keep the interesting part.
    329         $interfaceName =~ s/$parameters{namespace}(.*)Element/$1/;
    330         $tagConstructorMap{$tagName} = lc($interfaceName);
    331     }
    332 
    333     return %tagConstructorMap;
    334 }
    335 
    336 # Helper method that print the constructor's signature avoiding
    337 # unneeded arguments.
    338 sub printConstructorSignature
    339 {
    340     my ($F, $tagName, $constructorName, $constructorTagName) = @_;
    341 
    342     print F "static PassRefPtr<$parameters{namespace}Element> ${constructorName}Constructor(const QualifiedName& $constructorTagName, Document* document";
    343     if ($parameters{namespace} eq "HTML") {
    344         print F ", HTMLFormElement*";
    345         print F " formElement" if $enabledTags{$tagName}{constructorNeedsFormElement};
    346     }
    347     print F ", bool";
    348     print F " createdByParser" if $enabledTags{$tagName}{constructorNeedsCreatedByParser};
    349     print F ")\n{\n";
    350 }
    351 
    352 # Helper method to dump the constructor interior and call the
    353 # Element constructor with the right arguments.
    354 # The variable names should be kept in sync with the previous method.
    355 sub printConstructorInterior
    356 {
    357     my ($F, $tagName, $interfaceName, $constructorTagName) = @_;
    358 
    359     # Handle media elements.
    360     if ($enabledTags{$tagName}{wrapperOnlyIfMediaIsAvailable}) {
    361         print F <<END
    362     Settings* settings = document->settings();
    363     if (!RuntimeEnabledFeatures::mediaEnabled() || (settings && !settings->mediaEnabled()))
    364         return 0;
    365 
    366 END
    367 ;
    368     }
    369 
    370     my $contextConditional = $enabledTags{$tagName}{contextConditional};
    371     if ($contextConditional) {
    372         print F <<END
    373     if (!ContextFeatures::${contextConditional}Enabled(document))
    374         return 0;
    375 END
    376 ;
    377     }
    378 
    379     my $runtimeConditional = $enabledTags{$tagName}{runtimeConditional};
    380     if ($runtimeConditional) {
    381         print F <<END
    382     if (!RuntimeEnabledFeatures::${runtimeConditional}Enabled())
    383         return 0;
    384 END
    385 ;
    386     }
    387 
    388     # Call the constructor with the right parameters.
    389     print F "    return ${interfaceName}::create($constructorTagName, document";
    390     print F ", formElement" if $enabledTags{$tagName}{constructorNeedsFormElement};
    391     print F ", createdByParser" if $enabledTags{$tagName}{constructorNeedsCreatedByParser};
    392     print F ");\n}\n\n";
    393 }
    394 
    395 sub printConstructors
    396 {
    397     my ($F, $tagConstructorMapRef) = @_;
    398     my %tagConstructorMap = %$tagConstructorMapRef;
    399 
    400     # This is to avoid generating the same constructor several times.
    401     my %uniqueTags = ();
    402     for my $tagName (sort keys %tagConstructorMap) {
    403         my $interfaceName = $enabledTags{$tagName}{interfaceName};
    404 
    405         # Ignore the mapped tag
    406         # FIXME: It could be moved inside this loop but was split for readibility.
    407         next if (defined($uniqueTags{$interfaceName}) || $enabledTags{$tagName}{mapToTagName});
    408         # Tags can have wrappers without constructors.
    409         # This is useful to make user-agent shadow elements internally testable
    410         # while keeping them from being avaialble in the HTML markup.
    411         next if $enabledTags{$tagName}{noConstructor};
    412 
    413         $uniqueTags{$interfaceName} = '1';
    414 
    415         my $conditional = $enabledTags{$tagName}{conditional};
    416         if ($conditional) {
    417             my $conditionalString = "ENABLE(" . join(") && ENABLE(", split(/&/, $conditional)) . ")";
    418             print F "#if ${conditionalString}\n\n";
    419         }
    420 
    421         printConstructorSignature($F, $tagName, $tagConstructorMap{$tagName}, "tagName");
    422         printConstructorInterior($F, $tagName, $interfaceName, "tagName");
    423 
    424         if ($conditional) {
    425             print F "#endif\n";
    426         }
    427     }
    428 
    429     # Mapped tag name uses a special wrapper to keep their prefix and namespaceURI while using the mapped localname.
    430     for my $tagName (sort keys %tagConstructorMap) {
    431         if ($enabledTags{$tagName}{mapToTagName}) {
    432             my $mappedName = $enabledTags{$tagName}{mapToTagName};
    433             printConstructorSignature($F, $mappedName, $mappedName . "To" . $tagName, "tagName");
    434             printConstructorInterior($F, $mappedName, $enabledTags{$mappedName}{interfaceName}, "QualifiedName(tagName.prefix(), ${mappedName}Tag.localName(), tagName.namespaceURI())");
    435         }
    436     }
    437 }
    438 
    439 sub printFunctionInits
    440 {
    441     my ($F, $tagConstructorMap) = @_;
    442     my %tagConstructorMap = %$tagConstructorMap;
    443 
    444     for my $tagName (sort keys %tagConstructorMap) {
    445         next if $enabledTags{$tagName}{noConstructor};
    446 
    447         my $conditional = $enabledTags{$tagName}{conditional};
    448         if ($conditional) {
    449             my $conditionalString = "ENABLE(" . join(") && ENABLE(", split(/&/, $conditional)) . ")";
    450             print F "#if ${conditionalString}\n";
    451         }
    452 
    453         if ($enabledTags{$tagName}{mapToTagName}) {
    454             print F "    addTag(${tagName}Tag, $enabledTags{$tagName}{mapToTagName}To${tagName}Constructor);\n";
    455         } else {
    456             print F "    addTag(${tagName}Tag, $tagConstructorMap{$tagName}Constructor);\n";
    457         }
    458 
    459         if ($conditional) {
    460             print F "#endif\n\n";
    461         }
    462     }
    463 }
    464 
    465 sub svgCapitalizationHacks
    466 {
    467     my $name = shift;
    468 
    469     $name = "FE" . ucfirst $1 if $name =~ /^fe(.+)$/;
    470 
    471     return $name;
    472 }
    473 
    474 sub upperCaseName
    475 {
    476     my $name = shift;
    477 
    478     $name = svgCapitalizationHacks($name) if ($parameters{namespace} eq "SVG");
    479 
    480     while ($name =~ /^(.*?)_(.*)/) {
    481         $name = $1 . ucfirst $2;
    482     }
    483 
    484     return ucfirst $name;
    485 }
    486 
    487 sub printHeaderHead
    488 {
    489     my ($F, $prefix, $nsName, $includes) = @_;
    490 
    491     print F "#ifndef ${prefix}_${nsName}Names_h\n";
    492     print F "#define ${prefix}_${nsName}Names_h\n\n";
    493     print F "$includes\n\n";
    494 
    495     print F "namespace WebCore {\n\n";
    496     print F "namespace ${nsName}Names {\n\n";
    497 
    498     print F "#ifndef ${prefix}_${nsName}NAMES_HIDE_GLOBALS\n";
    499 }
    500 
    501 sub printCppHead
    502 {
    503     my ($F, $prefix, $nsName, $usedNamespace) = @_;
    504 
    505     print F "#include \"config.h\"\n\n";
    506     print F "#ifdef SKIP_STATIC_CONSTRUCTORS_ON_GCC\n";
    507     print F "#define ${prefix}_${nsName}NAMES_HIDE_GLOBALS 1\n";
    508     print F "#else\n";
    509     print F "#define QNAME_DEFAULT_CONSTRUCTOR 1\n";
    510     print F "#endif\n\n";
    511 
    512     print F "#include \"${nsName}Names.h\"\n\n";
    513     print F "#include \"wtf/StaticConstructors.h\"\n";
    514 
    515     print F "namespace WebCore {\n\n";
    516     print F "namespace ${nsName}Names {\n\n";
    517     print F "using namespace $usedNamespace;\n\n";
    518 }
    519 
    520 sub printInit
    521 {
    522     my ($F, $isDefinition) = @_;
    523 
    524     if ($isDefinition) {
    525         print F "\nvoid init();\n\n";
    526         print F "} }\n\n";
    527         print F "#endif\n\n";
    528         return;
    529     }
    530 
    531 print F "\nvoid init()
    532 {
    533     // Use placement new to initialize the globals.
    534 
    535 ";
    536 }
    537 
    538 sub printLicenseHeader
    539 {
    540     my $F = shift;
    541     print F "/*
    542  * THIS FILE WAS AUTOMATICALLY GENERATED, DO NOT EDIT.
    543  *
    544  * This file was generated by the core/scripts/make_names.pl script.
    545  *
    546  * Copyright (C) 2005, 2006, 2007, 2008, 2009 Apple Inc.  All rights reserved.
    547  *
    548  * Redistribution and use in source and binary forms, with or without
    549  * modification, are permitted provided that the following conditions
    550  * are met:
    551  * 1. Redistributions of source code must retain the above copyright
    552  *    notice, this list of conditions and the following disclaimer.
    553  * 2. Redistributions in binary form must reproduce the above copyright
    554  *    notice, this list of conditions and the following disclaimer in the
    555  *    documentation and/or other materials provided with the distribution.
    556  *
    557  * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
    558  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
    559  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
    560  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
    561  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
    562  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
    563  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
    564  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
    565  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    566  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    567  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    568  */
    569 
    570 ";
    571 }
    572 
    573 sub printNamesHeaderFile
    574 {
    575     my ($headerPath) = shift;
    576     my $F;
    577     open F, ">$headerPath";
    578 
    579     printLicenseHeader($F);
    580     printHeaderHead($F, "DOM", $parameters{namespace}, "#include \"core/dom/QualifiedName.h\"");
    581 
    582     my $lowerNamespace = lc($parameters{namespacePrefix});
    583     print F "// Namespace\n";
    584     print F "extern const WTF::AtomicString ${lowerNamespace}NamespaceURI;\n\n";
    585 
    586     if (keys %allTags) {
    587         print F "// Tags\n";
    588         printMacros($F, "extern const WebCore::QualifiedName", "Tag", \%allTags);
    589     }
    590 
    591     if (keys %allAttrs) {
    592         print F "// Attributes\n";
    593         printMacros($F, "extern const WebCore::QualifiedName", "Attr", \%allAttrs);
    594     }
    595     print F "#endif\n\n";
    596 
    597     if (keys %allTags) {
    598         print F "const unsigned $parameters{namespace}TagsCount = ", scalar(keys %allTags), ";\n";
    599         print F "WebCore::QualifiedName** get$parameters{namespace}Tags();\n";
    600     }
    601 
    602     if (keys %allAttrs) {
    603         print F "const unsigned $parameters{namespace}AttrsCount = ", scalar(keys %allAttrs), ";\n";
    604         print F "WebCore::QualifiedName** get$parameters{namespace}Attrs();\n";
    605     }
    606 
    607     printInit($F, 1);
    608     close F;
    609 }
    610 
    611 sub printNamesCppFile
    612 {
    613     my $cppPath = shift;
    614     my $F;
    615     open F, ">$cppPath";
    616 
    617     printLicenseHeader($F);
    618     printCppHead($F, "DOM", $parameters{namespace}, "WebCore");
    619 
    620     my $lowerNamespace = lc($parameters{namespacePrefix});
    621 
    622     print F "DEFINE_GLOBAL(AtomicString, ${lowerNamespace}NamespaceURI)\n\n";
    623 
    624     if (keys %allTags) {
    625         print F "// Tags\n";
    626         for my $name (sort keys %allTags) {
    627             print F "DEFINE_GLOBAL(QualifiedName, ", $name, "Tag)\n";
    628         }
    629 
    630         print F "\n\nWebCore::QualifiedName** get$parameters{namespace}Tags()\n";
    631         print F "{\n    static WebCore::QualifiedName* $parameters{namespace}Tags[] = {\n";
    632         for my $name (sort keys %allTags) {
    633             print F "        (WebCore::QualifiedName*)&${name}Tag,\n";
    634         }
    635         print F "    };\n";
    636         print F "    return $parameters{namespace}Tags;\n";
    637         print F "}\n";
    638     }
    639 
    640     if (keys %allAttrs) {
    641         print F "\n// Attributes\n";
    642         for my $name (sort keys %allAttrs) {
    643             print F "DEFINE_GLOBAL(QualifiedName, ", $name, "Attr)\n";
    644         }
    645         print F "\n\nWebCore::QualifiedName** get$parameters{namespace}Attrs()\n";
    646         print F "{\n    static WebCore::QualifiedName* $parameters{namespace}Attr[] = {\n";
    647         for my $name (sort keys %allAttrs) {
    648             print F "        (WebCore::QualifiedName*)&${name}Attr,\n";
    649         }
    650         print F "    };\n";
    651         print F "    return $parameters{namespace}Attr;\n";
    652         print F "}\n";
    653     }
    654 
    655     printInit($F, 0);
    656 
    657     print(F "    AtomicString ${lowerNamespace}NS(\"$parameters{namespaceURI}\", AtomicString::ConstructFromLiteral);\n\n");
    658 
    659     print(F "    // Namespace\n");
    660     print(F "    new ((void*)&${lowerNamespace}NamespaceURI) AtomicString(${lowerNamespace}NS);\n");
    661     print(F "\n");
    662     print F StaticString::GenerateStringImpls(\%allStrings);
    663 
    664     if (keys %allTags) {
    665         my $tagsNamespace = $parameters{tagsNullNamespace} ? "nullAtom" : "${lowerNamespace}NS";
    666         printDefinitions($F, \%allTags, "tags", $tagsNamespace);
    667     }
    668     if (keys %allAttrs) {
    669         my $attrsNamespace = $parameters{attrsNullNamespace} ? "nullAtom" : "${lowerNamespace}NS";
    670         printDefinitions($F, \%allAttrs, "attributes", $attrsNamespace);
    671     }
    672 
    673     print F "}\n\n} }\n\n";
    674     close F;
    675 }
    676 
    677 sub printJSElementIncludes
    678 {
    679     my $F = shift;
    680 
    681     my %tagsSeen;
    682     for my $tagName (sort keys %enabledTags) {
    683         my $JSInterfaceName = $enabledTags{$tagName}{JSInterfaceName};
    684         next if defined($tagsSeen{$JSInterfaceName}) || usesDefaultJSWrapper($tagName);
    685         if ($enabledTags{$tagName}{conditional}) {
    686             # We skip feature-define-specific #includes here since we handle them separately.
    687             next;
    688         }
    689         $tagsSeen{$JSInterfaceName} = 1;
    690 
    691         print F "#include \"V8${JSInterfaceName}.h\"\n";
    692     }
    693     print F "#include \"V8$parameters{fallbackJSInterfaceName}.h\"\n";
    694 }
    695 
    696 sub printElementIncludes
    697 {
    698     my $F = shift;
    699 
    700     my %tagsSeen;
    701     for my $tagName (sort keys %enabledTags) {
    702         my $interfaceName = $enabledTags{$tagName}{interfaceName};
    703         next if defined($tagsSeen{$interfaceName});
    704         if ($enabledTags{$tagName}{conditional}) {
    705             # We skip feature-define-specific #includes here since we handle them separately.
    706             next;
    707         }
    708         $tagsSeen{$interfaceName} = 1;
    709 
    710         print F "#include \"${interfaceName}.h\"\n";
    711     }
    712     print F "#include \"$parameters{fallbackInterfaceName}.h\"\n";
    713 }
    714 
    715 sub printConditionalElementIncludes
    716 {
    717     my ($F, $shouldIncludeV8Headers) = @_;
    718 
    719     my %conditionals;
    720     my %unconditionalElementIncludes;
    721     my %unconditionalJSElementIncludes;
    722 
    723     for my $tagName (keys %enabledTags) {
    724         my $conditional = $enabledTags{$tagName}{conditional};
    725         my $interfaceName = $enabledTags{$tagName}{interfaceName};
    726         my $JSInterfaceName = $enabledTags{$tagName}{JSInterfaceName};
    727 
    728         if ($conditional) {
    729             $conditionals{$conditional}{interfaceNames}{$interfaceName} = 1;
    730             $conditionals{$conditional}{JSInterfaceNames}{$JSInterfaceName} = 1;
    731         } else {
    732             $unconditionalElementIncludes{$interfaceName} = 1;
    733             $unconditionalJSElementIncludes{$JSInterfaceName} = 1;
    734         }
    735     }
    736 
    737     for my $conditional (sort keys %conditionals) {
    738         print F "\n#if ENABLE($conditional)\n";
    739         for my $interfaceName (sort keys %{$conditionals{$conditional}{interfaceNames}}) {
    740             next if $unconditionalElementIncludes{$interfaceName};
    741             print F "#include \"$interfaceName.h\"\n";
    742         }
    743         if ($shouldIncludeV8Headers) {
    744             for my $JSInterfaceName (sort keys %{$conditionals{$conditional}{JSInterfaceNames}}) {
    745                 next if $unconditionalJSElementIncludes{$JSInterfaceName};
    746                 print F "#include \"V8$JSInterfaceName.h\"\n";
    747             }
    748         }
    749         print F "#endif\n";
    750     }
    751 }
    752 
    753 sub printDefinitions
    754 {
    755     my ($F, $namesRef, $type, $namespaceURI) = @_;
    756     my $singularType = substr($type, 0, -1);
    757     my $shortType = substr($singularType, 0, 4);
    758     my $shortCamelType = ucfirst($shortType);
    759     my $shortUpperType = uc($shortType);
    760 
    761     print F "    // " . ucfirst($type) . "\n";
    762 
    763     for my $name (sort keys %$namesRef) {
    764         # To generate less code in init(), the common case of nullAtom for the namespace, we call createQualifiedName() without passing $namespaceURI.
    765         if ($namespaceURI eq "nullAtom") {
    766             print F "    createQualifiedName((void*)&$name","${shortCamelType}, ${name}Impl);\n";
    767         } else {
    768             print F "    createQualifiedName((void*)&$name","${shortCamelType}, ${name}Impl, $namespaceURI);\n";
    769         }
    770     }
    771 }
    772 
    773 ## ElementFactory routines
    774 
    775 sub printFactoryCppFile
    776 {
    777     my $cppPath = shift;
    778     my $F;
    779     open F, ">$cppPath";
    780 
    781 printLicenseHeader($F);
    782 
    783 print F <<END
    784 #include "config.h"
    785 END
    786 ;
    787 
    788 print F "\n#if $parameters{guardFactoryWith}\n\n" if $parameters{guardFactoryWith};
    789 
    790 print F <<END
    791 #include "$parameters{namespace}ElementFactory.h"
    792 #include "$parameters{namespace}Names.h"
    793 END
    794 ;
    795 
    796 printElementIncludes($F);
    797 
    798 print F "\n#include <wtf/HashMap.h>\n";
    799 
    800 printConditionalElementIncludes($F);
    801 
    802 print F <<END
    803 
    804 #include "ContextFeatures.h"
    805 #include "CustomElement.h"
    806 #include "Document.h"
    807 #include "RuntimeEnabledFeatures.h"
    808 #include "Settings.h"
    809 
    810 namespace WebCore {
    811 
    812 using namespace $parameters{namespace}Names;
    813 
    814 END
    815 ;
    816 
    817 print F "typedef PassRefPtr<$parameters{namespace}Element> (*ConstructorFunction)(const QualifiedName&, Document*";
    818 print F ", HTMLFormElement*" if $parameters{namespace} eq "HTML";
    819 print F ", bool createdByParser);\n";
    820 print F <<END
    821 typedef HashMap<StringImpl*, ConstructorFunction> FunctionMap;
    822 
    823 static FunctionMap* gFunctionMap = 0;
    824 
    825 END
    826 ;
    827 
    828 my %tagConstructorMap = buildConstructorMap();
    829 
    830 printConstructors($F, \%tagConstructorMap);
    831 
    832 print F <<END
    833 static void addTag(const QualifiedName& tag, ConstructorFunction func)
    834 {
    835     gFunctionMap->set(tag.localName().impl(), func);
    836 }
    837 
    838 static void createFunctionMap()
    839 {
    840     ASSERT(!gFunctionMap);
    841 
    842     // Create the table.
    843     gFunctionMap = new FunctionMap;
    844 
    845     // Populate it with constructor functions.
    846 END
    847 ;
    848 
    849 printFunctionInits($F, \%tagConstructorMap);
    850 
    851 print F "}\n";
    852 
    853 
    854 print F "\nPassRefPtr<$parameters{namespace}Element> $parameters{namespace}ElementFactory::create$parameters{namespace}Element(const QualifiedName& qName, Document* document";
    855 print F ", HTMLFormElement* formElement" if $parameters{namespace} eq "HTML";
    856 print F ", bool createdByParser)\n{\n";
    857 
    858 print F <<END
    859     if (!document)
    860         return 0;
    861 
    862     if (CustomElement::isValidName(qName.localName()) && document->registrationContext()) {
    863         RefPtr<Element> element = document->registrationContext()->createCustomTagElement(document, qName);
    864         ASSERT_WITH_SECURITY_IMPLICATION(element->is$parameters{namespace}Element());
    865         return static_pointer_cast<$parameters{namespace}Element>(element.release());
    866     }
    867 
    868     if (!gFunctionMap)
    869         createFunctionMap();
    870     if (ConstructorFunction function = gFunctionMap->get(qName.localName().impl())) {
    871 END
    872 ;
    873 
    874 if ($parameters{namespace} eq "HTML") {
    875     print F "        if (PassRefPtr<$parameters{namespace}Element> element = function(qName, document, formElement, createdByParser))\n";
    876     print F "            return element;\n";
    877 } else {
    878     print F "        if (PassRefPtr<$parameters{namespace}Element> element = function(qName, document, createdByParser))\n";
    879     print F "            return element;\n";
    880 }
    881 print F <<END
    882     }
    883 
    884     return $parameters{fallbackInterfaceName}::create(qName, document);
    885 }
    886 
    887 } // namespace WebCore
    888 
    889 END
    890 ;
    891 
    892     print F "#endif\n" if $parameters{guardFactoryWith};
    893 
    894     close F;
    895 }
    896 
    897 sub printFactoryHeaderFile
    898 {
    899     my $headerPath = shift;
    900     my $F;
    901     open F, ">$headerPath";
    902 
    903     printLicenseHeader($F);
    904 
    905     print F<<END
    906 #ifndef $parameters{namespace}ElementFactory_h
    907 #define $parameters{namespace}ElementFactory_h
    908 
    909 #include <wtf/Forward.h>
    910 #include <wtf/PassRefPtr.h>
    911 
    912 namespace WebCore {
    913     class Element;
    914     class Document;
    915     class QualifiedName;
    916 }
    917 
    918 namespace WebCore {
    919 
    920     class $parameters{namespace}Element;
    921 END
    922 ;
    923 
    924 print F "     class HTMLFormElement;\n" if $parameters{namespace} eq "HTML";
    925 
    926 print F<<END
    927     // The idea behind this class is that there will eventually be a mapping from namespace URIs to ElementFactories that can dispense
    928     // elements. In a compound document world, the generic createElement function (will end up being virtual) will be called.
    929     class $parameters{namespace}ElementFactory {
    930     public:
    931         PassRefPtr<Element> createElement(const WebCore::QualifiedName&, WebCore::Document*, bool createdByParser = true);
    932 END
    933 ;
    934 print F "        static PassRefPtr<$parameters{namespace}Element> create$parameters{namespace}Element(const WebCore::QualifiedName&, WebCore::Document*";
    935 print F ", HTMLFormElement* = 0" if $parameters{namespace} eq "HTML";
    936 print F ", bool createdByParser = true);\n";
    937 
    938 printf F<<END
    939     };
    940 }
    941 
    942 #endif // $parameters{namespace}ElementFactory_h
    943 
    944 END
    945 ;
    946 
    947     close F;
    948 }
    949 
    950 ## Wrapper Factory routines
    951 
    952 sub usesDefaultJSWrapper
    953 {
    954     my $name = shift;
    955 
    956     # A tag reuses the default wrapper if its JSInterfaceName matches the default namespace Element.
    957     return $enabledTags{$name}{JSInterfaceName} eq $parameters{namespace} . "Element";
    958 }
    959 
    960 sub printWrapperFunctions
    961 {
    962     my $F = shift;
    963 
    964     my %tagsSeen;
    965     for my $tagName (sort keys %enabledTags) {
    966         # Avoid defining the same wrapper method twice.
    967         my $JSInterfaceName = $enabledTags{$tagName}{JSInterfaceName};
    968         next if defined($tagsSeen{$JSInterfaceName}) || (usesDefaultJSWrapper($tagName) && ($parameters{fallbackJSInterfaceName} eq $parameters{namespace} . "Element"));
    969         $tagsSeen{$JSInterfaceName} = 1;
    970 
    971         my $conditional = $enabledTags{$tagName}{conditional};
    972         if ($conditional) {
    973             my $conditionalString = "ENABLE(" . join(") && ENABLE(", split(/&/, $conditional)) . ")";
    974             print F "#if ${conditionalString}\n\n";
    975         }
    976 
    977         if ($enabledTags{$tagName}{wrapperOnlyIfMediaIsAvailable}) {
    978             print F <<END
    979 static v8::Handle<v8::Object> create${JSInterfaceName}Wrapper($parameters{namespace}Element* element, v8::Handle<v8::Object> creationContext, v8::Isolate* isolate)
    980 {
    981     Settings* settings = element->document()->settings();
    982     if (!RuntimeEnabledFeatures::mediaEnabled() || (settings && !settings->mediaEnabled()))
    983         return createV8$parameters{namespace}DirectWrapper(element, creationContext, isolate);
    984     return wrap(static_cast<${JSInterfaceName}*>(element), creationContext, isolate);
    985 }
    986 
    987 END
    988 ;
    989         } elsif ($enabledTags{$tagName}{contextConditional}) {
    990             my $contextConditional = $enabledTags{$tagName}{contextConditional};
    991             print F <<END
    992 static v8::Handle<v8::Object> create${JSInterfaceName}Wrapper($parameters{namespace}Element* element, v8::Handle<v8::Object> creationContext, v8::Isolate* isolate)
    993 {
    994     if (!ContextFeatures::${contextConditional}Enabled(element->document()))
    995         return createV8$parameters{namespace}FallbackWrapper(to$parameters{fallbackInterfaceName}(element), creationContext, isolate);
    996     return wrap(static_cast<${JSInterfaceName}*>(element), creationContext, isolate);
    997 }
    998 END
    999 ;
   1000         } elsif ($enabledTags{$tagName}{runtimeConditional}) {
   1001             my $runtimeConditional = $enabledTags{$tagName}{runtimeConditional};
   1002             print F <<END
   1003 static v8::Handle<v8::Object> create${JSInterfaceName}Wrapper($parameters{namespace}Element* element, v8::Handle<v8::Object> creationContext, v8::Isolate* isolate)
   1004 {
   1005     if (!RuntimeEnabledFeatures::${runtimeConditional}Enabled())
   1006         return createV8$parameters{namespace}FallbackWrapper(to$parameters{fallbackInterfaceName}(element), creationContext, isolate);
   1007     return wrap(static_cast<${JSInterfaceName}*>(element), creationContext, isolate);
   1008 }
   1009 END
   1010 ;
   1011         } elsif (${JSInterfaceName} eq "HTMLElement") {
   1012             print F <<END
   1013 static v8::Handle<v8::Object> create${JSInterfaceName}Wrapper($parameters{namespace}Element* element, v8::Handle<v8::Object> creationContext, v8::Isolate* isolate)
   1014 {
   1015     ASSERT_NOT_REACHED();
   1016     return v8::Handle<v8::Object>();
   1017 }
   1018 
   1019 END
   1020 ;
   1021         } else {
   1022             print F <<END
   1023 static v8::Handle<v8::Object> create${JSInterfaceName}Wrapper($parameters{namespace}Element* element, v8::Handle<v8::Object> creationContext, v8::Isolate* isolate)
   1024 {
   1025     return wrap(static_cast<${JSInterfaceName}*>(element), creationContext, isolate);
   1026 }
   1027 
   1028 
   1029 END
   1030 ;
   1031         }
   1032 
   1033         if ($conditional) {
   1034             print F "#endif\n\n";
   1035         }
   1036     }
   1037 }
   1038 
   1039 sub printWrapperFactoryCppFile
   1040 {
   1041     my $outputDir = shift;
   1042     my $wrapperFactoryFileName = shift;
   1043     my $F;
   1044     open F, ">" . $outputDir . "/V8" . $wrapperFactoryFileName . ".cpp";
   1045 
   1046     printLicenseHeader($F);
   1047 
   1048     print F "#include \"config.h\"\n";
   1049     print F "#include \"V8$parameters{namespace}ElementWrapperFactory.h\"\n";
   1050 
   1051     print F "\n#if $parameters{guardFactoryWith}\n\n" if $parameters{guardFactoryWith};
   1052 
   1053     printJSElementIncludes($F);
   1054 
   1055     print F "\n#include \"$parameters{namespace}Names.h\"\n\n";
   1056 
   1057     printElementIncludes($F);
   1058 
   1059     print F "\n#include <wtf/StdLibExtras.h>\n";
   1060 
   1061     printConditionalElementIncludes($F, 1);
   1062 
   1063     print F <<END
   1064 
   1065 #include "ContextFeatures.h"
   1066 #include "Document.h"
   1067 #include "RuntimeEnabledFeatures.h"
   1068 #include "Settings.h"
   1069 
   1070 #include "V8$parameters{namespace}Element.h"
   1071 
   1072 #include "bindings/v8/CustomElementWrapper.h"
   1073 
   1074 #include <v8.h>
   1075 
   1076 namespace WebCore {
   1077 
   1078 using namespace $parameters{namespace}Names;
   1079 
   1080 typedef v8::Handle<v8::Object> (*Create$parameters{namespace}ElementWrapperFunction)($parameters{namespace}Element*, v8::Handle<v8::Object> creationContext, v8::Isolate*);
   1081 
   1082 END
   1083 ;
   1084 
   1085     printWrapperFunctions($F);
   1086 
   1087     print F <<END
   1088 v8::Handle<v8::Object> createV8$parameters{namespace}Wrapper($parameters{namespace}Element* element, v8::Handle<v8::Object> creationContext, v8::Isolate* isolate)
   1089 {
   1090     typedef HashMap<WTF::StringImpl*, Create$parameters{namespace}ElementWrapperFunction> FunctionMap;
   1091     DEFINE_STATIC_LOCAL(FunctionMap, map, ());
   1092     if (map.isEmpty()) {
   1093 END
   1094 ;
   1095 
   1096     for my $tag (sort keys %enabledTags) {
   1097         # Do not add the name to the map if it does not have a JS wrapper constructor or uses the default wrapper.
   1098         next if (usesDefaultJSWrapper($tag, \%enabledTags) && ($parameters{fallbackJSInterfaceName} eq $parameters{namespace} . "Element"));
   1099 
   1100         my $conditional = $enabledTags{$tag}{conditional};
   1101         if ($conditional) {
   1102             my $conditionalString = "ENABLE(" . join(") && ENABLE(", split(/&/, $conditional)) . ")";
   1103             print F "#if ${conditionalString}\n";
   1104         }
   1105 
   1106         my $ucTag = $enabledTags{$tag}{JSInterfaceName};
   1107         print F "       map.set(${tag}Tag.localName().impl(), create${ucTag}Wrapper);\n";
   1108 
   1109         if ($conditional) {
   1110             print F "#endif\n";
   1111         }
   1112     }
   1113 
   1114     print F <<END
   1115     }
   1116 
   1117     Create$parameters{namespace}ElementWrapperFunction createWrapperFunction = map.get(element->localName().impl());
   1118 END
   1119 ;
   1120     if ($parameters{namespace} eq "HTML") {
   1121         print F <<END
   1122     if (createWrapperFunction == createHTMLElementWrapper)
   1123         createWrapperFunction = createV8HTMLDirectWrapper;
   1124 END
   1125 ;
   1126     }
   1127     print F <<END
   1128     if (element->isCustomElement())
   1129         return CustomElementWrapper<$parameters{namespace}Element, V8$parameters{namespace}Element>::wrap(element, creationContext, isolate, createWrapperFunction);
   1130 
   1131     if (createWrapperFunction)
   1132         return createWrapperFunction(element, creationContext, isolate);
   1133 END
   1134 ;
   1135     if ($parameters{namespace} eq "SVG") {
   1136         print F <<END
   1137     return V8SVGElement::createWrapper(element, creationContext, isolate);
   1138 END
   1139 ;
   1140     } else {
   1141         print F <<END
   1142     return wrap(to$parameters{fallbackInterfaceName}(element), creationContext, isolate);
   1143 END
   1144 ;
   1145     }
   1146     print F <<END
   1147 }
   1148 
   1149 const QualifiedName* find$parameters{namespace}TagNameOfV8Type(const WrapperTypeInfo* type)
   1150 {
   1151     typedef HashMap<const WrapperTypeInfo*, const QualifiedName*> TypeNameMap;
   1152     DEFINE_STATIC_LOCAL(TypeNameMap, map, ());
   1153     if (map.isEmpty()) {
   1154 END
   1155 ;
   1156 
   1157     for my $tagName (sort keys %enabledTags) {
   1158         if (!usesDefaultJSWrapper($tagName)) {
   1159             my $conditional = $enabledTags{$tagName}{conditional};
   1160             if ($conditional) {
   1161                 my $conditionalString = "ENABLE(" . join(") && ENABLE(", split(/&/, $conditional)) . ")";
   1162                 print F "#if ${conditionalString}\n";
   1163             }
   1164 
   1165             my $JSInterfaceName = $enabledTags{$tagName}{JSInterfaceName};
   1166             print F "       map.set(WrapperTypeTraits<${JSInterfaceName}>::info(), &${tagName}Tag);\n";
   1167 
   1168             if ($conditional) {
   1169                 print F "#endif\n";
   1170             }
   1171         }
   1172     }
   1173 
   1174     print F <<END
   1175     }
   1176 
   1177     return map.get(type);
   1178 }
   1179 
   1180 END
   1181 ;
   1182 
   1183     print F "}\n\n";
   1184     print F "#endif\n" if $parameters{guardFactoryWith};
   1185 
   1186     close F;
   1187 }
   1188 
   1189 sub printWrapperFactoryHeaderFile
   1190 {
   1191     my $outputDir = shift;
   1192     my $wrapperFactoryFileName = shift;
   1193     my $F;
   1194     open F, ">" . $outputDir . "/V8" . $wrapperFactoryFileName . ".h";
   1195 
   1196     printLicenseHeader($F);
   1197 
   1198     print F "#ifndef V8$parameters{namespace}ElementWrapperFactory_h\n";
   1199     print F "#define V8$parameters{namespace}ElementWrapperFactory_h\n\n";
   1200 
   1201     print F "#if $parameters{guardFactoryWith}\n" if $parameters{guardFactoryWith};
   1202 
   1203     print F <<END
   1204 #include <V8$parameters{namespace}Element.h>
   1205 #include <V8$parameters{fallbackJSInterfaceName}.h>
   1206 #include <v8.h>
   1207 
   1208 namespace WebCore {
   1209 
   1210     class $parameters{namespace}Element;
   1211 
   1212     const QualifiedName* find$parameters{namespace}TagNameOfV8Type(const WrapperTypeInfo*);
   1213     v8::Handle<v8::Object> createV8$parameters{namespace}Wrapper($parameters{namespace}Element*, v8::Handle<v8::Object> creationContext, v8::Isolate*);
   1214     inline v8::Handle<v8::Object> createV8$parameters{namespace}DirectWrapper($parameters{namespace}Element* element, v8::Handle<v8::Object> creationContext, v8::Isolate* isolate)
   1215     {
   1216         return V8$parameters{namespace}Element::createWrapper(element, creationContext, isolate);
   1217     }
   1218     inline v8::Handle<v8::Object> createV8$parameters{namespace}FallbackWrapper($parameters{fallbackJSInterfaceName}* element, v8::Handle<v8::Object> creationContext, v8::Isolate* isolate)
   1219     {
   1220         return V8$parameters{fallbackJSInterfaceName}::createWrapper(element, creationContext, isolate);
   1221     }
   1222 }
   1223 END
   1224 ;
   1225     print F "#endif // $parameters{guardFactoryWith}\n\n" if $parameters{guardFactoryWith};
   1226 
   1227     print F "#endif // V8$parameters{namespace}ElementWrapperFactory_h\n";
   1228 
   1229     close F;
   1230 }
   1231 
   1232 sub createGenericNamesFile
   1233 {
   1234     my $inputName = shift;
   1235     my $baseName = shift;
   1236     my $basePrefix = shift;
   1237 
   1238     my $names = new IO::File;
   1239     open($names, $inputName) or die "Failed to open file: $inputName";
   1240 
   1241     $initDefaults = 0;
   1242     my $Parser = InFilesParser->new();
   1243     my $dummy;
   1244     $Parser->parse($names, \&parametersHandler, \&dummy);
   1245 
   1246     my $F;
   1247     my $header = File::Spec->catfile($outputDir, "${baseName}Names.h");
   1248     open F, ">$header" or die "Unable to open $header for writing.";
   1249 
   1250     printLicenseHeader($F);
   1251     printHeaderHead($F, $basePrefix, $baseName, "#include \"wtf/text/AtomicString.h\"");
   1252 
   1253     printMacros($F, "extern const WTF::AtomicString", "", \%parameters);
   1254     print F "#endif\n\n";
   1255 
   1256     printInit($F, 1);
   1257     close F;
   1258 
   1259     my $source = File::Spec->catfile($outputDir, "${baseName}Names.cpp");
   1260     open F, ">$source" or die "Unable to open $source for writing.";
   1261 
   1262     printLicenseHeader($F);
   1263     printCppHead($F, $basePrefix, $baseName, "WTF");
   1264 
   1265     while ( my ($name, $identifier) = each %parameters ) {
   1266         print F "DEFINE_GLOBAL(AtomicString, $name)\n";
   1267     }
   1268 
   1269     printInit($F, 0);
   1270 
   1271     print F "\n";
   1272     print F StaticString::GenerateStringImpls(\%parameters);
   1273 
   1274     while ( my ($name, $identifier) = each %parameters ) {
   1275         print F "    new ((void*)&$name) AtomicString(${name}Impl);\n";
   1276     }
   1277 
   1278     print F "}\n}\n}\n";
   1279     close F;
   1280     exit 0;
   1281 }
   1282