summaryrefslogtreecommitdiff
path: root/test/transform/test-to-c.xsl
diff options
context:
space:
mode:
Diffstat (limited to 'test/transform/test-to-c.xsl')
-rw-r--r--test/transform/test-to-c.xsl448
1 files changed, 448 insertions, 0 deletions
diff --git a/test/transform/test-to-c.xsl b/test/transform/test-to-c.xsl
new file mode 100644
index 0000000..469633b
--- /dev/null
+++ b/test/transform/test-to-c.xsl
@@ -0,0 +1,448 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!--
+This transform generates C source code from a language independent
+test representation.
+-->
+
+<xsl:stylesheet version="1.0"
+ xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ xmlns:str="http://exslt.org/strings"><!-- TODO: exslt not currently used -->
+ <xsl:param name="interfaces-docname">dom1-interfaces.xml</xsl:param>
+ <xsl:param name="target-uri-base">http://www.w3.org/2001/DOM-Test-Suite/tests/Level-1/</xsl:param>
+ <xsl:output method="text" encoding="UTF-8"/>
+ <xsl:variable name="domspec" select="document($interfaces-docname)"/>
+
+
+<!-- swallow any text which we don't understand -->
+<xsl:template match="text()" mode="body"/>
+
+<!--
+for anything that doesn't match another template,
+we expect this the element to be found in the library located
+at $interfaces-docname.
+
+This should either be a <method> or <attribute>. If it is neither,
+we generate an <xsl:message> reporting that the element is not known.
+-->
+<xsl:template match="*" mode="body">
+ <!-- the element name matches by this template -->
+ <xsl:variable name="feature" select="local-name(.)"/>
+ <xsl:variable name="interface" select="@interface"/>
+
+ <!--
+ Try to find a method having the @name of $feature.
+ If $interface is defined, make sure search for
+ a match on that interface in the $domspec document.
+ -->
+ <xsl:variable name="method" select="$domspec/library/interface[not($interface) or @name = $interface]/method[@name = $feature]"/>
+ <xsl:choose>
+ <xsl:when test="$method">
+ <xsl:call-template name="produce-method">
+ <xsl:with-param name="method" select="$method"/>
+ <!-- TODO: vardefs not yet done <xsl:with-param name="vardefs" select="$vardefs"/>-->
+ </xsl:call-template>
+ </xsl:when>
+ <xsl:otherwise>
+ <!--
+ Try to find an attribute having the name of $feature.
+ Again, if $interface is defined, restrict the search to
+ that interface
+ -->
+ <xsl:variable name="attribute" select="$domspec/library/interface[not($interface) or @name = $interface]/attribute[@name = $feature]"/>
+ <xsl:choose>
+ <xsl:when test="$attribute">
+ <xsl:call-template name="produce-attribute">
+ <!-- TODO: vardefs not yet done <xsl:with-param name="vardefs" select="$vardefs"/> -->
+ </xsl:call-template>
+ </xsl:when>
+
+ <xsl:otherwise>
+ <xsl:message>Unrecognized element <xsl:value-of select="local-name(.)"/></xsl:message>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:otherwise>
+ </xsl:choose>
+</xsl:template>
+
+<xsl:template match="/">
+ <xsl:apply-templates/>
+</xsl:template>
+
+<xsl:template match="*[local-name() = 'test']">
+<xsl:text>#include &lt;string.h&gt;
+
+#include &lt;dom/dom.h&gt;
+#include "testutils.h"
+
+</xsl:text>
+
+ <xsl:apply-templates select="*[local-name() = 'metadata']"/>
+<xsl:text>
+int main(int argc, char **argv)
+{
+ dom_exception err;
+</xsl:text>
+<xsl:apply-templates mode="body"/>
+<xsl:text>
+ return 0;
+}
+</xsl:text>
+</xsl:template>
+
+<xsl:template match="comment()[contains(., 'Copyright')]">
+/*
+This source file was generated by test-to-c.xsl
+and is a derived work from the source document.
+The source document contained the following notice:
+
+<xsl:value-of select="."/>
+*/
+</xsl:template>
+
+<xsl:template match="*[local-name() = 'metadata']">
+<xsl:text>/**
+</xsl:text>
+ <xsl:call-template name="emit-description">
+ <xsl:with-param name="description" select="translate(*[local-name() = 'description'], '&#9;', ' ')"/>
+ </xsl:call-template>
+ <xsl:text> */</xsl:text>
+</xsl:template>
+
+<!-- swallowing templates in body mode -->
+<xsl:template match="*[local-name() = 'metadata']" mode="body"/>
+
+<xsl:template match="*[local-name() = 'load']" mode="body">
+ <!--
+ TODO: need to handle the case where we load more than one testObject.
+ append a counter to the variable name?
+ -->
+ <xsl:text>
+ TestObject *testObject = test_object_create(argc, argv, "</xsl:text><xsl:value-of select="@href"/><xsl:text>.xml", false);
+ assert(testObject != NULL);
+
+ </xsl:text><xsl:value-of select="@var"/><xsl:text> = test_object_get_doc(testObject);
+ assert(</xsl:text><xsl:value-of select="@var"/><xsl:text> != NULL);
+</xsl:text>
+</xsl:template>
+
+<!--
+not sure what <contentType> is used for,
+but it's implemented in subclasses of DOMTestDocumentBuilderFactory.getContentType()
+-->
+<xsl:template match="*[local-name() = 'contentType']" mode="body">
+ <xsl:text>strcmp(test_object_get_mimetype(testObject), "</xsl:text><xsl:value-of select="@type"/><xsl:text>") == 0</xsl:text>
+</xsl:template>
+
+<!--
+================================
+Language construct templates
+================================
+-->
+
+<xsl:template match="*[local-name() = 'var']" mode="body">
+<xsl:text> struct </xsl:text><xsl:call-template name="convert_var_type"> <xsl:with-param name="var_type" select="@type"/>
+</xsl:call-template> *<xsl:value-of select="@name"/>;
+</xsl:template>
+
+<xsl:template match="*[local-name() = 'if']" mode="body">
+<xsl:text>
+ if (</xsl:text><xsl:apply-templates select="*[1]" mode="body"/><xsl:text>) {
+</xsl:text>
+<xsl:apply-templates select="*[position() &gt; 1 and local-name() != 'else']" mode="body"/>
+<xsl:text> }</xsl:text>
+<xsl:for-each select="*[local-name() = 'else']">
+ <xsl:text> else {
+</xsl:text>
+ <xsl:apply-templates mode="body"/>
+ <xsl:text> }</xsl:text>
+</xsl:for-each>
+<xsl:text>
+</xsl:text>
+</xsl:template>
+
+<!--
+================================
+DOM templates
+================================
+-->
+
+<xsl:template name="produce-method">
+ <xsl:variable name="methodName" select="local-name(.)"/>
+ <!-- if interface is specified -->
+ <xsl:choose>
+ <xsl:when test="@interface">
+ <xsl:variable name="interface" select="@interface"/>
+ <xsl:call-template name="produce-specific-method">
+ <xsl:with-param name="method" select="$domspec/library/interface[@name = $interface]/method[@name = $methodName]"/>
+ <!--<xsl:with-param name="vardefs" select="$vardefs"/>-->
+ </xsl:call-template>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:variable name="methods" select="$domspec/library/interface/method[@name = $methodName]"/>
+ <xsl:call-template name="produce-specific-method">
+ <xsl:with-param name="method" select="$methods[1]"/>
+ <!--<xsl:with-param name="vardefs" select="$vardefs"/>-->
+ </xsl:call-template>
+ </xsl:otherwise>
+ </xsl:choose>
+</xsl:template>
+
+<xsl:template name="produce-specific-method">
+ <xsl:param name="method"/>
+ <xsl:variable name="current" select="."/>
+ <xsl:variable name="obj" select="@obj"/>
+ <!--<xsl:variable name="var" select="@var"/>-->
+
+ <xsl:text> </xsl:text>
+ <xsl:call-template name="convert_method_name">
+ <xsl:with-param name="method_target"><xsl:value-of select="//*[local-name() = 'var' and @name = $obj]/@type"/></xsl:with-param>
+ <xsl:with-param name="method_name"><xsl:value-of select="$method/@name"/></xsl:with-param>
+ </xsl:call-template>
+ <xsl:text>(</xsl:text><xsl:value-of select="@obj"/>
+ <xsl:for-each select="$method/parameters/param">
+ <xsl:variable name="paramDef" select="."/>
+ <xsl:text>, </xsl:text><xsl:value-of select="$current/@*[name() = $paramDef/@name]"/>
+ </xsl:for-each>
+ <xsl:if test="@var">
+ <xsl:text>, &amp;</xsl:text><xsl:value-of select="@var"/>
+ </xsl:if>
+ <xsl:text>);</xsl:text>
+</xsl:template>
+
+<xsl:template name="produce-attribute">
+ <!-- <xsl:param name="vardefs"/> -->
+ <xsl:variable name="attribName" select="local-name(.)"/>
+ <xsl:choose>
+ <!-- if interface is specified -->
+ <xsl:when test="@interface">
+ <xsl:variable name="interface" select="@interface"/>
+ <xsl:call-template name="produce-specific-attribute">
+ <xsl:with-param name="attribute" select="$domspec/library/interface[@name = $interface]/attribute[@name = $attribName]"/>
+ <!-- <xsl:with-param name="vardefs" select="$vardefs"/> -->
+ </xsl:call-template>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:call-template name="produce-specific-attribute">
+ <xsl:with-param name="attribute" select="$domspec/library/interface/attribute[@name = $attribName]"/>
+ <!-- <xsl:with-param name="vardefs" select="$vardefs"/> -->
+ </xsl:call-template>
+ </xsl:otherwise>
+ </xsl:choose>
+</xsl:template>
+
+<xsl:template name="produce-specific-attribute">
+ <!-- <xsl:param name="vardefs"/> -->
+ <xsl:param name="attribute"/>
+ <xsl:variable name="obj" select="@obj"/>
+ <xsl:variable name="value" select="@value"/>
+ <xsl:variable name="obj_type" select="//*[local-name() = 'var' and @name = $obj]/@type"/>
+ <xsl:variable name="interface_type" select="$domspec/library/interface[attribute = $attribute]/@name"/>
+ <!-- check if attribute name starts with is -->
+ <xsl:if test="@value">
+ <!-- TODO: set attribute to a value -->
+ </xsl:if>
+ <!--
+ call an attribute accessor. this takes the form
+ err = dom_<objecttype>_get_<attributename>(<objectstruct>, &<targetattributestruct>);
+ -->
+ <xsl:if test="@var">
+ <xsl:text>
+ err = </xsl:text>
+ <xsl:call-template name="convert_var_type">
+ <xsl:with-param name="var_type"><xsl:value-of select="$interface_type"/></xsl:with-param>
+ </xsl:call-template>
+ <xsl:text>_get_</xsl:text>
+ <xsl:call-template name="convert_attribute_name">
+ <xsl:with-param name="attribute_name"><xsl:value-of select="$attribute/@name"/></xsl:with-param>
+ </xsl:call-template>
+ <xsl:text>(</xsl:text>
+ <!-- cast to target interface if this is different from the type of the variable @obj -->
+ <xsl:if test="$obj_type != $interface_type">
+ <xsl:text>(struct </xsl:text>
+ <xsl:call-template name="convert_var_type">
+ <xsl:with-param name="var_type"><xsl:value-of select="$interface_type"/></xsl:with-param>
+ </xsl:call-template>
+ <xsl:text> *) </xsl:text>
+ </xsl:if>
+ <!-- TODO: cast to the type expected by the interface if necessary -->
+ <xsl:value-of select="@obj"/><xsl:text>, &amp;</xsl:text><xsl:value-of select="@var"/>
+ <xsl:text>);
+ assert(err == DOM_NO_ERR);
+</xsl:text>
+
+ </xsl:if>
+</xsl:template>
+
+
+<!--
+================================
+Assert templates
+================================
+-->
+
+<xsl:template match="*[local-name() = 'assertNotNull']" mode="body">
+ <!-- TODO: what does the @id string do, and do we need it here? -->
+ <xsl:text>
+ assert(</xsl:text><xsl:value-of select="@actual"/><xsl:text> != NULL);
+</xsl:text>
+</xsl:template>
+
+<xsl:template match="*[local-name() = 'assertNull']" mode="body">
+ <!-- TODO: what does the @id string do, and do we need it here? -->
+ <xsl:text>
+ assert(</xsl:text><xsl:value-of select="@actual"/><xsl:text> == NULL);
+ </xsl:text>
+</xsl:template>
+
+<xsl:template match="*[local-name() = 'assertEquals']" mode="body">
+ <xsl:variable name="actual" select="@actual"/>
+ <xsl:variable name="var_type" select="//*[local-name() = 'var' and @name = $actual]/@type"/>
+
+ <!-- implement equality test depending upon $var_type -->
+ <xsl:choose>
+ <xsl:when test="$var_type = 'DOMString'">
+
+ <xsl:text>
+ /* begin assertEquals */
+ struct dom_string *match;
+
+ err = dom_string_create_from_const_ptr(</xsl:text>
+ <!-- use the first variable we find that's of @type 'Document' -->
+ <xsl:value-of select="//*[local-name() = 'var' and @type = 'Document'][1]/@name"/>
+ <xsl:text>, (uint8_t *) </xsl:text><xsl:value-of select="@expected"/><xsl:text>,
+ SLEN(</xsl:text><xsl:value-of select="@expected"/><xsl:text>), &amp;match);
+ assert(err == DOM_NO_ERR); <!-- TODO: pull this line out, since it's reused everywhere -->
+
+ assert(</xsl:text>
+ <xsl:choose>
+ <xsl:when test="@ignoreCase = 'true'">
+ <xsl:text>dom_string_icmp</xsl:text>
+ </xsl:when>
+ <xsl:when test="@ignoreCase = 'auto'">
+ <!--
+ TODO: implement auto case comparison (see java's DOMTestCase.assertEqualsAutoCase()
+ -->
+ <xsl:message>&lt;assertEquals ignoreCase='auto'&gt; not supported</xsl:message>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:text>dom_string_cmp</xsl:text>
+ </xsl:otherwise>
+ </xsl:choose>
+ <xsl:text>(</xsl:text><xsl:value-of select="@actual"/><xsl:text>, match) == 0);
+</xsl:text>
+ </xsl:when>
+ <xsl:when test="$var_type = 'int'">
+ <xsl:text>
+ assert(</xsl:text><xsl:value-of select="@actual"/><xsl:text> == </xsl:text><xsl:value-of select="@expected"/><xsl:text>);</xsl:text>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:message terminate="no">Warning in assertEquals template: don't know how to compare variable type '<xsl:value-of select="$var_type"/>'</xsl:message>
+ </xsl:otherwise>
+ </xsl:choose>
+ <xsl:text>
+ /* end assertEquals */
+</xsl:text>
+</xsl:template>
+
+<!-- helper templates -->
+
+<xsl:template name="convert_var_type">
+<!-- TODO: convert certain types, e.g. from DocumentType to dom_document_type -->
+ <xsl:param name="var_type"/>
+ <xsl:choose>
+ <xsl:when test="$var_type = 'Document'">
+ <xsl:text>dom_document</xsl:text>
+ </xsl:when>
+ <xsl:when test="$var_type = 'DocumentType'">
+ <xsl:text>dom_document_type</xsl:text>
+ </xsl:when>
+ <xsl:when test="$var_type = 'DOMString'">
+ <xsl:text>dom_string</xsl:text>
+ </xsl:when>
+ <xsl:when test="$var_type = 'Element'">
+ <xsl:text>dom_element</xsl:text>
+ </xsl:when>
+ <xsl:when test="$var_type = 'Node'">
+ <xsl:text>dom_node</xsl:text>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="$var_type"/>
+ </xsl:otherwise>
+ </xsl:choose>
+</xsl:template>
+
+<xsl:template name="convert_attribute_name">
+ <xsl:param name="attribute_name"/>
+ <xsl:message><xsl:value-of select="$attribute_name"/></xsl:message>
+ <xsl:choose>
+ <xsl:when test="$attribute_name = 'nodeName'">
+ <xsl:text>node_name</xsl:text>
+ </xsl:when>
+ <xsl:when test="$attribute_name = 'nodeValue'">
+ <xsl:text>node_value</xsl:text>
+ </xsl:when>
+ <xsl:when test="$attribute_name = 'nodeType'">
+ <xsl:text>node_type</xsl:text>
+ </xsl:when>
+ <xsl:otherwise>
+ <!-- assume no conversion is needed -->
+ <xsl:value-of select="$attribute_name"/>
+ </xsl:otherwise>
+ </xsl:choose>
+</xsl:template>
+
+<!--
+Method name is in the form dom_<type>_<methodName>
+For example, dom_document_create_element
+-->
+<xsl:template name="convert_method_name">
+ <xsl:param name="method_target"/>
+ <xsl:param name="method_name"/>
+ <xsl:message><xsl:value-of select="$method_name"/></xsl:message>
+ <xsl:call-template name="convert_var_type">
+ <xsl:with-param name="var_type"><xsl:value-of select="$method_target"/></xsl:with-param>
+ </xsl:call-template>
+ <xsl:text>_</xsl:text>
+ <xsl:choose>
+ <xsl:when test="$method_name = 'createElement'">
+ <xsl:text>create_element</xsl:text>
+ </xsl:when>
+ <xsl:otherwise>
+ <!-- assume no conversion is needed -->
+ <xsl:value-of select="$method_name"/>
+ </xsl:otherwise>
+ </xsl:choose>
+</xsl:template>
+
+<!--
+stolen from test-to-java.xsl
+Prepends every line with asterisks, suitable for use in a block comment
+-->
+<xsl:template name="emit-description">
+ <xsl:param name="description"/>
+ <xsl:choose>
+ <xsl:when test="contains($description, '&#xA;')">
+ <xsl:variable name="preceding" select="substring-before($description, '&#xA;')"/>
+ <xsl:if test="string-length($preceding) &gt; 0">
+ <xsl:text> * </xsl:text>
+ <xsl:value-of select="substring-before($description, '&#xA;')"/>
+<xsl:text>
+</xsl:text>
+ </xsl:if>
+ <xsl:variable name="following" select="substring-after($description, '&#xA;')"/>
+ <xsl:if test="string-length($following) &gt; 0">
+ <xsl:call-template name="emit-description">
+ <xsl:with-param name="description" select="substring-after($description, '&#xA;')"/>
+ </xsl:call-template>
+ </xsl:if>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:text> * </xsl:text>
+ <xsl:value-of select="$description"/>
+ <xsl:text>
+ </xsl:text>
+ </xsl:otherwise>
+ </xsl:choose>
+</xsl:template>
+
+</xsl:stylesheet>