⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 make_names.pl

📁 linux下开源浏览器WebKit的源码,市面上的很多商用浏览器都是移植自WebKit
💻 PL
📖 第 1 页 / 共 2 页
字号:
#!/usr/bin/perl -w# Copyright (C) 2005, 2006, 2007, 2009 Apple Inc. All rights reserved.# Copyright (C) 2009, Julien Chaffraix <jchaffraix@webkit.org>## Redistribution and use in source and binary forms, with or without# modification, are permitted provided that the following conditions# are met:## 1.  Redistributions of source code must retain the above copyright#     notice, this list of conditions and the following disclaimer. # 2.  Redistributions in binary form must reproduce the above copyright#     notice, this list of conditions and the following disclaimer in the#     documentation and/or other materials provided with the distribution. # 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of#     its contributors may be used to endorse or promote products derived#     from this software without specific prior written permission. ## THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE# DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.use strict;use Config;use Getopt::Long;use File::Path;use IO::File;use InFilesParser;use Switch;my $printFactory = 0; my $printWrapperFactory = 0;my $tagsFile = "";my $attrsFile = "";my $outputDir = ".";my %tags = ();my %attrs = ();my %parameters = ();my $extraDefines = 0;my $preprocessor = "/usr/bin/gcc -E -P -x c++";GetOptions('tags=s' => \$tagsFile,     'attrs=s' => \$attrsFile,    'factory' => \$printFactory,    'outputDir=s' => \$outputDir,    'extraDefines=s' => \$extraDefines,    'preprocessor=s' => \$preprocessor,    'wrapperFactory' => \$printWrapperFactory);die "You must specify at least one of --tags <file> or --attrs <file>" unless (length($tagsFile) || length($attrsFile));readNames($tagsFile, "tags") if length($tagsFile);readNames($attrsFile, "attrs") if length($attrsFile);die "You must specify a namespace (e.g. SVG) for <namespace>Names.h" unless $parameters{'namespace'};die "You must specify a namespaceURI (e.g. http://www.w3.org/2000/svg)" unless $parameters{'namespaceURI'};$parameters{'namespacePrefix'} = $parameters{'namespace'} unless $parameters{'namespacePrefix'};mkpath($outputDir);my $namesBasePath = "$outputDir/$parameters{'namespace'}Names";my $factoryBasePath = "$outputDir/$parameters{'namespace'}ElementFactory";my $wrapperFactoryBasePath = "$outputDir/JS$parameters{'namespace'}ElementWrapperFactory";printNamesHeaderFile("$namesBasePath.h");printNamesCppFile("$namesBasePath.cpp");if ($printFactory) {    printFactoryCppFile("$factoryBasePath.cpp");    printFactoryHeaderFile("$factoryBasePath.h");}if ($printWrapperFactory) {    printWrapperFactoryCppFile("$wrapperFactoryBasePath.cpp");    printWrapperFactoryHeaderFile("$wrapperFactoryBasePath.h");}### Hash initializationsub initializeTagPropertyHash{    return ('constructorNeedsCreatedByParser' => 0,            'constructorNeedsFormElement' => 0,            'exportString' => 0,            'interfaceName' => defaultInterfaceName($_[0]),            # By default, the JSInterfaceName is the same as the interfaceName.            'JSInterfaceName' => defaultInterfaceName($_[0]),            'mapToTagName' => '',            'wrapperOnlyIfMediaIsAvailable' => 0);}sub initializeAttrPropertyHash{    return ('exportString' => 0);}sub initializeParametersHash{    return ('namespace' => '',            'namespacePrefix' => '',            'namespaceURI' => '',            'guardFactoryWith' => '',            'tagsNullNamespace' => 0,            'attrsNullNamespace' => 0,            'exportStrings' => 0);}sub defaultInterfaceName{    die "No namespace found" if !$parameters{'namespace'};    return $parameters{'namespace'} . upperCaseName($_[0]) . "Element"}### Parsing handlerssub tagsHandler{    my ($tag, $property, $value) = @_;    $tag =~ s/-/_/g;    # Initialize default properties' values.    $tags{$tag} = { initializeTagPropertyHash($tag) } if !defined($tags{$tag});    if ($property) {        die "Unknown property $property for tag $tag\n" if !defined($tags{$tag}{$property});        # The code rely on JSInterfaceName deriving from interfaceName to check for custom JSInterfaceName.        # So just override JSInterfaceName if it was not already set.        if ($property eq "interfaceName" && $tags{$tag}{'JSInterfaceName'} eq $tags{$tag}{'interfaceName'}) {                $tags{$tag}{'JSInterfaceName'} = $value;        }        $tags{$tag}{$property} = $value;    }}sub attrsHandler{    my ($attr, $property, $value) = @_;    $attr =~ s/-/_/g;    # Initialize default properties' values.    $attrs{$attr} = { initializeAttrPropertyHash($attr) } if !defined($attrs{$attr});    if ($property) {        die "Unknown property $property for attribute $attr\n" if !defined($attrs{$attr}{$property});        $attrs{$attr}{$property} = $value;    }}sub parametersHandler{    my ($parameter, $value) = @_;    # Initialize default properties' values.    %parameters = initializeParametersHash() if !(keys %parameters);    die "Unknown parameter $parameter for tags/attrs\n" if !defined($parameters{$parameter});    $parameters{$parameter} = $value;}## Support routinessub readNames{    my ($namesFile, $type) = @_;    my $names = new IO::File;    if ($extraDefines eq 0) {        open($names, $preprocessor . " " . $namesFile . "|") or die "Failed to open file: $namesFile";    } else {        open($names, $preprocessor . " -D" . join(" -D", split(" ", $extraDefines)) . " " . $namesFile . "|") or die "Failed to open file: $namesFile";    }    # Store hashes keys count to know if some insertion occured.    my $tagsCount = keys %tags;    my $attrsCount = keys %attrs;    my $InParser = InFilesParser->new();    switch ($type) {        case "tags" {            $InParser->parse($names, \&parametersHandler, \&tagsHandler);        }        case "attrs" {            $InParser->parse($names, \&parametersHandler, \&attrsHandler);        }        else {            die "Do not know how to parse $type";        }    }    close($names);    die "Failed to read names from file: $namesFile" if ((keys %tags == $tagsCount) && (keys %attrs == $attrsCount));}sub printMacros{    my ($F, $macro, $suffix, $namesRef) = @_;    my %names = %$namesRef;    for my $name (sort keys %$namesRef) {        print F "$macro $name","$suffix;\n";        if ($parameters{'exportStrings'} or $names{$name}{"exportString"}) {             print F "extern char $name", "${suffix}String[];\n";        }    }}sub usesDefaultWrapper{    my $tagName = shift;    return $tagName eq $parameters{'namespace'} . "Element";}# Build a direct mapping from the tags to the Element to create, excluding# Element that have not constructor.sub buildConstructorMap{    my %tagConstructorMap = ();    for my $tagName (keys %tags) {        my $interfaceName = $tags{$tagName}{'interfaceName'};        next if (usesDefaultWrapper($interfaceName));        if ($tags{$tagName}{'mapToTagName'}) {            die "Cannot handle multiple mapToTagName for $tagName\n" if $tags{$tags{$tagName}{'mapToTagName'}}{'mapToTagName'};            $interfaceName = $tags{ $tags{$tagName}{'mapToTagName'} }{'interfaceName'};        }        # Chop the string to keep the interesting part.        $interfaceName =~ s/$parameters{'namespace'}(.*)Element/$1/;        $tagConstructorMap{$tagName} = lc($interfaceName);    }    return %tagConstructorMap;}# Helper method that print the constructor's signature avoiding# unneeded arguments.sub printConstructorSignature{    my ($F, $tagName, $constructorName, $constructorTagName) = @_;    print F "static PassRefPtr<$parameters{'namespace'}Element> ${constructorName}Constructor(const QualifiedName& $constructorTagName, Document* doc";    if ($parameters{'namespace'} eq "HTML") {        print F ", HTMLFormElement*";        if ($tags{$tagName}{'constructorNeedsFormElement'}) {            print F " formElement";        }    }    print F ", bool";    if ($tags{$tagName}{'constructorNeedsCreatedByParser'}) {        print F " createdByParser";     }    print F ")\n{\n";}# Helper method to dump the constructor interior and call the # Element constructor with the right arguments.# The variable names should be kept in sync with the previous method.sub printConstructorInterior{    my ($F, $tagName, $interfaceName, $constructorTagName) = @_;    # Handle media elements.    if ($tags{$tagName}{'wrapperOnlyIfMediaIsAvailable'}) {        print F <<END    if (!MediaPlayer::isAvailable())        return new HTMLElement($constructorTagName, doc);END;    }    # Now call the constructor with the right parameters.    print F "    return new ${interfaceName}($constructorTagName, doc";    if ($tags{$tagName}{'constructorNeedsFormElement'}) {        print F ", formElement";    }    if ($tags{$tagName}{'constructorNeedsCreatedByParser'}) {        print F ", createdByParser";    }    print F ");\n}\n\n";}sub printConstructors{    my ($F, $tagConstructorMapRef) = @_;    my %tagConstructorMap = %$tagConstructorMapRef;    print F "#if $parameters{'guardFactoryWith'}\n" if $parameters{'guardFactoryWith'};    # This is to avoid generating the same constructor several times.    my %uniqueTags = ();    for my $tagName (sort keys %tagConstructorMap) {        my $interfaceName = $tags{$tagName}{'interfaceName'};        # Ignore the mapped tag        # FIXME: It could be moved inside this loop but was split for readibility.        next if (defined($uniqueTags{$interfaceName}) || $tags{$tagName}{'mapToTagName'});        $uniqueTags{$interfaceName} = '1';        printConstructorSignature($F, $tagName, $tagConstructorMap{$tagName}, "tagName");        printConstructorInterior($F, $tagName, $interfaceName, "tagName");    }    # Mapped tag name uses a special wrapper to keep their prefix and namespaceURI while using the mapped localname.    for my $tagName (sort keys %tagConstructorMap) {        if ($tags{$tagName}{'mapToTagName'}) {            my $mappedName = $tags{$tagName}{'mapToTagName'};            printConstructorSignature($F, $mappedName, $mappedName . "To" . $tagName, "tagName");            printConstructorInterior($F, $mappedName, $tags{$mappedName}{'interfaceName'}, "QualifiedName(tagName.prefix(), ${mappedName}Tag.localName(), tagName.namespaceURI())");        }    }    print F "#endif\n" if $parameters{'guardFactoryWith'};}sub printFunctionInits{    my ($F, $tagConstructorMap) = @_;    my %tagConstructorMap = %$tagConstructorMap;    for my $tagName (sort keys %tagConstructorMap) {        if ($tags{$tagName}{'mapToTagName'}) {            print F "    addTag(${tagName}Tag, $tags{$tagName}{'mapToTagName'}To${tagName}Constructor);\n";        } else {            print F "    addTag(${tagName}Tag, $tagConstructorMap{$tagName}Constructor);\n";        }    }}sub svgCapitalizationHacks{    my $name = shift;    if ($name =~ /^fe(.+)$/) {        $name = "FE" . ucfirst $1;    }    return $name;}sub upperCaseName{    my $name = shift;        $name = svgCapitalizationHacks($name) if ($parameters{'namespace'} eq "SVG");    while ($name =~ /^(.*?)_(.*)/) {        $name = $1 . ucfirst $2;    }        return ucfirst $name;}sub printLicenseHeader{    my $F = shift;    print F "/* * THIS FILE IS AUTOMATICALLY GENERATED, DO NOT EDIT. * * * Copyright (C) 2005 Apple Computer, Inc.  All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright *    notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimer in the *    documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.  */";}sub printNamesHeaderFile{    my ($headerPath) = shift;    my $F;    open F, ">$headerPath";        printLicenseHeader($F);    print F "#ifndef DOM_$parameters{'namespace'}NAMES_H\n";    print F "#define DOM_$parameters{'namespace'}NAMES_H\n\n";    print F "#include \"QualifiedName.h\"\n\n";        print F "namespace WebCore {\n\n namespace $parameters{'namespace'}Names {\n\n";        my $lowerNamespace = lc($parameters{'namespacePrefix'});    print F "#ifndef DOM_$parameters{'namespace'}NAMES_HIDE_GLOBALS\n";    print F "// Namespace\n";    print F "extern const WebCore::AtomicString ${lowerNamespace}NamespaceURI;\n\n";    if (keys %tags) {        print F "// Tags\n";        printMacros($F, "extern const WebCore::QualifiedName", "Tag", \%tags);    }        if (keys %attrs) {        print F "// Attributes\n";        printMacros($F, "extern const WebCore::QualifiedName", "Attr", \%attrs);    }    print F "#endif\n\n";        if (keys %tags) {        print F "WebCore::QualifiedName** get$parameters{'namespace'}Tags(size_t* size);\n";    }    if (keys %attrs) {        print F "WebCore::QualifiedName** get$parameters{'namespace'}Attrs(size_t* size);\n";    }        print F "\nvoid init();\n\n";    print F "} }\n\n";    print F "#endif\n\n";        close F;}sub printNamesCppFile{    my $cppPath = shift;    my $F;    open F, ">$cppPath";        printLicenseHeader($F);        my $lowerNamespace = lc($parameters{'namespacePrefix'});print F "#include \"config.h\"\n";print F "#ifdef SKIP_STATIC_CONSTRUCTORS_ON_GCC\n";print F "#define DOM_$parameters{'namespace'}NAMES_HIDE_GLOBALS 1\n";print F "#else\n";print F "#define QNAME_DEFAULT_CONSTRUCTOR 1\n";print F "#endif\n\n";print F "#include \"$parameters{'namespace'}Names.h\"\n\n";print F "#include \"StaticConstructors.h\"\n";print F "namespace WebCore {\n\n namespace $parameters{'namespace'}Names {using namespace WebCore;DEFINE_GLOBAL(AtomicString, ${lowerNamespace}NamespaceURI, \"$parameters{'namespaceURI'}\")";    if (keys %tags) {        print F "// Tags\n";        for my $name (sort keys %tags) {            print F "DEFINE_GLOBAL(QualifiedName, ", $name, "Tag, nullAtom, \"$name\", ${lowerNamespace}NamespaceURI);\n";        }                print F "\n\nWebCore::QualifiedName** get$parameters{'namespace'}Tags(size_t* size)\n";        print F "{\n    static WebCore::QualifiedName* $parameters{'namespace'}Tags[] = {\n";        for my $name (sort keys %tags) {            print F "        (WebCore::QualifiedName*)&${name}Tag,\n";        }        print F "    };\n";        print F "    *size = ", scalar(keys %tags), ";\n";        print F "    return $parameters{'namespace'}Tags;\n";        print F "}\n";    }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -