FortranWrapper_Source.xslt 31.5 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:output method="text" omit-xml-declaration="yes"/>

<xsl:variable name="std_namespace_id" select="/GCC_XML/Namespace[@name='std']/@id"/>
<xsl:variable name="openmm_namespace_id" select="/GCC_XML/Namespace[@name='OpenMM']/@id"/>
<xsl:variable name="void_type_id" select="/GCC_XML/FundamentalType[@name='void']/@id"/>
<xsl:variable name="bool_type_id" select="/GCC_XML/FundamentalType[@name='bool']/@id"/>
<xsl:variable name="int_type_id" select="/GCC_XML/FundamentalType[@name='int']/@id"/>
<xsl:variable name="double_type_id" select="/GCC_XML/FundamentalType[@name='double']/@id"/>
<xsl:variable name="char_type_id" select="/GCC_XML/FundamentalType[@name='char']/@id"/>
<xsl:variable name="string_type_id" select="/GCC_XML/*[@name='string' and @context=$std_namespace_id]/@id"/>
<xsl:variable name="const_char_type_id" select="/GCC_XML/CvQualifiedType[@type=$char_type_id]/@id"/>
<xsl:variable name="ptr_const_char_type_id" select="/GCC_XML/PointerType[@type=$const_char_type_id]/@id"/>
<xsl:variable name="const_string_type_id" select="/GCC_XML/CvQualifiedType[@type=$string_type_id]/@id"/>
<xsl:variable name="const_ref_string_type_id" select="/GCC_XML/ReferenceType[@type=$const_string_type_id]/@id"/>
<xsl:variable name="vec3_type_id" select="/GCC_XML/Class[@name='Vec3' and @context=$openmm_namespace_id]/@id"/>
<xsl:variable name="vector_string_type_id" select="/GCC_XML/Class[starts-with(@name, 'vector&lt;std::basic_string')]/@id"/>
<xsl:variable name="vector_vec3_type_id" select="/GCC_XML/Class[starts-with(@name, 'vector&lt;OpenMM::Vec3')]/@id"/>
<xsl:variable name="vector_bond_type_id" select="/GCC_XML/Class[starts-with(@name, 'vector&lt;std::pair&lt;int, int')]/@id"/>
22
23
<xsl:variable name="map_parameter_type_id" select="/GCC_XML/Class[starts-with(@name, 'map&lt;std::basic_string') and contains(@name, 'double')]/@id"/>
<xsl:variable name="map_property_type_id" select="/GCC_XML/Class[starts-with(@name, 'map&lt;std::basic_string') and not(contains(@name, 'double'))]/@id"/>
24
<xsl:variable name="vector_double_type_id" select="/GCC_XML/Class[starts-with(@name, 'vector&lt;double')]/@id"/>
25
<xsl:variable name="vector_int_type_id" select="/GCC_XML/Class[starts-with(@name, 'vector&lt;int')]/@id"/>
26
27
28
29
30
31
32
33
34
<xsl:variable name="newline">
<xsl:text>
</xsl:text>
</xsl:variable>


<!-- Do not generate functions for the following classes -->
<xsl:variable name="skip_classes" select="('Vec3', 'Kernel', 'Stream', 'KernelImpl', 'StreamImpl', 'KernelFactory', 'StreamFactory')"/>
<!-- Do not generate the following functions -->
35
<xsl:variable name="skip_methods" select="('OpenMM_Context_getState', 'OpenMM_Platform_loadPluginsFromDirectory', 'OpenMM_Context_createCheckpoint', 'OpenMM_Context_loadCheckpoint')"/>
36
<!-- Suppress any function which references any of the following classes -->
37
<xsl:variable name="hide_classes" select="('Kernel', 'Stream', 'KernelImpl', 'StreamImpl', 'KernelFactory', 'StreamFactory', 'ContextImpl')"/>
38
39
40
41

<!-- Main loop over all classes in the OpenMM namespace -->
<xsl:template match="/GCC_XML">
#include "OpenMM.h"
42
#include "OpenMMCWrapper.h"
43
44
45
46
47
48
#include &lt;cstring&gt;
#include &lt;vector&gt;

using namespace OpenMM;
using namespace std;

49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
/* Utilities for dealing with Fortran's blank-padded strings. */
static void copyAndPadString(char* dest, const char* source, int length) {
    bool reachedEnd = false;
    for (int i = 0; i &lt; length; i++) {
        if (source[i] == 0)
            reachedEnd = true;
        dest[i] = (reachedEnd ? ' ' : source[i]);
    }
}

static string makeString(const char* fsrc, int length) {
    while (length &amp;&amp; fsrc[length-1]==' ')
        --length;
    return string(fsrc, length);
}

