* A template to generate a MS IDL compatible interface definition file * from the generic interface definition expressed in XML. Copyright (C) 2006-2007 innotek GmbH This file is part of VirtualBox Open Source Edition (OSE), as you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, in version 2 as it comes in the "COPYING" file of the VirtualBox OSE distribution. VirtualBox OSE is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY of any kind. <
xsl:
output method="text"/>
<
xsl:
strip-
space elements="*"/>
///////////////////////////////////////////////////////////////////////////// * capitalizes the first letter <
xsl:
template name="capitalize">
<
xsl:
param name="str" select="."/>
translate(substring($str,1,1),'abcdefghijklmnopqrstuvwxyz','ABCDEFGHIJKLMNOPQRSTUVWXYZ'), * uncapitalizes the first letter only if the second one is not capital * otherwise leaves the string unchanged <
xsl:
template name="uncapitalize">
<
xsl:
param name="str" select="."/>
<
xsl:
when test="not(contains('ABCDEFGHIJKLMNOPQRSTUVWXYZ', substring($str,2,1)))">
translate(substring($str,1,1),'ABCDEFGHIJKLMNOPQRSTUVWXYZ','abcdefghijklmnopqrstuvwxyz'), <
xsl:
value-
of select="string($str)"/>
///////////////////////////////////////////////////////////////////////////// <
xsl:
template match="/idl">
* This IDL is automatically generated from the generic interface definition
* using MS IDL (MIDL) syntax.
<
xsl:
text>
</
xsl:
text>
<
xsl:
text>import "
unknwn.idl";

