/*
 * THIS FILE WAS AUTOMATICALLY GENERATED, DO NOT EDIT.
 *
 * This file was generated by the dom/make_names.pl script.
 *
 * Copyright (C) 2005, 2006, 2007, 2008, 2009, 2013 Apple 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 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 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.
 */

#include "config.h"

#ifdef SKIP_STATIC_CONSTRUCTORS_ON_GCC
#define DOM_XLink_NAMES_HIDE_GLOBALS 1
#else
#define QNAME_DEFAULT_CONSTRUCTOR 1
#endif

#include "XLinkNames.h"

#include <wtf/StaticConstructors.h>
namespace WebCore {

namespace XLinkNames {

using namespace WebCore;

WEBCORE_EXPORT DEFINE_GLOBAL(AtomicString, xlinkNamespaceURI)

static const LChar actuateString8[] = "actuate";
static const LChar arcroleString8[] = "arcrole";
static const LChar hrefString8[] = "href";
static const LChar roleString8[] = "role";
static const LChar showString8[] = "show";
static const LChar titleString8[] = "title";
static const LChar typeString8[] = "type";

static StringImpl::StaticASCIILiteral actuateData = {
    StringImpl::StaticASCIILiteral::s_initialRefCount,
    7,
    actuateString8,
    StringImpl::StaticASCIILiteral::s_initialFlags | (5578769 << StringImpl::StaticASCIILiteral::s_hashShift)
};
static StringImpl::StaticASCIILiteral arcroleData = {
    StringImpl::StaticASCIILiteral::s_initialRefCount,
    7,
    arcroleString8,
    StringImpl::StaticASCIILiteral::s_initialFlags | (11561565 << StringImpl::StaticASCIILiteral::s_hashShift)
};
static StringImpl::StaticASCIILiteral hrefData = {
    StringImpl::StaticASCIILiteral::s_initialRefCount,
    4,
    hrefString8,
    StringImpl::StaticASCIILiteral::s_initialFlags | (5797448 << StringImpl::StaticASCIILiteral::s_hashShift)
};
static StringImpl::StaticASCIILiteral roleData = {
    StringImpl::StaticASCIILiteral::s_initialRefCount,
    4,
    roleString8,
    StringImpl::StaticASCIILiteral::s_initialFlags | (16084934 << StringImpl::StaticASCIILiteral::s_hashShift)
};
static StringImpl::StaticASCIILiteral showData = {
    StringImpl::StaticASCIILiteral::s_initialRefCount,
    4,
    showString8,
    StringImpl::StaticASCIILiteral::s_initialFlags | (3191658 << StringImpl::StaticASCIILiteral::s_hashShift)
};
static StringImpl::StaticASCIILiteral titleData = {
    StringImpl::StaticASCIILiteral::s_initialRefCount,
    5,
    titleString8,
    StringImpl::StaticASCIILiteral::s_initialFlags | (2337488 << StringImpl::StaticASCIILiteral::s_hashShift)
};
static StringImpl::StaticASCIILiteral typeData = {
    StringImpl::StaticASCIILiteral::s_initialRefCount,
    4,
    typeString8,
    StringImpl::StaticASCIILiteral::s_initialFlags | (1916283 << StringImpl::StaticASCIILiteral::s_hashShift)
};


// Attributes
WEBCORE_EXPORT DEFINE_GLOBAL(QualifiedName, actuateAttr)
WEBCORE_EXPORT DEFINE_GLOBAL(QualifiedName, arcroleAttr)
WEBCORE_EXPORT DEFINE_GLOBAL(QualifiedName, hrefAttr)
WEBCORE_EXPORT DEFINE_GLOBAL(QualifiedName, roleAttr)
WEBCORE_EXPORT DEFINE_GLOBAL(QualifiedName, showAttr)
WEBCORE_EXPORT DEFINE_GLOBAL(QualifiedName, titleAttr)
WEBCORE_EXPORT DEFINE_GLOBAL(QualifiedName, typeAttr)


const WebCore::QualifiedName* const* getXLinkAttrs()
{
    static const WebCore::QualifiedName* const XLinkAttrs[] = {
        reinterpret_cast<const WebCore::QualifiedName*>(&actuateAttr),
        reinterpret_cast<const WebCore::QualifiedName*>(&arcroleAttr),
        reinterpret_cast<const WebCore::QualifiedName*>(&hrefAttr),
        reinterpret_cast<const WebCore::QualifiedName*>(&roleAttr),
        reinterpret_cast<const WebCore::QualifiedName*>(&showAttr),
        reinterpret_cast<const WebCore::QualifiedName*>(&titleAttr),
        reinterpret_cast<const WebCore::QualifiedName*>(&typeAttr),
    };
    return XLinkAttrs;
}

void init()
{
    static bool initialized = false;
    if (initialized)
        return;
    initialized = true;

    // Use placement new to initialize the globals.

    AtomicString::init();
    AtomicString xlinkNS("http://www.w3.org/1999/xlink", AtomicString::ConstructFromLiteral);

    // Namespace
    new (NotNull, (void*)&xlinkNamespaceURI) AtomicString(xlinkNS);

#ifndef NDEBUG
    reinterpret_cast<StringImpl*>(&actuateData)->assertHashIsCorrect();
    reinterpret_cast<StringImpl*>(&arcroleData)->assertHashIsCorrect();
    reinterpret_cast<StringImpl*>(&hrefData)->assertHashIsCorrect();
    reinterpret_cast<StringImpl*>(&roleData)->assertHashIsCorrect();
    reinterpret_cast<StringImpl*>(&showData)->assertHashIsCorrect();
    reinterpret_cast<StringImpl*>(&titleData)->assertHashIsCorrect();
    reinterpret_cast<StringImpl*>(&typeData)->assertHashIsCorrect();
#endif // NDEBUG


    struct AttributesTableEntry {
        void* targetAddress;
        StringImpl& name;
    };

    static const AttributesTableEntry attributesTable[] = {
        { (void*)&actuateAttr, *reinterpret_cast<StringImpl*>(&actuateData) },
        { (void*)&arcroleAttr, *reinterpret_cast<StringImpl*>(&arcroleData) },
        { (void*)&hrefAttr, *reinterpret_cast<StringImpl*>(&hrefData) },
        { (void*)&roleAttr, *reinterpret_cast<StringImpl*>(&roleData) },
        { (void*)&showAttr, *reinterpret_cast<StringImpl*>(&showData) },
        { (void*)&titleAttr, *reinterpret_cast<StringImpl*>(&titleData) },
        { (void*)&typeAttr, *reinterpret_cast<StringImpl*>(&typeData) },
    };

    for (unsigned i = 0; i < WTF_ARRAY_LENGTH(attributesTable); ++i)
        createQualifiedName(attributesTable[i].targetAddress, &attributesTable[i].name, xlinkNS);
}

} }

