diff options
author | Lars Knoll <lars.knoll@nokia.com> | 2009-03-23 09:18:55 (GMT) |
---|---|---|
committer | Simon Hausmann <simon.hausmann@nokia.com> | 2009-03-23 09:18:55 (GMT) |
commit | e5fcad302d86d316390c6b0f62759a067313e8a9 (patch) | |
tree | c2afbf6f1066b6ce261f14341cf6d310e5595bc1 /src/xmlpatterns/qtokenautomaton/qautomaton2cpp.xsl | |
download | Qt-e5fcad302d86d316390c6b0f62759a067313e8a9.zip Qt-e5fcad302d86d316390c6b0f62759a067313e8a9.tar.gz Qt-e5fcad302d86d316390c6b0f62759a067313e8a9.tar.bz2 |
Long live Qt 4.5!
Diffstat (limited to 'src/xmlpatterns/qtokenautomaton/qautomaton2cpp.xsl')
-rw-r--r-- | src/xmlpatterns/qtokenautomaton/qautomaton2cpp.xsl | 298 |
1 files changed, 298 insertions, 0 deletions
diff --git a/src/xmlpatterns/qtokenautomaton/qautomaton2cpp.xsl b/src/xmlpatterns/qtokenautomaton/qautomaton2cpp.xsl new file mode 100644 index 0000000..16084a0 --- /dev/null +++ b/src/xmlpatterns/qtokenautomaton/qautomaton2cpp.xsl @@ -0,0 +1,298 @@ +<?xml version='1.0' encoding="UTF-8"?> +<xsl:stylesheet version="2.0" + xml:lang="en" + xmlns:xsl="http://www.w3.org/1999/XSL/Transform" + xmlns:local="http://www.w3.org/2005/xquery-local-functions" + xmlns:xs="http://www.w3.org/2001/XMLSchema"> + + <xsl:variable name="className" as="xs:string" select="tokenAutomaton/@className"/> + <xsl:variable name="defaultToken" as="xs:string" select="tokenAutomaton/@defaultToken"/> + <xsl:variable name="tokens" as="element(token)+" select="tokenAutomaton/tokens/token"/> + <xsl:variable name="tokenEnum" as="xs:string" select="tokenAutomaton/@tokenEnum"/> + + <xsl:variable name="warningGenerated" as="xs:string">/* NOTE: This file is AUTO GENERATED by qautomaton2cpp.xsl. */
</xsl:variable> + + <xsl:template match="tokenAutomaton"> + + <xsl:variable name="uniqueLengths" as="xs:integer+" select="distinct-values(tokens/token/string-length())"/> + + <xsl:result-document method="text" href="{@headerFile}"> + + <xsl:variable name="includeGuardName" select="string(@includeGuardName)"/> + + <xsl:value-of select="boilerplate/prolog"/> + + <xsl:value-of select="$warningGenerated"/> + + <xsl:text>
#ifndef </xsl:text> + <xsl:value-of select="$includeGuardName"/> + <xsl:text>
#define </xsl:text> + <xsl:value-of select="$includeGuardName"/> + <xsl:text>