65
66
67
extern "C" {

/* OpenMM_Vec3 */
68
OPENMM_EXPORT void openmm_vec3_scale_(const OpenMM_Vec3&amp; vec, double const&amp; scale, OpenMM_Vec3&amp; result) {
69
70
    result = OpenMM_Vec3_scale(vec, scale);
}
71
OPENMM_EXPORT void OPENMM_VEC3_SCALE(const OpenMM_Vec3&amp; vec, double const&amp; scale, OpenMM_Vec3&amp; result) {
72
73
74
75
    result = OpenMM_Vec3_scale(vec, scale);
}

/* OpenMM_Vec3Array */
76
OPENMM_EXPORT void openmm_vec3array_create_(OpenMM_Vec3Array*&amp; result, const int&amp; size) {
77
78
    result = OpenMM_Vec3Array_create(size);
}
79
OPENMM_EXPORT void OPENMM_VEC3ARRAY_CREATE(OpenMM_Vec3Array*&amp; result, const int&amp; size) {
80
81
    result = OpenMM_Vec3Array_create(size);
}
82
OPENMM_EXPORT void openmm_vec3array_destroy_(OpenMM_Vec3Array*&amp; array) {
83
84
85
    OpenMM_Vec3Array_destroy(array);
    array = 0;
}
86
OPENMM_EXPORT void OPENMM_VEC3ARRAY_DESTROY(OpenMM_Vec3Array*&amp; array) {
87
88
89
    OpenMM_Vec3Array_destroy(array);
    array = 0;
}
90
OPENMM_EXPORT int openmm_vec3array_getsize_(const OpenMM_Vec3Array* const&amp; array) {
91
92
    return OpenMM_Vec3Array_getSize(array);
}
93
OPENMM_EXPORT int OPENMM_VEC3ARRAY_GETSIZE(const OpenMM_Vec3Array* const&amp; array) {
94
95
    return OpenMM_Vec3Array_getSize(array);
}
96
OPENMM_EXPORT void openmm_vec3array_resize_(OpenMM_Vec3Array* const&amp; array, const int&amp; size) {
97
98
    OpenMM_Vec3Array_resize(array, size);
}
99
OPENMM_EXPORT void OPENMM_VEC3ARRAY_RESIZE(OpenMM_Vec3Array* const&amp; array, const int&amp; size) {
100
101
    OpenMM_Vec3Array_resize(array, size);
}
102
OPENMM_EXPORT void openmm_vec3array_append_(OpenMM_Vec3Array* const&amp; array, const OpenMM_Vec3&amp; vec) {
103
104
    OpenMM_Vec3Array_append(array, vec);
}
105
OPENMM_EXPORT void OPENMM_VEC3ARRAY_APPEND(OpenMM_Vec3Array* const&amp; array, const OpenMM_Vec3&amp; vec) {
106
107
    OpenMM_Vec3Array_append(array, vec);
}
108
OPENMM_EXPORT void openmm_vec3array_set_(OpenMM_Vec3Array* const&amp; array, const int&amp; index, const OpenMM_Vec3&amp; vec) {
109
110
    OpenMM_Vec3Array_set(array, index-1, vec);
}
111
OPENMM_EXPORT void OPENMM_VEC3ARRAY_SET(OpenMM_Vec3Array* const&amp; array, const int&amp; index, const OpenMM_Vec3&amp; vec) {
112
113
    OpenMM_Vec3Array_set(array, index-1, vec);
}
114
OPENMM_EXPORT void openmm_vec3array_get_(const OpenMM_Vec3Array* const&amp; array, const int&amp; index, OpenMM_Vec3&amp; result) {
115
    result = *OpenMM_Vec3Array_get(array, index-1);
116
}
117
OPENMM_EXPORT void OPENMM_VEC3ARRAY_GET(const OpenMM_Vec3Array* const&amp; array, const int&amp; index, OpenMM_Vec3&amp; result) {
118
    result = *OpenMM_Vec3Array_get(array, index-1);
119
120
121
}

/* OpenMM_StringArray */
122
OPENMM_EXPORT void openmm_stringarray_create_(OpenMM_StringArray*&amp; result, const int&amp; size) {
123
124
    result = OpenMM_StringArray_create(size);
}
125
OPENMM_EXPORT void OPENMM_STRINGARRAY_CREATE(OpenMM_StringArray*&amp; result, const int&amp; size) {
126
127
    result = OpenMM_StringArray_create(size);
}
128
OPENMM_EXPORT void openmm_stringarray_destroy_(OpenMM_StringArray*&amp; array) {
129
130
131
    OpenMM_StringArray_destroy(array);
    array = 0;
}
132
OPENMM_EXPORT void OPENMM_STRINGARRAY_DESTROY(OpenMM_StringArray*&amp; array) {
133
134
135
    OpenMM_StringArray_destroy(array);
    array = 0;
}
136
OPENMM_EXPORT int openmm_stringarray_getsize_(const OpenMM_StringArray* const&amp; array) {
137
138
    return OpenMM_StringArray_getSize(array);
}
139
OPENMM_EXPORT int OPENMM_STRINGARRAY_GETSIZE(const OpenMM_StringArray* const&amp; array) {
140
141
    return OpenMM_StringArray_getSize(array);
}
142
OPENMM_EXPORT void openmm_stringarray_resize_(OpenMM_StringArray* const&amp; array, const int&amp; size) {
143
144
    OpenMM_StringArray_resize(array, size);
}
145
OPENMM_EXPORT void OPENMM_STRINGARRAY_RESIZE(OpenMM_StringArray* const&amp; array, const int&amp; size) {
146
147
    OpenMM_StringArray_resize(array, size);
}
148
OPENMM_EXPORT void openmm_stringarray_append_(OpenMM_StringArray* const&amp; array, const char* str, int length) {
149
    OpenMM_StringArray_append(array, makeString(str, length).c_str());
150
}
151
OPENMM_EXPORT void OPENMM_STRINGARRAY_APPEND(OpenMM_StringArray* const&amp; array, const char* str, int length) {
152
    OpenMM_StringArray_append(array, makeString(str, length).c_str());
153
}
154
OPENMM_EXPORT void openmm_stringarray_set_(OpenMM_StringArray* const&amp; array, const int&amp; index, const char* str, int length) {
155
156
  OpenMM_StringArray_set(array, index-1, makeString(str, length).c_str());
  }
157
OPENMM_EXPORT void OPENMM_STRINGARRAY_SET(OpenMM_StringArray* const&amp; array, const int&amp; index, const char* str, int length) {
158
  OpenMM_StringArray_set(array, index-1, makeString(str, length).c_str());
159
}
160
OPENMM_EXPORT void openmm_stringarray_get_(const OpenMM_StringArray* const&amp; array, const int&amp; index, char* result, int length) {
161
    const char* str = OpenMM_StringArray_get(array, index-1);
162
    copyAndPadString(result, str, length);
163
}
164
OPENMM_EXPORT void OPENMM_STRINGARRAY_GET(const OpenMM_StringArray* const&amp; array, const int&amp; index, char* result, int length) {
165
    const char* str = OpenMM_StringArray_get(array, index-1);
166
    copyAndPadString(result, str, length);
167
168
169
}

/* OpenMM_BondArray */
170
OPENMM_EXPORT void openmm_bondarray_create_(OpenMM_BondArray*&amp; result, const int&amp; size) {
171
172
    result = OpenMM_BondArray_create(size);
}
173
OPENMM_EXPORT void OPENMM_BONDARRAY_CREATE(OpenMM_BondArray*&amp; result, const int&amp; size) {
174
175
    result = OpenMM_BondArray_create(size);
}
176
OPENMM_EXPORT void openmm_bondarray_destroy_(OpenMM_BondArray*&amp; array) {
177
178
179
    OpenMM_BondArray_destroy(array);
    array = 0;
}
180
OPENMM_EXPORT void OPENMM_BONDARRAY_DESTROY(OpenMM_BondArray*&amp; array) {
181
182
183
    OpenMM_BondArray_destroy(array);
    array = 0;
}
184
OPENMM_EXPORT int openmm_bondarray_getsize_(const OpenMM_BondArray* const&amp; array) {
185
186
    return OpenMM_BondArray_getSize(array);
}
187
OPENMM_EXPORT int OPENMM_BONDARRAY_GETSIZE(const OpenMM_BondArray* const&amp; array) {
188
189
    return OpenMM_BondArray_getSize(array);
}
190
OPENMM_EXPORT void openmm_bondarray_resize_(OpenMM_BondArray* const&amp; array, const int&amp; size) {
191
192
    OpenMM_BondArray_resize(array, size);
}
193
OPENMM_EXPORT void OPENMM_BONDARRAY_RESIZE(OpenMM_BondArray* const&amp; array, const int&amp; size) {
194
195
    OpenMM_BondArray_resize(array, size);
}
196
OPENMM_EXPORT void openmm_bondarray_append_(OpenMM_BondArray* const&amp; array, const int&amp; particle1, const int&amp; particle2) {
197
198
    OpenMM_BondArray_append(array, particle1, particle2);
}
199
OPENMM_EXPORT void OPENMM_BONDARRAY_APPEND(OpenMM_BondArray* const&amp; array, const int&amp; particle1, const int&amp; particle2) {
200
201
    OpenMM_BondArray_append(array, particle1, particle2);
}
202
OPENMM_EXPORT void openmm_bondarray_set_(OpenMM_BondArray* const&amp; array, const int&amp; index, const int&amp; particle1, const int&amp; particle2) {
203
204
    OpenMM_BondArray_set(array, index-1, particle1, particle2);
}
205
OPENMM_EXPORT void OPENMM_BONDARRAY_SET(OpenMM_BondArray* const&amp; array, const int&amp; index, const int&amp; particle1, const int&amp; particle2) {
206
207
    OpenMM_BondArray_set(array, index-1, particle1, particle2);
}
208
OPENMM_EXPORT void openmm_bondarray_get_(const OpenMM_BondArray* const&amp; array, const int&amp; index, int* particle1, int* particle2) {
209
210
    OpenMM_BondArray_get(array, index-1, particle1, particle2);
}
211
OPENMM_EXPORT void OPENMM_BONDARRAY_GET(const OpenMM_BondArray* const&amp; array, const int&amp; index, int* particle1, int* particle2) {
212
213
214
215
    OpenMM_BondArray_get(array, index-1, particle1, particle2);
}

/* OpenMM_ParameterArray */
216
OPENMM_EXPORT int openmm_parameterarray_getsize_(const OpenMM_ParameterArray* const&amp; array) {
217
218
    return OpenMM_ParameterArray_getSize(array);
}
219
OPENMM_EXPORT int OPENMM_PARAMETERARRAY_GETSIZE(const OpenMM_ParameterArray* const&amp; array) {
220
221
    return OpenMM_ParameterArray_getSize(array);
}
222
OPENMM_EXPORT double openmm_parameterarray_get_(const OpenMM_ParameterArray* const&amp; array, const char* name, int length) {
223
    return OpenMM_ParameterArray_get(array, makeString(name, length).c_str());
224
}
225
OPENMM_EXPORT double OPENMM_PARAMETERARRAY_GET(const OpenMM_ParameterArray* const&amp; array, const char* name, int length) {
226
    return OpenMM_ParameterArray_get(array, makeString(name, length).c_str());
227
}
228
229
230
231
232
233
234
235
236
237
238
239
240
241

/* OpenMM_PropertyArray */
OPENMM_EXPORT int openmm_propertyarray_getsize_(const OpenMM_PropertyArray* const&amp; array) {
    return OpenMM_PropertyArray_getSize(array);
}
OPENMM_EXPORT int OPENMM_PROPERTYARRAY_GETSIZE(const OpenMM_PropertyArray* const&amp; array) {
    return OpenMM_PropertyArray_getSize(array);
}
OPENMM_EXPORT const char* openmm_propertyarray_get_(const OpenMM_PropertyArray* const&amp; array, const char* name, int length) {
    return OpenMM_PropertyArray_get(array, makeString(name, length).c_str());
}
OPENMM_EXPORT const char* OPENMM_PROPERTYARRAY_GET(const OpenMM_PropertyArray* const&amp; array, const char* name, int length) {
    return OpenMM_PropertyArray_get(array, makeString(name, length).c_str());
}
242
243
244
245
<xsl:call-template name="primitive_array">
 <xsl:with-param name="element_type" select="'double'"/>
 <xsl:with-param name="name" select="'OpenMM_DoubleArray'"/>
</xsl:call-template>
246
247
248

/* These methods need to be handled specially, since their C++ APIs cannot be directly translated to C.
   Unlike the C++ versions, the return value is allocated on the heap, and you must delete it yourself. */
249
250
OPENMM_EXPORT void openmm_context_getstate_(const OpenMM_Context*&amp; target, int const&amp; types, int const&amp; enforcePeriodicBox, OpenMM_State*&amp; result) {
    result = OpenMM_Context_getState(target, types, enforcePeriodicBox);
251
};
252
253
OPENMM_EXPORT void OPENMM_CONTEXT_GETSTATE(const OpenMM_Context*&amp; target, int const&amp; types, int const&amp; enforcePeriodicBox, OpenMM_State*&amp; result) {
    result = OpenMM_Context_getState(target, types, enforcePeriodicBox);
254
};
255
OPENMM_EXPORT void openmm_platform_loadpluginsfromdirectory_(const char* directory, OpenMM_StringArray*&amp; result, int length) {
256
    result = OpenMM_Platform_loadPluginsFromDirectory(makeString(directory, length).c_str());
257
};
258
OPENMM_EXPORT void OPENMM_PLATFORM_LOADPLUGINSFROMDIRECTORY(const char* directory, OpenMM_StringArray*&amp; result, int length) {
259
    result = OpenMM_Platform_loadPluginsFromDirectory(makeString(directory, length).c_str());
260
261
262
263
264
265
266
267
268
269
};

 <!-- Class members -->
 <xsl:for-each select="Class[@context=$openmm_namespace_id and empty(index-of($skip_classes, @name))]">
  <xsl:call-template name="class"/>
 </xsl:for-each>

}
</xsl:template>

