source: trunk/src/xmlpatterns/qtokenautomaton/qautomaton2cpp.xsl@ 792

Last change on this file since 792 was 2, checked in by Dmitry A. Kuminov, 16 years ago

Initially imported qt-all-opensource-src-4.5.1 from Trolltech.

File size: 12.6 KB
Line 
1<?xml version='1.0' encoding="UTF-8"?>
2<xsl:stylesheet version="2.0"
3 xml:lang="en"
4 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
5 xmlns:local="http://www.w3.org/2005/xquery-local-functions"
6 xmlns:xs="http://www.w3.org/2001/XMLSchema">
7
8 <xsl:variable name="className" as="xs:string" select="tokenAutomaton/@className"/>
9 <xsl:variable name="defaultToken" as="xs:string" select="tokenAutomaton/@defaultToken"/>
10 <xsl:variable name="tokens" as="element(token)+" select="tokenAutomaton/tokens/token"/>
11 <xsl:variable name="tokenEnum" as="xs:string" select="tokenAutomaton/@tokenEnum"/>
12
13 <xsl:variable name="warningGenerated" as="xs:string">/* NOTE: This file is AUTO GENERATED by qautomaton2cpp.xsl. */&#xA;</xsl:variable>
14
15 <xsl:template match="tokenAutomaton">
16
17 <xsl:variable name="uniqueLengths" as="xs:integer+" select="distinct-values(tokens/token/string-length())"/>
18
19 <xsl:result-document method="text" href="{@headerFile}">
20
21 <xsl:variable name="includeGuardName" select="string(@includeGuardName)"/>
22
23 <xsl:value-of select="boilerplate/prolog"/>
24
25 <xsl:value-of select="$warningGenerated"/>
26
27 <xsl:text>&#xA;#ifndef </xsl:text>
28 <xsl:value-of select="$includeGuardName"/>
29 <xsl:text>&#xA;#define </xsl:text>
30 <xsl:value-of select="$includeGuardName"/>
31 <xsl:text>&#xA;&#xA;</xsl:text>
32
33 <xsl:text>#include &lt;QtCore/QString>&#xA;</xsl:text>
34 <xsl:text>&#xA;</xsl:text>
35 <xsl:text>QT_BEGIN_NAMESPACE&#xA;</xsl:text>
36 <xsl:text>&#xA;</xsl:text>
37
38 <xsl:if test="@namespace">
39 <xsl:text>namespace </xsl:text>
40 <xsl:value-of select="@namespace"/>
41 {
42 </xsl:if>
43
44 <xsl:text>class </xsl:text>
45 <xsl:value-of select="@className"/>
46 {
47 <xsl:value-of select="@scope"/>:
48 <xsl:text>enum </xsl:text>
49 <xsl:value-of select="$tokenEnum"/>
50 <xsl:text>&#xA;</xsl:text>
51 {
52 <xsl:value-of separator=",&#xA;">
53 <xsl:sequence select="@defaultToken"/>
54 <xsl:perform-sort select="tokens/token/local:tokenToEnumName(.)">
55 <xsl:sort select="."/>
56 </xsl:perform-sort>
57 </xsl:value-of>
58 };
59
60 <xsl:text>static inline </xsl:text>
61 <xsl:value-of select="$tokenEnum"/>
62 <xsl:text> toToken(const QString &amp;value);&#xA;</xsl:text>
63 <xsl:text>static inline </xsl:text>
64 <xsl:value-of select="$tokenEnum"/>
65 <xsl:text> toToken(const QStringRef &amp;value);&#xA;</xsl:text>
66 <xsl:text>static </xsl:text>
67 <xsl:value-of select="$tokenEnum"/>
68 <xsl:text> toToken(const QChar *data, int length);&#xA;</xsl:text>
69 <xsl:if test="xs:boolean(@hasToString)">
70 <xsl:text>static QString toString(</xsl:text>
71 <xsl:value-of select="$tokenEnum"/>
72 <xsl:text> token);&#xA;</xsl:text>
73 </xsl:if>
74
75 private:
76 <xsl:for-each select="$uniqueLengths">
77 <xsl:sort select="."/>
78 <xsl:text>static inline </xsl:text>
79 <xsl:value-of select="$tokenEnum"/>
80 <xsl:text> classifier</xsl:text>
81 <xsl:value-of select="."/>
82 <xsl:text>(const QChar *data);&#xA;</xsl:text>
83 </xsl:for-each>
84 };
85
86 <xsl:text>inline </xsl:text>
87 <xsl:value-of select="@className"/>::<xsl:value-of select="$tokenEnum"/>
88 <xsl:text> </xsl:text>
89 <xsl:value-of select="@className"/>::toToken(const QString &amp;value)
90 {
91 return toToken(value.constData(), value.length());
92 }
93
94 <xsl:text>inline </xsl:text>
95 <xsl:value-of select="@className"/>::<xsl:value-of select="$tokenEnum"/>
96 <xsl:text> </xsl:text>
97 <xsl:value-of select="@className"/>::toToken(const QStringRef &amp;value)
98 {
99 return toToken(value.constData(), value.length());
100 }
101
102 <xsl:if test="@namespace">
103 <xsl:text>}&#xA;</xsl:text>
104 </xsl:if>
105
106 <xsl:text>&#xA;</xsl:text>
107 <xsl:text>QT_END_NAMESPACE&#xA;</xsl:text>
108 <xsl:text>&#xA;</xsl:text>
109
110 <xsl:text>#endif&#xA;</xsl:text>
111 </xsl:result-document>
112
113 <xsl:result-document method="text" href="{@sourceFile}">
114 <xsl:value-of select="boilerplate/prolog"/>
115
116 <xsl:value-of select="$warningGenerated"/>
117
118 <xsl:text>&#xA;#include "</xsl:text>
119 <xsl:value-of select="@headerFile"/>
120 <xsl:text>"&#xA;</xsl:text>
121 <xsl:text>&#xA;</xsl:text>
122 <xsl:text>QT_BEGIN_NAMESPACE&#xA;</xsl:text>
123
124 <xsl:if test="@namespace">
125 <xsl:text>&#xA;</xsl:text>
126 <xsl:text>using namespace </xsl:text>
127 <xsl:value-of select="@namespace"/>
128 <xsl:text>;&#xA;</xsl:text>
129 </xsl:if>
130
131 <xsl:text>&#xA;</xsl:text>
132 <xsl:variable name="tokens" select="tokens/token"/>
133
134 <xsl:for-each select="$uniqueLengths">
135 <xsl:sort select="."/>
136 <xsl:call-template name="generate-classifier">
137 <xsl:with-param name="strings" select="$tokens[string-length() eq current()]"/>
138 </xsl:call-template>
139 </xsl:for-each>
140
141 <xsl:value-of select="@className"/>::<xsl:value-of select="$tokenEnum"/>
142 <xsl:text> </xsl:text>
143 <xsl:value-of select="@className"/>::toToken(const QChar *data, int length)
144 {
145 switch(length)
146 {
147 <xsl:for-each select="$uniqueLengths">
148 <xsl:sort data-type="number" select="."/>
149 case <xsl:value-of select="."/>:
150 return classifier<xsl:value-of select="."/>(data);
151
152 </xsl:for-each>
153 default:
154 return <xsl:value-of select="@defaultToken"/>;
155 }
156 }
157
158 <xsl:if test="xs:boolean(@hasToString)">
159 QString <xsl:value-of select="@className"/>::toString(<xsl:value-of select="$tokenEnum"/> token)
160 {
161 const unsigned short *data = 0;
162 int length = 0;
163
164 switch(token)
165 {
166 <xsl:for-each select="tokens/token">
167 <xsl:sort select="local:tokenToEnumName(.)"/>
168 case <xsl:sequence select="local:tokenToEnumName(.)"/>:
169 {<!-- Without these braces, the code doesn't compile on MSVC 2008. -->
170 static const unsigned short staticallyStored<xsl:value-of select="local:tokenToEnumName(.)"/>[] =
171 {
172 <xsl:value-of separator=", " select="string-to-codepoints(.), 0"/>
173 };
174 data = staticallyStored<xsl:value-of select="local:tokenToEnumName(.)"/>;
175 length = <xsl:value-of select="string-length(.)"/>;
176 break;
177 }
178 </xsl:for-each>
179 default:
180 /* It's either the default token, or an undefined enum
181 * value. We silence a compiler warning, and return the
182 * empty string. */
183 ;
184 }
185
186 union
187 {
188 const unsigned short *data;
189 const QChar *asQChar;
190 } converter;
191 converter.data = data;
192
193 return QString::fromRawData(converter.asQChar, length);
194 }
195 </xsl:if>
196
197 <xsl:text>&#xA;</xsl:text>
198 <xsl:text>QT_END_NAMESPACE&#xA;</xsl:text>
199 <xsl:text>&#xA;</xsl:text>
200 </xsl:result-document>
201
202 </xsl:template>
203
204 <xsl:template name="generate-classifier">
205 <xsl:param name="strings" as="xs:string+"/>
206
207 <xsl:value-of select="$className"/>::<xsl:value-of select="$tokenEnum"/>
208 <xsl:text> </xsl:text>
209 <xsl:value-of select="$className"/>::classifier<xsl:value-of select="."/>(const QChar *data)
210
211 {
212 <xsl:sequence select="local:generateBranching($strings, 1, 1)"/>
213
214 return <xsl:value-of select="$defaultToken"/>;
215 }
216 </xsl:template>
217
218 <xsl:function name="local:generateBranching" ><!--as="xs:string+">-->
219 <xsl:param name="strings" as="xs:string+"/>
220 <xsl:param name="depth" as="xs:integer"/>
221 <xsl:param name="currentPos" as="xs:integer"/>
222
223 <xsl:choose>
224 <xsl:when test="count($strings) eq 1">
225 <xsl:variable name="remainingLength" as="xs:integer" select="(string-length($strings) - $currentPos) + 1"/>
226 <xsl:variable name="toMatch" as="xs:integer+" select="string-to-codepoints(substring($strings, $currentPos))"/>
227
228 <xsl:if test="$remainingLength ne 0">
229 <xsl:choose>
230 <xsl:when test="$remainingLength eq 1">
231 if(data[<xsl:sequence select="$depth - 1"/>] == <xsl:sequence select="$toMatch"/>)
232 </xsl:when>
233 <xsl:when test="$remainingLength &gt; 1">
234 static const unsigned short string[] =
235 {
236 <xsl:value-of separator=", " select="string-to-codepoints(substring($strings, $currentPos))"/>
237 };
238 if(memcmp(&amp;data[<xsl:sequence select="$depth - 1"/>], &amp;string, sizeof(QChar) * <xsl:value-of select="$remainingLength"/>) == 0)
239 </xsl:when>
240 </xsl:choose>
241 </xsl:if>
242
243 return <xsl:value-of select="local:tokenToEnumName($strings)"/>;
244 </xsl:when>
245 <xsl:otherwise>
246 <xsl:for-each select="distinct-values(for $i in $strings return substring($i, $currentPos, 1))">
247 <xsl:if test="position() &gt; 1">
248 <xsl:text>else </xsl:text>
249 </xsl:if>
250
251 <xsl:text>if (data[</xsl:text>
252 <xsl:sequence select="string($depth - 1)"/>
253 <xsl:text>] == </xsl:text>
254 <xsl:sequence select="string-to-codepoints(.)"/>
255 <xsl:text>)&#xA;</xsl:text>
256
257 {
258 <xsl:sequence select="local:generateBranching($strings[substring(., $currentPos, 1) eq current()], $depth + 1, $currentPos + 1)"/>
259 }
260
261 </xsl:for-each>
262 </xsl:otherwise>
263 </xsl:choose>
264 </xsl:function>
265
266 <xsl:function name="local:toCamelCase" as="xs:string">
267 <xsl:param name="arg" as="xs:string"/>
268
269 <xsl:sequence select="string-join((for $word in tokenize($arg,'[:-]+')
270 return concat(upper-case(substring($word,1,1)),
271 substring($word, 2))) ,'')"/>
272
273 </xsl:function>
274
275 <xsl:function name="local:tokenToEnumName" as="xs:string">
276 <xsl:param name="string" as="xs:string"/>
277
278 <xsl:variable name="token" select="$tokens[. eq $string]"/>
279
280 <xsl:choose>
281 <xsl:when test="$token/@name">
282 <xsl:sequence select="$token/@name"/>
283 </xsl:when>
284 <xsl:otherwise>
285 <!-- We take the token's string value, and coerces into a C++
286 name. So get rid of invalid characters. Also do basic camel casing. -->
287 <xsl:variable name="normalized" select="translate($string, 'ABCDEFGHIJKLMNOPQRSTYXZabcdefghijklmnopqrstyxz1234567890_', 'ABCDEFGHIJKLMNOPQRSTYXZabcdefghijklmnopqrstyxz1234567890_')"/>
288 <xsl:value-of select="local:toCamelCase($normalized)"/>
289 </xsl:otherwise>
290 </xsl:choose>
291
292 </xsl:function>
293
294</xsl:stylesheet>
295
296<!--
297vim: et:ts=4:sw=4:sts=4
298-->
Note: See TracBrowser for help on using the repository browser.