From a89a3c9fecd05a623aef900114cf936ba9ecd9e7 Mon Sep 17 00:00:00 2001 From: "N.N." Date: Wed, 15 Mar 2006 04:55:34 +0000 Subject: 0.8.1 svn path=/trunk/; revision=4710 --- .../gridflow/optional/rblti/gen_ltilib_classes.py | 354 +++++++++++++++++++++ 1 file changed, 354 insertions(+) create mode 100644 externals/gridflow/optional/rblti/gen_ltilib_classes.py (limited to 'externals/gridflow/optional/rblti/gen_ltilib_classes.py') diff --git a/externals/gridflow/optional/rblti/gen_ltilib_classes.py b/externals/gridflow/optional/rblti/gen_ltilib_classes.py new file mode 100644 index 00000000..09c2aee9 --- /dev/null +++ b/externals/gridflow/optional/rblti/gen_ltilib_classes.py @@ -0,0 +1,354 @@ +#!/usr/bin/env python +#****************************************************************************** +# rblti, Copyright 2005 by Mathieu Bouchard and Heri Andria +# pylti, Copyright 2005 by Michael Neuroth +# a wrapper for ltilib using SWIG +#****************************************************************************** +# +# Tool to generate header files for SWIG to process the nested classes "parameters" +# +# 1) generate XML files for the ltilib with doxygen (tested with version 1.4.3) (use this switch in doc.cfg file: GENERATE_XML = YES) +# 2) generate the new header files for SWIG with this python script + +from xml.dom import minidom +import os +import sys +from distutils.text_file import TextFile +str_version = '0.32' + +basedir=None +# handle the settings: WORKAREA has to be defined ! +if len(sys.argv)>1: + basedir = sys.argv[1] +else: + workarea = os.getenv('WORKAREA') + # is pylti not part of the ltilib ? Yes --> than we need a directory structure of WORKAREA_PATH/import/ltilib/xml + if workarea<>None: + basedir = workarea+os.sep+'import'+os.sep+'ltilib'+os.sep+'xml'+os.sep + # check if we are in misc directory of the ltilib distribution (ltilib/misc/pylti) + # very simple way: navigate up and navigate down again + else: + strCheckPath = '..'+os.sep+'..'+os.sep+'misc'+os.sep+'pylti'+'-'+str_version + try: + # try to read lti.i, this is a good indication of a pylti directory + aTestFile = TextFile(filename=strCheckPath+os.sep+'lti.i') + basedir = '..'+os.sep+'..'+os.sep+'xml'+os.sep # move up ltipy and misc directory + except IOError: pass + +output_dir = 'generated' +#output_dir = 'generated_ruby' + +def f(x): return 'classlti_1_1'+x+'.xml' +#def g(x): return 'lti::_'+x+'::_'+x+'_parameters' +def g(x): return 'lti::_'+x+'::'+x+'_parameters' + +# list of tuples with ( xml-file-name, full-qualified-name of the base class ) +lst = [ (f('functor_1_1parameters'), 'lti::ioObject') + , (f('ioFunctor_1_1parameters'), g('functor')) + , (f('ioImage_1_1parameters'), g('ioFunctor')) + , (f('usePalette_1_1parameters'), g('functor')) + , (f('segmentation_1_1parameters'), g('functor')) + , (f('regionGrowing_1_1parameters'), g('segmentation')) + , (f('meanShiftSegmentation_1_1parameters'), g('segmentation')) + , (f('kMeansSegmentation_1_1parameters'), g('segmentation')) + , (f('whiteningSegmentation_1_1parameters'), g('segmentation')) + , (f('csPresegmentation_1_1parameters'), g('segmentation')) + , (f('colorQuantization_1_1parameters'), g('functor')) + , (f('kMColorQuantization_1_1parameters'), g('colorQuantization')) + , (f('viewerBase_1_1parameters'), g('functor')) + , (f('externViewer_1_1parameters'), g('viewerBase')) + , (f('objectsFromMask_1_1parameters'), g('segmentation')) + , (f('objectsFromMask_1_1objectStruct'), 'lti::ioObject') + , (f('tree_1_1node'), 'lti::ioObject') + , (f('featureExtractor_1_1parameters'), g('functor')) + , (f('globalFeatureExtractor_1_1parameters'),g('featureExtractor')) + , (f('localFeatureExtractor_1_1parameters'), g('featureExtractor')) + , (f('geometricFeatures_1_1parameters'), g('globalFeatureExtractor')) + , (f('localMoments_1_1parameters'), g('localFeatureExtractor')) + , (f('chromaticityHistogram_1_1parameters'), g('globalFeatureExtractor')) + , (f('modifier_1_1parameters'), g('functor')) + , (f('polygonApproximation_1_1parameters'), g('modifier')) + , (f('transform_1_1parameters'), g('functor')) + , (f('gradientFunctor_1_1parameters'), g('transform')) + , (f('skeleton_1_1parameters'), g('transform')) + , (f('colorContrastGradient_1_1parameters'), g('gradientFunctor')) + , (f('edgeDetector_1_1parameters'), g('modifier')) + , (f('classicEdgeDetector_1_1parameters'), g('edgeDetector')) + , (f('cannyEdges_1_1parameters'), g('edgeDetector')) + , (f('filter_1_1parameters'), g('modifier')) + , (f('convolution_1_1parameters'), g('filter')) + , (f('morphology_1_1parameters'), g('modifier')) + , (f('dilation_1_1parameters'), g('morphology')) + , (f('erosion_1_1parameters'), g('morphology')) + , (f('distanceTransform_1_1parameters'), g('morphology')) + , (f('classifier_1_1parameters'), 'lti::ioObject') + , (f('classifier_1_1outputTemplate'), 'lti::ioObject') + , (f('classifier_1_1outputVector'), 'lti::ioObject') + , (f('decisionTree_1_1parameters'), g('classifier')) + , (f('ioBMP_1_1parameters'), g('ioFunctor')) + , (f('ioPNG_1_1parameters'), g('ioFunctor')) + , (f('ioJPEG_1_1parameters'), g('ioFunctor')) + , (f('distanceTransform_1_1sedMask'), None) + ] + +# some constants +nl = '\n' + +# Doku: +#------- +# 'memberdef' ==> 'kind'=function +# --> 'name' +# --> 'type' # Return Type +# --> 'param' # Argumente +# --> 'type' + +def WriteFile(name,txt): + f = open(name,'w') + f.write(txt) + +def GetAttribute(attribs,key): + for k,v in attribs: + if k==key: + return v + +def GetValue(elem): + #print elem,elem.firstChild,elem.nodeType + if elem.nodeType == elem.TEXT_NODE: + return elem.data + elif elem.nodeType == elem.ELEMENT_NODE: + if elem.firstChild <> None: + s = '' + for e in elem.childNodes: + s += GetValue(e) #+' ' + return s + return '' + elif elem.nodeType == elem.ATTRIBUTE_NODE: + return 'xxxx' + elif elem.firstChild.nodeType == elem.TEXT_NODE: + return elem.firstChild.data + return '???' + +def GetValueForItem(node,itemname,bOnlyFirst=False): + s = '' + nodes = node.getElementsByTagName(itemname) + #print '>>>>>>>',nodes,itemname,len(nodes) + if bOnlyFirst: + s += GetValue( nodes[0] ) + else: + for node in nodes: + s += GetValue( node ) + s += ' ' + return s + +def ProcessFunction(member,classname,newclassname,bIsConst=False,bIsPureVirtual=False,bIsHeader=True): + s = '' + arg = 'arg' + names = member.getElementsByTagName('name') + # es sollte immer nur einen Namen geben ! + nameNode = names[0] + name = GetValue(nameNode) + + s += GetValueForItem(member,'type',bOnlyFirst=True) + s += ' ' + if not bIsHeader: + s += classname+'::' + s += GetValueForItem(member,'name') + s += '( ' + + # Behandlung des Constructors + bIsConstructor = (name == classname) + + params = member.getElementsByTagName('param') + for i in range(len(params)): + if i>0: + s += ', ' + s += GetValueForItem(params[i],'type') + s += ' '+arg+str(i) + + s += ' )' + if bIsConst: + s += ' const' + if bIsPureVirtual: + s += ' = 0' + + if not bIsHeader: + s += nl + s += '{'+nl + s += ' '+'pObj->'+name+'(' + for i in range(len(params)): + if i>0: + s += ', ' + s += arg+str(i) + s += ');'+nl + s += '}' + + s += ';'+nl + + # dies ist fuer das manuelle name mangling notwendig ! + s = s.replace(classname,newclassname) + + return s + +def VerifyParameterType(sType): + """ + Sonderbehandlung fuer den Typ, falls es ein parameters Typ ist, + notwendig, da der parameters Typ mit einem define umbenannt wird... + + Beispiel: gradientFunctor::parameters --> gradientFunctor_parameters + """ + s = sType + elem = sType.split('::') + if len(elem)>1 and elem[-1]=='parameters': + s = 'lti_'+sType.replace('::','_') + print "FOUND:",s + return s + +def ProcessAttribute(member): + s = '' + sType = GetValueForItem(member,'type',bOnlyFirst=True) + sType = VerifyParameterType(sType) + s += sType + s += ' ' + s += GetValueForItem(member,'name') + s += GetValueForItem(member,'argsstring') + s += ';' + return s + +def ProcessEnum(member): + s = '' + s += 'enum ' + name = GetValueForItem(member,'name',bOnlyFirst=True) + # Behandlung der unbenannten enums + if name[0]=='@': + name = '' + s += name + s += ' {'+nl + items = member.getElementsByTagName('enumvalue') + for i in range(len(items)): + e = items[i] + if i>0: + s += ',' + s += GetValueForItem(e,'name') + val = GetValueForItem(e,'initializer') + if val<>None and len(val)>0: + s += ' = ' + val + s += nl + s += '};'+nl + return s + +def ProcessMember(member,classname,newclassname,bIsHeader): + s = '' + attribs = member.attributes.items() + if GetAttribute(attribs,'prot')=='public': + if GetAttribute(attribs,'kind')=='function': + s = ProcessFunction(member, classname, newclassname, GetAttribute(attribs,'const')=='yes', GetAttribute(attribs,'virt')=='pure-virtual', bIsHeader ) #, GetAttribute(attribs,'virtual')=='virtual' + elif GetAttribute(attribs,'kind')=='variable': + s = ProcessAttribute(member) + elif GetAttribute(attribs,'kind')=='enum': + s = ProcessEnum(member) + else: + s = '/* not a function or attribute */' + return s+'\n' + +def ProcessAllMembers(theclassname,thenewclassname,members,bIsHeader=True,indent=' '*4): + s = '' + for member in members: + s += indent+ProcessMember(member,theclassname,thenewclassname,bIsHeader) + return s + +def ProcessHeaderFile(classname,theclassname,thenewclassname,members,baseclassname=None): + s = '' + s += '#ifndef _'+thenewclassname+'_h'+nl + s += '#define _'+thenewclassname+'_h'+nl + s += nl + sClose = '' + names = classname.split('::') + sTypedef = 'typedef ' + for n in range(len(names)): + if n0: + sPre += '_' + s += sPre+names[n]+' {'+nl + if nNone: + s += ' : public '+baseclassname + s += nl + s += '{'+nl + s += 'public:'+nl + s += ProcessAllMembers(theclassname,thenewclassname,members) + #s += 'private:'+nl + #s += ' /*pObj*/'+nl + s += '};'+nl + s += sClose +# s += sTypedef+thenewclassname+' '+thenewclassname[1:]+';'+nl # erstes _ vom Klassennamen entfernen + s += sTypedef+thenewclassname+' '+thenewclassname+';'+nl + s += '}' + s += nl + s += '#endif'+nl + return s + +def ProcessCppFile(classname,theclassname,thenewclassname,members): + s = '' + s += nl + s += '#include "'+thenewclassname+'.h"'+nl + s += nl + s += ProcessAllMembers(theclassname,thenewclassname,members,bIsHeader=False,indent='') + s += nl + return s + +def ProcessClass(classname,theclassname,thenewclassname,members,baseclassname=None): + s = '' + s += ProcessHeaderFile(classname,theclassname,thenewclassname,members,baseclassname) + s += nl + #s += ProcessCppFile(classname,theclassname,thenewclassname,members) + return s + +def ProcessFile(filename,baseclassname,add_to_output=None): + dom = minidom.parse(filename) + + #elem = dom.getElementsByTagName('compoundname') + members = dom.getElementsByTagName('memberdef') + + classitem = dom.getElementsByTagName('compoundname') + classname = GetValue(classitem[0]) # lti::object + print "processing",classname,"...", + + nameitems = classname.split('::') + + theclassname = nameitems[-1] # object + s = '' + for i in range(len(nameitems)): + # ignoriere das erste lti:: + if i>0: +# s += '_' + if i>1: s += '_' #to prevent class names starting with '_', Ruby hates that + s += nameitems[i] + + thenewclassname = s #classname.replace('::','_') # lti_object + print thenewclassname + +# outputfilename = thenewclassname + outputfilename = '_'+thenewclassname + if add_to_output<>None: + outputfilename += add_to_output + outputfilename += '.h' + + s = ProcessClass(classname,theclassname,thenewclassname,members,baseclassname) + + WriteFile(output_dir+os.sep+outputfilename,s) + +def ProcessAllFiles(lst): + for e in lst: + filename = basedir+e[0] + ProcessFile(filename,e[1]) + +#------------------------------------------------- + +ProcessAllFiles(lst) + + -- cgit v1.2.1