270
271
272
273
274
275
276
<!-- Print out the definitions for a (Primitive)Array type -->
<xsl:template name="primitive_array">
 <xsl:param name="element_type"/>
 <xsl:param name="name"/>
 <xsl:variable name="name_lower" select="lower-case($name)"/>
 <xsl:variable name="name_upper" select="upper-case($name)"/>
/* <xsl:value-of select="$name"/> */
277
OPENMM_EXPORT void <xsl:value-of select="$name_lower"/>_create_(<xsl:value-of select="$name"/>*&amp; result, const int&amp; size) {
278
279
    result = <xsl:value-of select="$name"/>_create(size);
}
280
OPENMM_EXPORT void <xsl:value-of select="$name_upper"/>_CREATE(<xsl:value-of select="$name"/>*&amp; result, const int&amp; size) {
281
282
    result = <xsl:value-of select="$name"/>_create(size);
}
283
OPENMM_EXPORT void <xsl:value-of select="$name_lower"/>_destroy_(<xsl:value-of select="$name"/>*&amp; array) {
284
285
286
    <xsl:value-of select="$name"/>_destroy(array);
    array = 0;
}
287
OPENMM_EXPORT void <xsl:value-of select="$name_upper"/>_DESTROY(<xsl:value-of select="$name"/>*&amp; array) {
288
289
290
    <xsl:value-of select="$name"/>_destroy(array);
    array = 0;
}
291
OPENMM_EXPORT int <xsl:value-of select="$name_lower"/>_getsize_(const <xsl:value-of select="$name"/>* const&amp; array) {
292
293
    return <xsl:value-of select="$name"/>_getSize(array);
}
294
OPENMM_EXPORT int <xsl:value-of select="$name_upper"/>_GETSIZE(const <xsl:value-of select="$name"/>* const&amp; array) {
295
296
    return <xsl:value-of select="$name"/>_getSize(array);
}
297
OPENMM_EXPORT void <xsl:value-of select="$name_lower"/>_resize_(<xsl:value-of select="$name"/>* const&amp; array, const int&amp; size) {
298
299
    <xsl:value-of select="$name"/>_resize(array, size);
}
300
OPENMM_EXPORT void <xsl:value-of select="$name_upper"/>_RESIZE(<xsl:value-of select="$name"/>* const&amp; array, const int&amp; size) {
301
302
    <xsl:value-of select="$name"/>_resize(array, size);
}
303
OPENMM_EXPORT void <xsl:value-of select="$name_lower"/>_append_(<xsl:value-of select="$name"/>* const&amp; array, const <xsl:value-of select="$element_type"/>&amp; value) {
304
305
    <xsl:value-of select="$name"/>_append(array, value);
}
306
OPENMM_EXPORT void <xsl:value-of select="$name_upper"/>_APPEND(<xsl:value-of select="$name"/>* const&amp; array, const <xsl:value-of select="$element_type"/>&amp; value) {
307
308
    <xsl:value-of select="$name"/>_append(array, value);
}
309
OPENMM_EXPORT void <xsl:value-of select="$name_lower"/>_set_(<xsl:value-of select="$name"/>* const&amp; array, const int&amp; index, const <xsl:value-of select="$element_type"/>&amp; value) {
310
311
    <xsl:value-of select="$name"/>_set(array, index-1, value);
}
312
OPENMM_EXPORT void <xsl:value-of select="$name_upper"/>_SET(<xsl:value-of select="$name"/>* const&amp; array, const int&amp; index, const <xsl:value-of select="$element_type"/>&amp; value) {
313
314
    <xsl:value-of select="$name"/>_set(array, index-1, value);
}
315
OPENMM_EXPORT void <xsl:value-of select="$name_lower"/>_get_(const <xsl:value-of select="$name"/>* const&amp; array, const int&amp; index, <xsl:value-of select="$element_type"/>&amp; result) {
316
317
    result = <xsl:value-of select="$name"/>_get(array, index-1);
}
318
OPENMM_EXPORT void <xsl:value-of select="$name_upper"/>_GET(const <xsl:value-of select="$name"/>* const&amp; array, const int&amp; index, <xsl:value-of select="$element_type"/>&amp; result) {
319
320
321
322
    result = <xsl:value-of select="$name"/>_get(array, index-1);
}
</xsl:template>