</xsl:text> + + <xsl:text>#include <QtCore/QString>
</xsl:text> + <xsl:text>
</xsl:text> + <xsl:text>QT_BEGIN_NAMESPACE
</xsl:text> + <xsl:text>
</xsl:text> + + <xsl:if test="@namespace"> + <xsl:text>namespace </xsl:text> + <xsl:value-of select="@namespace"/> + { + </xsl:if> + + <xsl:text>class </xsl:text> + <xsl:value-of select="@className"/> + { + <xsl:value-of select="@scope"/>: + <xsl:text>enum </xsl:text> + <xsl:value-of select="$tokenEnum"/> + <xsl:text>
</xsl:text> + { + <xsl:value-of separator=",
"> + <xsl:sequence select="@defaultToken"/> + <xsl:perform-sort select="tokens/token/local:tokenToEnumName(.)"> + <xsl:sort select="."/> + </xsl:perform-sort> + </xsl:value-of> + }; + + <xsl:text>static inline </xsl:text> + <xsl:value-of select="$tokenEnum"/> + <xsl:text> toToken(const QString &value);
</xsl:text> + <xsl:text>static inline </xsl:text> + <xsl:value-of select="$tokenEnum"/> + <xsl:text> toToken(const QStringRef &value);
</xsl:text> + <xsl:text>static </xsl:text> + <xsl:value-of select="$tokenEnum"/> + <xsl:text> toToken(const QChar *data, int length);
</xsl:text> + <xsl:if test="xs:boolean(@hasToString)"> + <xsl:text>static QString toString(</xsl:text> + <xsl:value-of select="$tokenEnum"/> + <xsl:text> token);
</xsl:text> + </xsl:if> + + private: + <xsl:for-each select="$uniqueLengths"> + <xsl:sort select="."/> + <xsl:text>static inline </xsl:text> + <xsl:value-of select="$tokenEnum"/> + <xsl:text> classifier</xsl:text> + <xsl:value-of select="."/> + <xsl:text>(const QChar *data);
</xsl:text> + </xsl:for-each> + }; + + <xsl:text>inline </xsl:text> + <xsl:value-of select="@className"/>::<xsl:value-of select="$tokenEnum"/> + <xsl:text> </xsl:text> + <xsl:value-of select="@className"/>::toToken(const QString &value) + { + return toToken(value.constData(), value.length()); + } + + <xsl:text>inline </xsl:text> + <xsl:value-of select="@className"/>::<xsl:value-of select="$tokenEnum"/> + <xsl:text> </xsl:text> + <xsl:value-of select="@className"/>::toToken(const QStringRef &value) + { + return toToken(value.constData(), value.length()); + } + + <xsl:if test="@namespace"> + <xsl:text>}
</xsl:text> + </xsl:if> + + <xsl:text>
</xsl:text> + <xsl:text>QT_END_NAMESPACE
</xsl:text> + <xsl:text>
</xsl:text> + + <xsl:text>#endif
</xsl:text> + </xsl:result-document> + + <xsl:result-document method="text" href="{@sourceFile}"> + <xsl:value-of select="boilerplate/prolog"/> + + <xsl:value-of select="$warningGenerated"/> + + <xsl:text>
#include "</xsl:text> + <xsl:value-of select="@headerFile"/> + <xsl:text>"
</xsl:text> + <xsl:text>
</xsl:text> + <xsl:text>QT_BEGIN_NAMESPACE
</xsl:text> + + <xsl:if test="@namespace"> + <xsl:text>
</xsl:text> + <xsl:text>using namespace </xsl:text> + <xsl:value-of select="@namespace"/> + <xsl:text>;
</xsl:text> + </xsl:if> + + <xsl:text>
</xsl:text> + <xsl:variable name="tokens" select="tokens/token"/> + + <xsl:for-each select="$uniqueLengths"> + <xsl:sort select="."/> + <xsl:call-template name="generate-classifier"> + <xsl:with-param name="strings" select="$tokens[string-length() eq current()]"/> + </xsl:call-template> + </xsl:for-each> + + <xsl:value-of select="@className"/>::<xsl:value-of select="$tokenEnum"/> + <xsl:text> </xsl:text> + <xsl:value-of select="@className"/>::toToken(const QChar *data, int length) + { + switch(length) + { + <xsl:for-each select="$uniqueLengths"> + <xsl:sort data-type="number" select="."/> + case <xsl:value-of select="."/>: + return classifier<xsl:value-of select="."/>(data); + + </xsl:for-each> + default: + return <xsl:value-of select="@defaultToken"/>; + } + } + + <xsl:if test="xs:boolean(@hasToString)"> + QString <xsl:value-of select="@className"/>::toString(<xsl:value-of select="$tokenEnum"/> token) + { + const unsigned short *data = 0; + int length = 0; + + switch(token) + { + <xsl:for-each select="tokens/token"> + <xsl:sort select="local:tokenToEnumName(.)"/> + case <xsl:sequence select="local:tokenToEnumName(.)"/>: + {<!-- Without these braces, the code doesn't compile on MSVC 2008. --> + static const unsigned short staticallyStored<xsl:value-of select="local:tokenToEnumName(.)"/>[] = + { + <xsl:value-of separator=", " select="string-to-codepoints(.), 0"/> + }; + data = staticallyStored<xsl:value-of select="local:tokenToEnumName(.)"/>; + length = <xsl:value-of select="string-length(.)"/>; + break; + } + </xsl:for-each> + default: + /* It's either the default token, or an undefined enum + * value. We silence a compiler warning, and return the + * empty string. */ + ; + } + + union + { + const unsigned short *data; + const QChar *asQChar; + } converter; + converter.data = data; + + return QString::fromRawData(converter.asQChar, length); + } + </xsl:if> + + <xsl:text>
</xsl:text> + <xsl:text>QT_END_NAMESPACE
</xsl:text> + <xsl:text>
</xsl:text> + </xsl:result-document> + + </xsl:template> + + <xsl:template name="generate-classifier"> + <xsl:param name="strings" as="xs:string+"/> + + <xsl:value-of select="$className"/>::<xsl:value-of select="$tokenEnum"/> + <xsl:text> </xsl:text> + <xsl:value-of select="$className"/>::classifier<xsl:value-of select="."/>(const QChar *data) + + { + <xsl:sequence select="local:generateBranching($strings, 1, 1)"/> + + return <xsl:value-of select="$defaultToken"/>; + } + </xsl:template> + + <xsl:function name="local:generateBranching" ><!--as="xs:string+">--> + <xsl:param name="strings" as="xs:string+"/> + <xsl:param name="depth" as="xs:integer"/> + <xsl:param name="currentPos" as="xs:integer"/> + + <xsl:choose> + <xsl:when test="count($strings) eq 1"> + <xsl:variable name="remainingLength" as="xs:integer" select="(string-length($strings) - $currentPos) + 1"/> + <xsl:variable name="toMatch" as="xs:integer+" select="string-to-codepoints(substring($strings, $currentPos))"/> + + <xsl:if test="$remainingLength ne 0"> + <xsl:choose> + <xsl:when test="$remainingLength eq 1"> + if(data[<xsl:sequence select="$depth - 1"/>] == <xsl:sequence select="$toMatch"/>) + </xsl:when> + <xsl:when test="$remainingLength > 1"> + static const unsigned short string[] = + { + <xsl:value-of separator=", " select="string-to-codepoints(substring($strings, $currentPos))"/> + }; + if(memcmp(&data[<xsl:sequence select="$depth - 1"/>], &string, sizeof(QChar) * <xsl:value-of select="$remainingLength"/>) == 0) + </xsl:when> + </xsl:choose> + </xsl:if> + + return <xsl:value-of select="local:tokenToEnumName($strings)"/>; + </xsl:when> + <xsl:otherwise> + <xsl:for-each select="distinct-values(for $i in $strings return substring($i, $currentPos, 1))"> + <xsl:if test="position() > 1"> + <xsl:text>else </xsl:text> + </xsl:if> + + <xsl:text>if (data[</xsl:text> + <xsl:sequence select="string($depth - 1)"/> + <xsl:text>] == </xsl:text> + <xsl:sequence select="string-to-codepoints(.)"/> + <xsl:text>)
</xsl:text> + + { + <xsl:sequence select="local:generateBranching($strings[substring(., $currentPos, 1) eq current()], $depth + 1, $currentPos + 1)"/> + } + + </xsl:for-each> + </xsl:otherwise> + </xsl:choose> + </xsl:function> + + <xsl:function name="local:toCamelCase" as="xs:string"> + <xsl:param name="arg" as="xs:string"/> + + <xsl:sequence select="string-join((for $word in tokenize($arg,'[:-]+') + return concat(upper-case(substring($word,1,1)), + substring($word, 2))) ,'')"/> + + </xsl:function> + + <xsl:function name="local:tokenToEnumName" as="xs:string"> + <xsl:param name="string" as="xs:string"/> + + <xsl:variable name="token" select="$tokens[. eq $string]"/> + + <xsl:choose> + <xsl:when test="$token/@name"> + <xsl:sequence select="$token/@name"/> + </xsl:when> + <xsl:otherwise> + <!-- We take the token's string value, and coerces into a C++ + name. So get rid of invalid characters. Also do basic camel casing. --> + <xsl:variable name="normalized" select="translate($string, 'ABCDEFGHIJKLMNOPQRSTYXZabcdefghijklmnopqrstyxz1234567890_', 'ABCDEFGHIJKLMNOPQRSTYXZabcdefghijklmnopqrstyxz1234567890_')"/> + <xsl:value-of select="local:toCamelCase($normalized)"/> + </xsl:otherwise> + </xsl:choose> + + </xsl:function> + +</xsl:stylesheet> + +<!-- +vim: et:ts=4:sw=4:sts=4 +--> |