KIDS  ver-0.0.1
KIDS : Kernel Integrated Dynamics Simulator
Loading...
Searching...
No Matches
swigInputBuilder.py
Go to the documentation of this file.
1#!/usr/bin/env python
2"""Build swig imput file from xml encoded header files (see gccxml)."""
3__author__ = "Randall J. Radmer"
4__version__ = "1.0"
5
6
7import sys, os
8import time
9import getopt
10import re
11import xml.etree.ElementTree as etree
12
13try:
14 from html.parser import HTMLParser
15except ImportError:
16 # python 2
17 from HTMLParser import HTMLParser
18
19INDENT = " "
20docTags = {'emphasis':'i', 'bold':'b', 'itemizedlist':'ul', 'listitem':'li', 'preformatted':'pre', 'computeroutput':'tt', 'subscript':'sub', 'verbatim': 'verbatim'}
21
22def is_method_abstract(argstring):
23 return argstring.split(")")[-1].find("=0") >= 0
24
26 """Strip a couple html tags used inside docstrings in the C++ source
27 to produce something more easily read as plain text.
28 """
29 class ConvertLists(HTMLParser):
30 def reset(self):
31 HTMLParser.reset(self)
32 self.out = []
33
34 def handle_starttag(self, tag, attrs):
35 if tag == 'li':
36 self.out.append('\n - ')
37 def handle_data(self, data):
38 self.out.append(data.strip())
39
40 convertlists = ConvertLists()
41
42 def replace_ul_tags(m):
43 a, b = m.span()
44 sub = s[a:b]
45
46 convertlists.reset()
47 convertlists.feed(sub)
48 return '\n%s\n\n' % ''.join(convertlists.out)
49
50 s = s.replace('<i>', '_').replace('</i>', '_')
51 s = s.replace('<b>', '*').replace('</b>', '*')
52
53 s = re.sub('\s*(<ul>.*?</ul>\s*)', replace_ul_tags, s, flags=re.MULTILINE | re.DOTALL)
54 return s
55
57 if text is None or len(text) == 0:
58 return ""
59 t = text.strip()
60 if len(t) == 0:
61 return t
62 if text[0].isspace():
63 t = " %s" % t
64 if text[-1].isspace():
65 t = "%s " % t
66 return t
67
68def getNodeText(node):
69 if node.text is not None:
70 s = node.text
71 else:
72 s = ""
73 for n in node:
74 if n.tag == "para":
75 s = "%s%s\n\n" % (s, getNodeText(n))
76 elif n.tag == "ref":
77 s = "%s%s" % (s, getNodeText(n))
78 elif n.tag == "xrefsect":
79 title = n.find("xreftitle")
80 description = n.find("xrefdescription")
81 if title is not None and description is not None and getNodeText(title).lower() == "deprecated":
82 s = "%s\n@deprecated %s\n\n" % (s, getNodeText(description))
83 else:
84 if n.tag in docTags:
85 tag = docTags[n.tag]
86 s = "%s<%s>%s</%s>" % (s, tag, getNodeText(n), tag)
87 if n.tail is not None:
88 s = "%s%s" % (s, n.tail)
89 return s
90
91def getText(subNodePath, node):
92 s = ""
93 for n in node.findall(subNodePath):
94 s = "%s%s" % (s, trimToSingleSpace(getNodeText(n)))
95 if n.tag == "para":
96 s = "%s\n\n" % s
97 return s.strip()
98
99NS_RE_PATTERN=re.compile("(.*)PROJECT_NS:[a-zA-Z0-9:]*:(.*)")
100def stripNSPrefix(name, rePattern=NS_RE_PATTERN):
101 try:
102 m=rePattern.search(name)
103 rValue = "%s%s" % m.group(1,2)
104 rValue.strip()
105 return rValue
106 except:
107 return name
108
109def findNodes(parent, path, **args):
110 nodes = []
111 for node in parent.findall(path):
112 match = True
113 for arg in args:
114 if arg not in node.attrib or node.attrib[arg] != args[arg]:
115 match = False
116 if match:
117 nodes.append(node)
118 return nodes
119
120def getClassMethodList(classNode, skipMethods):
121 className = getText("compoundname", classNode)
122 shortClassName=stripNSPrefix(className)
123 methodList=[]
124 for section in findNodes(classNode, "sectiondef", kind="public-static-func")+findNodes(classNode, "sectiondef", kind="public-func"):
125 for memberNode in findNodes(section, "memberdef", kind="function", prot="public"):
126 methDefinition = getText("definition", memberNode)
127 shortMethDefinition=stripNSPrefix(methDefinition)
128 shortMethDefinition = shortMethDefinition.replace(' &', '&')
129 methName=shortMethDefinition.split()[-1]
130 if (shortClassName, methName) in skipMethods: continue
131 numParams=len(findNodes(memberNode, 'param'))
132 if (shortClassName, methName, numParams) in skipMethods: continue
133 for catchString in ['Factory', 'Impl', 'Info', 'Kernel']:
134 if shortClassName.endswith(catchString):
135 sys.stderr.write("Warning: Including class %s\n" %
136 shortClassName)
137 continue
138
139 if (shortClassName, methName) in skipMethods: continue
140
141 # set template info
142
143 templateType = getText("templateparamlist/param/type", memberNode)
144 templateName = getText("templateparamlist/param/declname", memberNode)
145
146 methodList.append( (shortClassName,
147 memberNode,
148 shortMethDefinition,
149 methName,
150 shortClassName==methName,
151 '~'+shortClassName==methName, templateType, templateName ) )
152 return methodList
153
154
155def docstringTypemap(cpptype):
156 """Translate a C++ type to Python for inclusion in the Python docstrings.
157 This doesn't need to be perfectly accurate -- it's not used for generating
158 the actual swig wrapper code. It's only used for generating the docstrings.
159 """
160 pytype = cpptype
161 if pytype.startswith('const '):
162 pytype = pytype[6:]
163 if pytype.startswith('std::'):
164 pytype = pytype[5:]
165 pytype = pytype.strip('&')
166 return pytype.strip()
167
168
170 def __init__(self,
171 inputDirname,
172 configFilename,
173 outputFilename=None,
174 docstringFilename=None,
175 pythonprependFilename=None,
176 pythonappendFilename=None,
177 skipAdditionalMethods=[],
178 SWIG_VERSION='3.0.2'):
179 self.nodeByID={}
180
181 self.configModule = __import__(os.path.splitext(configFilename)[0])
182
183 self.skipMethods=self.configModule.SKIP_METHODS[:]
184 for skipMethod in skipAdditionalMethods:
185 items=skipMethod.split('::')
186 if len(items)==3:
187 items[2]=int(items[2])
188 self.skipMethods.append(tuple(items))
189
190 # Read all the XML files and merge them into a single document.
191 self.doc = etree.ElementTree(etree.Element('root'))
192 for file in os.listdir(inputDirname):
193 if file.lower().endswith('xml'):
194 root = etree.parse(os.path.join(inputDirname, file)).getroot()
195 for node in root:
196 self.doc.getroot().append(node)
197
198 if outputFilename:
199 self.fOut = open(outputFilename, 'w')
200 else:
201 self.fOut = sys.stdout
202
203 if docstringFilename:
204 self.fOutDocstring = open(docstringFilename, 'w')
205 else:
206 self.fOutDocstring = None
207
208 if pythonprependFilename:
209 self.fOutPythonprepend = open(pythonprependFilename, 'w')
210 else:
211 self.fOutPythonprepend = None
212
213 if pythonappendFilename:
214 self.fOutPythonappend = open(pythonappendFilename, 'w')
215 else:
216 self.fOutPythonappend = None
217
219
221
222 def _getNodeByID(self, id):
223 if id not in self.nodeByID:
224 for node in findNodes(self.doc.getroot(), "compounddef", id=id):
225 self.nodeByID[id] = node
226 return self.nodeByID[id]
227
229 orderedClassNodes=[]
230 for node in findNodes(self.doc.getroot(), "compounddef", kind="class", prot="public"):
231 self._findBaseNodes(node, orderedClassNodes)
232 return orderedClassNodes
233
234 def _findBaseNodes(self, node, excludedClassNodes=[]):
235 if node in excludedClassNodes: return
236 nodeName = getText("compoundname", node)
237 if (nodeName.split("::")[-1],) in self.skipMethods:
238 return
239 for baseNodePnt in findNodes(node, "basecompoundref", prot="public"):
240 if "refid" in baseNodePnt.attrib:
241 baseNodeID = baseNodePnt.attrib["refid"]
242 baseNode = self._getNodeByID(baseNodeID)
243 self._findBaseNodes(baseNode, excludedClassNodes)
244 excludedClassNodes.append(node)
245
246
247 def writeFactories(self):
248 self.fOut.write("\n/* Declare factories */\n\n")
249 modelSubclassList = []
250 integratorSubclassList = []
251 tabulatedFunctionSubclassList = []
252 for classNode in findNodes(self.doc.getroot(), "compounddef", kind="class", prot="public"):
253 className = getText("compoundname", classNode)
254 shortClassName=stripNSPrefix(className)
255 if (className.split("::")[-1],) in self.skipMethods:
256 continue
257 for baseNodePnt in findNodes(classNode, "basecompoundref", prot="public"):
258 if "refid" in baseNodePnt.attrib:
259 baseNodeID=baseNodePnt.attrib["refid"]
260 baseNode=self._getNodeByID(baseNodeID)
261 baseName = getText("compoundname", baseNode)
262 if baseName == 'OpenMM::Model':
263 modelSubclassList.append(shortClassName)
264 elif baseName in ('OpenMM::Integrator'):
265 integratorSubclassList.append(shortClassName)
266 elif baseName == 'OpenMM::TabulatedFunction':
267 tabulatedFunctionSubclassList.append(shortClassName)
268
269 self.fOut.write("%factory(OpenMM::Model& OpenMM::System::getForce")
270 for name in sorted(modelSubclassList):
271 self.fOut.write(",\n OpenMM::%s" % name)
272 self.fOut.write(");\n\n")
273
274 self.fOut.write("%factory(OpenMM::Model* OpenMM_XmlSerializer__cloneForce")
275 for name in sorted(modelSubclassList):
276 self.fOut.write(",\n OpenMM::%s" % name)
277 self.fOut.write(");\n\n")
278
279 self.fOut.write("%factory(OpenMM::Model* OpenMM_XmlSerializer__deserializeForce")
280 for name in sorted(modelSubclassList):
281 self.fOut.write(",\n OpenMM::%s" % name)
282 self.fOut.write(");\n\n")
283
284 self.fOut.write("%factory(OpenMM::Model& OpenMM::CustomCVForce::getCollectiveVariable")
285 for name in sorted(modelSubclassList):
286 self.fOut.write(",\n OpenMM::%s" % name)
287 self.fOut.write(");\n\n")
288
289 self.fOut.write("%factory(OpenMM::Integrator* OpenMM_XmlSerializer__cloneIntegrator")
290 for name in sorted(integratorSubclassList):
291 self.fOut.write(",\n OpenMM::%s" % name)
292 self.fOut.write(");\n\n")
293
294 self.fOut.write("%factory(OpenMM::Integrator* OpenMM_XmlSerializer__deserializeIntegrator")
295 for name in sorted(integratorSubclassList):
296 self.fOut.write(",\n OpenMM::%s" % name)
297 self.fOut.write(");\n\n")
298
299 self.fOut.write("%factory(OpenMM::Integrator& OpenMM::Context::getIntegrator")
300 for name in sorted(integratorSubclassList):
301 self.fOut.write(",\n OpenMM::%s" % name)
302 self.fOut.write(");\n\n")
303
304 self.fOut.write("%factory(OpenMM::Integrator& OpenMM::CompoundIntegrator::getIntegrator")
305 for name in sorted(integratorSubclassList):
306 self.fOut.write(",\n OpenMM::%s" % name)
307 self.fOut.write(");\n\n")
308
309 self.fOut.write("%factory(OpenMM::TabulatedFunction* OpenMM_XmlSerializer__cloneTabulatedFunction")
310 for name in sorted(tabulatedFunctionSubclassList):
311 self.fOut.write(",\n OpenMM::%s" % name)
312 self.fOut.write(");\n\n")
313
314 self.fOut.write("%factory(OpenMM::TabulatedFunction* OpenMM_XmlSerializer__deserializeTabulatedFunction")
315 for name in sorted(tabulatedFunctionSubclassList):
316 self.fOut.write(",\n OpenMM::%s" % name)
317 self.fOut.write(");\n\n")
318
319 for classNode in self._orderedClassNodes:
320 methodList=getClassMethodList(classNode, self.skipMethods)
321 for items in methodList:
322 (shortClassName, memberNode,
323 shortMethDefinition, methName,
324 isConstructors, isDestructor, templateType, templateName) = items
325 if shortMethDefinition == 'TabulatedFunction& getTabulatedFunction':
326 self.fOut.write("%factory(OpenMM::TabulatedFunction& OpenMM::")
327 self.fOut.write("%s::%s" % (shortClassName, methName))
328 for name in sorted(tabulatedFunctionSubclassList):
329 self.fOut.write(",\n OpenMM::%s" % name)
330 self.fOut.write(");\n\n")
331
332 self.fOut.write("%factory(OpenMM::VirtualSite& OpenMM::System::getVirtualSite, OpenMM::TwoParticleAverageSite, OpenMM::ThreeParticleAverageSite, OpenMM::OutOfPlaneSite, OpenMM::LocalCoordinatesSite);\n\n")
333 self.fOut.write("\n")
334
336 self.fOut.write("/* Global Constants */\n\n")
337 node = next((x for x in findNodes(self.doc.getroot(), "compounddef", kind="namespace") if x.findtext("compoundname") == "OpenMM"))
338 for section in findNodes(node, "sectiondef", kind="var"):
339 for memberNode in findNodes(section, "memberdef", kind="variable", mutable="no", prot="public", static="yes"):
340 vDef = stripNSPrefix(getText("definition", memberNode))
341 iDef = getText("initializer", memberNode)
342 if iDef.startswith("="):
343 iDef = iDef[1:]
344 self.fOut.write("static %s = %s;\n" % (vDef, iDef))
345 self.fOut.write("\n")
346
348 self.fOut.write("\n/* Forward Declarations */\n\n")
349
350 for classNode in self._orderedClassNodes:
351 hasConstructor=False
352 methodList=getClassMethodList(classNode, self.skipMethods)
353 for items in methodList:
354 (shortClassName, memberNode,
355 shortMethDefinition, methName,
356 isConstructors, isDestructor, templateType, templateName) = items
357 if isConstructors:
358 hasConstructor=True
359
360 className = stripNSPrefix(getText("compoundname", classNode))
361 # If has a constructor then tell swig tell to make a copy method
362 if hasConstructor:
363 self.fOut.write("%%copyctor %s ;\n" % className)
364 self.fOut.write("class %s ;\n" % className)
365 self.fOut.write("\n")
366
368 self.fOut.write("\n/* Class Declarations */\n\n")
369 for classNode in self._orderedClassNodes:
370 className = stripNSPrefix(getText("compoundname", classNode))
371 if self.fOutDocstring:
372 dNode = classNode.find('detaileddescription')
373 if dNode is not None:
374 docstring = getNodeText(dNode).strip().replace('"', '\\"')
375 docstring = striphtmltags(docstring)
376 self.fOutDocstring.write('%%feature("docstring") %s "%s";\n' % (className, docstring))
377 self.fOut.write("class %s" % className)
378 if className in self.configModule.MISSING_BASE_CLASSES:
379 self.fOut.write(" : public %s" %
380 self.configModule.MISSING_BASE_CLASSES[className])
381
382 for baseNodePnt in findNodes(classNode, "basecompoundref", prot="public"):
383 if "refid" in baseNodePnt.attrib:
384 baseName = stripNSPrefix(getText(".", baseNodePnt))
385 self.fOut.write(" : public %s" % baseName)
386 self.fOut.write(" {\n")
387 self.fOut.write("public:\n")
388 self.writeEnumerations(classNode)
389 self.writeMethods(classNode)
390 self.fOut.write("};\n\n")
391 self.fOut.write("\n")
392
393 def writeEnumerations(self, classNode):
394 enumNodes = []
395 for section in findNodes(classNode, "sectiondef", kind="public-type"):
396 for node in findNodes(section, "memberdef", kind="enum", prot="public"):
397 enumNodes.append(node)
398 for enumNode in enumNodes:
399 className = getText("compoundname", classNode)
400 shortClassName=stripNSPrefix(className)
401 enumName = getText("name", enumNode)
402 try:
403 self._enumByClassname[shortClassName].append(enumName)
404 except KeyError:
405 self._enumByClassname[shortClassName]=[enumName]
406 self.fOut.write("%senum %s {" % (INDENT, enumName))
407 argSep="\n"
408 for valueNode in findNodes(enumNode, "enumvalue", prot="public"):
409 vName = getText("name", valueNode)
410 vInit = getText("initializer", valueNode)
411 if vInit.startswith("="):
412 vInit = vInit[1:]
413 self.fOut.write("%s%s%s = %s" % (argSep, 2*INDENT, vName, vInit))
414 argSep=",\n"
415 self.fOut.write("\n%s};\n" % INDENT)
416 if len(enumNodes)>0: self.fOut.write("\n")
417
418 def writeMethods(self, classNode):
419 methodList=getClassMethodList(classNode, self.skipMethods)
420
421 #write only Constructors
422 for items in methodList:
423 (shortClassName, memberNode,
424 shortMethDefinition, methName,
425 isConstructors, isDestructor, templateType, templateName) = items
426 if isConstructors:
427 mArgsstring = getText("argsstring", memberNode)
428 try:
429 pExceptions = " %s" % getText('exceptions', memberNode)
430 except IndexError:
431 pExceptions = ""
432 self.fOut.write("%s%s%s%s;\n" % (INDENT, shortMethDefinition,
433 mArgsstring, pExceptions))
434 #write only Destructors
435 for items in methodList:
436 (shortClassName, memberNode,
437 shortMethDefinition, methName,
438 isConstructors, isDestructor, templateType, templateName) = items
439 if isDestructor:
440 mArgsstring = getText("argsstring", memberNode)
441 try:
442 pExceptions = " %s" % getText('exceptions', memberNode)
443 except IndexError:
444 pExceptions = ""
445 self.fOut.write("%s%s%s%s;\n" % (INDENT, shortMethDefinition,
446 mArgsstring, pExceptions))
447
448 #write only non Constructor and Destructor methods and python mods
449 self.fOut.write("\n")
450 methodsWithOutputArgs = set()
451 for items in methodList:
452 clearOutput=""
453 (shortClassName, memberNode,
454 shortMethDefinition, methName,
455 isConstructors, isDestructor, templateType, templateName) = items
456 if isConstructors or isDestructor: continue
457
458 key = (shortClassName, methName)
459 if key in self.configModule.DOC_STRINGS:
460 self.fOut.write('%%feature("autodoc", "%s") %s;\n' %
461 (self.configModule.DOC_STRINGS[key], methName))
462
463 paramList=findNodes(memberNode, 'param')
464 for pNode in paramList:
465 try:
466 pType = getText('type', pNode)
467 except IndexError:
468 pType = getText('type/ref', pNode)
469 pName = getText('declname', pNode)
470 key = (shortClassName, methName, pName)
471 if pType.find('&')>=0 and \
472 'const' not in pType.split():
473 if key not in self.configModule.NO_OUTPUT_ARGS:
474 eType = pType.split()[0]
475 if shortClassName in self._enumByClassname and \
476 eType in self._enumByClassname[shortClassName]:
477 simpleType = re.sub(eType, 'int', pType)
478 else:
479 simpleType = pType
480 self.fOut.write("%s%%apply %s OUTPUT { %s %s };\n" %
481 (INDENT, simpleType, pType, pName))
482 clearOutput = "%s%s%%clear %s %s;\n" \
483 % (clearOutput, INDENT, pType, pName)
484 methodsWithOutputArgs.add((shortClassName, methName))
485
486 mArgsstring = getText("argsstring", memberNode)
487 try:
488 pExceptions = " %s" % getText('exceptions', memberNode)
489 except IndexError:
490 pExceptions = ""
491 if memberNode.attrib["virt"].strip()!='non-virtual':
492 if 'virtual' not in shortMethDefinition.split():
493 shortMethDefinition="virtual %s" % shortMethDefinition
494 if( len(templateType) > 0 ):
495 self.fOut.write("%stemplate<%s %s> %s%s%s;\n" % (INDENT, templateType, templateName, shortMethDefinition, mArgsstring, pExceptions))
496 else:
497 self.fOut.write("%s%s%s%s;\n" % (INDENT, shortMethDefinition, mArgsstring, pExceptions))
498 if clearOutput:
499 self.fOut.write(clearOutput)
500
501 #write python mod blocks
502 for items in methodList:
503 (shortClassName, memberNode,
504 shortMethDefinition, methName,
505 isConstructors, isDestructor, templateType, templateName) = items
506 paramList = findNodes(memberNode, 'param')
507
508 # write pythonprepend blocks
509 if isConstructors:
510 mArgsstring = '' # specifying args to constructors seems to prevent append and prepend from working
511 else:
512 mArgsstring = getText("argsstring", memberNode)
513 if self.fOutPythonprepend and \
514 len(paramList) and \
515 not is_method_abstract(mArgsstring):
516 text = '''
517%pythonprepend OpenMM::{shortClassName}::{methName}{mArgsstring} %{{{{{{0}}
518%}}}}'''.format(shortClassName=shortClassName, methName=methName, mArgsstring=mArgsstring)
519 textInside = ''
520 key = (shortClassName, methName)
521 for argNum in self.configModule.STEAL_OWNERSHIP.get(key, []):
522 argName = getText('declname', paramList[argNum])
523
524 textInside += '''
525 if not {argName}.thisown:
526 s = ("the %s object does not own its corresponding OpenMM object"
527 % self.__class__.__name__)
528 raise Exception(s)'''.format(argName=argName)
529
530
531 # Convert input arguments to the proper units, if specified.
532 if key not in methodsWithOutputArgs:
533 if key in self.configModule.UNITS:
534 argUnits=self.configModule.UNITS[key][1]
535 elif ("*", methName) in self.configModule.UNITS:
536 argUnits=self.configModule.UNITS[("*", methName)][1]
537 else:
538 argUnits = ()
539 if len(argUnits) > 0 and isConstructors:
540 textInside += '''
541 args = list(args)'''
542 for i, units in enumerate(argUnits):
543 if units is not None:
544 if isConstructors:
545 argName = 'args[%s]' % i
546 else:
547 argName = getText('declname', paramList[i])
548 textInside += '''
549 if unit.is_quantity({argName}):
550 {argName} = {argName}.value_in_unit({units})'''.format(argName=argName, units=units)
551
552 for argNum in self.configModule.REQUIRE_ORDERED_SET.get(key, []):
553 argName = getText('declname', paramList[argNum])
554
555 textInside += '''
556 {argName} = list({argName})'''.format(argName=argName)
557 if textInside:
558 self.fOutPythonprepend.write(text.format(textInside))
559
560 # write pythonappend blocks
561 if self.fOutPythonappend \
562 and not is_method_abstract(mArgsstring):
563 key = (shortClassName, methName)
564 #sys.stdout.write("key %s %s \n" % (shortClassName, methName))
565
566 addText=''
567 returnType = getText("type", memberNode)
568
569 if key in self.configModule.UNITS:
570 valueUnits=self.configModule.UNITS[key]
571 elif ("*", methName) in self.configModule.UNITS:
572 valueUnits=self.configModule.UNITS[("*", methName)]
573 elif methName.startswith('get') and returnType not in ('void', 'int', 'bool', 'std::string', 'const std::string &'):
574 s = 'do not know how to add units to %s %s::%s' \
575 % (returnType, shortClassName, methName)
576 raise Exception(s)
577 else:
578 valueUnits=[None, ()]
579
580 index=0
581 if valueUnits[0] is not None:
582 sys.stdout.write("%s.%s() returns %s\n" %
583 (shortClassName, methName, valueUnits[0]))
584 if len(valueUnits[1])>0:
585 addText = "%s%sval[%d]=unit.Quantity(val[%d], %s)\n" \
586 % (addText, INDENT,
587 index, index,
588 valueUnits[0])
589 index+=1
590 else:
591 addText = "%s%sval=unit.Quantity(val, %s)\n" \
592 % (addText, INDENT, valueUnits[0])
593
594 for vUnit in valueUnits[1]:
595 if vUnit is not None and key in methodsWithOutputArgs:
596 addText = "%s%sval[%s]=unit.Quantity(val[%s], %s)\n" \
597 % (addText, INDENT, index, index, vUnit)
598 index+=1
599
600 if key in self.configModule.STEAL_OWNERSHIP:
601 for argNum in self.configModule.STEAL_OWNERSHIP[key]:
602 argName = getText('declname', paramList[argNum])
603 addText = "%s%s%s.thisown=0\n" \
604 % (addText, INDENT, argName)
605
606 if addText:
607 self.fOutPythonappend.write("%pythonappend")
608 self.fOutPythonappend.write(" OpenMM::%s::%s(" % key)
609 sepChar=''
610 outputIndex=0
611 for pNode in paramList:
612 try:
613 pType = getText('type', pNode)
614 except IndexError:
615 pType = getText('type/ref', pNode)
616 # parse default arguments
617 try:
618 defaultValue = getText('defval', pNode)
619 except:
620 defaultValue = ""
621 if defaultValue != "":
622 defaultValue = "=%s" %defaultValue
623 pName = getText('declname', pNode)
624 self.fOutPythonappend.write("%s%s %s%s" % (sepChar, pType, pName, defaultValue))
625 sepChar=', '
626
627 if pType.find('&')>=0 and \
628 'const' not in pType.split() and \
629 key not in self.configModule.NO_OUTPUT_ARGS and \
630 len(valueUnits[1])>0:
631 try:
632 unitType=valueUnits[1][outputIndex]
633 except IndexError:
634 s = "missing unit type for %s.%s() arg named %s" \
635 % (shortClassName, methName, pName)
636 raise Exception(s)
637 sys.stdout.write("%s.%s() returns %s as %s\n" %
638 (shortClassName, methName,
639 pName, unitType))
640 outputIndex+=1
641 if memberNode.attrib["const"]=="yes":
642 constString=' const'
643 else:
644 constString=''
645 self.fOutPythonappend.write(")%s %%{\n" % constString)
646 self.fOutPythonappend.write(addText)
647 self.fOutPythonappend.write("%}\n\n")
648
649
650 #print "Done python mod blocks\n"
651 #write Docstring info
652 for items in methodList:
653 (shortClassName, memberNode,
654 shortMethDefinition, methName,
655 isConstructors, isDestructor, templateType, templateName ) = items
656
657 if self.fOutDocstring:
658 signatureParams = findNodes(memberNode, 'param')
659 assert len(findNodes(memberNode, 'detaileddescription')) == 1
660 dNode = findNodes(memberNode, 'detaileddescription')[0]
661
662 try:
663 description=getText('para', dNode)
664 description.strip()
665 except IndexError:
666 description = ''
667 params = findNodes(dNode, 'para/parameterlist/parameteritem')
668
669 paramString = ['Parameters', '----------']
670 returnString = ['Returns', '-------']
671
672 if len(params) > 0:
673 if len(signatureParams) != len(params):
674 raise ValueError('docstring in %s.%s does not match the signature' % (shortClassName, methName))
675
676 for pNode, pSignatureNode in zip(params, signatureParams):
677 parameterNameNode = findNodes(pNode, 'parameternamelist/parametername')[0]
678 argDoc = getText('parameterdescription/para', pNode)
679 argName = getNodeText(parameterNameNode)
680 argType = docstringTypemap(getText('type', pSignatureNode))
681
682 isOutput = parameterNameNode.get('direction') == 'out'
683 if isOutput:
684 returnString.extend(['%s : %s' % (argName, argType), ' %s' % argDoc])
685 else:
686 paramString.extend(['%s : %s' % (argName, argType), ' %s' % argDoc])
687
688
689 returnSection = findNodes(dNode, 'para/simplesect')
690 if len(returnSection) > 0:
691 returnNode = returnSection[0]
692 if returnNode.get('kind') == 'return':
693 argType = getNodeText(findNodes(memberNode, 'type')[0])
694 argType = docstringTypemap(argType)
695 returnString.extend([argType, ' %s' % getNodeText(returnNode).strip()])
696
697 dString = '\n'.join(
698 ([description] + [''] if len(description) > 0 else []) +
699 (paramString + [''] if len(paramString) > 2 else []) +
700 (returnString if len(returnString) > 2 else [])).strip()
701 if dString:
702 dString = re.sub(r'([^\\])"', r'\g<1>\"', dString)
703 s = '%%feature("docstring") OpenMM::%s::%s "%s";' \
704 % (shortClassName, methName, dString)
705 self.fOutDocstring.write("%s\n" % s)
706
707 self.fOutDocstring.write("\n\n")
708
709
710 def writeSwigFile(self):
711 self.fOut.write("/* Swig input file,\n")
712 self.fOut.write("%sgenerated by %s on %s\n*/\n\n\n"
713 % (INDENT, sys.argv[0], time.asctime()))
714 self.fOut.write("%include \"factory.i\"\n")
715 self.fOut.write("\nnamespace OpenMM {\n\n")
716 # self.writeFactories()
717 # self.writeGlobalConstants()
718 # self.writeForwardDeclarations()
719 # self.writeClassDeclarations()
720 self.fOut.write("\n} // namespace OpenMM\n\n")
721
722
724 opts, args_proper = getopt.getopt(sys.argv[1:], 'hi:c:o:d:a:z:s:v:')
725 inputDirname = None
726 configFilename = None
727 outputFilename = ""
728 docstringFilename = ""
729 pythonprependFilename = ""
730 pythonappendFilename = ""
731 skipAdditionalMethods = []
732 swigVersion = '3.0.2'
733 for option, parameter in opts:
734 if option=='-h': usageError()
735 if option=='-i': inputDirname = parameter
736 if option=='-c': configFilename=parameter
737 if option=='-o': outputFilename = parameter
738 if option=='-d': docstringFilename = parameter
739 if option=='-a': pythonprependFilename=parameter
740 if option=='-z': pythonappendFilename=parameter
741 if option=='-s': skipAdditionalMethods.append(parameter)
742 if option=='-v': swigVersion = parameter
743 if not inputDirname: usageError()
744 if not configFilename: usageError()
745 return (args_proper, inputDirname, configFilename, outputFilename,
746 docstringFilename, pythonprependFilename, pythonappendFilename,
747 skipAdditionalMethods, swigVersion)
748
749def main():
750 (args_proper, inputDirname, configFilename, outputFilename,
751 docstringFilename, pythonprependFilename, pythonappendFilename,
752 skipAdditionalMethods, swigVersion) = parseCommandLine()
753 sBuilder = SwigInputBuilder(inputDirname, configFilename, outputFilename,
754 docstringFilename, pythonprependFilename,
755 pythonappendFilename, skipAdditionalMethods,
756 swigVersion)
757 #print "Calling writeSwigFile\n"
758 sBuilder.writeSwigFile()
759 #print "Done writeSwigFile\n"
760
761 return
762
763
765 sys.stdout.write('usage: %s -i xmlHeadersFilename \\\n' \
766 % os.path.basename(sys.argv[0]))
767 sys.stdout.write(' %s -c inputConfigFilename\n' \
768 % (' '*len(os.path.basename(sys.argv[0]))))
769 sys.stdout.write(' %s[-o swigInputDirname]\n' \
770 % (' '*len(os.path.basename(sys.argv[0]))))
771 sys.stdout.write(' %s[-d docstringFilename]\n' \
772 % (' '*len(os.path.basename(sys.argv[0]))))
773 sys.stdout.write(' %s[-a pythonprependFilename]\n' \
774 % (' '*len(os.path.basename(sys.argv[0]))))
775 sys.stdout.write(' %s[-z pythonappendFilename]\n' \
776 % (' '*len(os.path.basename(sys.argv[0]))))
777 sys.stdout.write(' %s[-s skippedClasses]\n' \
778 % (' '*len(os.path.basename(sys.argv[0]))))
779 sys.stdout.write(' %s[-v swigVersion]\n' \
780 % (' '*len(os.path.basename(sys.argv[0]))))
781 sys.exit(1)
782
783if __name__=='__main__':
784 main()
785
786
__init__(self, inputDirname, configFilename, outputFilename=None, docstringFilename=None, pythonprependFilename=None, pythonappendFilename=None, skipAdditionalMethods=[], SWIG_VERSION='3.0.2')
_findBaseNodes(self, node, excludedClassNodes=[])
stripNSPrefix(name, rePattern=NS_RE_PATTERN)
is_method_abstract(argstring)
getClassMethodList(classNode, skipMethods)
findNodes(parent, path, **args)
getText(subNodePath, node)