323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
<!-- Print out information for a class -->
<xsl:template name="class">
 <xsl:variable name="class_name" select="@name"/>
 <xsl:variable name="class_id" select="@id"/>

/* OpenMM::<xsl:value-of select="concat(@name, '*/', $newline)"/>
 <!-- Constructors and destructor -->
 <xsl:if test="not(@abstract=1)">
  <xsl:variable name="constructors" select="/GCC_XML/Constructor[@context=$class_id and @access='public' and not(@artificial='1')]"/>
  <xsl:for-each select="$constructors">
   <xsl:variable name="suffix" select="if (position() > 1) then concat('_', position()) else ''"/>
   <xsl:variable name="function_name" select="concat('openmm_', $class_name, '_create', $suffix)"/>
   <xsl:call-template name="constructor">
    <xsl:with-param name="function_name" select="lower-case(concat($function_name, '_'))"/>
    <xsl:with-param name="suffix" select="$suffix"/>
   </xsl:call-template>
   <xsl:call-template name="constructor">
    <xsl:with-param name="function_name" select="upper-case($function_name)"/>
    <xsl:with-param name="suffix" select="$suffix"/>
   </xsl:call-template>
  </xsl:for-each>
 </xsl:if>
 <xsl:variable name="function_name" select="concat('openmm_', $class_name, '_destroy')"/>
 <xsl:call-template name="destructor">
  <xsl:with-param name="function_name" select="lower-case(concat($function_name, '_'))"/>
 </xsl:call-template>
 <xsl:call-template name="destructor">
  <xsl:with-param name="function_name" select="upper-case($function_name)"/>
 </xsl:call-template>
 <!-- Methods -->
 <xsl:variable name="methods" select="/GCC_XML/Method[@context=$class_id and @access='public']"/>
 <xsl:for-each select="$methods">
  <xsl:variable name="node" select="."/>
  <!-- The next line is to deal with overloaded methods that have a const and a non-const version. -->
  <xsl:if test="not(@const=1) or empty($methods[@name=$node/@name and not(@const=1)])">
   <xsl:variable name="hide">
    <xsl:call-template name="should_hide"/>
   </xsl:variable>
   <xsl:if test="string-length($hide)=0">
    <xsl:variable name="function_name" select="concat('openmm_', $class_name, '_', @name)"/>
    <xsl:call-template name="method">
     <xsl:with-param name="class_name" select="$class_name"/>
     <xsl:with-param name="class_id" select="$class_id"/>
     <xsl:with-param name="function_name" select="lower-case(concat($function_name, '_'))"/>
    </xsl:call-template>
    <xsl:call-template name="method">
     <xsl:with-param name="class_name" select="$class_name"/>
     <xsl:with-param name="class_id" select="$class_id"/>
     <xsl:with-param name="function_name" select="upper-case($function_name)"/>
    </xsl:call-template>
   </xsl:if>
  </xsl:if>
 </xsl:for-each>