</
xsl:
text>
* ignore all |if|s except those for MIDL target <
xsl:
template match="if">
<
xsl:
if test="@target='midl'">
<
xsl:
template match="if" mode="forward">
<
xsl:
if test="@target='midl'">
<
xsl:
apply-
templates mode="forward"/>
<
xsl:
template match="cpp">
<
xsl:
text>cpp_quote("</
xsl:
text>
<
xsl:
value-
of select="@line"/>
<
xsl:
text>")

</
xsl:
text>
* #if statement (@if attribute) <
xsl:
template match="@if" mode="begin">
<
xsl:
text>#if </
xsl:
text>
<
xsl:
value-
of select="."/>
<
xsl:
text>
</
xsl:
text>
<
xsl:
template match="@if" mode="end">
<
xsl:
text>#endif
</
xsl:
text>
<
xsl:
template match="module">[
uuid(<
xsl:
value-
of select="@uuid"/>),
version(<
xsl:
value-
of select="@version"/>),
helpstring("<
xsl:
value-
of select="@desc"/>")
<
xsl:
text>library </
xsl:
text>
<
xsl:
value-
of select="@name"/>
<
xsl:
text>
{
</
xsl:
text>
<
xsl:
text>
importlib("
stdole2.tlb");

</
xsl:
text>
<!-- forward declarations --> <
xsl:
apply-
templates select="if | interface | collection | enumerator" mode="forward"/>
<
xsl:
text>
</
xsl:
text>
<!-- all enums go first --> <
xsl:
apply-
templates select="enum | if/enum"/>
<!-- everything else but enums --> <
xsl:
apply-
templates select="*[not(self::enum) and not(self::if[enum])]"/>
<
xsl:
text>}; /* library </
xsl:
text>
<
xsl:
value-
of select="@name"/>
<
xsl:
text> */

</
xsl:
text>
<
xsl:
template match="interface | collection | enumerator" mode="forward">
<
xsl:
text>interface </
xsl:
text>
<
xsl:
value-
of select="@name"/>
<
xsl:
text>;
</
xsl:
text>
<
xsl:
template match="interface">[
uuid(<
xsl:
value-
of select="@uuid"/>),
<
xsl:
text>interface </
xsl:
text>
<
xsl:
value-
of select="@name"/>
<
xsl:
when test="@extends='$unknown'">IUnknown</
xsl:
when>
<
xsl:
when test="@extends='$dispatched'">IDispatch</
xsl:
when>
<
xsl:
when test="@extends='$errorinfo'">IErrorInfo</
xsl:
when>
<
xsl:
otherwise><
xsl:
value-
of select="@extends"/></
xsl:
otherwise>
<
xsl:
text>
{
</
xsl:
text>
<!-- attributes (properties) --> <
xsl:
apply-
templates select="attribute"/>
<
xsl:
apply-
templates select="method"/>
<!-- 'if' enclosed elements, unsorted --> <
xsl:
apply-
templates select="if"/>
<
xsl:
text>}; /* interface </
xsl:
text>
<
xsl:
value-
of select="@name"/>
<
xsl:
text> */

</
xsl:
text>
<
xsl:
template match="interface//attribute | collection//attribute">
<
xsl:
apply-
templates select="@if" mode="begin"/>
<
xsl:
text> [propget] HRESULT </
xsl:
text>
<
xsl:
call-
template name="capitalize">
<
xsl:
with-
param name="str" select="@name"/>
<
xsl:
text> ([out, retval] </
xsl:
text>
<
xsl:
apply-
templates select="@type"/>
<
xsl:
text> * a</
xsl:
text>
<
xsl:
call-
template name="capitalize">
<
xsl:
with-
param name="str" select="@name"/>
<
xsl:
text>);
</
xsl:
text>
<
xsl:
if test="not(@readonly='yes')">
<
xsl:
text> [propput] HRESULT </
xsl:
text>
<
xsl:
call-
template name="capitalize">
<
xsl:
with-
param name="str" select="@name"/>
<
xsl:
text> ([in] </
xsl:
text>
<
xsl:
apply-
templates select="@type"/>
<
xsl:
call-
template name="capitalize">
<
xsl:
with-
param name="str" select="@name"/>
<
xsl:
text>);
</
xsl:
text>
<
xsl:
apply-
templates select="@if" mode="end"/>
<
xsl:
text>
</
xsl:
text>
<
xsl:
template match="interface//method | collection//method">
<
xsl:
apply-
templates select="@if" mode="begin"/>
<
xsl:
text> HRESULT </
xsl:
text>
<
xsl:
call-
template name="capitalize">
<
xsl:
with-
param name="str" select="@name"/>
<
xsl:
text> (
</
xsl:
text>
<
xsl:
for-
each select="param [position() != last()]">
<
xsl:
apply-
templates select="."/>
<
xsl:
text>,
</
xsl:
text>
<
xsl:
apply-
templates select="param [last()]"/>
<
xsl:
text>
 );
</
xsl:
text>
<
xsl:
if test="not(param)">
<
xsl:
text>();
</
xsl:
text>
<
xsl:
apply-
templates select="@if" mode="end"/>
<
xsl:
text>
</
xsl:
text>
<
xsl:
template match="class">[
uuid(<
xsl:
value-
of select="@uuid"/>)
<
xsl:
text>coclass </
xsl:
text>
<
xsl:
value-
of select="@name"/>
<
xsl:
text>
{
</
xsl:
text>
<
xsl:
for-
each select="interface">
<
xsl:
if test="@default='yes'">
<
xsl:
text>[default] </
xsl:
text>
<
xsl:
text>interface </
xsl:
text>
<
xsl:
value-
of select="@name"/>
<
xsl:
text>;
</
xsl:
text>
<
xsl:
text>
}; /* coclass </
xsl:
text>
<
xsl:
value-
of select="@name"/>
<
xsl:
text> */

</
xsl:
text>
<
xsl:
template match="enumerator">[
uuid(<
xsl:
value-
of select="@uuid"/>),
<
xsl:
text>interface </
xsl:
text>
<
xsl:
value-
of select="@name"/>
<
xsl:
text> : IUnknown
{
</
xsl:
text>
<
xsl:
text> HRESULT HasMore ([out, retval] BOOL * more);

</
xsl:
text>
<
xsl:
text> HRESULT GetNext ([out, retval] </
xsl:
text>
<
xsl:
apply-
templates select="@type"/>
<
xsl:
text> * next);

</
xsl:
text>
<
xsl:
text>
}; /* interface </
xsl:
text>
<
xsl:
value-
of select="@name"/>
<
xsl:
text> */

</
xsl:
text>
<
xsl:
template match="collection">
<
xsl:
if test="not(@readonly='yes')">
<
xsl:
message terminate="yes">
<
xsl:
value-
of select="concat(@name,': ')"/>
<
xsl:
text>non-readonly collections are not currently supported</
xsl:
text>
uuid(<
xsl:
value-
of select="@uuid"/>),
<
xsl:
text>interface </
xsl:
text>
<
xsl:
value-
of select="@name"/>
<
xsl:
text> : IUnknown
{
</
xsl:
text>
<
xsl:
text> [propget] HRESULT Count ([out, retval] ULONG * count);

</
xsl:
text>
<
xsl:
text> HRESULT GetItemAt ([in] ULONG index, [out, retval] </
xsl:
text>
<
xsl:
apply-
templates select="@type"/>
<
xsl:
text> * item);

</
xsl:
text>
<
xsl:
text> HRESULT Enumerate ([out, retval] </
xsl:
text>
<
xsl:
apply-
templates select="@enumerator"/>
<
xsl:
text> * enumerator);

</
xsl:
text>
<!-- other extra attributes (properties) --> <
xsl:
apply-
templates select="attribute"/>
<!-- other extra methods --> <
xsl:
apply-
templates select="method"/>
<!-- 'if' enclosed elements, unsorted --> <
xsl:
apply-
templates select="if"/>
<
xsl:
text>
}; /* interface </
xsl:
text>
<
xsl:
value-
of select="@name"/>
<
xsl:
text> */

</
xsl:
text>
<
xsl:
template match="enum">[
uuid(<
xsl:
value-
of select="@uuid"/>),
<
xsl:
text>typedef enum 
{
</
xsl:
text>
<
xsl:
for-
each select="const">
<
xsl:
value-
of select="@name"/> = <
xsl:
value-
of select="@value"/>
<
xsl:
when test="position()!=last()"><
xsl:
text>,
</
xsl:
text></
xsl:
when>
<
xsl:
otherwise><
xsl:
text>
</
xsl:
text></
xsl:
otherwise>
<
xsl:
value-
of select="@name"/>
<
xsl:
text>;

</
xsl:
text>
<
xsl:
value-
of select="concat('/* cross-platform type name for ', @name, ' */
')"/>
<
xsl:
value-
of select="concat('cpp_quote("#define ', @name, '_T', ' ', @name, '")

')"/>
<
xsl:
text>cpp_quote("")
</
xsl:
text>
<
xsl:
value-
of select="concat('/* cross-platform constants for ', @name, ' */
')"/>
<
xsl:
for-
each select="const">
<
xsl:
value-
of select="concat('cpp_quote("#define ', ../@name, '_', @name, ' ', @name, '")
')"/>
<
xsl:
when test="position()=last()"><
xsl:
text>cpp_quote("")
</
xsl:
text></
xsl:
when>
<
xsl:
text>

</
xsl:
text>
<
xsl:
when test="@dir='in'">in</
xsl:
when>
<
xsl:
when test="@dir='out'">out</
xsl:
when>
<
xsl:
when test="@dir='return'">out, retval</
xsl:
when>
<
xsl:
otherwise>in</
xsl:
otherwise>
<
xsl:
if test="@dir='return'">
<
xsl:
message terminate="yes">
<
xsl:
value-
of select="concat(../../@name,'::',../@name,'::',@name,': ')"/>
<
xsl:
text>return array parameters are not currently supported</
xsl:
text>
<
xsl:
when test="/param[@name=current()/@array]">
<
xsl:
if test="/param[@name=current()/@array]/@dir != @dir">
<
xsl:
message terminate="yes">
<
xsl:
value-
of select="concat(../../@name,'::',../@name,': ')"/>
<
xsl:
value-
of select="concat(@name,' and ',/param[@name=current()/@array]/@name)"/>
<
xsl:
text> must have the same direction</
xsl:
text>
<
xsl:
text>, size_is(</
xsl:
text>
<
xsl:
if test="@dir='out'">
<
xsl:
if test="/param[@name=current()/@array]/@dir='out'">
<!--xsl:value-of select="@array"/--> <
xsl:
call-
template name="capitalize">
<
xsl:
with-
param name="str" select="@array"/>
<
xsl:
message terminate="yes">
<
xsl:
value-
of select="concat(../../@name,'::',../@name,'::',@name,': ')"/>
<
xsl:
text>array attribute refers to non-existent param: </
xsl:
text>
<
xsl:
value-
of select="@array"/>
<
xsl:
apply-
templates select="@type"/>
<
xsl:
if test="@dir='out' or @dir='return'">
<!--xsl:value-of select="@name"/--> <
xsl:
call-
template name="capitalize">
<
xsl:
with-
param name="str" select="@name"/>
attribute/@type | param/@type | enumerator/@type | collection/@type | collection/@enumerator <
xsl:
variable name="self_target" select="current()/ancestor::if/@target"/>
<!-- modifiers (ignored for 'enumeration' attributes)--> <
xsl:
when test="name(current())='type' and ../@mod">
<
xsl:
if test="../@array">
<
xsl:
message terminate="yes">
<
xsl:
value-
of select="concat(../../../@name,'::',../../@name,'::',../@name,': ')"/>
<
xsl:
text>either 'array' or 'mod' attribute is allowed, but not both!</
xsl:
text>
<
xsl:
when test="../@mod='ptr'">
<!--xsl:when test=".='result'">??</xsl:when--> <
xsl:
when test=".='boolean'">BOOL *</
xsl:
when>
<
xsl:
when test=".='octet'">BYTE *</
xsl:
when>
<
xsl:
when test=".='short'">SHORT *</
xsl:
when>
<
xsl:
when test=".='unsigned short'">USHORT *</
xsl:
when>
<
xsl:
when test=".='long'">LONG *</
xsl:
when>
<
xsl:
when test=".='long long'">LONG64 *</
xsl:
when>
<
xsl:
when test=".='unsigned long'">ULONG *</
xsl:
when>
<
xsl:
when test=".='unsigned long long'">ULONG64 *</
xsl:
when>
<
xsl:
when test=".='char'">CHAR *</
xsl:
when>
<!--xsl:when test=".='string'">??</xsl:when--> <
xsl:
when test=".='wchar'">OLECHAR *</
xsl:
when>
<!--xsl:when test=".='wstring'">??</xsl:when--> <
xsl:
message terminate="yes">
<
xsl:
value-
of select="concat(../../../@name,'::',../../@name,'::',../@name,': ')"/>
<
xsl:
text>attribute 'mod=</
xsl:
text>
<
xsl:
value-
of select="concat('"',../@mod,'"')"/>
<
xsl:
text>' cannot be used with type </
xsl:
text>
<
xsl:
value-
of select="concat('"',current(),'"!')"/>
<
xsl:
message terminate="yes">
<
xsl:
value-
of select="concat(../../../@name,'::',../../@name,'::',../@name,': ')"/>
<
xsl:
value-
of select="concat('value "',../@mod,'" ')"/>
<
xsl:
text>of attibute 'mod' is invalid!</
xsl:
text>
<
xsl:
when test=".='result'">HRESULT</
xsl:
when>
<
xsl:
when test=".='boolean'">BOOL</
xsl:
when>
<
xsl:
when test=".='octet'">BYTE</
xsl:
when>
<
xsl:
when test=".='short'">SHORT</
xsl:
when>
<
xsl:
when test=".='unsigned short'">USHORT</
xsl:
when>
<
xsl:
when test=".='long'">LONG</
xsl:
when>
<
xsl:
when test=".='long long'">LONG64</
xsl:
when>
<
xsl:
when test=".='unsigned long'">ULONG</
xsl:
when>
<
xsl:
when test=".='unsigned long long'">ULONG64</
xsl:
when>
<
xsl:
when test=".='char'">CHAR</
xsl:
when>
<
xsl:
when test=".='string'">CHAR *</
xsl:
when>
<
xsl:
when test=".='wchar'">OLECHAR</
xsl:
when>
<
xsl:
when test=".='wstring'">BSTR</
xsl:
when>
<
xsl:
when test=".='uuid'">GUID</
xsl:
when>
<!-- system interface types --> <
xsl:
when test=".='$unknown'">IUnknown *</
xsl:
when>
(ancestor::module/if[@target=$self_target]/enum[@name=current()]) <
xsl:
value-
of select="."/>
<!-- custom interface types --> (name(current())='enumerator' and (ancestor::module/if[@target=$self_target]/enumerator[@name=current()])) (ancestor::module/if[@target=$self_target]/interface[@name=current()]) (ancestor::module/if[@target=$self_target]/collection[@name=current()]) <
xsl:
value-
of select="."/><
xsl:
text> *</
xsl:
text>
<
xsl:
message terminate="yes">
<
xsl:
text>Unknown parameter type: </
xsl:
text>
<
xsl:
value-
of select="."/>