</xsl:template>

<!-- Print out the definition of a constructor -->
<xsl:template name="constructor">
 <xsl:param name="function_name"/>
 <xsl:param name="suffix"/>
382
OPENMM_EXPORT <xsl:value-of select="concat('void ', $function_name, '(OpenMM_', @name, '*&amp; result')"/>
383
384
385
386
  <!-- Generate the list of arguments -->
  <xsl:for-each select="Argument">
   <xsl:value-of select="', '"/>
   <xsl:call-template name="wrap_type"><xsl:with-param name="type_id" select="@type"/></xsl:call-template>
387
388
389
390
391
392
393
394
395
   <xsl:variable name="is_handle">
    <xsl:call-template name="is_handle_type">
     <xsl:with-param name="type_id" select="@type"/>
    </xsl:call-template>
   </xsl:variable>
   <xsl:if test="string-length($is_handle)>0">&amp;</xsl:if>
   <xsl:variable name="type_id" select="@type"/>
   <xsl:variable name="type_node" select="/GCC_XML/*[@id=$type_id]"/>
   <xsl:if test="not(local-name($type_node)='ReferenceType' or local-name($type_node)='PointerType')"> const&amp;</xsl:if>
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
   <xsl:value-of select="concat(' ', @name)"/>
  </xsl:for-each>
  <!-- If any argument is a string, include a length argument -->
  <xsl:for-each select="Argument">
   <xsl:if test="@type=$const_ref_string_type_id">
    <xsl:value-of select="concat(', int ', @name, '_length')"/>
   </xsl:if>
  </xsl:for-each>
  <!-- Now the constructor body -->
  <xsl:value-of select="') {'"/>
    result = OpenMM_<xsl:value-of select="concat(@name, '_create', $suffix, '(')"/>
  <xsl:for-each select="Argument">
   <xsl:if test="position() > 1">, </xsl:if>
   <xsl:choose>
    <xsl:when test="@type=$const_ref_string_type_id">
411
     <xsl:value-of select="concat('makeString(', @name, ', ', @name, '_length).c_str()')"/>
412
413
414
415
416
417
418
419
420
421
422
423
424
    </xsl:when>
    <xsl:otherwise>
     <xsl:value-of select="@name"/>
    </xsl:otherwise>
   </xsl:choose>
  </xsl:for-each>
  <xsl:value-of select="');'"/>
}
</xsl:template>

<!-- Print out the definition of a destructor -->
<xsl:template name="destructor">
 <xsl:param name="function_name"/>
425
OPENMM_EXPORT <xsl:value-of select="concat('void ', $function_name, '(OpenMM_', @name, '*&amp; destroy) {')"/>
426
427
428
429
430
431
432
433
434
435
436
437
438
    OpenMM_<xsl:value-of select="concat(@name, '_destroy(destroy);')"/>
    destroy = 0;
}
</xsl:template>

<!-- Print out the definition of a method -->
<xsl:template name="method">
 <xsl:param name="class_name"/>
 <xsl:param name="class_id"/>
 <xsl:param name="function_name"/>
 <!-- First the method signature -->
 <xsl:variable name="has_return" select="@returns=$int_type_id or @returns=$double_type_id"/>
 <xsl:variable name="has_return_arg" select="not($has_return or @returns=$void_type_id)"/>
439
OPENMM_EXPORT <xsl:if test="$has_return">
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
  <xsl:call-template name="wrap_type"><xsl:with-param name="type_id" select="@returns"/></xsl:call-template>
 </xsl:if>
 <xsl:if test="not($has_return)">
  <xsl:value-of select="'void'"/>
 </xsl:if>
 <xsl:value-of select="concat(' ', $function_name, '(')"/>
 <xsl:if test="not(@static='1')">
  <xsl:if test="@const='1'">
   <xsl:value-of select="'const '"/>
  </xsl:if>
  <xsl:value-of select="concat('OpenMM_', $class_name, '*&amp; target')"/>
 </xsl:if>
 <!-- Generate the list of arguments -->
 <xsl:variable name="method" select="."/>
 <xsl:for-each select="Argument">
  <xsl:if test="position() > 1 or not($method/@static='1')">, </xsl:if>
  <xsl:call-template name="wrap_type"><xsl:with-param name="type_id" select="@type"/></xsl:call-template>
457
458
459
460
461
462
  <xsl:variable name="is_handle">
   <xsl:call-template name="is_handle_type">
    <xsl:with-param name="type_id" select="@type"/>
   </xsl:call-template>
  </xsl:variable>
  <xsl:if test="string-length($is_handle)>0">&amp;</xsl:if>
463
464
465
466
467
468
469
470
471
472
473
474
475
  <xsl:variable name="type_id" select="@type"/>
  <xsl:variable name="type_node" select="/GCC_XML/*[@id=$type_id]"/>
  <xsl:if test="not(local-name($type_node)='ReferenceType' or local-name($type_node)='PointerType')"> const&amp;</xsl:if>
  <xsl:value-of select="concat(' ', @name)"/>
 </xsl:for-each>
 <xsl:if test="$has_return_arg">
  <xsl:if test="not(@static='1') or not(empty(Argument)) or not($method/@static='1')">, </xsl:if>
  <xsl:choose>
   <xsl:when test="@returns=$const_ref_string_type_id or @returns=$ptr_const_char_type_id">
    <xsl:value-of select="'char*'"/> <!-- We need a non-const buffer to copy the result into -->
   </xsl:when>
   <xsl:otherwise>
    <xsl:call-template name="wrap_type"><xsl:with-param name="type_id" select="@returns"/></xsl:call-template>
476
    <xsl:value-of select="'&amp;'"/>
477
478
   </xsl:otherwise>
  </xsl:choose>
479
  <xsl:value-of select="' result'"/>
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
 </xsl:if>
 <!-- If any argument is a string, include a length argument -->
 <xsl:for-each select="Argument">
  <xsl:if test="@type=$const_ref_string_type_id or @type=$ptr_const_char_type_id">
   <xsl:value-of select="concat(', int ', @name, '_length')"/>
  </xsl:if>
 </xsl:for-each>
 <xsl:if test="$has_return_arg and (@returns=$const_ref_string_type_id or @returns=$ptr_const_char_type_id)">
  <xsl:value-of select="', int result_length'"/>
 </xsl:if>
 <xsl:value-of select="concat(') {', $newline, '    ')"/>
 <!-- Now the method body -->
 <xsl:choose>
  <xsl:when test="$has_return">
   <xsl:value-of select="'return '"/>
  </xsl:when>
  <xsl:when test="$has_return_arg and (@returns=$const_ref_string_type_id or @returns=$ptr_const_char_type_id)">
   <xsl:value-of select="'const char* result_chars = '"/>
  </xsl:when>
  <xsl:when test="$has_return_arg">
   <xsl:value-of select="'result = '"/>
  </xsl:when>
 </xsl:choose>
 <xsl:value-of select="concat('OpenMM_', $class_name, '_', @name, '(')"/>
 <xsl:if test="not(@static='1')">target</xsl:if>
 <xsl:for-each select="Argument">
  <xsl:if test="position() > 1 or not($method/@static='1')">, </xsl:if>
   <xsl:variable name="type_id" select="@type"/>
   <xsl:variable name="type_node" select="/GCC_XML/*[@id=$type_id]"/>
   <xsl:choose>
   <xsl:when test="@type=$const_ref_string_type_id or @type=$ptr_const_char_type_id">
511
    <xsl:value-of select="concat('makeString(', @name, ', ', @name, '_length).c_str()')"/>
512
513
514
515
516
   </xsl:when>
   <xsl:when test="local-name($type_node)='Enumeration'">
    <xsl:variable name="enum_class" select="/GCC_XML/*[@id=$type_node/@context]"/>
    <xsl:value-of select="concat('(OpenMM_', $enum_class/@name, '_', $type_node/@name, ') ', @name)"/>
   </xsl:when>
517
518
519
520
521
   <xsl:when test="local-name($type_node)='ReferenceType' and not(empty(/GCC_XML/Enumeration[@id=$type_node/@type]))">
    <xsl:variable name="enum_node" select="/GCC_XML/Enumeration[@id=$type_node/@type]"/>
    <xsl:variable name="enum_class" select="/GCC_XML/*[@id=$enum_node/@context]"/>
    <xsl:value-of select="concat('(OpenMM_', $enum_class/@name, '_', $enum_node/@name, '*) ', @name)"/>
   </xsl:when>
522
523
524
525
526
527
528
   <xsl:otherwise>
    <xsl:value-of select="@name"/>
   </xsl:otherwise>
  </xsl:choose>
 </xsl:for-each>
 <xsl:value-of select="');'"/>
 <xsl:if test="$has_return_arg and (@returns=$const_ref_string_type_id or @returns=$ptr_const_char_type_id)">
529
    copyAndPadString(result, result_chars, result_length);</xsl:if>
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
};
</xsl:template>

<!-- Print out the description of a type in the wrapper API -->
<xsl:template name="wrap_type">
 <xsl:param name="type_id"/>
 <xsl:variable name="node" select="/GCC_XML/*[@id=$type_id]"/>
 <xsl:choose>
  <xsl:when test="$type_id=$bool_type_id">
   <xsl:value-of select="'OpenMM_Boolean'"/>
  </xsl:when>
  <xsl:when test="$type_id=$string_type_id">
   <xsl:value-of select="'char*'"/>
  </xsl:when>
  <xsl:when test="$type_id=$const_ref_string_type_id">
   <xsl:value-of select="'const char*'"/>
  </xsl:when>
  <xsl:when test="$type_id=$vector_string_type_id">
   <xsl:value-of select="'OpenMM_StringArray'"/>
  </xsl:when>
  <xsl:when test="$type_id=$vector_vec3_type_id">
   <xsl:value-of select="'OpenMM_Vec3Array'"/>
  </xsl:when>
  <xsl:when test="$type_id=$vector_bond_type_id">
   <xsl:value-of select="'OpenMM_BondArray'"/>
  </xsl:when>
  <xsl:when test="$type_id=$map_parameter_type_id">
   <xsl:value-of select="'OpenMM_ParameterArray'"/>
  </xsl:when>
559
560
561
  <xsl:when test="$type_id=$map_property_type_id">
   <xsl:value-of select="'OpenMM_PropertyArray'"/>
  </xsl:when>
562
563
564
  <xsl:when test="$type_id=$vector_double_type_id">
   <xsl:value-of select="'OpenMM_DoubleArray'"/>
  </xsl:when>
565
566
567
  <xsl:when test="$type_id=$vector_int_type_id">
   <xsl:value-of select="'OpenMM_IntArray'"/>
  </xsl:when>
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
  <xsl:when test="local-name($node)='ReferenceType' or local-name($node)='PointerType'">
   <xsl:call-template name="wrap_type">
    <xsl:with-param name="type_id" select="$node/@type"/>
   </xsl:call-template>
   <xsl:value-of select="'*'"/>
  </xsl:when>
  <xsl:when test="local-name($node)='CvQualifiedType'">
   <xsl:if test="$node/@const=1">
    <xsl:value-of select="'const '"/>
   </xsl:if>
   <xsl:call-template name="wrap_type">
    <xsl:with-param name="type_id" select="$node/@type"/>
   </xsl:call-template>
  </xsl:when>
  <xsl:when test="local-name($node)='Enumeration'">
   <xsl:value-of select="'int'"/>
  </xsl:when>
  <xsl:when test="$node/@context=$openmm_namespace_id">
   <xsl:value-of select="concat('OpenMM_', $node/@name)"/>
  </xsl:when>
  <xsl:otherwise>
   <xsl:value-of select="$node/@name"/>
  </xsl:otherwise>
 </xsl:choose>
</xsl:template>

594
595
596
597
598
599
600
601
602
603
<!-- Determine whether a type is one of the special handle types -->
<xsl:template name="is_handle_type">
 <xsl:param name="type_id"/>
 <xsl:variable name="node" select="/GCC_XML/*[@id=$type_id]"/>
 <xsl:choose>
  <xsl:when test="$type_id=$vec3_type_id"></xsl:when>
  <xsl:when test="$type_id=$vector_string_type_id">1</xsl:when>
  <xsl:when test="$type_id=$vector_vec3_type_id">1</xsl:when>
  <xsl:when test="$type_id=$vector_bond_type_id">1</xsl:when>
  <xsl:when test="$type_id=$map_parameter_type_id">1</xsl:when>
604
  <xsl:when test="$type_id=$map_property_type_id">1</xsl:when>
605
  <xsl:when test="$type_id=$vector_double_type_id">1</xsl:when>
606
  <xsl:when test="$type_id=$vector_int_type_id">1</xsl:when>
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
  <xsl:when test="$type_id=$vector_string_type_id">1</xsl:when>
  <xsl:when test="local-name($node)='Class' and $node/@context=$openmm_namespace_id">1</xsl:when>
  <xsl:when test="local-name($node)='ReferenceType' or local-name($node)='PointerType'">
   <xsl:call-template name="is_handle_type">
    <xsl:with-param name="type_id" select="$node/@type"/>
   </xsl:call-template>
  </xsl:when>
  <xsl:when test="local-name($node)='CvQualifiedType'">
   <xsl:call-template name="is_handle_type">
    <xsl:with-param name="type_id" select="$node/@type"/>
   </xsl:call-template>
  </xsl:when>
 </xsl:choose>
</xsl:template>

622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
<!-- Determine whether a method should be hidden -->
<xsl:template name="should_hide">
 <xsl:variable name="class_id" select="@context"/>
 <xsl:variable name="method_name" select="concat('OpenMM_', /GCC_XML/Class[@id=$class_id]/@name, '_', @name)"/>
 <xsl:if test="not(empty(index-of($skip_methods, $method_name)))">1</xsl:if>
 <xsl:call-template name="hide_type">
  <xsl:with-param name="type_id" select="@returns"/>
 </xsl:call-template>
 <xsl:for-each select="Argument">
  <xsl:call-template name="hide_type">
   <xsl:with-param name="type_id" select="@type"/>
  </xsl:call-template>
 </xsl:for-each>
</xsl:template>

<!-- This is called by should_hide.  It generates output if the specified type should be hidden. -->
<xsl:template name="hide_type">
 <xsl:param name="type_id"/>
 <xsl:variable name="node" select="/GCC_XML/*[@id=$type_id]"/>
 <xsl:choose>
  <xsl:when test="local-name($node)='ReferenceType' or local-name($node)='PointerType' or local-name($node)='CvQualifiedType'">
   <xsl:call-template name="hide_type">
    <xsl:with-param name="type_id" select="$node/@type"/>
   </xsl:call-template>
  </xsl:when>
647
  <xsl:when test="local-name($node)='Enumeration' or (local-name($node)='ReferenceType' and not(empty(/GCC_XML/Enumeration[@id=$node/@type])))">
648
649
650
651
652
653
654
655
656
657
   <xsl:call-template name="hide_type">
    <xsl:with-param name="type_id" select="$node/@context"/>
   </xsl:call-template>
  </xsl:when>
  <xsl:when test="$node/@context=$openmm_namespace_id and not(empty(index-of($hide_classes, $node/@name)))">
   <xsl:value-of select="1"/>
  </xsl:when>
 </xsl:choose>
</xsl:template>

658
</xsl:stylesheet>