1 |
elmer |
1.1 |
diff -Naur root.orig/reflex/python/genreflex/gendict06.py root/reflex/python/genreflex/gendict06.py
|
2 |
|
|
--- root.orig/reflex/python/genreflex/gendict06.py 1970-01-01 01:00:00.000000000 +0100
|
3 |
|
|
+++ root/reflex/python/genreflex/gendict06.py 2007-11-04 05:24:03.000000000 +0100
|
4 |
|
|
@@ -0,0 +1,1744 @@
|
5 |
|
|
+# Copyright CERN, CH-1211 Geneva 23, 2004-2006, All rights reserved.
|
6 |
|
|
+#
|
7 |
|
|
+# Permission to use, copy, modify, and distribute this software for any
|
8 |
|
|
+# purpose is hereby granted without fee, provided that this copyright and
|
9 |
|
|
+# permissions notice appear in all copies and derivatives.
|
10 |
|
|
+#
|
11 |
|
|
+# This software is provided "as is" without express or implied warranty.
|
12 |
|
|
+
|
13 |
|
|
+import xml.parsers.expat
|
14 |
|
|
+import os, sys, string, time
|
15 |
|
|
+import gccdemangler
|
16 |
|
|
+
|
17 |
|
|
+class genDictionary(object) :
|
18 |
|
|
+#----------------------------------------------------------------------------------
|
19 |
|
|
+ def __init__(self, hfile, opts):
|
20 |
|
|
+ self.classes = []
|
21 |
|
|
+ self.namespaces = []
|
22 |
|
|
+ self.typeids = []
|
23 |
|
|
+ self.fktypeids = []
|
24 |
|
|
+ self.files = {}
|
25 |
|
|
+ self.typedefs = []
|
26 |
|
|
+ self.basictypes = []
|
27 |
|
|
+ self.methods = []
|
28 |
|
|
+ self.functions = []
|
29 |
|
|
+ self.enums = []
|
30 |
|
|
+ self.variables = []
|
31 |
|
|
+ self.vtables = {}
|
32 |
|
|
+ self.hfile = os.path.normpath(hfile).replace(os.sep,'/')
|
33 |
|
|
+ self.pool = opts.get('pool',False)
|
34 |
|
|
+ self.interpreter= opts.get('interpreter',False)
|
35 |
|
|
+ self.quiet = opts.get('quiet',False)
|
36 |
|
|
+ self.resolvettd = opts.get('resolvettd',True)
|
37 |
|
|
+ self.xref = {}
|
38 |
|
|
+ self.xrefinv = {}
|
39 |
|
|
+ self.cppClassSelect = {}
|
40 |
|
|
+ self.cppVariableSelect = {}
|
41 |
|
|
+ self.cppEnumSelect = {}
|
42 |
|
|
+ self.cppFunctionSelect = {}
|
43 |
|
|
+ self.last_id = ''
|
44 |
|
|
+ self.transtable = string.maketrans('<>&*,: ().$-', '__rp__s___dm')
|
45 |
|
|
+ self.ignoremeth = ('rbegin', 'rend', '_Eq','_Lt', 'value_comp')
|
46 |
|
|
+ self.x_id = iter(xrange(sys.maxint))
|
47 |
|
|
+ self.errors = 0
|
48 |
|
|
+ self.warnings = 0
|
49 |
|
|
+ self.comments = opts.get('comments', False)
|
50 |
|
|
+ self.iocomments = opts.get('iocomments', False)
|
51 |
|
|
+ self.no_membertypedefs = opts.get('no_membertypedefs', False)
|
52 |
|
|
+ self.generated_shadow_classes = []
|
53 |
|
|
+ self.selectionname = 'ROOT::Reflex::Selection'
|
54 |
|
|
+ self.unnamedNamespaces = []
|
55 |
|
|
+ self.globalNamespaceID = ''
|
56 |
|
|
+ # The next is to avoid a known problem with gccxml that it generates a
|
57 |
|
|
+ # references to id equal '_0' which is not defined anywhere
|
58 |
|
|
+ self.xref['_0'] = {'elem':'Unknown', 'attrs':{'id':'_0','name':''}, 'subelems':[]}
|
59 |
|
|
+#----------------------------------------------------------------------------------
|
60 |
|
|
+ def start_element(self, name, attrs):
|
61 |
|
|
+ if 'id' in attrs :
|
62 |
|
|
+ self.xref[attrs['id']] = {'elem':name, 'attrs':attrs, 'subelems':[]}
|
63 |
|
|
+ self.last_id = attrs['id']
|
64 |
|
|
+ if name in ('EnumValue','Argument') :
|
65 |
|
|
+ self.xref[self.last_id]['subelems'].append(attrs)
|
66 |
|
|
+ elif name in ('Base',) :
|
67 |
|
|
+ if not 'bases' in self.xref[self.last_id] : self.xref[self.last_id]['bases'] = []
|
68 |
|
|
+ self.xref[self.last_id]['bases'].append(attrs)
|
69 |
|
|
+ elif name in ('Class','Struct') :
|
70 |
|
|
+ self.classes.append(attrs)
|
71 |
|
|
+ elif name in ('Function',) :
|
72 |
|
|
+ self.functions.append(attrs)
|
73 |
|
|
+ elif name in ('Enumeration',) :
|
74 |
|
|
+ self.enums.append(attrs)
|
75 |
|
|
+ elif name in ('Variable',) :
|
76 |
|
|
+ self.variables.append(attrs)
|
77 |
|
|
+ elif name in ('OperatorFunction',) :
|
78 |
|
|
+ attrs['operator'] = 'true'
|
79 |
|
|
+ self.functions.append(attrs)
|
80 |
|
|
+ elif name in ('Constructor','Method','OperatorMethod') :
|
81 |
|
|
+ if 'name' in attrs and attrs['name'][0:3] != '_ZT' :
|
82 |
|
|
+ self.methods.append(attrs)
|
83 |
|
|
+ elif name == 'Namespace' :
|
84 |
|
|
+ self.namespaces.append(attrs)
|
85 |
|
|
+ elif name == 'File' :
|
86 |
|
|
+ self.files[attrs['id']] = {'name':attrs['name']}
|
87 |
|
|
+ elif name == 'Typedef' :
|
88 |
|
|
+ self.typedefs.append(attrs)
|
89 |
|
|
+ elif name == 'Variable' :
|
90 |
|
|
+ if 'name' in attrs and attrs['name'][0:4] == '_ZTV':
|
91 |
|
|
+ if 'context' in attrs : self.vtables[attrs['context']] = attrs
|
92 |
|
|
+ elif name == 'FundamentalType' :
|
93 |
|
|
+ self.basictypes.append(normalizeFragment(attrs['name']))
|
94 |
|
|
+#----------------------------------------------------------------------------------
|
95 |
|
|
+ def findSpecialNamespace(self):
|
96 |
|
|
+ for ns in self.namespaces:
|
97 |
|
|
+ if ns['name'].find('.') != -1:
|
98 |
|
|
+ self.unnamedNamespaces.append(ns['id'])
|
99 |
|
|
+ elif ns['name'] == '::' :
|
100 |
|
|
+ self.globalNamespaceID = ns['id']
|
101 |
|
|
+#----------------------------------------------------------------------------------
|
102 |
|
|
+# This function is not used anymore, because it had a problem with templated types
|
103 |
|
|
+# showing up as members of a scope in the gccxml generated output. If gccxml puts
|
104 |
|
|
+# templated types as members this function should be resurrected for performance
|
105 |
|
|
+# reasons. It shall be called from self.parse instead of 'for col in [self.class...'
|
106 |
|
|
+ def collectCppSelections(self, ns) :
|
107 |
|
|
+ for m in ns.get('members').split():
|
108 |
|
|
+ xm = self.xref[m]
|
109 |
|
|
+ xelem = xm['elem']
|
110 |
|
|
+ if xelem in ('Namespace',) :
|
111 |
|
|
+ self.collectCppSelections(xm['attrs'])
|
112 |
|
|
+ cname = self.genTypeName(m)
|
113 |
|
|
+ if xelem in ('Class','Struct'):
|
114 |
|
|
+ #self.xrefinv[cname] = m
|
115 |
|
|
+ self.cppClassSelect[cname[len(self.selectionname)+2:]] = m
|
116 |
|
|
+ if xelem in ('Variable',):
|
117 |
|
|
+ self.cppVariableSelect[cname[len(self.selectionname)+2:]] = m
|
118 |
|
|
+ if xelem in ('Enumeration',):
|
119 |
|
|
+ self.cppEnumSelect[cname[len(self.selectionname)+2:]] = m
|
120 |
|
|
+ if xelem in ('Function',):
|
121 |
|
|
+ self.cppFunctionSelect[cname[len(self.selectionname)+2:]] = m
|
122 |
|
|
+#----------------------------------------------------------------------------------
|
123 |
|
|
+ def inScope(self, item, ctxt):
|
124 |
|
|
+ ictxt = item.get('context')
|
125 |
|
|
+ if ictxt :
|
126 |
|
|
+ if ictxt == ctxt : return 1
|
127 |
|
|
+ else : return self.inScope(self.xref[ictxt]['attrs'], ctxt)
|
128 |
|
|
+ return 0
|
129 |
|
|
+#----------------------------------------------------------------------------------
|
130 |
|
|
+ def addCppClassSelect(self, key, value ) : self.cppClassSelect[key] = value
|
131 |
|
|
+ def addCppStructSelect(self, key, value ) : self.cppClassSelect[key] = value
|
132 |
|
|
+ def addCppFunctionSelect(self, key, value ) : self.cppFunctionSelect[key] = value
|
133 |
|
|
+ def addCppVariableSelect(self, key, value ) : self.cppVariableSelect[key] = value
|
134 |
|
|
+ def addCppEnumerationSelect(self, key, value ) : self.cppEnumSelect[key] = value
|
135 |
|
|
+#----------------------------------------------------------------------------------
|
136 |
|
|
+ def parse(self, file) :
|
137 |
|
|
+ p = xml.parsers.expat.ParserCreate()
|
138 |
|
|
+ p.StartElementHandler = self.start_element
|
139 |
|
|
+ f = open(file)
|
140 |
|
|
+ p.ParseFile(f)
|
141 |
|
|
+ f.close()
|
142 |
|
|
+ cppselid = '';
|
143 |
|
|
+ cppsellen = len(self.selectionname)+2
|
144 |
|
|
+ # get the id of the selection namespace
|
145 |
|
|
+ for n in self.namespaces:
|
146 |
|
|
+ if self.genTypeName(n['id']) == self.selectionname :
|
147 |
|
|
+ cppselid = n.get('id')
|
148 |
|
|
+ break
|
149 |
|
|
+ # for all classes, variables etc. check if they are in the seleciton ns and add them if
|
150 |
|
|
+ for col in [self.classes, self.variables, self.enums, self.functions ]:
|
151 |
|
|
+ for it in col:
|
152 |
|
|
+ if self.inScope(it, cppselid) :
|
153 |
|
|
+ cid = it['id']
|
154 |
|
|
+ funname = 'addCpp'+self.xref[cid]['elem']+'Select'
|
155 |
|
|
+ if funname in dir(self):
|
156 |
|
|
+ self.__class__.__dict__[funname](self, self.genTypeName(cid)[cppsellen:], cid)
|
157 |
|
|
+ self.tryCppSelections()
|
158 |
|
|
+ self.findSpecialNamespace()
|
159 |
|
|
+#----------------------------------------------------------------------------------
|
160 |
|
|
+ def tryCppSelections(self):
|
161 |
|
|
+ for c in self.classes:
|
162 |
|
|
+ id = self.cppClassSelect.get(self.genTypeName(c['id'],alltempl=True))
|
163 |
|
|
+ if (id != None) :
|
164 |
|
|
+ selection = {'id' : id}
|
165 |
|
|
+ self.add_template_defaults (c, selection)
|
166 |
|
|
+ self.notice_transient (c, selection)
|
167 |
|
|
+ self.notice_autoselect (c, selection)
|
168 |
|
|
+ for v in self.variables:
|
169 |
|
|
+ id = self.cppVariableSelect.get(self.genTypeName(v['id']))
|
170 |
|
|
+ if (id != None):
|
171 |
|
|
+ if v.has_key('extra') : v['extra']['autoselect'] = 'true'
|
172 |
|
|
+ else : v['extra'] = {'autoselect':'true'}
|
173 |
|
|
+ for e in self.enums:
|
174 |
|
|
+ id = self.cppEnumSelect.get(self.genTypeName(e['id']))
|
175 |
|
|
+ if (id != None):
|
176 |
|
|
+ if e.has_key('extra') : e['extra']['autoselect'] = 'true'
|
177 |
|
|
+ else : e['extra'] = {'autoselect':'true'}
|
178 |
|
|
+ for f in self.functions:
|
179 |
|
|
+ id = self.cppFunctionSelect.get(self.genTypeName(f['id']))
|
180 |
|
|
+ #fixme: check if signature (incl. return type?) is the same
|
181 |
|
|
+ if (id != None):
|
182 |
|
|
+ if f.has_key('extra') : f['extra']['autoselect'] = 'true'
|
183 |
|
|
+ else : f['extra'] = {'autoselect':'true'}
|
184 |
|
|
+ return
|
185 |
|
|
+#----------------------------------------------------------------------------------
|
186 |
|
|
+ def notice_transient (self, c, selection):
|
187 |
|
|
+ transient_fields = []
|
188 |
|
|
+ for f in self.get_fields (selection):
|
189 |
|
|
+ tid = f['type']
|
190 |
|
|
+ tname = self.genTypeName (tid)
|
191 |
|
|
+ if tname.startswith (self.selectionname+"::TRANSIENT"):
|
192 |
|
|
+ transient_fields.append (f['name'])
|
193 |
|
|
+
|
194 |
|
|
+ if transient_fields:
|
195 |
|
|
+ for f in self.get_fields (c):
|
196 |
|
|
+ fname = f['name']
|
197 |
|
|
+ if fname in transient_fields:
|
198 |
|
|
+ if f.has_key('extra') : f['extra']['transient'] = 'true'
|
199 |
|
|
+ else : f['extra'] = {'transient':'true'}
|
200 |
|
|
+ transient_fields.remove (fname)
|
201 |
|
|
+
|
202 |
|
|
+ if transient_fields:
|
203 |
|
|
+ print "--->> genreflex: WARNING: Transient fields declared in selection " +\
|
204 |
|
|
+ "not present in class:", \
|
205 |
|
|
+ self.xref[selection['id']]['attrs']['name'], transient_fields
|
206 |
|
|
+ self.warnings += 1
|
207 |
|
|
+ return
|
208 |
|
|
+#----------------------------------------------------------------------------------
|
209 |
|
|
+ def notice_autoselect (self, c, selection):
|
210 |
|
|
+ self_autoselect = 1
|
211 |
|
|
+ for f in self.get_fields (selection):
|
212 |
|
|
+ tid = f['type']
|
213 |
|
|
+ tname = self.genTypeName (tid)
|
214 |
|
|
+ if tname.startswith( self.selectionname+'::NO_SELF_AUTOSELECT'): self_autoselect = 0
|
215 |
|
|
+ if tname.startswith (self.selectionname+'::AUTOSELECT'):
|
216 |
|
|
+ if 'members' in c:
|
217 |
|
|
+ for mnum in c['members'].split():
|
218 |
|
|
+ m = self.xref[mnum]
|
219 |
|
|
+ if 'name' in m['attrs'] and m['attrs']['name'] == f['name']:
|
220 |
|
|
+ if m['elem'] == 'Field':
|
221 |
|
|
+ fattrs = self.xref[m['attrs']['type']]['attrs']
|
222 |
|
|
+ if fattrs.has_key('extra') : fattrs['extra']['autoselect'] = 'true'
|
223 |
|
|
+ else : fattrs['extra'] = {'autoselect':'true'}
|
224 |
|
|
+ else :
|
225 |
|
|
+ print '--->> genreflex: WARNING: AUTOSELECT selection functionality for %s not implemented yet' % m['elem']
|
226 |
|
|
+ self.warnings += 1
|
227 |
|
|
+ if self_autoselect :
|
228 |
|
|
+ attrs = self.xref[c['id']]['attrs']
|
229 |
|
|
+ if attrs.has_key('extra') : attrs['extra']['autoselect'] = 'true'
|
230 |
|
|
+ else : attrs['extra'] = {'autoselect':'true'}
|
231 |
|
|
+ return
|
232 |
|
|
+#----------------------------------------------------------------------------------
|
233 |
|
|
+ def get_fields (self, c):
|
234 |
|
|
+ xref = self.xref
|
235 |
|
|
+ cid = c['id']
|
236 |
|
|
+ attrs = xref[cid]['attrs']
|
237 |
|
|
+ return [xref[m]['attrs']
|
238 |
|
|
+ for m in attrs.get('members', '').split()
|
239 |
|
|
+ if xref[m]['elem'] == 'Field']
|
240 |
|
|
+#----------------------------------------------------------------------------------
|
241 |
|
|
+ def get_member (self, c, name):
|
242 |
|
|
+ xref = self.xref
|
243 |
|
|
+ cid = c['id']
|
244 |
|
|
+ attrs = self.xref[cid]['attrs']
|
245 |
|
|
+ for m in attrs.get('members', '').split():
|
246 |
|
|
+ if xref[m]['attrs']['name'] == name:
|
247 |
|
|
+ return m
|
248 |
|
|
+ return None
|
249 |
|
|
+#----------------------------------------------------------------------------------
|
250 |
|
|
+ def has_typedef (self, c, name):
|
251 |
|
|
+ cid = c['id']
|
252 |
|
|
+ attrs = self.xref[cid]['attrs']
|
253 |
|
|
+ for m in attrs.get('members', '').split():
|
254 |
|
|
+ if (self.xref[m]['elem'] == 'Typedef' and
|
255 |
|
|
+ self.xref[m]['attrs']['name'] == name):
|
256 |
|
|
+ return self.xref[m]['attrs']['type']
|
257 |
|
|
+ return None
|
258 |
|
|
+#----------------------------------------------------------------------------------
|
259 |
|
|
+ def resolveTypedefName( self, name ) :
|
260 |
|
|
+ notname = ['*','<','>',',',':',' ']
|
261 |
|
|
+ for td in self.typedefs :
|
262 |
|
|
+ tdname = self.genTypeName(td['id'])
|
263 |
|
|
+ f = name.find(tdname)
|
264 |
|
|
+ if f != -1 :
|
265 |
|
|
+ g = f + len(tdname)
|
266 |
|
|
+ if (f == 0 or name[f-1] in notname) and (g == len(tdname) or name[g] in notname) :
|
267 |
|
|
+ defname = self.genTypeName(td['type'])
|
268 |
|
|
+ if defname[len(defname)-1] == '>' : defname += ' '
|
269 |
|
|
+ name = self.resolveTypedefName(name.replace(tdname, defname, 1))
|
270 |
|
|
+ return name
|
271 |
|
|
+#----------------------------------------------------------------------------------
|
272 |
|
|
+ def genFakeTypedef( self, cid, name ) :
|
273 |
|
|
+ nid = cid+'f'
|
274 |
|
|
+ while nid in self.fktypeids : nid += 'f'
|
275 |
|
|
+ catt = self.xref[cid]['attrs']
|
276 |
|
|
+ attrs = {'name':name,'id':nid,'type':catt['id'],'context':self.globalNamespaceID}
|
277 |
|
|
+ for i in ['location','file','line'] : attrs[i] = catt[i]
|
278 |
|
|
+ self.typedefs.append(attrs)
|
279 |
|
|
+ self.xref[attrs['id']] = {'elem':'Typedef', 'attrs':attrs, 'subelems':[]}
|
280 |
|
|
+ self.fktypeids.append(nid)
|
281 |
|
|
+#----------------------------------------------------------------------------------
|
282 |
|
|
+ def resolveSelectorTypedefs( self, sltor ):
|
283 |
|
|
+ newselector = []
|
284 |
|
|
+ for sel in sltor :
|
285 |
|
|
+ if not sel.has_key('used'):
|
286 |
|
|
+ attrs = sel['attrs']
|
287 |
|
|
+ for n in ['name', 'pattern']:
|
288 |
|
|
+ if attrs.has_key(n) and attrs[n].find('<') != -1 :
|
289 |
|
|
+ newname = self.resolveTypedefName(attrs[n])
|
290 |
|
|
+ if newname != attrs[n]:
|
291 |
|
|
+ sel['attrs']['o_'+n] = attrs[n]
|
292 |
|
|
+ sel['attrs'][n] = newname
|
293 |
|
|
+ newselector.append(sel)
|
294 |
|
|
+ return newselector
|
295 |
|
|
+#----------------------------------------------------------------------------------
|
296 |
|
|
+ def selclasses(self, sel, deep) :
|
297 |
|
|
+ selec = []
|
298 |
|
|
+ if sel :
|
299 |
|
|
+ self.selector = sel # remember the selector
|
300 |
|
|
+ for c in self.classes :
|
301 |
|
|
+ if 'incomplete' in c : continue
|
302 |
|
|
+ # this check fixes a bug in gccxml 0.6.0_patch3 which sometimes generates incomplete definitions
|
303 |
|
|
+ # of classes (without members). Every version after 0.6.0_patch3 is tested and fixes this bug
|
304 |
|
|
+ if not c.has_key('members') : continue
|
305 |
|
|
+
|
306 |
|
|
+ # Filter any non-public data members for minimal interpreter dict
|
307 |
|
|
+ if self.interpreter:
|
308 |
|
|
+ cxref = self.xref[c['id']]
|
309 |
|
|
+ # assumes that the default is "public"
|
310 |
|
|
+ if cxref.has_key('attrs') and 'access' in cxref['attrs'] :
|
311 |
|
|
+ continue
|
312 |
|
|
+
|
313 |
|
|
+ match = self.selector.matchclass( self.genTypeName(c['id']), self.files[c['file']]['name'])
|
314 |
|
|
+ if match[0] and not match[1] :
|
315 |
|
|
+ c['extra'] = match[0]
|
316 |
|
|
+ selec.append(c)
|
317 |
|
|
+ for t in self.typedefs:
|
318 |
|
|
+ match = self.selector.matchclass( self.genTypeName(t['id']), self.files[t['file']]['name'])
|
319 |
|
|
+ if match[0] and not match[1] :
|
320 |
|
|
+ c = self.xref[t['type']]
|
321 |
|
|
+ while c['elem'] == 'Typedef': c = self.xref[c['attrs']['type']]
|
322 |
|
|
+ if c['elem'] in ('Class','Struct'):
|
323 |
|
|
+ self.genTypeID(t['id'])
|
324 |
|
|
+ catt = c['attrs']
|
325 |
|
|
+ catt['extra'] = match[0]
|
326 |
|
|
+ if catt not in selec :
|
327 |
|
|
+ print '--->> genreflex: INFO: Using typedef %s to select class %s' % (self.genTypeName(t['id']), self.genTypeName(catt['id']))
|
328 |
|
|
+ selec.append(catt)
|
329 |
|
|
+ if self.resolvettd :
|
330 |
|
|
+ newselector = self.resolveSelectorTypedefs( self.selector.sel_classes )
|
331 |
|
|
+ if newselector:
|
332 |
|
|
+ for c in self.classes:
|
333 |
|
|
+ match = self.selector.matchclassTD( self.genTypeName(c['id']), self.files[c['file']]['name'], newselector )
|
334 |
|
|
+ if match[0] and not match[1] :
|
335 |
|
|
+ n = 'name'
|
336 |
|
|
+ if 'pattern' in match[0] : n = 'pattern'
|
337 |
|
|
+ if not self.quiet:
|
338 |
|
|
+ print '--->> genreflex: INFO: Replacing selection %s "%s" with "%s"' % ( n, match[0]['o_'+n], match[0][n] )
|
339 |
|
|
+ c['extra'] = match[0]
|
340 |
|
|
+ if c not in selec : selec.append(c)
|
341 |
|
|
+ if n == 'name' : self.genFakeTypedef(c['id'], match[0]['o_name'])
|
342 |
|
|
+ return self.autosel (selec)
|
343 |
|
|
+ else : self.selector = None
|
344 |
|
|
+ local = filter(self.filefilter, self.classes)
|
345 |
|
|
+ typed = self.typedefclasses()
|
346 |
|
|
+ templ = self.tmplclasses(local)
|
347 |
|
|
+ if deep :
|
348 |
|
|
+ types = []
|
349 |
|
|
+ for c in local : self.getdependent(c['id'], types)
|
350 |
|
|
+ for c in typed : self.getdependent(c['id'], types)
|
351 |
|
|
+ for c in templ : self.getdependent(c['id'], types)
|
352 |
|
|
+ classes = map( lambda t : self.xref[t]['attrs'], types)
|
353 |
|
|
+ else :
|
354 |
|
|
+ classes = clean( local + typed + templ )
|
355 |
|
|
+ # Filter STL implementation specific classes
|
356 |
|
|
+ classes = filter( lambda c: self.genTypeName(c['id'])[:6] != 'std::_' ,classes)
|
357 |
|
|
+ classes = filter( lambda c: c['name'][:2] != '._' ,classes) # unamed structs and unions
|
358 |
|
|
+ return self.autosel( classes )
|
359 |
|
|
+ #----------------------------------------------------------------------------------
|
360 |
|
|
+ def autosel(self, classes):
|
361 |
|
|
+ types = []
|
362 |
|
|
+ for c in self.classes:
|
363 |
|
|
+ self.getdependent(c['id'], types)
|
364 |
|
|
+ for t in types:
|
365 |
|
|
+ c = self.xref[t]['attrs']
|
366 |
|
|
+ if 'extra' in c and c['extra'].get('autoselect') and c not in classes:
|
367 |
|
|
+ classes.append (c)
|
368 |
|
|
+ return classes
|
369 |
|
|
+#----------------------------------------------------------------------------------
|
370 |
|
|
+ def selfunctions(self, sel) :
|
371 |
|
|
+ selec = []
|
372 |
|
|
+ self.selector = sel # remember the selector
|
373 |
|
|
+ if self.selector :
|
374 |
|
|
+ for f in self.functions :
|
375 |
|
|
+ funcname = self.genTypeName(f['id'])
|
376 |
|
|
+ if self.selector.selfunction( funcname ) and not self.selector.excfunction( funcname ) :
|
377 |
|
|
+ selec.append(f)
|
378 |
|
|
+ elif 'extra' in f and f['extra'].get('autoselect') and f not in selec:
|
379 |
|
|
+ selec.append(f)
|
380 |
|
|
+ return selec
|
381 |
|
|
+#----------------------------------------------------------------------------------
|
382 |
|
|
+ def selenums(self, sel) :
|
383 |
|
|
+ selec = []
|
384 |
|
|
+ self.selector = sel # remember the selector
|
385 |
|
|
+ if self.selector :
|
386 |
|
|
+ for e in self.enums :
|
387 |
|
|
+ # Filter any non-public data members for minimal interpreter dict
|
388 |
|
|
+ if self.interpreter:
|
389 |
|
|
+ exref = self.xref[e['id']]
|
390 |
|
|
+ # assumes that the default is "public"
|
391 |
|
|
+ if exref.has_key('attrs') and 'access' in exref['attrs'] :
|
392 |
|
|
+ continue
|
393 |
|
|
+
|
394 |
|
|
+ ename = self.genTypeName(e['id'])
|
395 |
|
|
+ if self.selector.selenum( ename ) and not self.selector.excenum( ename ) :
|
396 |
|
|
+ selec.append(e)
|
397 |
|
|
+ elif 'extra' in e and e['extra'].get('autoselect') and e not in selec:
|
398 |
|
|
+ selec.append(e)
|
399 |
|
|
+ return selec
|
400 |
|
|
+#---------------------------------------------------------------------------------
|
401 |
|
|
+ def selvariables(self, sel) :
|
402 |
|
|
+ selec = []
|
403 |
|
|
+ self.selector = sel # remember the selector
|
404 |
|
|
+ if self.selector :
|
405 |
|
|
+ for v in self.variables :
|
406 |
|
|
+ varname = self.genTypeName(v['id'])
|
407 |
|
|
+ if self.selector.selvariable( varname ) and not self.selector.excvariable( varname ) :
|
408 |
|
|
+ selec.append(v)
|
409 |
|
|
+ elif 'extra' in v and v['extra'].get('autoselect') and v not in selec:
|
410 |
|
|
+ selec.append(v)
|
411 |
|
|
+ return selec
|
412 |
|
|
+#----------------------------------------------------------------------------------
|
413 |
|
|
+ def getdependent(self, cid, types ) :
|
414 |
|
|
+ elem = self.xref[cid]['elem']
|
415 |
|
|
+ attrs = self.xref[cid]['attrs']
|
416 |
|
|
+ if elem in ('Typedef', 'ArrayType', 'PointerType','ReferenceType' ):
|
417 |
|
|
+ self.getdependent(attrs['type'], types)
|
418 |
|
|
+ elif elem in ('Class','Struct') :
|
419 |
|
|
+ if 'incomplete' in attrs : return
|
420 |
|
|
+ if attrs['id'] not in types :
|
421 |
|
|
+ types.append(attrs['id'])
|
422 |
|
|
+ if 'members' in attrs :
|
423 |
|
|
+ for m in attrs['members'].split() :
|
424 |
|
|
+ if self.xref[m]['elem'] == 'Field' :
|
425 |
|
|
+ type = self.xref[m]['attrs']['type']
|
426 |
|
|
+ self.getdependent(type, types)
|
427 |
|
|
+ if 'bases' in attrs :
|
428 |
|
|
+ for b in attrs['bases'].split() :
|
429 |
|
|
+ if b[:10] == 'protected:' : b = b[10:]
|
430 |
|
|
+ if b[:8] == 'private:' : b = b[8:]
|
431 |
|
|
+ self.getdependent(b, types)
|
432 |
|
|
+#----------------------------------------------------------------------------------
|
433 |
|
|
+ def sortselclasses(self, l):
|
434 |
|
|
+ nolit = [' ', ':', '<', '>']
|
435 |
|
|
+ l2 = []
|
436 |
|
|
+ for x in l:
|
437 |
|
|
+ ap = 1
|
438 |
|
|
+ for i in range(len(l2)):
|
439 |
|
|
+ l2ifn = l2[i]['fullname']
|
440 |
|
|
+ xfn = x['fullname']
|
441 |
|
|
+ bpos = l2ifn.find(xfn)
|
442 |
|
|
+ epos = bpos + len(xfn)
|
443 |
|
|
+ if bpos != -1 and ( bpos == 0 or l2ifn[bpos-1] in nolit ) and ( epos == len(l2ifn) or l2ifn[epos] in nolit ) :
|
444 |
|
|
+ l2.insert(i,x)
|
445 |
|
|
+ ap = 0
|
446 |
|
|
+ break
|
447 |
|
|
+ if ap : l2.append(x)
|
448 |
|
|
+ return l2
|
449 |
|
|
+#----------------------------------------------------------------------------------
|
450 |
|
|
+ def generate(self, file, selclasses, selfunctions, selenums, selvariables, cppinfo) :
|
451 |
|
|
+ for c in selclasses : c['fullname'] = self.genTypeName(c['id'])
|
452 |
|
|
+ selclasses = self.sortselclasses(selclasses)
|
453 |
|
|
+ names = []
|
454 |
|
|
+ f = open(file,'w')
|
455 |
|
|
+ f.write(self.genHeaders(cppinfo))
|
456 |
|
|
+ f_buffer = ''
|
457 |
|
|
+ f_shadow = '\n// Shadow classes to obtain the data member offsets \n'
|
458 |
|
|
+ f_shadow += 'namespace __shadow__ {\n'
|
459 |
|
|
+ for c in selclasses :
|
460 |
|
|
+ if 'incomplete' not in c :
|
461 |
|
|
+ if not self.quiet : print 'class '+ c['fullname']
|
462 |
|
|
+ names.append(c['fullname'])
|
463 |
|
|
+ self.completeClass( c )
|
464 |
|
|
+ self.enhanceClass( c )
|
465 |
|
|
+ scons, stubs = self.genClassDict( c )
|
466 |
|
|
+ f_buffer += stubs
|
467 |
|
|
+ f_buffer += scons
|
468 |
|
|
+ f_shadow += self.genClassShadow(c)
|
469 |
|
|
+ f_shadow += '}\n\n'
|
470 |
|
|
+ f_buffer += self.genFunctionsStubs( selfunctions )
|
471 |
|
|
+ f_buffer += self.genInstantiateDict(selclasses, selfunctions, selenums, selvariables)
|
472 |
|
|
+ f.write('namespace {\n')
|
473 |
|
|
+ f.write(self.genNamespaces(selclasses + selfunctions + selenums + selvariables))
|
474 |
|
|
+ f.write(self.genAllTypes())
|
475 |
|
|
+ f.write('} // unnamed namespace\n')
|
476 |
|
|
+ f.write(f_shadow)
|
477 |
|
|
+ f.write('namespace {\n')
|
478 |
|
|
+ f.write(f_buffer)
|
479 |
|
|
+ f.write('} // unnamed namespace\n')
|
480 |
|
|
+ f.close()
|
481 |
|
|
+ return names, self.warnings, self.errors
|
482 |
|
|
+#----------------------------------------------------------------------------------
|
483 |
|
|
+ def add_template_defaults (self, c, selection):
|
484 |
|
|
+ tlist = []
|
485 |
|
|
+ for f in self.get_fields (selection):
|
486 |
|
|
+ tid = f['type']
|
487 |
|
|
+ tname = self.genTypeName (tid)
|
488 |
|
|
+ if tname.startswith (self.selectionname+"::TEMPLATE_DEFAULTS"):
|
489 |
|
|
+ tid = {'id': tid}
|
490 |
|
|
+ nodefault_tid = self.has_typedef (tid, 'nodefault')
|
491 |
|
|
+ i = 1
|
492 |
|
|
+ while 1:
|
493 |
|
|
+ arg = self.has_typedef (tid, 't%d' % i)
|
494 |
|
|
+ if not arg:
|
495 |
|
|
+ break
|
496 |
|
|
+ if arg == nodefault_tid:
|
497 |
|
|
+ tlist.append ('=')
|
498 |
|
|
+ else:
|
499 |
|
|
+ tlist.append (self.genTypeName (arg))
|
500 |
|
|
+ i += 1
|
501 |
|
|
+ if tlist:
|
502 |
|
|
+ name = self.xref[c['id']]['attrs']['name']
|
503 |
|
|
+ i = name.find ('<')
|
504 |
|
|
+ if i>=0 : name = name[:i]
|
505 |
|
|
+ stldeftab[name] = tuple (tlist)
|
506 |
|
|
+ return
|
507 |
|
|
+#----------------------------------------------------------------------------------
|
508 |
|
|
+ def isUnnamedType(self, name) :
|
509 |
|
|
+ if name and (name.find('.') != -1 or name.find('$') != -1): return 1
|
510 |
|
|
+ else : return 0
|
511 |
|
|
+#----------------------------------------------------------------------------------
|
512 |
|
|
+ def filefilter(self, attrs):
|
513 |
|
|
+ if self.genTypeName(attrs['id'])[:len(self.selectionname)] == self.selectionname : return 0
|
514 |
|
|
+ fileid = attrs['file']
|
515 |
|
|
+ if self.files[fileid]['name'] == self.hfile : return 1
|
516 |
|
|
+ else : return 0
|
517 |
|
|
+#----------------------------------------------------------------------------------
|
518 |
|
|
+ def memberfilter( self, id ) :
|
519 |
|
|
+ elem = self.xref[id]['elem']
|
520 |
|
|
+ attrs = self.xref[id]['attrs']
|
521 |
|
|
+ args = self.xref[id]['subelems']
|
522 |
|
|
+ if 'name' in attrs :
|
523 |
|
|
+ if attrs['name'] in self.ignoremeth : return 0
|
524 |
|
|
+ #----Filter any method and operator for minimal POOL dict -----
|
525 |
|
|
+ if self.pool :
|
526 |
|
|
+ if elem in ('OperatorMethod','Converter') : return 0
|
527 |
|
|
+ elif elem in ('Method',) :
|
528 |
|
|
+ if attrs['name'] not in ('at','size','clear','resize') : return 0
|
529 |
|
|
+ elif elem in ('Constructor',) :
|
530 |
|
|
+ if len(args) > 1 : return 0
|
531 |
|
|
+ elif len(args) == 1 :
|
532 |
|
|
+ if self.genTypeName(args[0]['type']) != 'const '+self.genTypeName(attrs['context'])+'&' : return 0
|
533 |
|
|
+ #----Filter any non-public data members for minimal interpreter dict -----
|
534 |
|
|
+ if self.interpreter and elem in ('Field') and 'access' in attrs : # assumes that the default is "public"
|
535 |
|
|
+ return 0
|
536 |
|
|
+ #----Filter any non public method
|
537 |
|
|
+ if 'access' in attrs : # assumes that the default is "public"
|
538 |
|
|
+ if elem in ('Constructor','Destructor','Method','OperatorMethod','Converter') : return 0
|
539 |
|
|
+ #----Filter any copy constructor with a private copy constructor in any base
|
540 |
|
|
+ if elem == 'Constructor' and len(args) == 1 and 'name' in args[0] and args[0]['name'] == '_ctor_arg' :
|
541 |
|
|
+ if self.isConstructorPrivate(attrs['context']) : return 0
|
542 |
|
|
+ #----Filter any constructor for pure abstract classes
|
543 |
|
|
+ if 'context' in attrs :
|
544 |
|
|
+ if 'abstract' in self.xref[attrs['context']]['attrs'] :
|
545 |
|
|
+ if elem in ('Constructor',) : return 0
|
546 |
|
|
+ #----Filter using the exclusion list in the selection file
|
547 |
|
|
+ if self.selector and 'name' in attrs and elem in ('Constructor','Destructor','Method','OperatorMethod','Converter') :
|
548 |
|
|
+ if self.selector.excmethod(self.genTypeName(attrs['context']), attrs['name'] ) : return 0
|
549 |
|
|
+ return 1
|
550 |
|
|
+#----------------------------------------------------------------------------------
|
551 |
|
|
+ def tmplclasses(self, local):
|
552 |
|
|
+ result = []
|
553 |
|
|
+ for c in self.classes :
|
554 |
|
|
+ name = c['name']
|
555 |
|
|
+ if name.find('<') == -1 : continue
|
556 |
|
|
+ temp = name[name.find('<')+1:name.rfind('>')]
|
557 |
|
|
+ for lc in local :
|
558 |
|
|
+ if temp.find(lc['name']) != -1 : result.append(c)
|
559 |
|
|
+ return result
|
560 |
|
|
+#----------------------------------------------------------------------------------
|
561 |
|
|
+ def typedefclasses(self):
|
562 |
|
|
+ result = []
|
563 |
|
|
+ for t in self.typedefs :
|
564 |
|
|
+ fileid = t['location']
|
565 |
|
|
+ fileid = fileid[:fileid.index(':')]
|
566 |
|
|
+ if self.xref[fileid]['attrs']['name'] == self.hfile :
|
567 |
|
|
+ if self.xref[t['type']]['elem'] in ('Class','Struct') :
|
568 |
|
|
+ result.append(self.xref[t['type']]['attrs'])
|
569 |
|
|
+ return result
|
570 |
|
|
+#----------------------------------------------------------------------------------
|
571 |
|
|
+ def isConstructorPrivate(self, id ) :
|
572 |
|
|
+ attrs = self.xref[id]['attrs']
|
573 |
|
|
+ if 'members' in attrs :
|
574 |
|
|
+ for m in attrs['members'].split() :
|
575 |
|
|
+ elem = self.xref[m]['elem']
|
576 |
|
|
+ attr = self.xref[m]['attrs']
|
577 |
|
|
+ args = self.xref[m]['subelems']
|
578 |
|
|
+ if elem == 'Constructor' and len(args) == 1 :
|
579 |
|
|
+ if self.genTypeName(args[0]['type']) == 'const '+self.genTypeName(attr['context'])+'&' :
|
580 |
|
|
+ if 'access' in attr and attr['access'] == 'private' : return True
|
581 |
|
|
+ if 'bases' in attrs :
|
582 |
|
|
+ for b in attrs['bases'].split() :
|
583 |
|
|
+ if b[:10] == 'protected:' : b = b[10:]
|
584 |
|
|
+ if b[:8] == 'private:' : b = b[8:]
|
585 |
|
|
+ if self.isConstructorPrivate(b) : return True
|
586 |
|
|
+ return False
|
587 |
|
|
+#----------------------------------------------------------------------------------
|
588 |
|
|
+ def isDestructorNonPublic(self, id ) :
|
589 |
|
|
+ attrs = self.xref[id]['attrs']
|
590 |
|
|
+ if 'members' in attrs :
|
591 |
|
|
+ for m in attrs['members'].split() :
|
592 |
|
|
+ elem = self.xref[m]['elem']
|
593 |
|
|
+ attr = self.xref[m]['attrs']
|
594 |
|
|
+ if elem == 'Destructor' :
|
595 |
|
|
+ if attr.get('access') in ('private','protected') : return True
|
596 |
|
|
+ else : return False
|
597 |
|
|
+ if 'bases' in attrs :
|
598 |
|
|
+ for b in attrs['bases'].split() :
|
599 |
|
|
+ if b[:10] == 'protected:' : b = b[10:]
|
600 |
|
|
+ if b[:8] == 'private:' : b = b[8:]
|
601 |
|
|
+ if self.isDestructorNonPublic(b) : return True
|
602 |
|
|
+ return False
|
603 |
|
|
+#----------------------------------------------------------------------------------
|
604 |
|
|
+ def isClassVirtual(self, attrs ) :
|
605 |
|
|
+ if 'members' in attrs :
|
606 |
|
|
+ for m in attrs['members'].split() :
|
607 |
|
|
+ elem = self.xref[m]['elem']
|
608 |
|
|
+ attr = self.xref[m]['attrs']
|
609 |
|
|
+ if elem in ('Destructor','Method') :
|
610 |
|
|
+ if 'virtual' in attr : return True
|
611 |
|
|
+ if 'bases' in attrs :
|
612 |
|
|
+ for b in attrs['bases'].split() :
|
613 |
|
|
+ if b[:10] == 'protected:' : b = b[10:]
|
614 |
|
|
+ if b[:8] == 'private:' : b = b[8:]
|
615 |
|
|
+ if self.isClassVirtual(self.xref[b]['attrs']) : return True
|
616 |
|
|
+ return False
|
617 |
|
|
+#----------------------------------------------------------------------------------
|
618 |
|
|
+ def isClassPublic(self, id ) :
|
619 |
|
|
+ attrs = self.xref[id]['attrs']
|
620 |
|
|
+ if 'access' in attrs : return False
|
621 |
|
|
+ elif attrs['name'][-1] == '>' :
|
622 |
|
|
+ args = getTemplateArgs(attrs['name'])
|
623 |
|
|
+ for a in args :
|
624 |
|
|
+ while a[-1] in ('*','&') : a = a[:-1]
|
625 |
|
|
+ a = a.replace(', ',',')
|
626 |
|
|
+ if a in self.xrefinv :
|
627 |
|
|
+ if not self.isClassPublic(self.xrefinv[a]) : return False
|
628 |
|
|
+ else :
|
629 |
|
|
+ print '#%s#'% a, ' is not found in the table'
|
630 |
|
|
+ return True
|
631 |
|
|
+#----------------------------------------------------------------------------------
|
632 |
|
|
+ def genHeaders(self, gccxmlinfo):
|
633 |
|
|
+ c = '// Generated at %s. Do not modify it\n\n' % time.ctime(time.time())
|
634 |
|
|
+ if (gccxmlinfo) : c += '/*\n%s*/\n\n' % gccxmlinfo
|
635 |
|
|
+ c += '#ifdef _WIN32\n'
|
636 |
|
|
+ c += '#pragma warning ( disable : 4786 )\n'
|
637 |
|
|
+ c += '#endif\n'
|
638 |
|
|
+ c += '#include "%s"\n' % self.hfile
|
639 |
|
|
+ c += '#include "Reflex/Builder/ReflexBuilder.h"\n'
|
640 |
|
|
+ c += '#include <typeinfo>\n'
|
641 |
|
|
+ c += 'using namespace ROOT::Reflex;\n\n'
|
642 |
|
|
+ return c
|
643 |
|
|
+#----------------------------------------------------------------------------------
|
644 |
|
|
+ def genInstantiateDict( self, selclasses, selfunctions, selenums, selvariables) :
|
645 |
|
|
+ c = 'namespace {\n struct Dictionaries {\n Dictionaries() {\n'
|
646 |
|
|
+ for attrs in selclasses :
|
647 |
|
|
+ if 'incomplete' not in attrs :
|
648 |
|
|
+ clf = '::'+ attrs['fullname']
|
649 |
|
|
+ clt = string.translate(str(clf), self.transtable)
|
650 |
|
|
+ c += ' %s_dict(); \n' % (clt)
|
651 |
|
|
+ c += self.genFunctions(selfunctions)
|
652 |
|
|
+ c += self.genEnums(selenums)
|
653 |
|
|
+ c += self.genVariables(selvariables)
|
654 |
|
|
+ c += ' }\n ~Dictionaries() {\n'
|
655 |
|
|
+ for attrs in selclasses :
|
656 |
|
|
+ if 'incomplete' not in attrs :
|
657 |
|
|
+ c += ' %s.Unload(); // class %s \n' % (self.genTypeID(attrs['id']), attrs['fullname'])
|
658 |
|
|
+ c += ' }\n };\n'
|
659 |
|
|
+ c += ' static Dictionaries instance;\n}\n'
|
660 |
|
|
+ return c
|
661 |
|
|
+#---------------------------------------------------------------------------------
|
662 |
|
|
+
|
663 |
|
|
+ def translate_typedef (self, id):
|
664 |
|
|
+ while self.xref[id]['elem'] in ['CvQualifiedType', 'Typedef']:
|
665 |
|
|
+ id = self.xref[id]['attrs']['type']
|
666 |
|
|
+ return self.genTypeName(id,enum=True, const=True)
|
667 |
|
|
+
|
668 |
|
|
+ def genClassDict(self, attrs):
|
669 |
|
|
+ members, bases = [], []
|
670 |
|
|
+ cl = attrs['name']
|
671 |
|
|
+ clf = '::' + attrs['fullname']
|
672 |
|
|
+ cls = attrs['fullname']
|
673 |
|
|
+ clt = string.translate(str(clf), self.transtable)
|
674 |
|
|
+ bases = self.getBases( attrs['id'] )
|
675 |
|
|
+ if 'members' in attrs : members = string.split(attrs['members'])
|
676 |
|
|
+ mod = self.genModifier(attrs,None)
|
677 |
|
|
+ typ = self.xref[attrs['id']]['elem'].upper()
|
678 |
|
|
+ if attrs.has_key('abstract') : mod += ' | ABSTRACT'
|
679 |
|
|
+ if self.vtables :
|
680 |
|
|
+ if attrs['id'] in self.vtables : mod += ' | VIRTUAL'
|
681 |
|
|
+ else : # new in version 0.6.0
|
682 |
|
|
+ if self.isClassVirtual(attrs) : mod += ' | VIRTUAL'
|
683 |
|
|
+ members = filter(self.memberfilter, members) # Eliminate problematic members
|
684 |
|
|
+ # Fill the different streams sc: constructor, ss: stub functions
|
685 |
|
|
+ sc = '//------Dictionary for class %s -------------------------------\n' % cl
|
686 |
|
|
+ sc += 'void %s_dict() {\n' % (clt,)
|
687 |
|
|
+ if 'extra' in attrs and 'contid' in attrs['extra'] :
|
688 |
|
|
+ cid = attrs['extra']['contid'].upper()
|
689 |
|
|
+ else :
|
690 |
|
|
+ cid = getContainerId(clf)[0]
|
691 |
|
|
+ notAccessibleType = self.checkAccessibleType(self.xref[attrs['id']])
|
692 |
|
|
+ if self.isUnnamedType(clf) :
|
693 |
|
|
+ sc += ' ClassBuilder("%s", typeid(Unnamed%s), sizeof(%s), %s, %s)' % ( cls, self.xref[attrs['id']]['elem'], '__shadow__::'+ string.translate(str(clf),self.transtable), mod, typ )
|
694 |
|
|
+ elif notAccessibleType :
|
695 |
|
|
+ sc += ' ClassBuilder("%s", typeid(%s%s), sizeof(%s), %s, %s)' % ( cls, self.xref[notAccessibleType]['attrs']['access'].title(), self.xref[attrs['id']]['elem'], '__shadow__::'+ string.translate(str(clf),self.transtable), mod, typ )
|
696 |
|
|
+ else :
|
697 |
|
|
+ sc += ' ClassBuilder("%s", typeid(%s), sizeof(%s), %s, %s)' % (cls, cls, cls, mod, typ)
|
698 |
|
|
+ if 'extra' in attrs :
|
699 |
|
|
+ for pname, pval in attrs['extra'].items() :
|
700 |
|
|
+ if pname not in ('name','pattern','n_name','file_name','file_pattern') :
|
701 |
|
|
+ if pname == 'id' : pname = 'ClassID'
|
702 |
|
|
+ sc += '\n .AddProperty("%s", "%s")' % (pname, pval)
|
703 |
|
|
+ for b in bases :
|
704 |
|
|
+ sc += '\n' + self.genBaseClassBuild( clf, b )
|
705 |
|
|
+ for m in members :
|
706 |
|
|
+ funcname = 'gen'+self.xref[m]['elem']+'Build'
|
707 |
|
|
+ if funcname in dir(self) :
|
708 |
|
|
+ line = self.__class__.__dict__[funcname](self, self.xref[m]['attrs'], self.xref[m]['subelems'])
|
709 |
|
|
+ if line : sc += '\n' + line
|
710 |
|
|
+ sc += ';\n}\n\n'
|
711 |
|
|
+ ss = ''
|
712 |
|
|
+ if not self.isUnnamedType(clf) and not notAccessibleType:
|
713 |
|
|
+ ss = '//------Stub functions for class %s -------------------------------\n' % cl
|
714 |
|
|
+ for m in members :
|
715 |
|
|
+ funcname = 'gen'+self.xref[m]['elem']+'Def'
|
716 |
|
|
+ if funcname in dir(self) :
|
717 |
|
|
+ ss += self.__class__.__dict__[funcname](self, self.xref[m]['attrs'], self.xref[m]['subelems']) + '\n'
|
718 |
|
|
+ return sc, ss
|
719 |
|
|
+#----------------------------------------------------------------------------------
|
720 |
|
|
+ def checkAccessibleType( self, type ):
|
721 |
|
|
+ while type['elem'] in ('PointerType','Typedef','ArrayType') :
|
722 |
|
|
+ type = self.xref[type['attrs']['type']]
|
723 |
|
|
+ attrs = type['attrs']
|
724 |
|
|
+ if 'access' in attrs and attrs['access'] in ('private','protected') : return attrs['id']
|
725 |
|
|
+ if 'context' in attrs and self.checkAccessibleType(self.xref[attrs['context']]) : return attrs['id']
|
726 |
|
|
+ return 0
|
727 |
|
|
+#----------------------------------------------------------------------------------
|
728 |
|
|
+ def funPtrPos(self, name) :
|
729 |
|
|
+ if name.find(')(') != -1 :
|
730 |
|
|
+ opp = 0
|
731 |
|
|
+ clp = 0
|
732 |
|
|
+ pos = -2
|
733 |
|
|
+ for str in name.split(')('):
|
734 |
|
|
+ opp += str.count('<')
|
735 |
|
|
+ clp += str.count('>')
|
736 |
|
|
+ pos += len(str) + 2
|
737 |
|
|
+ if ( opp == clp ) : return pos
|
738 |
|
|
+ return 0
|
739 |
|
|
+#----------------------------------------------------------------------------------
|
740 |
|
|
+ def genClassShadow(self, attrs, inner = 0 ) :
|
741 |
|
|
+ inner_shadows = {}
|
742 |
|
|
+ bases = self.getBases( attrs['id'] )
|
743 |
|
|
+ cls = self.genTypeName(attrs['id'],const=True,colon=True)
|
744 |
|
|
+ clt = string.translate(str(cls), self.transtable)
|
745 |
|
|
+ if self.isUnnamedType(cls) and inner : clt = ''
|
746 |
|
|
+ xtyp = self.xref[attrs['id']]
|
747 |
|
|
+ typ = xtyp['elem'].lower()
|
748 |
|
|
+ indent = inner * 2 * ' '
|
749 |
|
|
+ if typ == 'enumeration' :
|
750 |
|
|
+ c = indent + 'enum %s {};\n' % clt
|
751 |
|
|
+ else:
|
752 |
|
|
+ if not bases :
|
753 |
|
|
+ c = indent + '%s %s {\n%s public:\n' % (typ, clt, indent)
|
754 |
|
|
+ else :
|
755 |
|
|
+ c = indent + '%s %s : ' % (typ, clt)
|
756 |
|
|
+ for b in bases :
|
757 |
|
|
+ if b.get('virtual','') == '1' : acc = 'virtual ' + b['access']
|
758 |
|
|
+ else : acc = b['access']
|
759 |
|
|
+ bname = self.genTypeName(b['type'],colon=True)
|
760 |
|
|
+ if self.xref[b['type']]['attrs'].get('access') in ('private','protected'):
|
761 |
|
|
+ bname = string.translate(str(bname),self.transtable)
|
762 |
|
|
+ c += indent + '%s %s' % ( acc , bname )
|
763 |
|
|
+ if b is not bases[-1] : c += ', '
|
764 |
|
|
+ c += indent + ' {\n' + indent +' public:\n'
|
765 |
|
|
+ if clt: # and not self.checkAccessibleType(xtyp):
|
766 |
|
|
+ c += indent + ' %s();\n' % (clt)
|
767 |
|
|
+ if self.isClassVirtual( attrs ) :
|
768 |
|
|
+ c += indent + ' virtual ~%s() throw();\n' % ( clt )
|
769 |
|
|
+ members = attrs.get('members','')
|
770 |
|
|
+ memList = members.split()
|
771 |
|
|
+ for m in memList :
|
772 |
|
|
+ member = self.xref[m]
|
773 |
|
|
+ if member['elem'] in ('Class','Struct','Union','Enumeration') \
|
774 |
|
|
+ and member['attrs'].get('access') in ('private','protected') \
|
775 |
|
|
+ and not self.isUnnamedType(member['attrs'].get('name')):
|
776 |
|
|
+ cmem = self.genTypeName(member['attrs']['id'],const=True,colon=True)
|
777 |
|
|
+ if cmem != cls and cmem not in inner_shadows :
|
778 |
|
|
+ inner_shadows[cmem] = string.translate(str(cmem), self.transtable)
|
779 |
|
|
+ c += self.genClassShadow(member['attrs'], inner + 1)
|
780 |
|
|
+ for m in memList :
|
781 |
|
|
+ member = self.xref[m]
|
782 |
|
|
+ if member['elem'] in ('Field',) :
|
783 |
|
|
+ a = member['attrs']
|
784 |
|
|
+ axref = self.xref[a['type']]
|
785 |
|
|
+ t = self.genTypeName(a['type'],colon=True,const=True)
|
786 |
|
|
+ arraytype = ""
|
787 |
|
|
+ if t[-1] == ']' : arraytype = t[t.find('['):]
|
788 |
|
|
+
|
789 |
|
|
+ fundtype = axref
|
790 |
|
|
+ while fundtype['elem'] in ('ArrayType', 'Typedef'):
|
791 |
|
|
+ fundtype = self.xref[fundtype['attrs']['type']]
|
792 |
|
|
+ mTypeElem = fundtype['elem']
|
793 |
|
|
+
|
794 |
|
|
+ #---- Check if pointer of reference - exact type irrelevant
|
795 |
|
|
+ if mTypeElem == 'PointerType' :
|
796 |
|
|
+ c += indent + ' void* %s;\n' % (a['name'] + arraytype)
|
797 |
|
|
+ continue
|
798 |
|
|
+ elif mTypeElem == 'ReferenceType' :
|
799 |
|
|
+ c += indent + ' int& %s;\n' % (a['name'] + arraytype)
|
800 |
|
|
+ continue
|
801 |
|
|
+
|
802 |
|
|
+ #---- Check if a type and a member with the same name exist in the same scope
|
803 |
|
|
+ if mTypeElem in ('Class','Struct'):
|
804 |
|
|
+ mTypeName = fundtype['attrs']['name']
|
805 |
|
|
+ mTypeId = fundtype['attrs']['id']
|
806 |
|
|
+ for el in self.xref[fundtype['attrs']['context']]['attrs'].get('members').split():
|
807 |
|
|
+ if self.xref[el]['attrs'].get('name') == mTypeName and mTypeId != el :
|
808 |
|
|
+ t = mTypeElem.lower() + ' ' + t[2:]
|
809 |
|
|
+ break
|
810 |
|
|
+ #---- Check for non public types------------------------
|
811 |
|
|
+ noPublicType = self.checkAccessibleType(axref)
|
812 |
|
|
+ if ( noPublicType and not self.isUnnamedType(axref['attrs'].get('name'))):
|
813 |
|
|
+ noPubTypeAttrs = self.xref[noPublicType]['attrs']
|
814 |
|
|
+ cmem = self.genTypeName(noPubTypeAttrs['id'],const=True,colon=True)
|
815 |
|
|
+ if cmem != cls and cmem not in inner_shadows :
|
816 |
|
|
+ inner_shadows[cmem] = string.translate(str(cmem), self.transtable)
|
817 |
|
|
+ c += self.genClassShadow(noPubTypeAttrs, inner + 1)
|
818 |
|
|
+ #---- translate the type with the inner shadow type-----
|
819 |
|
|
+ ikeys = inner_shadows.keys()
|
820 |
|
|
+ ikeys.sort(lambda x,y : len(y) - len(x))
|
821 |
|
|
+ for ikey in ikeys :
|
822 |
|
|
+ if t.find(ikey) == 0 : t = t.replace(ikey, inner_shadows[ikey]) # change current class by shadow name
|
823 |
|
|
+ elif t.find(ikey[2:]) != -1 : t = t.replace(ikey[2:], inner_shadows[ikey]) # idem without leading ::
|
824 |
|
|
+ mType = axref
|
825 |
|
|
+ if mType and self.isUnnamedType(mType['attrs'].get('name')) :
|
826 |
|
|
+ t = self.genClassShadow(mType['attrs'], inner+1)[:-2]
|
827 |
|
|
+ fPPos = self.funPtrPos(t)
|
828 |
|
|
+ if t[-1] == ']' : c += indent + ' %s %s;\n' % ( t[:t.find('[')], a['name'] + arraytype )
|
829 |
|
|
+ elif fPPos : c += indent + ' %s;\n' % ( t[:fPPos] + a['name'] + t[fPPos:] )
|
830 |
|
|
+ else : c += indent + ' %s %s;\n' % ( t, a['name'] )
|
831 |
|
|
+ c += indent + '};\n'
|
832 |
|
|
+ return c
|
833 |
|
|
+#----------------------------------------------------------------------------------
|
834 |
|
|
+ def genTypedefBuild(self, attrs, childs) :
|
835 |
|
|
+ if self.no_membertypedefs : return ''
|
836 |
|
|
+ # access selection doesn't work with gccxml0.6 - typedefs don't have it
|
837 |
|
|
+ if self.interpreter and 'access' in attrs : return ''
|
838 |
|
|
+ s = ''
|
839 |
|
|
+ s += ' .AddTypedef(%s, "%s::%s")' % ( self.genTypeID(attrs['type']), self.genTypeName(attrs['context']), attrs['name'])
|
840 |
|
|
+ return s
|
841 |
|
|
+#----------------------------------------------------------------------------------
|
842 |
|
|
+ def genEnumerationBuild(self, attrs, childs):
|
843 |
|
|
+ s = ''
|
844 |
|
|
+ name = self.genTypeName(attrs['id'])
|
845 |
|
|
+ values = ''
|
846 |
|
|
+ for child in childs : values += child['name'] + '=' + child['init'] +';'
|
847 |
|
|
+ values = values[:-1]
|
848 |
|
|
+ mod = self.genModifier(attrs, None)
|
849 |
|
|
+ if self.isUnnamedType(name) :
|
850 |
|
|
+ s += ' .AddEnum("%s", "%s", &typeid(ROOT::Reflex::UnnamedEnum), %s)' % (name[name.rfind('::')+3:], values, mod)
|
851 |
|
|
+ else :
|
852 |
|
|
+ if attrs.get('access') in ('protected','private'):
|
853 |
|
|
+ if not self.interpreter:
|
854 |
|
|
+ s += ' .AddEnum("%s", "%s", &typeid(ROOT::Reflex::UnknownType), %s)' % (name, values, mod)
|
855 |
|
|
+ else:
|
856 |
|
|
+ s += ' .AddEnum("%s", "%s", &typeid(%s), %s)' % (name, values, name, mod)
|
857 |
|
|
+ return s
|
858 |
|
|
+#----------------------------------------------------------------------------------
|
859 |
|
|
+ def genScopeName(self, attrs, enum=False, const=False, colon=False) :
|
860 |
|
|
+ s = ''
|
861 |
|
|
+ if 'context' in attrs :
|
862 |
|
|
+ ctxt = attrs['context']
|
863 |
|
|
+ while ctxt in self.unnamedNamespaces: ctxt = self.xref[ctxt]['attrs']['context']
|
864 |
|
|
+ ns = self.genTypeName(ctxt, enum, const, colon)
|
865 |
|
|
+ if ns : s = ns + '::'
|
866 |
|
|
+ elif colon : s = '::'
|
867 |
|
|
+ return s
|
868 |
|
|
+#----------------------------------------------------------------------------------
|
869 |
|
|
+ def genTypeName(self, id, enum=False, const=False, colon=False, alltempl=False) :
|
870 |
|
|
+ if id[-1] in ['c','v'] :
|
871 |
|
|
+ nid = id[:-1]
|
872 |
|
|
+ cvdict = {'c':'const','v':'volatile'}
|
873 |
|
|
+ prdict = {'PointerType':'*', 'ReferenceType':'&'}
|
874 |
|
|
+ nidelem = self.xref[nid]['elem']
|
875 |
|
|
+ if nidelem in ('PointerType','ReferenceType') :
|
876 |
|
|
+ if const : return self.genTypeName(nid, enum, False, colon)
|
877 |
|
|
+ else : return self.genTypeName(nid, enum, False, colon) + ' ' + cvdict[id[-1]]
|
878 |
|
|
+ else :
|
879 |
|
|
+ if const : return self.genTypeName(nid, enum, False, colon)
|
880 |
|
|
+ else : return cvdict[id[-1]] + ' ' + self.genTypeName(nid, enum, False, colon)
|
881 |
|
|
+ # "const" vetoeing must not recurse
|
882 |
|
|
+ const = False
|
883 |
|
|
+ elem = self.xref[id]['elem']
|
884 |
|
|
+ attrs = self.xref[id]['attrs']
|
885 |
|
|
+ s = self.genScopeName(attrs, enum, const, colon)
|
886 |
|
|
+ if elem == 'Namespace' :
|
887 |
|
|
+ if attrs['name'] != '::' : s += attrs['name']
|
888 |
|
|
+ elif elem == 'PointerType' :
|
889 |
|
|
+ t = self.genTypeName(attrs['type'],enum, const, colon)
|
890 |
|
|
+ if t[-1] == ')' or t[-7:] == ') const' or t[-10:] == ') volatile' : s += t.replace('::*)','::**)').replace('::)','::*)').replace('(*)', '(**)').replace('()','(*)')
|
891 |
|
|
+ elif t[-1] == ']' or t[-7:] == ') const' or t[-10:] == ') volatile' : s += t[:t.find('[')] + '(*)' + t[t.find('['):]
|
892 |
|
|
+ else : s += t + '*'
|
893 |
|
|
+ elif elem == 'ReferenceType' :
|
894 |
|
|
+ s += self.genTypeName(attrs['type'],enum, const, colon)+'&'
|
895 |
|
|
+ elif elem in ('FunctionType','MethodType') :
|
896 |
|
|
+ s = self.genTypeName(attrs['returns'], enum, const, colon)
|
897 |
|
|
+ if elem == 'MethodType' :
|
898 |
|
|
+ s += '('+ self.genTypeName(attrs['basetype'], enum, const, colon) + '::)('
|
899 |
|
|
+ else :
|
900 |
|
|
+ s += '()('
|
901 |
|
|
+ args = self.xref[id]['subelems']
|
902 |
|
|
+ if args :
|
903 |
|
|
+ for a in range(len(args)) :
|
904 |
|
|
+ s += self.genTypeName(args[a]['type'])
|
905 |
|
|
+ if a < len(args)-1 : s += ', '
|
906 |
|
|
+ s += ')'
|
907 |
|
|
+ else :
|
908 |
|
|
+ s += 'void)'
|
909 |
|
|
+ if (attrs.get('const') == '1') : s += ' const'
|
910 |
|
|
+ if (attrs.get('volatile') == '1') : s += ' volatile'
|
911 |
|
|
+ elif elem == 'ArrayType' :
|
912 |
|
|
+ arr = '[%s]' % str(int(attrs['max'])+1)
|
913 |
|
|
+ typ = self.genTypeName(attrs['type'], enum, const, colon)
|
914 |
|
|
+ if typ[-1] == ']' :
|
915 |
|
|
+ pos = typ.find('[')
|
916 |
|
|
+ s += typ[:pos] + arr + typ[pos:]
|
917 |
|
|
+ else:
|
918 |
|
|
+ s += typ + arr
|
919 |
|
|
+ elif elem == 'Unimplemented' :
|
920 |
|
|
+ s += attrs['tree_code_name']
|
921 |
|
|
+ elif elem == 'Enumeration' :
|
922 |
|
|
+ if enum : s = 'int' # Replace "enum type" by "int"
|
923 |
|
|
+ else : s += attrs['name'] # FIXME: Not always true
|
924 |
|
|
+ elif elem == 'Typedef' :
|
925 |
|
|
+ s = self.genScopeName(attrs, enum, const, colon)
|
926 |
|
|
+ s += attrs['name']
|
927 |
|
|
+ elif elem in ('Function', 'OperatorFunction') :
|
928 |
|
|
+ if 'name' in attrs : s += attrs['name']
|
929 |
|
|
+ else : pass
|
930 |
|
|
+ elif elem == 'OffsetType' :
|
931 |
|
|
+ s += self.genTypeName(attrs['type'], enum, const, colon) + ' '
|
932 |
|
|
+ s += self.genTypeName(attrs['basetype'], enum, const, colon) + '::'
|
933 |
|
|
+ else :
|
934 |
|
|
+ if 'name' in attrs : s += attrs['name']
|
935 |
|
|
+ s = normalizeClass(s,alltempl) # Normalize STL class names, primitives, etc.
|
936 |
|
|
+ return s
|
937 |
|
|
+#----------------------------------------------------------------------------------
|
938 |
|
|
+ def genTypeID(self, id ) :
|
939 |
|
|
+ if id[-1] in ('c','v') :
|
940 |
|
|
+ self.genTypeID(id[:-1])
|
941 |
|
|
+ else :
|
942 |
|
|
+ elem = self.xref[id]['elem']
|
943 |
|
|
+ attrs = self.xref[id]['attrs']
|
944 |
|
|
+ if elem in ('PointerType', 'ReferenceType', 'ArrayType', 'Typedef') :
|
945 |
|
|
+ self.genTypeID(attrs['type'])
|
946 |
|
|
+ elif elem in ('FunctionType', 'MethodType') :
|
947 |
|
|
+ if 'returns' in attrs : self.genTypeID(attrs['returns'])
|
948 |
|
|
+ args = self.xref[id]['subelems']
|
949 |
|
|
+ for a in args : self.genTypeID(a['type'])
|
950 |
|
|
+ elif elem in ('OperatorMethod', 'Method', 'Constructor', 'Converter', 'Destructor',
|
951 |
|
|
+ 'Function', 'OperatorFunction' ) :
|
952 |
|
|
+ if 'returns' in attrs : c = 'FunctionTypeBuilder(' + self.genTypeID(attrs['returns'])
|
953 |
|
|
+ else : c = 'FunctionTypeBuilder(type_void'
|
954 |
|
|
+ args = self.xref[id]['subelems']
|
955 |
|
|
+ for a in args : c += ', '+ self.genTypeID(a['type'])
|
956 |
|
|
+ c += ')'
|
957 |
|
|
+ return c
|
958 |
|
|
+ elif elem in ('Variable',) :
|
959 |
|
|
+ self.genTypeID(attrs['type'])
|
960 |
|
|
+ else :
|
961 |
|
|
+ pass
|
962 |
|
|
+ # Add this type in the list of types...
|
963 |
|
|
+ if id not in self.typeids : self.typeids.append(id)
|
964 |
|
|
+ return 'type'+id
|
965 |
|
|
+#----------------------------------------------------------------------------------
|
966 |
|
|
+ def genAllTypes(self) :
|
967 |
|
|
+ self.typeids += self.fktypeids
|
968 |
|
|
+ c = ' Type type_void = TypeBuilder("void");\n'
|
969 |
|
|
+ for id in self.typeids :
|
970 |
|
|
+ c += ' Type type%s = ' % id
|
971 |
|
|
+ if id[-1] == 'c':
|
972 |
|
|
+ c += 'ConstBuilder(type'+id[:-1]+');\n'
|
973 |
|
|
+ elif id[-1] == 'v':
|
974 |
|
|
+ c += 'VolatileBuilder(type'+id[:-1]+');\n'
|
975 |
|
|
+ else :
|
976 |
|
|
+ elem = self.xref[id]['elem']
|
977 |
|
|
+ attrs = self.xref[id]['attrs']
|
978 |
|
|
+ if elem == 'PointerType' :
|
979 |
|
|
+ c += 'PointerBuilder(type'+attrs['type']+');\n'
|
980 |
|
|
+ elif elem == 'ReferenceType' :
|
981 |
|
|
+ c += 'ReferenceBuilder(type'+attrs['type']+');\n'
|
982 |
|
|
+ elif elem == 'ArrayType' :
|
983 |
|
|
+ mx = attrs['max']
|
984 |
|
|
+ # check if array is bound (max='fff...' for unbound arrays)
|
985 |
|
|
+ if mx.isdigit() : len = str(int(mx)+1)
|
986 |
|
|
+ else : len = '0'
|
987 |
|
|
+ c += 'ArrayBuilder(type'+attrs['type']+', '+ len +');\n'
|
988 |
|
|
+ elif elem == 'Typedef' :
|
989 |
|
|
+ sc = self.genTypeName(attrs['context'])
|
990 |
|
|
+ if sc : sc += '::'
|
991 |
|
|
+ c += 'TypedefTypeBuilder("'+sc+attrs['name']+'", type'+ attrs['type']+');\n'
|
992 |
|
|
+ elif elem == 'OffsetType' :
|
993 |
|
|
+ c += 'TypeBuilder("%s");\n' % self.genTypeName(attrs['id'])
|
994 |
|
|
+ elif elem == 'FunctionType' :
|
995 |
|
|
+ if 'returns' in attrs : c += 'FunctionTypeBuilder(type'+attrs['returns']
|
996 |
|
|
+ else : c += 'FunctionTypeBuilder(type_void'
|
997 |
|
|
+ args = self.xref[id]['subelems']
|
998 |
|
|
+ for a in args : c += ', type'+ a['type']
|
999 |
|
|
+ c += ');\n'
|
1000 |
|
|
+ elif elem == 'MethodType' :
|
1001 |
|
|
+ c += 'TypeBuilder("%s");\n' % self.genTypeName(attrs['id'])
|
1002 |
|
|
+ elif elem in ('OperatorMethod', 'Method', 'Constructor', 'Converter', 'Destructor',
|
1003 |
|
|
+ 'Function', 'OperatorFunction') :
|
1004 |
|
|
+ pass
|
1005 |
|
|
+ elif elem == 'Enumeration' :
|
1006 |
|
|
+ sc = self.genTypeName(attrs['context'])
|
1007 |
|
|
+ if sc : sc += '::'
|
1008 |
|
|
+ # items = self.xref[id]['subelems']
|
1009 |
|
|
+ # values = string.join([ item['name'] + '=' + item['init'] for item in items],';"\n "')
|
1010 |
|
|
+ #c += 'EnumTypeBuilder("' + sc + attrs['name'] + '", "' + values + '");\n'
|
1011 |
|
|
+ c += 'EnumTypeBuilder("' + sc + attrs['name'] + '");\n'
|
1012 |
|
|
+ else :
|
1013 |
|
|
+ name = ''
|
1014 |
|
|
+ if 'context' in attrs :
|
1015 |
|
|
+ ns = self.genTypeName(attrs['context'])
|
1016 |
|
|
+ if ns : name += ns + '::'
|
1017 |
|
|
+ if 'name' in attrs :
|
1018 |
|
|
+ name += attrs['name']
|
1019 |
|
|
+ name = normalizeClass(name,False)
|
1020 |
|
|
+ c += 'TypeBuilder("'+name+'");\n'
|
1021 |
|
|
+ return c
|
1022 |
|
|
+#----------------------------------------------------------------------------------
|
1023 |
|
|
+ def genNamespaces(self, selected ) :
|
1024 |
|
|
+ used_context = []
|
1025 |
|
|
+ s = ''
|
1026 |
|
|
+ for c in selected :
|
1027 |
|
|
+ if 'incomplete' not in c : used_context.append(c['context'])
|
1028 |
|
|
+ idx = 0
|
1029 |
|
|
+ for ns in self.namespaces :
|
1030 |
|
|
+ if ns['id'] in used_context and ns['name'] != '::' :
|
1031 |
|
|
+ s += ' NamespaceBuilder nsb%d( "%s" );\n' % (idx, self.genTypeName(ns['id']))
|
1032 |
|
|
+ idx += 1
|
1033 |
|
|
+ return s
|
1034 |
|
|
+#----------------------------------------------------------------------------------
|
1035 |
|
|
+ def genFunctionsStubs(self, selfunctions) :
|
1036 |
|
|
+ s = ''
|
1037 |
|
|
+ for f in selfunctions :
|
1038 |
|
|
+ id = f['id']
|
1039 |
|
|
+ name = self.genTypeName(id)
|
1040 |
|
|
+ if 'operator' in f : name = 'operator '+name
|
1041 |
|
|
+ self.genTypeID(id)
|
1042 |
|
|
+ args = self.xref[id]['subelems']
|
1043 |
|
|
+ returns = self.genTypeName(f['returns'], enum=True, const=True)
|
1044 |
|
|
+ if not self.quiet : print 'function '+ name
|
1045 |
|
|
+ s += 'static void* '
|
1046 |
|
|
+ if len(args) :
|
1047 |
|
|
+ s += 'function%s( void*, const std::vector<void*>& arg, void*)\n{\n' % id
|
1048 |
|
|
+ else :
|
1049 |
|
|
+ s += 'function%s( void*, const std::vector<void*>&, void*)\n{\n' % id
|
1050 |
|
|
+ ndarg = self.getDefaultArgs(args)
|
1051 |
|
|
+ narg = len(args)
|
1052 |
|
|
+ if ndarg : iden = ' '
|
1053 |
|
|
+ else : iden = ''
|
1054 |
|
|
+ if returns != 'void' and (returns in self.basictypes or
|
1055 |
|
|
+ self.translate_typedef (f['returns']) in
|
1056 |
|
|
+ self.basictypes):
|
1057 |
|
|
+ s += ' static %s ret;\n' % returns
|
1058 |
|
|
+ for n in range(narg-ndarg, narg+1) :
|
1059 |
|
|
+ if ndarg :
|
1060 |
|
|
+ if n == narg-ndarg : s += ' if ( arg.size() == %d ) {\n' % n
|
1061 |
|
|
+ else : s += ' else if ( arg.size() == %d ) { \n' % n
|
1062 |
|
|
+ if returns == 'void' :
|
1063 |
|
|
+ first = iden + ' %s(' % ( name, )
|
1064 |
|
|
+ s += first + self.genMCOArgs(args, n, len(first)) + ');\n'
|
1065 |
|
|
+ s += iden + ' return 0;\n'
|
1066 |
|
|
+ else :
|
1067 |
|
|
+ if returns[-1] in ('*',')' ):
|
1068 |
|
|
+ first = iden + ' return (void*)%s(' % ( name, )
|
1069 |
|
|
+ s += first + self.genMCOArgs(args, n, len(first)) + ');\n'
|
1070 |
|
|
+ elif returns[-1] == '&' :
|
1071 |
|
|
+ first = iden + ' return (void*)&%s(' % ( name, )
|
1072 |
|
|
+ s += first + self.genMCOArgs(args, n, len(first)) + ');\n'
|
1073 |
|
|
+ elif (returns in self.basictypes or
|
1074 |
|
|
+ self.translate_typedef (f['returns']) in self.basictypes):
|
1075 |
|
|
+ first = iden + ' ret = %s(' % ( name, )
|
1076 |
|
|
+ s += first + self.genMCOArgs(args, n, len(first)) + ');\n'
|
1077 |
|
|
+ s += iden + ' return &ret;\n'
|
1078 |
|
|
+ else :
|
1079 |
|
|
+ first = iden + ' return new %s(%s(' % ( returns, name )
|
1080 |
|
|
+ s += first + self.genMCOArgs(args, n, len(first)) + '));\n'
|
1081 |
|
|
+ if ndarg :
|
1082 |
|
|
+ if n != narg : s += ' }\n'
|
1083 |
|
|
+ else :
|
1084 |
|
|
+ if returns == 'void' : s += ' }\n return 0;\n'
|
1085 |
|
|
+ else : s += ' }\n return 0;\n'
|
1086 |
|
|
+ s += '}\n'
|
1087 |
|
|
+ return s
|
1088 |
|
|
+#----------------------------------------------------------------------------------
|
1089 |
|
|
+ def genFunctions(self, selfunctions) :
|
1090 |
|
|
+ s = ''
|
1091 |
|
|
+ i = 0;
|
1092 |
|
|
+ for f in selfunctions :
|
1093 |
|
|
+ id = f['id']
|
1094 |
|
|
+ name = self.genTypeName(id)
|
1095 |
|
|
+ if ( self.xref[id]['attrs'].has_key('mangled') ):
|
1096 |
|
|
+ mm = self.xref[id]['attrs']['mangled'][2:]
|
1097 |
|
|
+ dname = gccdemangler.demangle_name(mm)
|
1098 |
|
|
+ else :
|
1099 |
|
|
+ dname = name
|
1100 |
|
|
+ name += getTemplateArgString(dname[1])
|
1101 |
|
|
+ args = self.xref[id]['subelems']
|
1102 |
|
|
+ if args : params = '"'+ string.join( map(self.genParameter, args),';')+'"'
|
1103 |
|
|
+ else : params = '0'
|
1104 |
|
|
+ mod = self.genModifier(f, None)
|
1105 |
|
|
+ s += ' Type t%s = %s;' % (i, self.genTypeID(id))
|
1106 |
|
|
+ s += ' FunctionBuilder(t%s, "%s", function%s, 0, %s, %s);\n' % (i, name, id, params, mod)
|
1107 |
|
|
+ i += 1;
|
1108 |
|
|
+ return s
|
1109 |
|
|
+#----------------------------------------------------------------------------------
|
1110 |
|
|
+ def genEnums(self, selenums) :
|
1111 |
|
|
+ s = ''
|
1112 |
|
|
+ i = 0;
|
1113 |
|
|
+ for e in selenums :
|
1114 |
|
|
+ id = e['id']
|
1115 |
|
|
+ cname = self.genTypeName(id, colon=True)
|
1116 |
|
|
+ name = self.genTypeName(id)
|
1117 |
|
|
+ mod = self.genModifier(self.xref[id]['attrs'], None)
|
1118 |
|
|
+ if not self.quiet : print 'enum ' + name
|
1119 |
|
|
+ s += ' EnumBuilder("%s",typeid(%s), %s)' % (name, cname, mod)
|
1120 |
|
|
+ items = self.xref[id]['subelems']
|
1121 |
|
|
+ for item in items :
|
1122 |
|
|
+ s += '\n .AddItem("%s",%s)' % (item['name'], item['init'])
|
1123 |
|
|
+ s += ';\n'
|
1124 |
|
|
+ return s
|
1125 |
|
|
+#----------------------------------------------------------------------------------
|
1126 |
|
|
+ def genVariables(self, selvars) :
|
1127 |
|
|
+ s = ''
|
1128 |
|
|
+ i = 0;
|
1129 |
|
|
+ for v in selvars :
|
1130 |
|
|
+ id = v['id']
|
1131 |
|
|
+ cname = self.genTypeName(id, colon=True)
|
1132 |
|
|
+ name = self.genTypeName(id)
|
1133 |
|
|
+ mod = self.genModifier(v, None)
|
1134 |
|
|
+ if not self.quiet : print 'variable ' + name
|
1135 |
|
|
+ s += ' VariableBuilder("%s", %s, (size_t)&%s, %s );\n' % (name, self.genTypeID(v['type']),self.genTypeName(id), mod)
|
1136 |
|
|
+ return s
|
1137 |
|
|
+ #----------------------------------------------------------------------------------
|
1138 |
|
|
+ def countColonsForOffset(self, name) :
|
1139 |
|
|
+ prn = 0
|
1140 |
|
|
+ cnt = 0
|
1141 |
|
|
+ for c in name :
|
1142 |
|
|
+ if c == ',' and not prn : cnt += 1
|
1143 |
|
|
+ elif c == '(' : prn += 1
|
1144 |
|
|
+ elif c == ')' : prn -= 1
|
1145 |
|
|
+ else : pass
|
1146 |
|
|
+ return cnt
|
1147 |
|
|
+#----------------------------------------------------------------------------------
|
1148 |
|
|
+ def genFieldBuild(self, attrs, childs):
|
1149 |
|
|
+ type = self.genTypeName(attrs['type'], enum=False, const=False)
|
1150 |
|
|
+ cl = self.genTypeName(attrs['context'],colon=True)
|
1151 |
|
|
+ cls = self.genTypeName(attrs['context'])
|
1152 |
|
|
+ name = attrs['name']
|
1153 |
|
|
+ if not name :
|
1154 |
|
|
+ ftype = self.xref[attrs['type']]
|
1155 |
|
|
+ # if the member type is an unnamed union we try to take the first member of the union as name
|
1156 |
|
|
+ if ftype['elem'] == 'Union':
|
1157 |
|
|
+ firstMember = ftype['attrs']['members'].split()[0]
|
1158 |
|
|
+ if firstMember : name = self.xref[firstMember]['attrs']['name']
|
1159 |
|
|
+ else : return '' # then this must be an unnamed union without members
|
1160 |
|
|
+ if type[-1] == '&' :
|
1161 |
|
|
+ print '--->> genreflex: WARNING: References are not supported as data members (%s %s::%s)' % ( type, cls, name )
|
1162 |
|
|
+ self.warnings += 1
|
1163 |
|
|
+ return ''
|
1164 |
|
|
+ if 'bits' in attrs:
|
1165 |
|
|
+ print '--->> genreflex: WARNING: Bit-fields are not supported as data members (%s %s::%s:%s)' % ( type, cls, name, attrs['bits'] )
|
1166 |
|
|
+ self.warnings += 1
|
1167 |
|
|
+ return ''
|
1168 |
|
|
+ if self.selector : xattrs = self.selector.selfield( cls,name)
|
1169 |
|
|
+ else : xattrs = None
|
1170 |
|
|
+ mod = self.genModifier(attrs,xattrs)
|
1171 |
|
|
+ if attrs['type'][-1] == 'c' :
|
1172 |
|
|
+ if mod : mod += ' | CONST'
|
1173 |
|
|
+ else : mod = 'CONST'
|
1174 |
|
|
+ if attrs['type'][-1] == 'v' :
|
1175 |
|
|
+ if mod : mod += ' | VOLATILE'
|
1176 |
|
|
+ else : mod = 'VOLATILE'
|
1177 |
|
|
+ shadow = '__shadow__::' + string.translate( str(cl), self.transtable)
|
1178 |
|
|
+ c = ' .AddDataMember(%s, "%s", OffsetOf(%s, %s), %s)' % (self.genTypeID(attrs['type']), name, shadow, name, mod)
|
1179 |
|
|
+ c += self.genCommentProperty(attrs)
|
1180 |
|
|
+ # Other properties
|
1181 |
|
|
+ if xattrs :
|
1182 |
|
|
+ for pname, pval in xattrs.items() :
|
1183 |
|
|
+ if pname not in ('name', 'transient', 'pattern') :
|
1184 |
|
|
+ c += '\n .AddProperty("%s","%s")' % (pname, pval)
|
1185 |
|
|
+ return c
|
1186 |
|
|
+#----------------------------------------------------------------------------------
|
1187 |
|
|
+ def genCommentProperty(self, attrs):
|
1188 |
|
|
+ if not (self.comments or self.iocomments) \
|
1189 |
|
|
+ or 'file' not in attrs \
|
1190 |
|
|
+ or ('artificial' in attrs and attrs['artificial'] == '1') : return ''
|
1191 |
|
|
+ fd = self.files[attrs['file']]
|
1192 |
|
|
+ # open and read the header file if not yet done
|
1193 |
|
|
+ if 'filelines' not in fd :
|
1194 |
|
|
+ try :
|
1195 |
|
|
+ f = file(fd['name'])
|
1196 |
|
|
+ fd['filelines'] = f.readlines()
|
1197 |
|
|
+ f.close()
|
1198 |
|
|
+ except :
|
1199 |
|
|
+ return ''
|
1200 |
|
|
+ line = fd['filelines'][int(attrs['line'])-1]
|
1201 |
|
|
+ poscomment = line.find('//')
|
1202 |
|
|
+ if poscomment == -1 : return ''
|
1203 |
|
|
+ if not self.comments and self.iocomments:
|
1204 |
|
|
+ if line[poscomment+2] != '!' \
|
1205 |
|
|
+ and line[poscomment+2] != '[' \
|
1206 |
|
|
+ and line[poscomment+2:poscomment+4] != '->' \
|
1207 |
|
|
+ and line[poscomment+2:poscomment+4] != '||': return ''
|
1208 |
|
|
+ return '\n .AddProperty("comment","%s")' % (line[poscomment+2:-1]).replace('"','\\"')
|
1209 |
|
|
+#----------------------------------------------------------------------------------
|
1210 |
|
|
+ def genArgument(self, attrs):
|
1211 |
|
|
+ c = self.genTypeName(attrs['type'], enum=True, const=False)
|
1212 |
|
|
+ return c
|
1213 |
|
|
+#----------------------------------------------------------------------------------
|
1214 |
|
|
+ def genParameter(self, attrs):
|
1215 |
|
|
+ c = ''
|
1216 |
|
|
+ if 'name' in attrs :
|
1217 |
|
|
+ c += attrs['name']
|
1218 |
|
|
+ if 'default' in attrs :
|
1219 |
|
|
+ c += '='+ attrs['default'].replace('"','\\"')
|
1220 |
|
|
+ return c
|
1221 |
|
|
+#----------------------------------------------------------------------------------
|
1222 |
|
|
+ def genModifier(self, attrs, xattrs ):
|
1223 |
|
|
+ if 'access' not in attrs : mod = 'PUBLIC'
|
1224 |
|
|
+ elif attrs['access'] == 'private' : mod = 'PRIVATE'
|
1225 |
|
|
+ elif attrs['access'] == 'protected' : mod = 'PROTECTED'
|
1226 |
|
|
+ else : mod = 'NONE'
|
1227 |
|
|
+ if 'virtual' in attrs : mod += ' | VIRTUAL'
|
1228 |
|
|
+ if 'static' in attrs : mod += ' | STATIC'
|
1229 |
|
|
+ # Extra modifiers
|
1230 |
|
|
+ xtrans = ''
|
1231 |
|
|
+ etrans = ''
|
1232 |
|
|
+ if xattrs :
|
1233 |
|
|
+ xtrans = xattrs.get('transient')
|
1234 |
|
|
+ if xtrans : xtrans = xtrans.lower()
|
1235 |
|
|
+ if 'extra' in attrs:
|
1236 |
|
|
+ etrans = attrs['extra'].get('transient')
|
1237 |
|
|
+ if etrans : etrans = etrans.lower()
|
1238 |
|
|
+ if xtrans == 'true' or etrans == 'true' : mod += ' | TRANSIENT'
|
1239 |
|
|
+ if 'artificial' in attrs : mod += ' | ARTIFICIAL'
|
1240 |
|
|
+ return mod
|
1241 |
|
|
+#----------------------------------------------------------------------------------
|
1242 |
|
|
+ def genMCODecl( self, type, name, attrs, args ) :
|
1243 |
|
|
+ return 'static void* %s%s(void*, const std::vector<void*>&, void*);' % (type, attrs['id'])
|
1244 |
|
|
+#----------------------------------------------------------------------------------
|
1245 |
|
|
+ def genMCOBuild(self, type, name, attrs, args):
|
1246 |
|
|
+ id = attrs['id']
|
1247 |
|
|
+ if self.isUnnamedType(self.xref[attrs['context']]['attrs'].get('name')) or \
|
1248 |
|
|
+ self.checkAccessibleType(self.xref[attrs['context']]) : return ''
|
1249 |
|
|
+ if type == 'constructor' : returns = 'void'
|
1250 |
|
|
+ else : returns = self.genTypeName(attrs['returns'])
|
1251 |
|
|
+ mod = self.genModifier(attrs, None)
|
1252 |
|
|
+ if type == 'constructor' : mod += ' | CONSTRUCTOR'
|
1253 |
|
|
+ elif type == 'operator' : mod += ' | OPERATOR'
|
1254 |
|
|
+ elif type == 'converter' : mod += ' | CONVERTER'
|
1255 |
|
|
+ if attrs.get('const')=='1' : mod += ' | CONST'
|
1256 |
|
|
+ if args : params = '"'+ string.join( map(self.genParameter, args),';')+'"'
|
1257 |
|
|
+ else : params = '0'
|
1258 |
|
|
+ s = ' .AddFunctionMember(%s, "%s", %s%s, 0, %s, %s)' % (self.genTypeID(id), name, type, id, params, mod)
|
1259 |
|
|
+ s += self.genCommentProperty(attrs)
|
1260 |
|
|
+ return s
|
1261 |
|
|
+#----------------------------------------------------------------------------------
|
1262 |
|
|
+ def genMCODef(self, type, name, attrs, args):
|
1263 |
|
|
+ id = attrs['id']
|
1264 |
|
|
+ cl = self.genTypeName(attrs['context'],colon=True)
|
1265 |
|
|
+ clt = string.translate(str(cl), self.transtable)
|
1266 |
|
|
+ returns = self.genTypeName(attrs['returns'],enum=True, const=True)
|
1267 |
|
|
+ s = 'static void* '
|
1268 |
|
|
+ if len(args) :
|
1269 |
|
|
+ s += '%s%s( void* o, const std::vector<void*>& arg, void*)\n{\n' %( type, id )
|
1270 |
|
|
+ else :
|
1271 |
|
|
+ s += '%s%s( void* o, const std::vector<void*>&, void*)\n{\n' %( type, id )
|
1272 |
|
|
+ # If we construct a conversion operator to pointer to function member the name
|
1273 |
|
|
+ # will contain TDF_<attrs['id']>
|
1274 |
|
|
+ tdfname = 'TDF%s'%attrs['id']
|
1275 |
|
|
+ if name.find(tdfname) != -1 :
|
1276 |
|
|
+ s += ' typedef %s;\n'%name
|
1277 |
|
|
+ name = 'operator ' + tdfname
|
1278 |
|
|
+ returns = tdfname
|
1279 |
|
|
+ ndarg = self.getDefaultArgs(args)
|
1280 |
|
|
+ narg = len(args)
|
1281 |
|
|
+ if ndarg : iden = ' '
|
1282 |
|
|
+ else : iden = ''
|
1283 |
|
|
+ if returns != 'void' :
|
1284 |
|
|
+ if (returns in self.basictypes or
|
1285 |
|
|
+ self.translate_typedef (attrs['returns']) in self.basictypes or
|
1286 |
|
|
+ name == 'operator %s'%tdfname):
|
1287 |
|
|
+ s += ' static %s ret;\n' % returns
|
1288 |
|
|
+ elif returns.find('::*)') != -1 :
|
1289 |
|
|
+ s += ' static %s;\n' % returns.replace('::*','::* ret')
|
1290 |
|
|
+ elif returns.find('::*') != -1 :
|
1291 |
|
|
+ s += ' static %s ret;\n' % returns
|
1292 |
|
|
+ if 'const' in attrs : cl = 'const '+ cl
|
1293 |
|
|
+ for n in range(narg-ndarg, narg+1) :
|
1294 |
|
|
+ if ndarg :
|
1295 |
|
|
+ if n == narg-ndarg : s += ' if ( arg.size() == %d ) {\n' % n
|
1296 |
|
|
+ else : s += ' else if ( arg.size() == %d ) { \n' % n
|
1297 |
|
|
+ if returns == 'void' :
|
1298 |
|
|
+ first = iden + ' ((%s*)o)->%s(' % ( cl, name )
|
1299 |
|
|
+ s += first + self.genMCOArgs(args, n, len(first)) + ');\n'
|
1300 |
|
|
+ s += iden + ' return 0;\n'
|
1301 |
|
|
+ else :
|
1302 |
|
|
+ if returns[-1] in ('*',')') and returns.find('::*') == -1 :
|
1303 |
|
|
+ first = iden + ' return (void*)((%s*)o)->%s(' % ( cl, name )
|
1304 |
|
|
+ s += first + self.genMCOArgs(args, n, len(first)) + ');\n'
|
1305 |
|
|
+ elif returns[-1] == '&' :
|
1306 |
|
|
+ first = iden + ' return (void*)&((%s*)o)->%s(' % ( cl, name )
|
1307 |
|
|
+ s += first + self.genMCOArgs(args, n, len(first)) + ');\n'
|
1308 |
|
|
+ elif (returns in self.basictypes or
|
1309 |
|
|
+ self.translate_typedef (attrs['returns']) in self.basictypes or
|
1310 |
|
|
+ returns.find('::*') != -1 or
|
1311 |
|
|
+ name == 'operator '+tdfname):
|
1312 |
|
|
+ first = iden + ' ret = ((%s*)o)->%s(' % ( cl, name )
|
1313 |
|
|
+ s += first + self.genMCOArgs(args, n, len(first)) + ');\n'
|
1314 |
|
|
+ s += iden + ' return &ret;\n'
|
1315 |
|
|
+ else :
|
1316 |
|
|
+ first = iden + ' return new %s(((%s*)o)->%s(' % ( returns, cl, name )
|
1317 |
|
|
+ s += first + self.genMCOArgs(args, n, len(first)) + '));\n'
|
1318 |
|
|
+ if ndarg :
|
1319 |
|
|
+ if n != narg : s += ' }\n'
|
1320 |
|
|
+ else :
|
1321 |
|
|
+ if returns == 'void' : s += ' }\n return 0;\n'
|
1322 |
|
|
+ else : s += ' }\n return 0;\n'
|
1323 |
|
|
+ s += '}\n'
|
1324 |
|
|
+ return s
|
1325 |
|
|
+#----------------------------------------------------------------------------------
|
1326 |
|
|
+ def getDefaultArgs(self, args):
|
1327 |
|
|
+ n = 0
|
1328 |
|
|
+ for a in args :
|
1329 |
|
|
+ if 'default' in a : n += 1
|
1330 |
|
|
+ return n
|
1331 |
|
|
+#----------------------------------------------------------------------------------
|
1332 |
|
|
+ def genMCOArgs(self, args, narg, pad):
|
1333 |
|
|
+ s = ''
|
1334 |
|
|
+ for i in range(narg) :
|
1335 |
|
|
+ a = args[i]
|
1336 |
|
|
+ #arg = self.genArgument(a, 0);
|
1337 |
|
|
+ arg = self.genTypeName(a['type'],colon=True)
|
1338 |
|
|
+ if arg[-1] == '*' or len(arg) > 7 and arg[-7:] == '* const':
|
1339 |
|
|
+ if arg[-2:] == ':*' or arg[-8:] == ':* const' : # Pointer to data member
|
1340 |
|
|
+ s += '*(%s*)arg[%d]' % (arg, i )
|
1341 |
|
|
+ else :
|
1342 |
|
|
+ s += '(%s)arg[%d]' % (arg, i )
|
1343 |
|
|
+ elif arg[-1] == ']' :
|
1344 |
|
|
+ s += '(%s)arg[%d]' % (arg, i)
|
1345 |
|
|
+ elif arg[-1] == ')' or (len(arg) > 7 and arg[-7:] == ') const'): # FIXME, the second check is a hack
|
1346 |
|
|
+ if arg.find('::*') != -1 : # Pointer to function member
|
1347 |
|
|
+ s += '*(%s)arg[%d]' %(arg.replace('::*','::**'), i)
|
1348 |
|
|
+ elif (len(arg) > 7 and arg[-7:] == ') const') :
|
1349 |
|
|
+ s += '(%s)arg[%d]' % (arg[:-6].replace('(*)','(* const)'), i) # 2nd part of the hack
|
1350 |
|
|
+ else :
|
1351 |
|
|
+ s += '(%s)arg[%d]' % (arg, i )
|
1352 |
|
|
+ elif arg[-1] == '&' :
|
1353 |
|
|
+ s += '*(%s*)arg[%d]' % (arg[:-1], i )
|
1354 |
|
|
+ else :
|
1355 |
|
|
+ s += '*(%s*)arg[%d]' % (arg, i )
|
1356 |
|
|
+ if i != narg - 1 : s += ',\n' + pad*' '
|
1357 |
|
|
+ return s
|
1358 |
|
|
+#----------------------------------------------------------------------------------
|
1359 |
|
|
+ def genMethodDecl(self, attrs, args):
|
1360 |
|
|
+ return self.genMCODecl( 'method', '', attrs, args )
|
1361 |
|
|
+#----------------------------------------------------------------------------------
|
1362 |
|
|
+ def genMethodBuild(self, attrs, args):
|
1363 |
|
|
+ return self.genMCOBuild( 'method', attrs['name'], attrs, args )
|
1364 |
|
|
+#----------------------------------------------------------------------------------
|
1365 |
|
|
+ def genMethodDef(self, attrs, args):
|
1366 |
|
|
+ return self.genMCODef( 'method', attrs['name'], attrs, args )
|
1367 |
|
|
+#----------------------------------------------------------------------------------
|
1368 |
|
|
+ def genConstructorDecl(self, attrs, args):
|
1369 |
|
|
+ return self.genMCODecl( 'constructor', '', attrs, args )
|
1370 |
|
|
+#----------------------------------------------------------------------------------
|
1371 |
|
|
+ def genConstructorBuild(self, attrs, args):
|
1372 |
|
|
+ return self.genMCOBuild( 'constructor', attrs['name'], attrs, args )
|
1373 |
|
|
+#----------------------------------------------------------------------------------
|
1374 |
|
|
+ def genConstructorDef(self, attrs, args):
|
1375 |
|
|
+ cl = self.genTypeName(attrs['context'], colon=True)
|
1376 |
|
|
+ clt = string.translate(str(cl), self.transtable)
|
1377 |
|
|
+ id = attrs['id']
|
1378 |
|
|
+ if len(args) :
|
1379 |
|
|
+ s = 'static void* constructor%s( void* mem, const std::vector<void*>& arg, void*) {\n' %( id, )
|
1380 |
|
|
+ else :
|
1381 |
|
|
+ s = 'static void* constructor%s( void* mem, const std::vector<void*>&, void*) {\n' %( id, )
|
1382 |
|
|
+ if 'pseudo' in attrs :
|
1383 |
|
|
+ s += ' return ::new(mem) %s( *(__void__*)0 );\n' % ( cl )
|
1384 |
|
|
+ else :
|
1385 |
|
|
+ ndarg = self.getDefaultArgs(args)
|
1386 |
|
|
+ narg = len(args)
|
1387 |
|
|
+ for n in range(narg-ndarg, narg+1) :
|
1388 |
|
|
+ if ndarg :
|
1389 |
|
|
+ if n == narg-ndarg : s += ' if ( arg.size() == %d ) {\n ' % n
|
1390 |
|
|
+ else : s += ' else if ( arg.size() == %d ) { \n ' % n
|
1391 |
|
|
+ first = ' return ::new(mem) %s(' % ( cl )
|
1392 |
|
|
+ s += first + self.genMCOArgs(args, n, len(first)) + ');\n'
|
1393 |
|
|
+ if ndarg :
|
1394 |
|
|
+ if n != narg : s += ' }\n'
|
1395 |
|
|
+ else : s += ' }\n return 0;\n'
|
1396 |
|
|
+ s += '}\n'
|
1397 |
|
|
+ return s
|
1398 |
|
|
+#----------------------------------------------------------------------------------
|
1399 |
|
|
+ def genDestructorDef(self, attrs, childs):
|
1400 |
|
|
+ cl = self.genTypeName(attrs['context'])
|
1401 |
|
|
+ return 'static void* destructor%s(void * o, const std::vector<void*>&, void *) {\n ((::%s*)o)->~%s(); return 0;\n}' % ( attrs['id'], cl, attrs['name'] )
|
1402 |
|
|
+#----------------------------------------------------------------------------------
|
1403 |
|
|
+ def genDestructorBuild(self, attrs, childs):
|
1404 |
|
|
+ if self.isUnnamedType(self.xref[attrs['context']]['attrs'].get('name')) or \
|
1405 |
|
|
+ self.checkAccessibleType(self.xref[attrs['context']]) : return ''
|
1406 |
|
|
+ mod = self.genModifier(attrs,None)
|
1407 |
|
|
+ id = attrs['id']
|
1408 |
|
|
+ s = ' .AddFunctionMember(%s, "~%s", destructor%s, 0, 0, %s | DESTRUCTOR )' % (self.genTypeID(id), attrs['name'], attrs['id'], mod)
|
1409 |
|
|
+ s += self.genCommentProperty(attrs)
|
1410 |
|
|
+ return s
|
1411 |
|
|
+#----------------------------------------------------------------------------------
|
1412 |
|
|
+ def genOperatorMethodDecl( self, attrs, args ) :
|
1413 |
|
|
+ if attrs['name'][0].isalpha() : name = 'operator '+ attrs['name']
|
1414 |
|
|
+ else : name = 'operator' + attrs['name']
|
1415 |
|
|
+ return self.genMCODecl( 'operator', name, attrs, args )
|
1416 |
|
|
+#----------------------------------------------------------------------------------
|
1417 |
|
|
+ def genOperatorMethodBuild( self, attrs, args ) :
|
1418 |
|
|
+ if attrs['name'][0].isalpha() : name = 'operator '+ attrs['name']
|
1419 |
|
|
+ else : name = 'operator' + attrs['name']
|
1420 |
|
|
+ return self.genMCOBuild( 'operator', name, attrs, args )
|
1421 |
|
|
+#----------------------------------------------------------------------------------
|
1422 |
|
|
+ def genOperatorMethodDef( self, attrs, args ) :
|
1423 |
|
|
+ if attrs['name'][0].isalpha() : name = 'operator '+ attrs['name']
|
1424 |
|
|
+ else : name = 'operator' + attrs['name']
|
1425 |
|
|
+ if name[-1] == '>' and name.find('<') != -1 : name = name[:name.find('<')]
|
1426 |
|
|
+ return self.genMCODef( 'operator', name, attrs, args )
|
1427 |
|
|
+#----------------------------------------------------------------------------------
|
1428 |
|
|
+ def genConverterDecl( self, attrs, args ) :
|
1429 |
|
|
+ return self.genMCODecl( 'converter', 'operator '+attrs['name'], attrs, args )
|
1430 |
|
|
+#----------------------------------------------------------------------------------
|
1431 |
|
|
+ def genConverterBuild( self, attrs, args ) :
|
1432 |
|
|
+ return self.genMCOBuild( 'converter', 'operator '+self.genTypeName(attrs['returns'],enum=True,const=False), attrs, args )
|
1433 |
|
|
+#----------------------------------------------------------------------------------
|
1434 |
|
|
+ def genConverterDef( self, attrs, args ) :
|
1435 |
|
|
+ # If this is a conversion operator to pointer to function member we will need
|
1436 |
|
|
+ # to create a typedef for the typename which is needed in the stub function
|
1437 |
|
|
+ tdf = 'operator '+self.genTypeName(attrs['returns'])
|
1438 |
|
|
+ t1 = self.xref[attrs['returns']]
|
1439 |
|
|
+ if t1['elem'] == 'PointerType':
|
1440 |
|
|
+ t2 = self.xref[t1['attrs']['type']]
|
1441 |
|
|
+ if t2['elem'] == 'MethodType':
|
1442 |
|
|
+ tdf = self.genTypeName(attrs['returns']).replace('*)(','* TDF%s)('%attrs['id'])
|
1443 |
|
|
+ return self.genMCODef( 'converter', tdf, attrs, args )
|
1444 |
|
|
+#----------------------------------------------------------------------------------
|
1445 |
|
|
+ def genEnumValue(self, attrs):
|
1446 |
|
|
+ return '%s = %s' % (attrs['name'], attrs['init'])
|
1447 |
|
|
+#----------------------------------------------------------------------------------
|
1448 |
|
|
+ def genBaseClassBuild(self, clf, b ):
|
1449 |
|
|
+ mod = b['access'].upper()
|
1450 |
|
|
+ if 'virtual' in b and b['virtual'] == '1' : mod = 'VIRTUAL | ' + mod
|
1451 |
|
|
+ return ' .AddBase(%s, BaseOffset< %s, %s >::Get(), %s)' % (self.genTypeID(b['type']), clf, self.genTypeName(b['type'],colon=True), mod)
|
1452 |
|
|
+#----------------------------------------------------------------------------------
|
1453 |
|
|
+ def enhanceClass(self, attrs):
|
1454 |
|
|
+ if self.isUnnamedType(attrs['name']) or self.checkAccessibleType(self.xref[attrs['id']]) : return
|
1455 |
|
|
+ # Default constructor
|
1456 |
|
|
+ if 'members' in attrs : members = attrs['members'].split()
|
1457 |
|
|
+ else : members = []
|
1458 |
|
|
+ for m in members :
|
1459 |
|
|
+ if self.xref[m]['elem'] == 'Constructor' :
|
1460 |
|
|
+ args = self.xref[m]['subelems']
|
1461 |
|
|
+ if len(args) > 0 and 'default' in args[0] :
|
1462 |
|
|
+ id = u'_x%d' % self.x_id.next()
|
1463 |
|
|
+ new_attrs = self.xref[m]['attrs'].copy()
|
1464 |
|
|
+ new_attrs['id'] = id
|
1465 |
|
|
+ new_attrs['artificial'] = 'true'
|
1466 |
|
|
+ self.xref[id] = {'elem':'Constructor', 'attrs':new_attrs,'subelems':[] }
|
1467 |
|
|
+ attrs['members'] += u' ' + id
|
1468 |
|
|
+ elif len(args) == 1 and self.genTypeName(args[0]['type']) == '__void__&' :
|
1469 |
|
|
+ id = u'_x%d' % self.x_id.next()
|
1470 |
|
|
+ new_attrs = self.xref[m]['attrs'].copy()
|
1471 |
|
|
+ new_attrs['id'] = id
|
1472 |
|
|
+ new_attrs['pseudo'] = True
|
1473 |
|
|
+ new_attrs['artificial'] = 'true'
|
1474 |
|
|
+ self.xref[id] = {'elem':'Constructor', 'attrs':new_attrs,'subelems':[] }
|
1475 |
|
|
+ attrs['members'] += u' ' + id
|
1476 |
|
|
+ if (len(args) == 0 or 'default' in args[0] ) \
|
1477 |
|
|
+ and 'abstract' not in attrs \
|
1478 |
|
|
+ and 'access' not in self.xref[m]['attrs'] \
|
1479 |
|
|
+ and not self.isDestructorNonPublic(attrs['id']):
|
1480 |
|
|
+ # NewDel functions extra function
|
1481 |
|
|
+ id = u'_x%d' % self.x_id.next()
|
1482 |
|
|
+ new_attrs = { 'id':id, 'context':attrs['id'], 'artificial':'true' }
|
1483 |
|
|
+ self.xref[id] = {'elem':'GetNewDelFunctions', 'attrs':new_attrs,'subelems':[] }
|
1484 |
|
|
+ attrs['members'] += u' ' + id
|
1485 |
|
|
+ # Bases extra function
|
1486 |
|
|
+ if 'bases' in attrs and attrs['bases'] != '':
|
1487 |
|
|
+ id = u'_x%d' % self.x_id.next()
|
1488 |
|
|
+ new_attrs = { 'id':id, 'context':attrs['id'], 'artificial':'true' }
|
1489 |
|
|
+ self.xref[id] = {'elem':'GetBasesTable', 'attrs':new_attrs,'subelems':[] }
|
1490 |
|
|
+ if 'members' in attrs : attrs['members'] += u' ' + id
|
1491 |
|
|
+ else : attrs['members'] = u' '+ id
|
1492 |
|
|
+ # Container extra functions
|
1493 |
|
|
+ type = getContainerId( self.genTypeName(attrs['id']) )[1]
|
1494 |
|
|
+ if 'extra' in attrs and 'type' in attrs['extra'] : type = attrs['extra']['type']
|
1495 |
|
|
+ if type :
|
1496 |
|
|
+ #--The new stuff from CollectionProxy--------
|
1497 |
|
|
+ id = u'_x%d' % self.x_id.next()
|
1498 |
|
|
+ new_attrs = { 'id':id, 'context':attrs['id'], 'artificial':'true' }
|
1499 |
|
|
+ self.xref[id] = {'elem':'CreateCollFuncTable', 'attrs':new_attrs,'subelems':[] }
|
1500 |
|
|
+ if 'members' in attrs : attrs['members'] += u' ' + id
|
1501 |
|
|
+ else : attrs['members'] = u' ' + id
|
1502 |
|
|
+#----CollectionProxy stuff--------------------------------------------------------
|
1503 |
|
|
+ def genCreateCollFuncTableDecl( self, attrs, args ) :
|
1504 |
|
|
+ return 'static void* method%s( void*, const std::vector<void*>&, void* ); ' % (attrs['id'])
|
1505 |
|
|
+ def genCreateCollFuncTableBuild( self, attrs, args ) :
|
1506 |
|
|
+ mod = self.genModifier(attrs, None)
|
1507 |
|
|
+ return ' .AddFunctionMember<void*(void)>("createCollFuncTable", method%s, 0, 0, %s)' % ( attrs['id'], mod)
|
1508 |
|
|
+ def genCreateCollFuncTableDef( self, attrs, args ) :
|
1509 |
|
|
+ cl = self.genTypeName(attrs['context'], colon=True)
|
1510 |
|
|
+ clt = string.translate(str(cl), self.transtable)
|
1511 |
|
|
+ t = getTemplateArgs(cl)[0]
|
1512 |
|
|
+ s = 'static void* method%s( void*, const std::vector<void*>&, void*)\n{\n' %( attrs['id'], )
|
1513 |
|
|
+ s += ' return ROOT::Reflex::Proxy< %s >::Generate();\n' % (cl,)
|
1514 |
|
|
+ s += '}\n'
|
1515 |
|
|
+ return s
|
1516 |
|
|
+#----BasesMap stuff--------------------------------------------------------
|
1517 |
|
|
+ def genGetBasesTableDecl( self, attrs, args ) :
|
1518 |
|
|
+ return 'static void* method%s( void*, const std::vector<void*>&, void* ); ' % (attrs['id'])
|
1519 |
|
|
+ def genGetBasesTableBuild( self, attrs, args ) :
|
1520 |
|
|
+ mod = self.genModifier(attrs, None)
|
1521 |
|
|
+ return ' .AddFunctionMember<void*(void)>("__getBasesTable", method%s, 0, 0, %s)' % (attrs['id'], mod)
|
1522 |
|
|
+ def genGetBasesTableDef( self, attrs, args ) :
|
1523 |
|
|
+ cid = attrs['context']
|
1524 |
|
|
+ cl = self.genTypeName(cid, colon=True)
|
1525 |
|
|
+ clt = string.translate(str(cl), self.transtable)
|
1526 |
|
|
+ s = 'static void* method%s( void*, const std::vector<void*>&, void*)\n{\n' %( attrs['id'], )
|
1527 |
|
|
+ s += ' static std::vector<std::pair<ROOT::Reflex::Base, int> > s_bases;\n'
|
1528 |
|
|
+ s += ' if ( !s_bases.size() ) {\n'
|
1529 |
|
|
+ bases = []
|
1530 |
|
|
+ self.getAllBases( cid, bases )
|
1531 |
|
|
+ for b in bases :
|
1532 |
|
|
+ bname = self.genTypeName(b[0],colon=True)
|
1533 |
|
|
+ bname2 = self.genTypeName(b[0])
|
1534 |
|
|
+ s += ' s_bases.push_back(std::make_pair(ROOT::Reflex::Base( ROOT::Reflex::TypeBuilder("%s"), ROOT::Reflex::BaseOffset< %s,%s >::Get(),%s), %d));\n' % (bname2, cl, bname, b[1], b[2])
|
1535 |
|
|
+ s += ' }\n return &s_bases;\n'
|
1536 |
|
|
+ s += '}\n'
|
1537 |
|
|
+ return s
|
1538 |
|
|
+#----Constructor/Destructor stuff--------------------------------------------------------
|
1539 |
|
|
+ def checkOperators(self,cid):
|
1540 |
|
|
+ opnewc = 0
|
1541 |
|
|
+ plopnewc = 0
|
1542 |
|
|
+ opnewa = 0
|
1543 |
|
|
+ plopnewa = 0
|
1544 |
|
|
+ attrs = self.xref[cid]['attrs']
|
1545 |
|
|
+ for m in attrs.get('members').split():
|
1546 |
|
|
+ mm = self.xref[m]
|
1547 |
|
|
+ if mm['elem'] == 'OperatorMethod':
|
1548 |
|
|
+ opname = mm['attrs'].get('name')
|
1549 |
|
|
+ # we assume that 'subelems' only contains Arguments
|
1550 |
|
|
+ sems = mm['subelems']
|
1551 |
|
|
+ if opname == 'new':
|
1552 |
|
|
+ if len(sems) == 1 and self.genTypeName(sems[0]['type']) in ('size_t',): opnewc = 1
|
1553 |
|
|
+ if len(sems) == 2 and self.genTypeName(sems[0]['type']) in ('size_t',) and self.genTypeName(sems[1]['type']) in ('void*',): plopnewc = 1
|
1554 |
|
|
+ if opname == 'new []':
|
1555 |
|
|
+ if len(sems) == 1 and self.genTypeName(sems[0]['type']) in ('size_t',): opnewa = 1
|
1556 |
|
|
+ if len(sems) == 2 and self.genTypeName(sems[0]['type']) in ('size_t',) and self.genTypeName(sems[1]['type']) in ('void*',): plopnewa = 1
|
1557 |
|
|
+ newc = ''
|
1558 |
|
|
+ newa = ''
|
1559 |
|
|
+ if opnewc and not plopnewc: newc = '_np'
|
1560 |
|
|
+ elif not opnewc and plopnewc : newc = '_p'
|
1561 |
|
|
+ if opnewa and not plopnewa: newa = '_np'
|
1562 |
|
|
+ elif not opnewa and plopnewa : newa = '_p'
|
1563 |
|
|
+ return (newc, newa)
|
1564 |
|
|
+#----Constructor/Destructor stuff--------------------------------------------------------
|
1565 |
|
|
+ def genGetNewDelFunctionsDecl( self, attrs, args ) :
|
1566 |
|
|
+ return 'static void* method%s( void*, const std::vector<void*>&, void* ); ' % (attrs['id'])
|
1567 |
|
|
+ def genGetNewDelFunctionsBuild( self, attrs, args ) :
|
1568 |
|
|
+ mod = self.genModifier(attrs, None)
|
1569 |
|
|
+ return ' .AddFunctionMember<void*(void)>("__getNewDelFunctions", method%s, 0, 0, %s)' % (attrs['id'], mod)
|
1570 |
|
|
+ def genGetNewDelFunctionsDef( self, attrs, args ) :
|
1571 |
|
|
+ cid = attrs['context']
|
1572 |
|
|
+ cl = self.genTypeName(cid, colon=True)
|
1573 |
|
|
+ clt = string.translate(str(cl), self.transtable)
|
1574 |
|
|
+ (newc, newa) = self.checkOperators(cid)
|
1575 |
|
|
+ s = 'static void* method%s( void*, const std::vector<void*>&, void*)\n{\n' %( attrs['id'] )
|
1576 |
|
|
+ s += ' static NewDelFunctions s_funcs;\n'
|
1577 |
|
|
+ s += ' s_funcs.fNew = NewDelFunctionsT< %s >::new%s_T;\n' % (cl, newc)
|
1578 |
|
|
+ s += ' s_funcs.fNewArray = NewDelFunctionsT< %s >::newArray%s_T;\n' % (cl, newa)
|
1579 |
|
|
+ s += ' s_funcs.fDelete = NewDelFunctionsT< %s >::delete_T;\n' % cl
|
1580 |
|
|
+ s += ' s_funcs.fDeleteArray = NewDelFunctionsT< %s >::deleteArray_T;\n' % cl
|
1581 |
|
|
+ s += ' s_funcs.fDestructor = NewDelFunctionsT< %s >::destruct_T;\n' % cl
|
1582 |
|
|
+ s += ' return &s_funcs;\n'
|
1583 |
|
|
+ s += '}\n'
|
1584 |
|
|
+ return s
|
1585 |
|
|
+#----------------------------------------------------------------------------------
|
1586 |
|
|
+ def getBases( self, cid ) :
|
1587 |
|
|
+ if 'bases' in self.xref[cid] :
|
1588 |
|
|
+ return self.xref[cid]['bases']
|
1589 |
|
|
+ elif 'bases' in self.xref[cid]['attrs'] :
|
1590 |
|
|
+ bases = []
|
1591 |
|
|
+ for b in self.xref[cid]['attrs']['bases'].split() :
|
1592 |
|
|
+ access = 'public'
|
1593 |
|
|
+ if b[:10] == 'protected:' : b = b[10:]; access = 'protected'
|
1594 |
|
|
+ if b[:8] == 'private:' : b = b[8:]; access = 'private'
|
1595 |
|
|
+ bases.append( {'type': b, 'access': access, 'virtual': '-1' } )
|
1596 |
|
|
+ return bases
|
1597 |
|
|
+ else :
|
1598 |
|
|
+ return []
|
1599 |
|
|
+#----------------------------------------------------------------------------------
|
1600 |
|
|
+ def getAllBases( self, cid, bases, level = 0, access = 'public', virtual = False ) :
|
1601 |
|
|
+ for b in self.getBases( cid ) :
|
1602 |
|
|
+ id = b['type']
|
1603 |
|
|
+ if id not in [ bid[0] for bid in bases] :
|
1604 |
|
|
+ if access == 'public' : access = b['access']
|
1605 |
|
|
+ if not virtual : virtual = ( b['virtual'] == '1' )
|
1606 |
|
|
+ mod = access.upper()
|
1607 |
|
|
+ if virtual : mod = 'VIRTUAL |' + mod
|
1608 |
|
|
+ bases.append( [id, mod, level] )
|
1609 |
|
|
+ self.getAllBases( id, bases, level+1, access, virtual )
|
1610 |
|
|
+#----------------------------------------------------------------------------------
|
1611 |
|
|
+ def completeClass(self, attrs):
|
1612 |
|
|
+ # Complete class with "instantiated" templated methods or constructors
|
1613 |
|
|
+ if 'members' in attrs : members = attrs['members'].split()
|
1614 |
|
|
+ else : members = []
|
1615 |
|
|
+ cid = attrs['id']
|
1616 |
|
|
+ for c in self.classes :
|
1617 |
|
|
+ if c['context'] == cid and c['id'] not in members :
|
1618 |
|
|
+ attrs['members'] += u' ' + c['id']
|
1619 |
|
|
+ for m in self.methods :
|
1620 |
|
|
+ if m['context'] == cid and m['id'] not in members :
|
1621 |
|
|
+ # replace the mame by the complete templated name. Use the demangle module for that
|
1622 |
|
|
+ if 'mangled' in m and m['name'].isalpha() :
|
1623 |
|
|
+ mm = m['mangled'][2:]
|
1624 |
|
|
+ dname = gccdemangler.demangle_name(mm)
|
1625 |
|
|
+ dret = gccdemangler.demangle_type(mm[dname[0]:])
|
1626 |
|
|
+ if dname[3] : mret = mm[dname[0]:dname[0]+dret[0]]
|
1627 |
|
|
+ else : mret = ''
|
1628 |
|
|
+ if [mret.find(t)!= -1 for t in ['T_']+['T%d_'%i for i in range(10)]].count(True) :
|
1629 |
|
|
+ fname = dname[1][dname[1].rfind('::' + m['name'])+2:]
|
1630 |
|
|
+ m['name'] = fname
|
1631 |
|
|
+ attrs['members'] += u' ' + m['id']
|
1632 |
|
|
+#---------------------------------------------------------------------------------------
|
1633 |
|
|
+def getContainerId(c):
|
1634 |
|
|
+ if c[-8:] == 'iterator' : return ('NOCONTAINER','')
|
1635 |
|
|
+ if c[:10] == 'std::deque' : return ('DEQUE','list')
|
1636 |
|
|
+ elif c[:9] == 'std::list' : return ('LIST','list')
|
1637 |
|
|
+ elif c[:8] == 'std::map' : return ('MAP','map')
|
1638 |
|
|
+ elif c[:13] == 'std::multimap': return ('MULTIMAP','map')
|
1639 |
|
|
+ elif c[:19] == '__gnu_cxx::hash_map': return ('HASHMAP','map')
|
1640 |
|
|
+ elif c[:24] == '__gnu_cxx::hash_multimap': return ('HASHMULTIMAP','map')
|
1641 |
|
|
+ elif c[:16] == 'stdext::hash_map': return ('HASHMAP','map')
|
1642 |
|
|
+ elif c[:21] == 'stdext::hash_multimap': return ('HASHMULTIMAP','map')
|
1643 |
|
|
+ elif c[:10] == 'std::queue' : return ('QUEUE','queue')
|
1644 |
|
|
+ elif c[:8] == 'std::set' : return ('SET','set')
|
1645 |
|
|
+ elif c[:13] == 'std::multiset': return ('MULTISET','set')
|
1646 |
|
|
+ elif c[:19] == '__gnu_cxx::hash_set': return ('HASHSET','set')
|
1647 |
|
|
+ elif c[:24] == '__gnu_cxx::hash_multiset': return ('HASHMULTISET','set')
|
1648 |
|
|
+ elif c[:16] == 'stdext::hash_set': return ('HASHSET','set')
|
1649 |
|
|
+ elif c[:21] == 'stdext::hash_multiset': return ('HASHMULTISET','set')
|
1650 |
|
|
+ elif c[:10] == 'std::stack' : return ('STACK','stack')
|
1651 |
|
|
+ elif c[:11] == 'std::vector' : return ('VECTOR','vector')
|
1652 |
|
|
+ else : return ('NOCONTAINER','')
|
1653 |
|
|
+#---------------------------------------------------------------------------------------
|
1654 |
|
|
+stldeftab = {}
|
1655 |
|
|
+stldeftab['deque'] = '=','std::allocator'
|
1656 |
|
|
+stldeftab['list'] = '=','std::allocator'
|
1657 |
|
|
+stldeftab['map'] = '=','=','std::less','std::allocator'
|
1658 |
|
|
+stldeftab['multimap'] = '=','=','std::less','std::allocator'
|
1659 |
|
|
+stldeftab['queue'] = '=','std::deque'
|
1660 |
|
|
+stldeftab['set'] = '=','std::less','std::allocator'
|
1661 |
|
|
+stldeftab['multiset'] = '=','std::less','std::allocator'
|
1662 |
|
|
+stldeftab['stack'] = '=','std::deque'
|
1663 |
|
|
+stldeftab['vector'] = '=','std::allocator'
|
1664 |
|
|
+stldeftab['basic_string'] = '=','std::char_traits','std::allocator'
|
1665 |
|
|
+#stldeftab['basic_ostream']= '=','std::char_traits'
|
1666 |
|
|
+#stldeftab['basic_istream']= '=','std::char_traits'
|
1667 |
|
|
+#stldeftab['basic_streambuf']= '=','std::char_traits'
|
1668 |
|
|
+if sys.platform == 'win32' :
|
1669 |
|
|
+ stldeftab['hash_set'] = '=', 'stdext::hash_compare', 'std::allocator'
|
1670 |
|
|
+ stldeftab['hash_multiset'] = '=', 'stdext::hash_compare', 'std::allocator'
|
1671 |
|
|
+ stldeftab['hash_map'] = '=', '=', 'stdext::hash_compare', 'std::allocator'
|
1672 |
|
|
+ stldeftab['hash_multimap'] = '=', '=', 'stdext::hash_compare', 'std::allocator'
|
1673 |
|
|
+else :
|
1674 |
|
|
+ stldeftab['hash_set'] = '=','__gnu_cxx::hash','std::equal_to','std::allocator'
|
1675 |
|
|
+ stldeftab['hash_multiset'] = '=','__gnu_cxx::hash','std::equal_to','std::allocator'
|
1676 |
|
|
+ stldeftab['hash_map'] = '=','=','__gnu_cxx::hash','std::equal_to','std::allocator'
|
1677 |
|
|
+ stldeftab['hash_multimap'] = '=','=','__gnu_cxx::hash','std::equal_to','std::allocator'
|
1678 |
|
|
+#---------------------------------------------------------------------------------------
|
1679 |
|
|
+def getTemplateArgs( cl ) :
|
1680 |
|
|
+ if cl.find('<') == -1 : return []
|
1681 |
|
|
+ args, cnt = [], 0
|
1682 |
|
|
+ for s in string.split(cl[cl.find('<')+1:cl.rfind('>')],',') :
|
1683 |
|
|
+ if cnt == 0 : args.append(s)
|
1684 |
|
|
+ else : args[-1] += ','+ s
|
1685 |
|
|
+ cnt += s.count('<')+s.count('(')-s.count('>')-s.count(')')
|
1686 |
|
|
+ if args[-1][-1] == ' ' : args[-1] = args[-1][:-1]
|
1687 |
|
|
+ return args
|
1688 |
|
|
+#---------------------------------------------------------------------------------------
|
1689 |
|
|
+def getTemplateArgString( cl ) :
|
1690 |
|
|
+ bc = 0
|
1691 |
|
|
+ if cl[-1] != '>' : return ''
|
1692 |
|
|
+ for i in range( len(cl)-1, -1, -1) :
|
1693 |
|
|
+ if cl[i] == '>' : bc += 1
|
1694 |
|
|
+ elif cl[i] == '<' : bc -= 1
|
1695 |
|
|
+ if bc == 0 : return cl[i:]
|
1696 |
|
|
+ return ''
|
1697 |
|
|
+#---------------------------------------------------------------------------------------
|
1698 |
|
|
+def normalizeClassAllTempl(name) : return normalizeClass(name,True)
|
1699 |
|
|
+def normalizeClassNoDefTempl(name) : return normalizeClass(name,False)
|
1700 |
|
|
+def normalizeClass(name,alltempl) :
|
1701 |
|
|
+ names, cnt = [], 0
|
1702 |
|
|
+ for s in string.split(name,'::') :
|
1703 |
|
|
+ if cnt == 0 : names.append(s)
|
1704 |
|
|
+ else : names[-1] += '::' + s
|
1705 |
|
|
+ cnt += s.count('<')-s.count('>')
|
1706 |
|
|
+ if alltempl : return string.join(map(normalizeFragmentAllTempl,names),'::')
|
1707 |
|
|
+ else : return string.join(map(normalizeFragmentNoDefTempl,names),'::')
|
1708 |
|
|
+#--------------------------------------------------------------------------------------
|
1709 |
|
|
+def normalizeFragmentAllTempl(name) : return normalizeFragment(name,True)
|
1710 |
|
|
+def normalizeFragmentNoDefTempl(name) : return normalizeFragment(name)
|
1711 |
|
|
+def normalizeFragment(name,alltempl=False) :
|
1712 |
|
|
+ name = name.strip()
|
1713 |
|
|
+ if name.find('<') == -1 :
|
1714 |
|
|
+ nor = name
|
1715 |
|
|
+ for e in [ ['long long unsigned int', 'unsigned long long'],
|
1716 |
|
|
+ ['long long int', 'long long'],
|
1717 |
|
|
+ ['unsigned short int', 'unsigned short'],
|
1718 |
|
|
+ ['short unsigned int', 'unsigned short'],
|
1719 |
|
|
+ ['short int', 'short'],
|
1720 |
|
|
+ ['long unsigned int', 'unsigned long'],
|
1721 |
|
|
+ ['unsigned long int', 'unsigned long'],
|
1722 |
|
|
+ ['long int', 'long']] :
|
1723 |
|
|
+ nor = nor.replace(e[0], e[1])
|
1724 |
|
|
+ return nor
|
1725 |
|
|
+ else : clname = name[:name.find('<')]
|
1726 |
|
|
+ if name.rfind('>') == -1 : suffix = ''
|
1727 |
|
|
+ else : suffix = name[name.rfind('>')+1:]
|
1728 |
|
|
+ args = getTemplateArgs(name)
|
1729 |
|
|
+ if alltempl :
|
1730 |
|
|
+ nor = clname + '<' + string.join(map(normalizeClassAllTempl,args),',')
|
1731 |
|
|
+ else :
|
1732 |
|
|
+ if clname in stldeftab :
|
1733 |
|
|
+ # select only the template parameters different from default ones
|
1734 |
|
|
+ sargs = []
|
1735 |
|
|
+ for i in range(len(args)) :
|
1736 |
|
|
+ if args[i].find(stldeftab[clname][i]) == -1 : sargs.append(args[i])
|
1737 |
|
|
+ nor = clname + '<' + string.join(map(normalizeClassNoDefTempl,sargs),',')
|
1738 |
|
|
+ else :
|
1739 |
|
|
+ nor = clname + '<' + string.join(map(normalizeClassNoDefTempl,args),',')
|
1740 |
|
|
+ if nor[-1] == '>' : nor += ' >' + suffix
|
1741 |
|
|
+ else : nor += '>' + suffix
|
1742 |
|
|
+ return nor
|
1743 |
|
|
+#--------------------------------------------------------------------------------------
|
1744 |
|
|
+def clean(a) :
|
1745 |
|
|
+ r = []
|
1746 |
|
|
+ for i in a :
|
1747 |
|
|
+ if i not in r : r.append(i)
|
1748 |
|
|
+ return r
|
1749 |
|
|
diff -Naur root.orig/reflex/python/genreflex/gendict.py root/reflex/python/genreflex/gendict.py
|
1750 |
|
|
--- root.orig/reflex/python/genreflex/gendict.py 2007-04-25 12:46:37.000000000 +0200
|
1751 |
|
|
+++ root/reflex/python/genreflex/gendict.py 2007-11-04 05:23:23.000000000 +0100
|
1752 |
|
|
@@ -27,6 +27,7 @@
|
1753 |
|
|
self.vtables = {}
|
1754 |
|
|
self.hfile = os.path.normpath(hfile).replace(os.sep,'/')
|
1755 |
|
|
self.pool = opts.get('pool',False)
|
1756 |
|
|
+ self.interpreter= opts.get('interpreter',False)
|
1757 |
|
|
self.quiet = opts.get('quiet',False)
|
1758 |
|
|
self.resolvettd = opts.get('resolvettd',True)
|
1759 |
|
|
self.xref = {}
|
1760 |
|
|
@@ -42,6 +43,7 @@
|
1761 |
|
|
self.errors = 0
|
1762 |
|
|
self.warnings = 0
|
1763 |
|
|
self.comments = opts.get('comments', False)
|
1764 |
|
|
+ self.iocomments = opts.get('iocomments', False)
|
1765 |
|
|
self.no_membertypedefs = opts.get('no_membertypedefs', False)
|
1766 |
|
|
self.generated_shadow_classes = []
|
1767 |
|
|
self.selectionname = 'ROOT::Reflex::Selection'
|
1768 |
|
|
@@ -88,7 +90,7 @@
|
1769 |
|
|
#----------------------------------------------------------------------------------
|
1770 |
|
|
def findSpecialNamespace(self):
|
1771 |
|
|
for ns in self.namespaces:
|
1772 |
|
|
- if ns['name'].find('.') != -1:
|
1773 |
|
|
+ if 'name' not in ns or ns['name'].find('.') != -1:
|
1774 |
|
|
self.unnamedNamespaces.append(ns['id'])
|
1775 |
|
|
elif ns['name'] == '::' :
|
1776 |
|
|
self.globalNamespaceID = ns['id']
|
1777 |
|
|
@@ -296,6 +298,14 @@
|
1778 |
|
|
# this check fixes a bug in gccxml 0.6.0_patch3 which sometimes generates incomplete definitions
|
1779 |
|
|
# of classes (without members). Every version after 0.6.0_patch3 is tested and fixes this bug
|
1780 |
|
|
if not c.has_key('members') : continue
|
1781 |
|
|
+
|
1782 |
|
|
+ # Filter any non-public data members for minimal interpreter dict
|
1783 |
|
|
+ if self.interpreter:
|
1784 |
|
|
+ cxref = self.xref[c['id']]
|
1785 |
|
|
+ # assumes that the default is "public"
|
1786 |
|
|
+ if cxref.has_key('attrs') and 'access' in cxref['attrs'] :
|
1787 |
|
|
+ continue
|
1788 |
|
|
+
|
1789 |
|
|
match = self.selector.matchclass( self.genTypeName(c['id']), self.files[c['file']]['name'])
|
1790 |
|
|
if match[0] and not match[1] :
|
1791 |
|
|
c['extra'] = match[0]
|
1792 |
|
|
@@ -361,7 +371,7 @@
|
1793 |
|
|
funcname = self.genTypeName(f['id'])
|
1794 |
|
|
if self.selector.selfunction( funcname ) and not self.selector.excfunction( funcname ) :
|
1795 |
|
|
selec.append(f)
|
1796 |
|
|
- if 'extra' in f and f['extra'].get('autoselect') and f not in selec:
|
1797 |
|
|
+ elif 'extra' in f and f['extra'].get('autoselect') and f not in selec:
|
1798 |
|
|
selec.append(f)
|
1799 |
|
|
return selec
|
1800 |
|
|
#----------------------------------------------------------------------------------
|
1801 |
|
|
@@ -370,10 +380,17 @@
|
1802 |
|
|
self.selector = sel # remember the selector
|
1803 |
|
|
if self.selector :
|
1804 |
|
|
for e in self.enums :
|
1805 |
|
|
+ # Filter any non-public data members for minimal interpreter dict
|
1806 |
|
|
+ if self.interpreter:
|
1807 |
|
|
+ exref = self.xref[e['id']]
|
1808 |
|
|
+ # assumes that the default is "public"
|
1809 |
|
|
+ if exref.has_key('attrs') and 'access' in exref['attrs'] :
|
1810 |
|
|
+ continue
|
1811 |
|
|
+
|
1812 |
|
|
ename = self.genTypeName(e['id'])
|
1813 |
|
|
if self.selector.selenum( ename ) and not self.selector.excenum( ename ) :
|
1814 |
|
|
selec.append(e)
|
1815 |
|
|
- if 'extra' in e and e['extra'].get('autoselect') and e not in selec:
|
1816 |
|
|
+ elif 'extra' in e and e['extra'].get('autoselect') and e not in selec:
|
1817 |
|
|
selec.append(e)
|
1818 |
|
|
return selec
|
1819 |
|
|
#---------------------------------------------------------------------------------
|
1820 |
|
|
@@ -385,7 +402,7 @@
|
1821 |
|
|
varname = self.genTypeName(v['id'])
|
1822 |
|
|
if self.selector.selvariable( varname ) and not self.selector.excvariable( varname ) :
|
1823 |
|
|
selec.append(v)
|
1824 |
|
|
- if 'extra' in v and v['extra'].get('autoselect') and v not in selec:
|
1825 |
|
|
+ elif 'extra' in v and v['extra'].get('autoselect') and v not in selec:
|
1826 |
|
|
selec.append(v)
|
1827 |
|
|
return selec
|
1828 |
|
|
#----------------------------------------------------------------------------------
|
1829 |
|
|
@@ -500,7 +517,7 @@
|
1830 |
|
|
args = self.xref[id]['subelems']
|
1831 |
|
|
if 'name' in attrs :
|
1832 |
|
|
if attrs['name'] in self.ignoremeth : return 0
|
1833 |
|
|
- #----Filter any method and operator for POOL -----
|
1834 |
|
|
+ #----Filter any method and operator for minimal POOL dict -----
|
1835 |
|
|
if self.pool :
|
1836 |
|
|
if elem in ('OperatorMethod','Converter') : return 0
|
1837 |
|
|
elif elem in ('Method',) :
|
1838 |
|
|
@@ -509,8 +526,11 @@
|
1839 |
|
|
if len(args) > 1 : return 0
|
1840 |
|
|
elif len(args) == 1 :
|
1841 |
|
|
if self.genTypeName(args[0]['type']) != 'const '+self.genTypeName(attrs['context'])+'&' : return 0
|
1842 |
|
|
+ #----Filter any non-public data members for minimal interpreter dict -----
|
1843 |
|
|
+ if self.interpreter and elem in ('Field') and 'access' in attrs : # assumes that the default is "public"
|
1844 |
|
|
+ return 0
|
1845 |
|
|
#----Filter any non public method
|
1846 |
|
|
- if 'access' in attrs : # assumes that the default is "public"
|
1847 |
|
|
+ if attrs.get('access') in ('protected', 'private') :
|
1848 |
|
|
if elem in ('Constructor','Destructor','Method','OperatorMethod','Converter') : return 0
|
1849 |
|
|
#----Filter any copy constructor with a private copy constructor in any base
|
1850 |
|
|
if elem == 'Constructor' and len(args) == 1 and 'name' in args[0] and args[0]['name'] == '_ctor_arg' :
|
1851 |
|
|
@@ -527,6 +547,7 @@
|
1852 |
|
|
def tmplclasses(self, local):
|
1853 |
|
|
result = []
|
1854 |
|
|
for c in self.classes :
|
1855 |
|
|
+ if not 'name' in c: continue
|
1856 |
|
|
name = c['name']
|
1857 |
|
|
if name.find('<') == -1 : continue
|
1858 |
|
|
temp = name[name.find('<')+1:name.rfind('>')]
|
1859 |
|
|
@@ -643,7 +664,7 @@
|
1860 |
|
|
|
1861 |
|
|
def genClassDict(self, attrs):
|
1862 |
|
|
members, bases = [], []
|
1863 |
|
|
- cl = attrs['name']
|
1864 |
|
|
+ cl = attrs.get('name')
|
1865 |
|
|
clf = '::' + attrs['fullname']
|
1866 |
|
|
cls = attrs['fullname']
|
1867 |
|
|
clt = string.translate(str(clf), self.transtable)
|
1868 |
|
|
@@ -694,7 +715,8 @@
|
1869 |
|
|
return sc, ss
|
1870 |
|
|
#----------------------------------------------------------------------------------
|
1871 |
|
|
def checkAccessibleType( self, type ):
|
1872 |
|
|
- while type['elem'] in ('PointerType','Typedef') : type = self.xref[type['attrs']['type']]
|
1873 |
|
|
+ while type['elem'] in ('PointerType','Typedef','ArrayType') :
|
1874 |
|
|
+ type = self.xref[type['attrs']['type']]
|
1875 |
|
|
attrs = type['attrs']
|
1876 |
|
|
if 'access' in attrs and attrs['access'] in ('private','protected') : return attrs['id']
|
1877 |
|
|
if 'context' in attrs and self.checkAccessibleType(self.xref[attrs['context']]) : return attrs['id']
|
1878 |
|
|
@@ -713,11 +735,17 @@
|
1879 |
|
|
return 0
|
1880 |
|
|
#----------------------------------------------------------------------------------
|
1881 |
|
|
def genClassShadow(self, attrs, inner = 0 ) :
|
1882 |
|
|
+ if not inner :
|
1883 |
|
|
+ if attrs['id'] in self.generated_shadow_classes : return ''
|
1884 |
|
|
+ else : self.generated_shadow_classes.append(attrs['id'])
|
1885 |
|
|
inner_shadows = {}
|
1886 |
|
|
bases = self.getBases( attrs['id'] )
|
1887 |
|
|
- cls = self.genTypeName(attrs['id'],const=True,colon=True)
|
1888 |
|
|
- clt = string.translate(str(cls), self.transtable)
|
1889 |
|
|
- if self.isUnnamedType(cls) and inner : clt = ''
|
1890 |
|
|
+ if inner and attrs.has_key('demangled') and self.isUnnamedType(attrs['demangled']) :
|
1891 |
|
|
+ cls = attrs['demangled']
|
1892 |
|
|
+ clt = ''
|
1893 |
|
|
+ else:
|
1894 |
|
|
+ cls = self.genTypeName(attrs['id'],const=True,colon=True)
|
1895 |
|
|
+ clt = string.translate(str(cls), self.transtable)
|
1896 |
|
|
xtyp = self.xref[attrs['id']]
|
1897 |
|
|
typ = xtyp['elem'].lower()
|
1898 |
|
|
indent = inner * 2 * ' '
|
1899 |
|
|
@@ -734,6 +762,7 @@
|
1900 |
|
|
bname = self.genTypeName(b['type'],colon=True)
|
1901 |
|
|
if self.xref[b['type']]['attrs'].get('access') in ('private','protected'):
|
1902 |
|
|
bname = string.translate(str(bname),self.transtable)
|
1903 |
|
|
+ if not inner: c = self.genClassShadow(self.xref[b['type']]['attrs']) + c
|
1904 |
|
|
c += indent + '%s %s' % ( acc , bname )
|
1905 |
|
|
if b is not bases[-1] : c += ', '
|
1906 |
|
|
c += indent + ' {\n' + indent +' public:\n'
|
1907 |
|
|
@@ -747,7 +776,7 @@
|
1908 |
|
|
member = self.xref[m]
|
1909 |
|
|
if member['elem'] in ('Class','Struct','Union','Enumeration') \
|
1910 |
|
|
and member['attrs'].get('access') in ('private','protected') \
|
1911 |
|
|
- and not self.isUnnamedType(member['attrs'].get('name')):
|
1912 |
|
|
+ and not self.isUnnamedType(member['attrs'].get('demangled')):
|
1913 |
|
|
cmem = self.genTypeName(member['attrs']['id'],const=True,colon=True)
|
1914 |
|
|
if cmem != cls and cmem not in inner_shadows :
|
1915 |
|
|
inner_shadows[cmem] = string.translate(str(cmem), self.transtable)
|
1916 |
|
|
@@ -756,19 +785,35 @@
|
1917 |
|
|
member = self.xref[m]
|
1918 |
|
|
if member['elem'] in ('Field',) :
|
1919 |
|
|
a = member['attrs']
|
1920 |
|
|
+ axref = self.xref[a['type']]
|
1921 |
|
|
t = self.genTypeName(a['type'],colon=True,const=True)
|
1922 |
|
|
+ arraytype = ""
|
1923 |
|
|
+ if t[-1] == ']' : arraytype = t[t.find('['):]
|
1924 |
|
|
+
|
1925 |
|
|
+ fundtype = axref
|
1926 |
|
|
+ while fundtype['elem'] in ('ArrayType', 'Typedef'):
|
1927 |
|
|
+ fundtype = self.xref[fundtype['attrs']['type']]
|
1928 |
|
|
+ mTypeElem = fundtype['elem']
|
1929 |
|
|
+
|
1930 |
|
|
+ #---- Check if pointer of reference - exact type irrelevant
|
1931 |
|
|
+ if mTypeElem == 'PointerType' :
|
1932 |
|
|
+ c += indent + ' void* %s;\n' % (a['name'] + arraytype)
|
1933 |
|
|
+ continue
|
1934 |
|
|
+ elif mTypeElem == 'ReferenceType' :
|
1935 |
|
|
+ c += indent + ' int& %s;\n' % (a['name'] + arraytype)
|
1936 |
|
|
+ continue
|
1937 |
|
|
+
|
1938 |
|
|
#---- Check if a type and a member with the same name exist in the same scope
|
1939 |
|
|
- mTypeElem = self.xref[a['type']]['elem']
|
1940 |
|
|
if mTypeElem in ('Class','Struct'):
|
1941 |
|
|
- mTypeName = self.xref[a['type']]['attrs']['name']
|
1942 |
|
|
- mTypeId = a['type']
|
1943 |
|
|
- for el in self.xref[self.xref[a['type']]['attrs']['context']]['attrs'].get('members').split():
|
1944 |
|
|
+ mTypeName = fundtype['attrs'].get('name')
|
1945 |
|
|
+ mTypeId = fundtype['attrs']['id']
|
1946 |
|
|
+ for el in self.xref[fundtype['attrs']['context']]['attrs'].get('members').split():
|
1947 |
|
|
if self.xref[el]['attrs'].get('name') == mTypeName and mTypeId != el :
|
1948 |
|
|
t = mTypeElem.lower() + ' ' + t[2:]
|
1949 |
|
|
break
|
1950 |
|
|
#---- Check for non public types------------------------
|
1951 |
|
|
- noPublicType = self.checkAccessibleType(self.xref[a['type']])
|
1952 |
|
|
- if ( noPublicType and not self.isUnnamedType(self.xref[a['type']]['attrs'].get('name'))):
|
1953 |
|
|
+ noPublicType = self.checkAccessibleType(axref)
|
1954 |
|
|
+ if ( noPublicType and not self.isUnnamedType(axref['attrs'].get('demangled'))):
|
1955 |
|
|
noPubTypeAttrs = self.xref[noPublicType]['attrs']
|
1956 |
|
|
cmem = self.genTypeName(noPubTypeAttrs['id'],const=True,colon=True)
|
1957 |
|
|
if cmem != cls and cmem not in inner_shadows :
|
1958 |
|
|
@@ -780,11 +825,11 @@
|
1959 |
|
|
for ikey in ikeys :
|
1960 |
|
|
if t.find(ikey) == 0 : t = t.replace(ikey, inner_shadows[ikey]) # change current class by shadow name
|
1961 |
|
|
elif t.find(ikey[2:]) != -1 : t = t.replace(ikey[2:], inner_shadows[ikey]) # idem without leading ::
|
1962 |
|
|
- mType = self.xref[a.get('type')]
|
1963 |
|
|
- if mType and self.isUnnamedType(mType['attrs'].get('name')) :
|
1964 |
|
|
+ mType = axref
|
1965 |
|
|
+ if mType and self.isUnnamedType(mType['attrs'].get('demangled')) :
|
1966 |
|
|
t = self.genClassShadow(mType['attrs'], inner+1)[:-2]
|
1967 |
|
|
fPPos = self.funPtrPos(t)
|
1968 |
|
|
- if t[-1] == ']' : c += indent + ' %s %s;\n' % ( t[:t.find('[')], a['name']+t[t.find('['):] )
|
1969 |
|
|
+ if t[-1] == ']' : c += indent + ' %s %s;\n' % ( t[:t.find('[')], a['name'] + arraytype )
|
1970 |
|
|
elif fPPos : c += indent + ' %s;\n' % ( t[:fPPos] + a['name'] + t[fPPos:] )
|
1971 |
|
|
else : c += indent + ' %s %s;\n' % ( t, a['name'] )
|
1972 |
|
|
c += indent + '};\n'
|
1973 |
|
|
@@ -792,6 +837,8 @@
|
1974 |
|
|
#----------------------------------------------------------------------------------
|
1975 |
|
|
def genTypedefBuild(self, attrs, childs) :
|
1976 |
|
|
if self.no_membertypedefs : return ''
|
1977 |
|
|
+ # access selection doesn't work with gccxml0.6 - typedefs don't have it
|
1978 |
|
|
+ if self.interpreter and 'access' in attrs : return ''
|
1979 |
|
|
s = ''
|
1980 |
|
|
s += ' .AddTypedef(%s, "%s::%s")' % ( self.genTypeID(attrs['type']), self.genTypeName(attrs['context']), attrs['name'])
|
1981 |
|
|
return s
|
1982 |
|
|
@@ -807,7 +854,8 @@
|
1983 |
|
|
s += ' .AddEnum("%s", "%s", &typeid(ROOT::Reflex::UnnamedEnum), %s)' % (name[name.rfind('::')+3:], values, mod)
|
1984 |
|
|
else :
|
1985 |
|
|
if attrs.get('access') in ('protected','private'):
|
1986 |
|
|
- s += ' .AddEnum("%s", "%s", &typeid(ROOT::Reflex::UnknownType), %s)' % (name, values, mod)
|
1987 |
|
|
+ if not self.interpreter:
|
1988 |
|
|
+ s += ' .AddEnum("%s", "%s", &typeid(ROOT::Reflex::UnknownType), %s)' % (name, values, mod)
|
1989 |
|
|
else:
|
1990 |
|
|
s += ' .AddEnum("%s", "%s", &typeid(%s), %s)' % (name, values, name, mod)
|
1991 |
|
|
return s
|
1992 |
|
|
@@ -823,6 +871,11 @@
|
1993 |
|
|
return s
|
1994 |
|
|
#----------------------------------------------------------------------------------
|
1995 |
|
|
def genTypeName(self, id, enum=False, const=False, colon=False, alltempl=False) :
|
1996 |
|
|
+ elem = self.xref[id]['elem']
|
1997 |
|
|
+ attrs = self.xref[id]['attrs']
|
1998 |
|
|
+ if self.isUnnamedType(attrs.get('demangled')) :
|
1999 |
|
|
+ if colon : return '__'+attrs['demangled']
|
2000 |
|
|
+ else : return attrs['demangled']
|
2001 |
|
|
if id[-1] in ['c','v'] :
|
2002 |
|
|
nid = id[:-1]
|
2003 |
|
|
cvdict = {'c':'const','v':'volatile'}
|
2004 |
|
|
@@ -836,11 +889,10 @@
|
2005 |
|
|
else : return cvdict[id[-1]] + ' ' + self.genTypeName(nid, enum, False, colon)
|
2006 |
|
|
# "const" vetoeing must not recurse
|
2007 |
|
|
const = False
|
2008 |
|
|
- elem = self.xref[id]['elem']
|
2009 |
|
|
- attrs = self.xref[id]['attrs']
|
2010 |
|
|
s = self.genScopeName(attrs, enum, const, colon)
|
2011 |
|
|
if elem == 'Namespace' :
|
2012 |
|
|
- if attrs['name'] != '::' : s += attrs['name']
|
2013 |
|
|
+ if 'name' not in attrs : s += '@anonymous@namespace@'
|
2014 |
|
|
+ elif attrs['name'] != '::' : s += attrs['name']
|
2015 |
|
|
elif elem == 'PointerType' :
|
2016 |
|
|
t = self.genTypeName(attrs['type'],enum, const, colon)
|
2017 |
|
|
if t[-1] == ')' or t[-7:] == ') const' or t[-10:] == ') volatile' : s += t.replace('::*)','::**)').replace('::)','::*)').replace('(*)', '(**)').replace('()','(*)')
|
2018 |
|
|
@@ -967,11 +1019,13 @@
|
2019 |
|
|
c += 'EnumTypeBuilder("' + sc + attrs['name'] + '");\n'
|
2020 |
|
|
else :
|
2021 |
|
|
name = ''
|
2022 |
|
|
- if 'context' in attrs :
|
2023 |
|
|
- ns = self.genTypeName(attrs['context'])
|
2024 |
|
|
- if ns : name += ns + '::'
|
2025 |
|
|
- if 'name' in attrs :
|
2026 |
|
|
- name += attrs['name']
|
2027 |
|
|
+ if 'name' not in attrs and 'demangled' in attrs : name = attrs.get('demangled')
|
2028 |
|
|
+ else:
|
2029 |
|
|
+ if 'context' in attrs :
|
2030 |
|
|
+ ns = self.genTypeName(attrs['context'])
|
2031 |
|
|
+ if ns : name += ns + '::'
|
2032 |
|
|
+ if 'name' in attrs :
|
2033 |
|
|
+ name += attrs['name']
|
2034 |
|
|
name = normalizeClass(name,False)
|
2035 |
|
|
c += 'TypeBuilder("'+name+'");\n'
|
2036 |
|
|
return c
|
2037 |
|
|
@@ -1141,7 +1195,9 @@
|
2038 |
|
|
return c
|
2039 |
|
|
#----------------------------------------------------------------------------------
|
2040 |
|
|
def genCommentProperty(self, attrs):
|
2041 |
|
|
- if not self.comments or 'file' not in attrs or ('artificial' in attrs and attrs['artificial'] == '1') : return ''
|
2042 |
|
|
+ if not (self.comments or self.iocomments) \
|
2043 |
|
|
+ or 'file' not in attrs \
|
2044 |
|
|
+ or ('artificial' in attrs and attrs['artificial'] == '1') : return ''
|
2045 |
|
|
fd = self.files[attrs['file']]
|
2046 |
|
|
# open and read the header file if not yet done
|
2047 |
|
|
if 'filelines' not in fd :
|
2048 |
|
|
@@ -1152,8 +1208,14 @@
|
2049 |
|
|
except :
|
2050 |
|
|
return ''
|
2051 |
|
|
line = fd['filelines'][int(attrs['line'])-1]
|
2052 |
|
|
- if line.find('//') == -1 : return ''
|
2053 |
|
|
- return '\n .AddProperty("comment","%s")' % (line[line.index('//')+2:-1]).replace('"','\\"')
|
2054 |
|
|
+ poscomment = line.find('//')
|
2055 |
|
|
+ if poscomment == -1 : return ''
|
2056 |
|
|
+ if not self.comments and self.iocomments:
|
2057 |
|
|
+ if line[poscomment+2] != '!' \
|
2058 |
|
|
+ and line[poscomment+2] != '[' \
|
2059 |
|
|
+ and line[poscomment+2:poscomment+4] != '->' \
|
2060 |
|
|
+ and line[poscomment+2:poscomment+4] != '||': return ''
|
2061 |
|
|
+ return '\n .AddProperty("comment","%s")' % (line[poscomment+2:-1]).replace('"','\\"')
|
2062 |
|
|
#----------------------------------------------------------------------------------
|
2063 |
|
|
def genArgument(self, attrs):
|
2064 |
|
|
c = self.genTypeName(attrs['type'], enum=True, const=False)
|
2065 |
|
|
@@ -1168,11 +1230,12 @@
|
2066 |
|
|
return c
|
2067 |
|
|
#----------------------------------------------------------------------------------
|
2068 |
|
|
def genModifier(self, attrs, xattrs ):
|
2069 |
|
|
- if 'access' not in attrs : mod = 'PUBLIC'
|
2070 |
|
|
+ if attrs.get('access') == 'public' or 'access' not in attrs : mod = 'PUBLIC'
|
2071 |
|
|
elif attrs['access'] == 'private' : mod = 'PRIVATE'
|
2072 |
|
|
elif attrs['access'] == 'protected' : mod = 'PROTECTED'
|
2073 |
|
|
else : mod = 'NONE'
|
2074 |
|
|
if 'virtual' in attrs : mod += ' | VIRTUAL'
|
2075 |
|
|
+ if 'pure_virtual' in attrs : mod += ' | ABSTRACT'
|
2076 |
|
|
if 'static' in attrs : mod += ' | STATIC'
|
2077 |
|
|
# Extra modifiers
|
2078 |
|
|
xtrans = ''
|
2079 |
|
|
@@ -1192,7 +1255,7 @@
|
2080 |
|
|
#----------------------------------------------------------------------------------
|
2081 |
|
|
def genMCOBuild(self, type, name, attrs, args):
|
2082 |
|
|
id = attrs['id']
|
2083 |
|
|
- if self.isUnnamedType(self.xref[attrs['context']]['attrs'].get('name')) or \
|
2084 |
|
|
+ if self.isUnnamedType(self.xref[attrs['context']]['attrs'].get('demangled')) or \
|
2085 |
|
|
self.checkAccessibleType(self.xref[attrs['context']]) : return ''
|
2086 |
|
|
if type == 'constructor' : returns = 'void'
|
2087 |
|
|
else : returns = self.genTypeName(attrs['returns'])
|
2088 |
|
|
@@ -1317,7 +1380,9 @@
|
2089 |
|
|
return self.genMCODecl( 'constructor', '', attrs, args )
|
2090 |
|
|
#----------------------------------------------------------------------------------
|
2091 |
|
|
def genConstructorBuild(self, attrs, args):
|
2092 |
|
|
- return self.genMCOBuild( 'constructor', attrs['name'], attrs, args )
|
2093 |
|
|
+ name = attrs.get('name')
|
2094 |
|
|
+ if not name : name = self.xref[attrs['context']]['attrs']['demangled'].split('::')[-1]
|
2095 |
|
|
+ return self.genMCOBuild( 'constructor', name, attrs, args )
|
2096 |
|
|
#----------------------------------------------------------------------------------
|
2097 |
|
|
def genConstructorDef(self, attrs, args):
|
2098 |
|
|
cl = self.genTypeName(attrs['context'], colon=True)
|
2099 |
|
|
@@ -1349,7 +1414,7 @@
|
2100 |
|
|
return 'static void* destructor%s(void * o, const std::vector<void*>&, void *) {\n ((::%s*)o)->~%s(); return 0;\n}' % ( attrs['id'], cl, attrs['name'] )
|
2101 |
|
|
#----------------------------------------------------------------------------------
|
2102 |
|
|
def genDestructorBuild(self, attrs, childs):
|
2103 |
|
|
- if self.isUnnamedType(self.xref[attrs['context']]['attrs'].get('name')) or \
|
2104 |
|
|
+ if self.isUnnamedType(self.xref[attrs['context']]['attrs'].get('demangled')) or \
|
2105 |
|
|
self.checkAccessibleType(self.xref[attrs['context']]) : return ''
|
2106 |
|
|
mod = self.genModifier(attrs,None)
|
2107 |
|
|
id = attrs['id']
|
2108 |
|
|
@@ -1399,7 +1464,7 @@
|
2109 |
|
|
return ' .AddBase(%s, BaseOffset< %s, %s >::Get(), %s)' % (self.genTypeID(b['type']), clf, self.genTypeName(b['type'],colon=True), mod)
|
2110 |
|
|
#----------------------------------------------------------------------------------
|
2111 |
|
|
def enhanceClass(self, attrs):
|
2112 |
|
|
- if self.isUnnamedType(attrs['name']) or self.checkAccessibleType(self.xref[attrs['id']]) : return
|
2113 |
|
|
+ if self.isUnnamedType(attrs.get('demangled')) or self.checkAccessibleType(self.xref[attrs['id']]) : return
|
2114 |
|
|
# Default constructor
|
2115 |
|
|
if 'members' in attrs : members = attrs['members'].split()
|
2116 |
|
|
else : members = []
|
2117 |
|
|
@@ -1421,8 +1486,10 @@
|
2118 |
|
|
new_attrs['artificial'] = 'true'
|
2119 |
|
|
self.xref[id] = {'elem':'Constructor', 'attrs':new_attrs,'subelems':[] }
|
2120 |
|
|
attrs['members'] += u' ' + id
|
2121 |
|
|
- elif len(args) == 0 and 'abstract' not in attrs and \
|
2122 |
|
|
- 'access' not in self.xref[m]['attrs'] and not self.isDestructorNonPublic(attrs['id']):
|
2123 |
|
|
+ if (len(args) == 0 or 'default' in args[0] ) \
|
2124 |
|
|
+ and 'abstract' not in attrs \
|
2125 |
|
|
+ and self.xref[m]['attrs'].get('access') == 'public' \
|
2126 |
|
|
+ and not self.isDestructorNonPublic(attrs['id']):
|
2127 |
|
|
# NewDel functions extra function
|
2128 |
|
|
id = u'_x%d' % self.x_id.next()
|
2129 |
|
|
new_attrs = { 'id':id, 'context':attrs['id'], 'artificial':'true' }
|
2130 |
|
|
diff -Naur root.orig/reflex/python/genreflex/genreflex06.py root/reflex/python/genreflex/genreflex06.py
|
2131 |
|
|
--- root.orig/reflex/python/genreflex/genreflex06.py 1970-01-01 01:00:00.000000000 +0100
|
2132 |
|
|
+++ root/reflex/python/genreflex/genreflex06.py 2007-11-04 05:24:45.000000000 +0100
|
2133 |
|
|
@@ -0,0 +1,349 @@
|
2134 |
|
|
+# Copyright CERN, CH-1211 Geneva 23, 2004-2006, All rights reserved.
|
2135 |
|
|
+#
|
2136 |
|
|
+# Permission to use, copy, modify, and distribute this software for any
|
2137 |
|
|
+# purpose is hereby granted without fee, provided that this copyright and
|
2138 |
|
|
+# permissions notice appear in all copies and derivatives.
|
2139 |
|
|
+#
|
2140 |
|
|
+# This software is provided "as is" without express or implied warranty.
|
2141 |
|
|
+
|
2142 |
|
|
+import sys, os, gendict06, selclass, gencapa, genrootmap, string, getopt
|
2143 |
|
|
+
|
2144 |
|
|
+class genreflex:
|
2145 |
|
|
+#----------------------------------------------------------------------------------
|
2146 |
|
|
+ def __init__(self):
|
2147 |
|
|
+ self.files = []
|
2148 |
|
|
+ self.output = None
|
2149 |
|
|
+ self.outputDir = None
|
2150 |
|
|
+ self.outputFile = None
|
2151 |
|
|
+ self.capabilities = None
|
2152 |
|
|
+ self.rootmap = None
|
2153 |
|
|
+ self.rootmaplib = None
|
2154 |
|
|
+ self.select = None
|
2155 |
|
|
+ self.cppopt = ''
|
2156 |
|
|
+ self.deep = False
|
2157 |
|
|
+ self.opts = {}
|
2158 |
|
|
+ self.gccxmlpath = None
|
2159 |
|
|
+ self.gccxmlopt = ''
|
2160 |
|
|
+ self.gccxmlvers = '0.6.0_patch3'
|
2161 |
|
|
+ self.selector = None
|
2162 |
|
|
+ self.gccxml = ''
|
2163 |
|
|
+ self.quiet = False
|
2164 |
|
|
+#----------------------------------------------------------------------------------
|
2165 |
|
|
+ def usage(self, status = 1) :
|
2166 |
|
|
+ print 'Usage:'
|
2167 |
|
|
+ print ' genreflex headerfile1.h [headerfile2.h] [options] [preprocesor options]'
|
2168 |
|
|
+ print 'Try "genreflex --help" for more information.'
|
2169 |
|
|
+ sys.exit(status)
|
2170 |
|
|
+#----------------------------------------------------------------------------------
|
2171 |
|
|
+ def help(self) :
|
2172 |
|
|
+ print """Generates the LCG dictionary file for each header file\n
|
2173 |
|
|
+ Usage:
|
2174 |
|
|
+ genreflex headerfile1.h [headerfile2.h] [options] [preprocesor options]\n
|
2175 |
|
|
+ Options:
|
2176 |
|
|
+ -s <file>, --selection_file=<file>
|
2177 |
|
|
+ Class selection file to specify for which classes the dictionary
|
2178 |
|
|
+ will be generated
|
2179 |
|
|
+ Format (XML):
|
2180 |
|
|
+ <lcgdict>
|
2181 |
|
|
+ [<selection>]
|
2182 |
|
|
+ <class [name="classname"] [pattern="wildname"]
|
2183 |
|
|
+ [file_name="filename"] [file_pattern="wildname"]
|
2184 |
|
|
+ [id="xxxx"] [type="vector"]/>
|
2185 |
|
|
+ <class name="classname" >
|
2186 |
|
|
+ <field name="m_transient" transient="true"/>
|
2187 |
|
|
+ <field name="m_anothertransient" transient="true"/>
|
2188 |
|
|
+ <properties prop1="value1" [prop2="value2"]/>
|
2189 |
|
|
+ </class>
|
2190 |
|
|
+ <function [name="funcname"] [pattern="wildname"] />
|
2191 |
|
|
+ <enum [name="enumname"] [patter="wildname"] />
|
2192 |
|
|
+ <variable [name="varname"] [patter="wildname"] />
|
2193 |
|
|
+ [</selection>]
|
2194 |
|
|
+ <exclusion>
|
2195 |
|
|
+ <class [name="classname"] [pattern="wildname"] />
|
2196 |
|
|
+ <method name="unwanted" />
|
2197 |
|
|
+ </class>
|
2198 |
|
|
+ ...
|
2199 |
|
|
+ </lcgdict>\n
|
2200 |
|
|
+ -o <file>, --output <file>
|
2201 |
|
|
+ Output file name. If an existing directory is specified instead of a file,
|
2202 |
|
|
+ then a filename will be build using the name of the input file and will
|
2203 |
|
|
+ be placed in the given directory. <headerfile>_rflx.cpp \n
|
2204 |
|
|
+ --pool, --dataonly
|
2205 |
|
|
+ Generate minimal dictionary required for POOL persistency\n
|
2206 |
|
|
+ --interpreteronly
|
2207 |
|
|
+ Generate minimal dictionary required for interpreter\n
|
2208 |
|
|
+ --deep
|
2209 |
|
|
+ Generate dictionary for all dependend classes\n
|
2210 |
|
|
+ --split (OBSOLETE)
|
2211 |
|
|
+ Generate separate file for stub functions. Option sometimes needed on Windows.\n
|
2212 |
|
|
+ --reflex (OBSOLETE)
|
2213 |
|
|
+ Generate Reflex dictionaries.\n
|
2214 |
|
|
+ --comments
|
2215 |
|
|
+ Add end-of-line comments in data and functions members as a property called "comment" \n
|
2216 |
|
|
+ --iocomments
|
2217 |
|
|
+ Add end-of-line comments in data and functions members as a property called "comment", but only for comments relevant for ROOT I/O \n
|
2218 |
|
|
+ --no_membertypedefs
|
2219 |
|
|
+ Disable the definition of class member typedefs \n
|
2220 |
|
|
+ --no_templatetypedefs
|
2221 |
|
|
+ Disable resolving of typedefs in template parameters for selection names. E.g. std::vector<MYINT>.\n
|
2222 |
|
|
+ --fail_on_warnings
|
2223 |
|
|
+ The genreflex command fails (retuns the value 1) if any warning message is issued \n
|
2224 |
|
|
+ --gccxmlpath=<path>
|
2225 |
|
|
+ Path path where the gccxml tool is installed.
|
2226 |
|
|
+ If not defined the standard PATH environ variable is used\n
|
2227 |
|
|
+ --gccxmlopt=<gccxmlopt>
|
2228 |
|
|
+ Options to be passed directly to gccxml\n
|
2229 |
|
|
+ -c <file>, --capabilities=<file>
|
2230 |
|
|
+ Generate the capabilities file to be used by the SEAL Plugin Manager. This file
|
2231 |
|
|
+ lists the names of all classes for which the reflection is formation is provided.\n
|
2232 |
|
|
+ --rootmap=<file>
|
2233 |
|
|
+ Generate the rootmap file to be used by ROOT/CINT. This file lists the names of
|
2234 |
|
|
+ all classes for which the reflection is formation is provided.\n
|
2235 |
|
|
+ --rootmap-lib=<library>
|
2236 |
|
|
+ Library name for the rootmap file.\n
|
2237 |
|
|
+ --debug
|
2238 |
|
|
+ Print extra debug information while processing. Keep intermediate files\n
|
2239 |
|
|
+ --quiet
|
2240 |
|
|
+ No not print informational messages\n
|
2241 |
|
|
+ -h, --help
|
2242 |
|
|
+ Print this help\n
|
2243 |
|
|
+ """
|
2244 |
|
|
+ sys.exit()
|
2245 |
|
|
+#----------------------------------------------------------------------------------
|
2246 |
|
|
+ def parse_args(self, argv = sys.argv) :
|
2247 |
|
|
+ options = []
|
2248 |
|
|
+ #----Ontain the list of files to process------------
|
2249 |
|
|
+ for a in argv[1:] :
|
2250 |
|
|
+ if a[0] != '-' :
|
2251 |
|
|
+ self.files.append(a)
|
2252 |
|
|
+ else :
|
2253 |
|
|
+ options = argv[argv.index(a):]
|
2254 |
|
|
+ break
|
2255 |
|
|
+ #----Process options--------------------------------
|
2256 |
|
|
+ try:
|
2257 |
|
|
+ opts, args = getopt.getopt(options, 'ho:s:c:I:U:D:PC', \
|
2258 |
|
|
+ ['help','debug=', 'output=','selection_file=','pool','dataonly','interpreteronly','deep','gccxmlpath=',
|
2259 |
|
|
+ 'capabilities=','rootmap=','rootmap-lib=','comments','iocomments','no_membertypedefs',
|
2260 |
|
|
+ 'fail_on_warnings', 'quiet', 'gccxmlopt=', 'reflex', 'split','no_templatetypedefs'])
|
2261 |
|
|
+ except getopt.GetoptError, e:
|
2262 |
|
|
+ print "--->> genreflex: ERROR:",e
|
2263 |
|
|
+ self.usage(2)
|
2264 |
|
|
+ self.output = '.'
|
2265 |
|
|
+ self.select = None
|
2266 |
|
|
+ self.gccxmlpath = None
|
2267 |
|
|
+ self.cppopt = ''
|
2268 |
|
|
+ self.pool = 0
|
2269 |
|
|
+ self.interpreter = 0
|
2270 |
|
|
+ for o, a in opts:
|
2271 |
|
|
+ if o in ('-h', '--help'):
|
2272 |
|
|
+ self.help()
|
2273 |
|
|
+ if o in ('--no_templatetypedefs',):
|
2274 |
|
|
+ self.opts['resolvettd'] = 0
|
2275 |
|
|
+ if o in ('--debug',):
|
2276 |
|
|
+ self.opts['debug'] = a
|
2277 |
|
|
+ if o in ('-o', '--output'):
|
2278 |
|
|
+ self.output = a
|
2279 |
|
|
+ if o in ('-s', '--selection_file'):
|
2280 |
|
|
+ self.select = a
|
2281 |
|
|
+ if o in ('--pool',):
|
2282 |
|
|
+ self.opts['pool'] = True
|
2283 |
|
|
+ if o in ('--dataonly',):
|
2284 |
|
|
+ self.opts['pool'] = True
|
2285 |
|
|
+ if o in ('--interpreteronly',):
|
2286 |
|
|
+ self.opts['interpreter'] = True
|
2287 |
|
|
+ if o in ('--deep',):
|
2288 |
|
|
+ self.deep = True
|
2289 |
|
|
+ if o in ('--split',):
|
2290 |
|
|
+ print '--->> genreflex: WARNING: --split option is obsolete'
|
2291 |
|
|
+ if o in ('--reflex',):
|
2292 |
|
|
+ print '--->> genreflex: WARNING: --reflex option is obsolete'
|
2293 |
|
|
+ if o in ('--comments',):
|
2294 |
|
|
+ self.opts['comments'] = True
|
2295 |
|
|
+ if o in ('--iocomments',):
|
2296 |
|
|
+ self.opts['iocomments'] = True
|
2297 |
|
|
+ if o in ('--no_membertypedefs',):
|
2298 |
|
|
+ self.opts['no_membertypedefs'] = True
|
2299 |
|
|
+ if o in ('--fail_on_warnings',):
|
2300 |
|
|
+ self.opts['fail_on_warnings'] = True
|
2301 |
|
|
+ if o in ('--quiet',):
|
2302 |
|
|
+ self.opts['quiet'] = True
|
2303 |
|
|
+ self.quiet = True
|
2304 |
|
|
+ if o in ('--gccxmlpath',):
|
2305 |
|
|
+ self.gccxmlpath = a
|
2306 |
|
|
+ if o in ('--gccxmlopt',):
|
2307 |
|
|
+ self.gccxmlopt += a +' '
|
2308 |
|
|
+ if o in ('-c', '--capabilities'):
|
2309 |
|
|
+ self.capabilities = a
|
2310 |
|
|
+ if o in ('--rootmap',):
|
2311 |
|
|
+ self.rootmap = a
|
2312 |
|
|
+ if o in ('--rootmap-lib',):
|
2313 |
|
|
+ self.rootmaplib = a
|
2314 |
|
|
+ if o in ('-I', '-U', '-D', '-P', '-C') :
|
2315 |
|
|
+ self.cppopt += '\'' + o + a + '\' '
|
2316 |
|
|
+#----------------------------------------------------------------------------------
|
2317 |
|
|
+ def check_files_dirs(self):
|
2318 |
|
|
+ #---Check existance of input files--------------------
|
2319 |
|
|
+ if self.files :
|
2320 |
|
|
+ for f in self.files :
|
2321 |
|
|
+ if not os.path.exists(f) :
|
2322 |
|
|
+ print '--->> genreflex: ERROR: C++ file "' + f + '" not found'
|
2323 |
|
|
+ self.usage()
|
2324 |
|
|
+ else :
|
2325 |
|
|
+ print '--->> genreflex: ERROR: No input file specified'
|
2326 |
|
|
+ self.usage()
|
2327 |
|
|
+ #---Check existance of output directory----------------
|
2328 |
|
|
+ if os.path.isdir(self.output) :
|
2329 |
|
|
+ self.outputDir = self.output
|
2330 |
|
|
+ self.outputFile = None
|
2331 |
|
|
+ else :
|
2332 |
|
|
+ self.outputDir, self.outputFile = os.path.split(self.output)
|
2333 |
|
|
+ if self.outputDir and not os.path.isdir(self.outputDir) :
|
2334 |
|
|
+ print '--->> genreflex: ERROR: Output directory ', self.outputDir, ' not found'
|
2335 |
|
|
+ self.usage()
|
2336 |
|
|
+ #---Hande selection class file-------------------------
|
2337 |
|
|
+ classes = []
|
2338 |
|
|
+ if self.select :
|
2339 |
|
|
+ if not os.path.exists(self.select) :
|
2340 |
|
|
+ print '--->> genreflex: ERROR: Class selection file "' + self.select + '" not found'
|
2341 |
|
|
+ self.usage()
|
2342 |
|
|
+ for l in open(self.select).readlines() : classes.append(l[:-1])
|
2343 |
|
|
+ #----------GCCXML command------------------------------
|
2344 |
|
|
+ if not self.gccxmlpath:
|
2345 |
|
|
+ try:
|
2346 |
|
|
+ import gccxmlpath
|
2347 |
|
|
+ self.gccxmlpath = gccxmlpath.gccxmlpath
|
2348 |
|
|
+ except:
|
2349 |
|
|
+ pass
|
2350 |
|
|
+ if self.gccxmlpath :
|
2351 |
|
|
+ if sys.platform == 'win32' :
|
2352 |
|
|
+ self.gccxml = self.gccxmlpath + os.sep + 'gccxml.exe'
|
2353 |
|
|
+ else :
|
2354 |
|
|
+ self.gccxml = self.gccxmlpath + os.sep + 'gccxml'
|
2355 |
|
|
+ if not os.path.isfile(self.gccxml) :
|
2356 |
|
|
+ print '--->> genreflex: ERROR: Path to gccxml given, but no executable found at', self.gccxml
|
2357 |
|
|
+ elif self.which('gccxml') :
|
2358 |
|
|
+ self.gccxml = 'gccxml'
|
2359 |
|
|
+ print '--->> genreflex: INFO: No explicit path to gccxml given. Found gccxml at', self.which('gccxml')
|
2360 |
|
|
+ else :
|
2361 |
|
|
+ if sys.platform == 'win32' :
|
2362 |
|
|
+ self.gccxml = r'\\cern.ch\dfs\Experiments\sw\lcg\external\gccxml\0.6.0_patch3\win32_vc71\bin\gccxml'
|
2363 |
|
|
+ else :
|
2364 |
|
|
+ self.gccxml = '/afs/cern.ch/sw/lcg/external/gccxml/0.6.0_patch3/slc3_ia32_gcc323/bin/gccxml'
|
2365 |
|
|
+ print '--->> genreflex: INFO: No gccxml executable found, using fallback location at', self.gccxml
|
2366 |
|
|
+ #---------------Open selection file-------------------
|
2367 |
|
|
+ try :
|
2368 |
|
|
+ if self.select : self.selector = selclass.selClass(self.select,parse=1)
|
2369 |
|
|
+ else : self.selector = None
|
2370 |
|
|
+ except :
|
2371 |
|
|
+ sys.exit(1)
|
2372 |
|
|
+
|
2373 |
|
|
+#----------------------------------------------------------------------------------
|
2374 |
|
|
+ def genGccxmlInfo(self):
|
2375 |
|
|
+ s = ''
|
2376 |
|
|
+ (inp,out,err) = os.popen3(self.gccxml + ' --print')
|
2377 |
|
|
+ serr = err.read()
|
2378 |
|
|
+ sout = out.read()
|
2379 |
|
|
+ if serr :
|
2380 |
|
|
+ print '--->> genreflex: WARNING: Could not invoke %s --print' % self.gccxml
|
2381 |
|
|
+ print '--->> genreflex: WARNING: %s' % serr
|
2382 |
|
|
+ return s
|
2383 |
|
|
+ gccxmlv = sout.split('\n')[0].split()[-1]
|
2384 |
|
|
+ # For 0.6.0 we can't do much because we have not put in a patch info into the version string
|
2385 |
|
|
+ if gccxmlv != '0.6.0' and gccxmlv != self.gccxmlvers :
|
2386 |
|
|
+ print '--->> genreflex: WARNING: gccxml versions differ. Used version: %s. Recommended version: %s. ' % ( gccxmlv, self.gccxmlvers)
|
2387 |
|
|
+ print '--->> genreflex: WARNING: gccxml binary used: %s' % ( self.gccxml )
|
2388 |
|
|
+ s += sout
|
2389 |
|
|
+ compiler = ''
|
2390 |
|
|
+ for l in sout.split('\n'):
|
2391 |
|
|
+ ll = l.split('"')
|
2392 |
|
|
+ if ll[0].find('GCCXML_COMPILER') != -1 :
|
2393 |
|
|
+ compiler = ll[1]
|
2394 |
|
|
+ break
|
2395 |
|
|
+ bcomp = os.path.basename(compiler)
|
2396 |
|
|
+ vopt = ''
|
2397 |
|
|
+ if bcomp in ('msvc7','msvc71') : return s
|
2398 |
|
|
+ elif bcomp in ('gcc','g++','c++') : vopt = '--version'
|
2399 |
|
|
+ elif bcomp in ('cl.exe','cl') : vopt = '' # there is no option to print only the version with cl
|
2400 |
|
|
+ else :
|
2401 |
|
|
+ print '--->> genreflex: WARNING: While trying to retrieve compiler version, found unknown compiler %s' % compiler
|
2402 |
|
|
+ return s
|
2403 |
|
|
+ (inp,out,err) = os.popen3('%s %s'%(compiler,vopt))
|
2404 |
|
|
+ serr = err.read()
|
2405 |
|
|
+ if serr :
|
2406 |
|
|
+ print '--->> genreflex: WARNING: While trying to retrieve compiler information. Cannot invoke %s %s' % (compiler,vopt)
|
2407 |
|
|
+ print '--->> genreflex: WARNING: %s' % serr
|
2408 |
|
|
+ return s
|
2409 |
|
|
+ s += '\nCompiler info:\n' + out.read()
|
2410 |
|
|
+ return s
|
2411 |
|
|
+#----------------------------------------------------------------------------------
|
2412 |
|
|
+ def process_files(self):
|
2413 |
|
|
+ total_warnings = 0
|
2414 |
|
|
+ file_extension = '_rflx.cpp'
|
2415 |
|
|
+ #----------Loop oover all the input files--------------
|
2416 |
|
|
+ for source in self.files :
|
2417 |
|
|
+ path, fullname = os.path.split(source)
|
2418 |
|
|
+ name = fullname[:fullname.find('.')]
|
2419 |
|
|
+ xmlfile = os.path.join(self.outputDir,name+'.xml')
|
2420 |
|
|
+ if( self.outputFile ) :
|
2421 |
|
|
+ dicfile = os.path.join(self.outputDir,self.outputFile)
|
2422 |
|
|
+ else :
|
2423 |
|
|
+ dicfile = os.path.join(self.outputDir,name+file_extension)
|
2424 |
|
|
+ #---------------Parse the header file with GCC_XML
|
2425 |
|
|
+ cmd = '%s %s \'%s\' \'-fxml=%s\' %s -D__REFLEX__' %(self.gccxml, self.gccxmlopt, source, xmlfile, self.cppopt)
|
2426 |
|
|
+ if not self.quiet : print '--->> genreflex: INFO: Parsing file %s with GCC_XML' % source,
|
2427 |
|
|
+ status = os.system(cmd)
|
2428 |
|
|
+ if status :
|
2429 |
|
|
+ print '\n--->> genreflex: ERROR: processing file with gccxml. genreflex command failed.'
|
2430 |
|
|
+ sys.exit(1)
|
2431 |
|
|
+ else:
|
2432 |
|
|
+ if not self.quiet : print 'OK'
|
2433 |
|
|
+ gccxmlinfo = self.genGccxmlInfo()
|
2434 |
|
|
+ #---------------Generate the dictionary---------------
|
2435 |
|
|
+ if not self.quiet : print '--->> genreflex: INFO: Generating Reflex Dictionary'
|
2436 |
|
|
+ dg = gendict06.genDictionary(source, self.opts)
|
2437 |
|
|
+ dg.parse(xmlfile)
|
2438 |
|
|
+ classes = dg.selclasses(self.selector, self.deep)
|
2439 |
|
|
+ functions = dg.selfunctions(self.selector)
|
2440 |
|
|
+ enums = dg.selenums(self.selector)
|
2441 |
|
|
+ variables = dg.selvariables(self.selector)
|
2442 |
|
|
+ cnames, warnings, errors = dg.generate(dicfile, classes, functions, enums, variables, gccxmlinfo )
|
2443 |
|
|
+ total_warnings += warnings
|
2444 |
|
|
+ #------------Produce Seal Capabilities source file------
|
2445 |
|
|
+ if self.capabilities :
|
2446 |
|
|
+ if os.path.isdir(self.capabilities) :
|
2447 |
|
|
+ capfile = os.path.join(self.capabilities, 'capabilities.cpp')
|
2448 |
|
|
+ else :
|
2449 |
|
|
+ capfile = os.path.join(self.outputDir, self.capabilities)
|
2450 |
|
|
+ gencapa.genCapabilities(capfile, name, cnames)
|
2451 |
|
|
+ #------------Produce rootmap file-----------------------
|
2452 |
|
|
+ if self.rootmap :
|
2453 |
|
|
+ if os.path.isdir(self.rootmap) :
|
2454 |
|
|
+ mapfile = os.path.join(self.rootmap, 'rootmap')
|
2455 |
|
|
+ else :
|
2456 |
|
|
+ mapfile = os.path.join(self.outputDir, self.rootmap)
|
2457 |
|
|
+ if not self.rootmaplib : self.rootmaplib = 'lib'+name+'.so'
|
2458 |
|
|
+ genrootmap.genRootMap(mapfile, name, self.rootmaplib, cnames, classes)
|
2459 |
|
|
+ #------------Report unused class selections in selection
|
2460 |
|
|
+ if self.selector :
|
2461 |
|
|
+ warnings += self.selector.reportUnusedClasses()
|
2462 |
|
|
+ #------------Delete intermediate files------------------
|
2463 |
|
|
+ if 'debug' not in self.opts :
|
2464 |
|
|
+ os.remove(xmlfile)
|
2465 |
|
|
+ #------------Exit with status if warnings --------------
|
2466 |
|
|
+ if warnings and self.opts.get('fail_on_warnings',False) :
|
2467 |
|
|
+ print '--->> genreflex: ERROR: Exiting with error due to %d warnings ( --fail_on_warnings enabled )' % warnings
|
2468 |
|
|
+ sys.exit(1)
|
2469 |
|
|
+#---------------------------------------------------------------------
|
2470 |
|
|
+ def which(self, name) :
|
2471 |
|
|
+ if 'PATH' in os.environ :
|
2472 |
|
|
+ if sys.platform == 'win32' : name += '.exe'
|
2473 |
|
|
+ for p in os.environ['PATH'].split(os.pathsep) :
|
2474 |
|
|
+ path = os.path.join(p,name)
|
2475 |
|
|
+ if os.path.exists(path) : return path
|
2476 |
|
|
+ return None
|
2477 |
|
|
+#---------------------------------------------------------------------
|
2478 |
|
|
+if __name__ == "__main__":
|
2479 |
|
|
+ l = genreflex()
|
2480 |
|
|
+ l.parse_args()
|
2481 |
|
|
+ l.check_files_dirs()
|
2482 |
|
|
+ l.process_files()
|
2483 |
|
|
diff -Naur root.orig/reflex/python/genreflex/genreflex.py root/reflex/python/genreflex/genreflex.py
|
2484 |
|
|
--- root.orig/reflex/python/genreflex/genreflex.py 2007-01-10 10:31:33.000000000 +0100
|
2485 |
|
|
+++ root/reflex/python/genreflex/genreflex.py 2007-11-04 05:24:28.000000000 +0100
|
2486 |
|
|
@@ -24,7 +24,7 @@
|
2487 |
|
|
self.opts = {}
|
2488 |
|
|
self.gccxmlpath = None
|
2489 |
|
|
self.gccxmlopt = ''
|
2490 |
|
|
- self.gccxmlvers = '0.6.0_patch3'
|
2491 |
|
|
+ self.gccxmlvers = '0.7.0_20070615'
|
2492 |
|
|
self.selector = None
|
2493 |
|
|
self.gccxml = ''
|
2494 |
|
|
self.quiet = False
|
2495 |
|
|
@@ -68,8 +68,10 @@
|
2496 |
|
|
Output file name. If an existing directory is specified instead of a file,
|
2497 |
|
|
then a filename will be build using the name of the input file and will
|
2498 |
|
|
be placed in the given directory. <headerfile>_rflx.cpp \n
|
2499 |
|
|
- --pool
|
2500 |
|
|
+ --pool, --dataonly
|
2501 |
|
|
Generate minimal dictionary required for POOL persistency\n
|
2502 |
|
|
+ --interpreteronly
|
2503 |
|
|
+ Generate minimal dictionary required for interpreter\n
|
2504 |
|
|
--deep
|
2505 |
|
|
Generate dictionary for all dependend classes\n
|
2506 |
|
|
--split (OBSOLETE)
|
2507 |
|
|
@@ -78,6 +80,8 @@
|
2508 |
|
|
Generate Reflex dictionaries.\n
|
2509 |
|
|
--comments
|
2510 |
|
|
Add end-of-line comments in data and functions members as a property called "comment" \n
|
2511 |
|
|
+ --iocomments
|
2512 |
|
|
+ Add end-of-line comments in data and functions members as a property called "comment", but only for comments relevant for ROOT I/O \n
|
2513 |
|
|
--no_membertypedefs
|
2514 |
|
|
Disable the definition of class member typedefs \n
|
2515 |
|
|
--no_templatetypedefs
|
2516 |
|
|
@@ -118,8 +122,8 @@
|
2517 |
|
|
#----Process options--------------------------------
|
2518 |
|
|
try:
|
2519 |
|
|
opts, args = getopt.getopt(options, 'ho:s:c:I:U:D:PC', \
|
2520 |
|
|
- ['help','debug=', 'output=','selection_file=','pool','deep','gccxmlpath=',
|
2521 |
|
|
- 'capabilities=','rootmap=','rootmap-lib=','comments','no_membertypedefs',
|
2522 |
|
|
+ ['help','debug=', 'output=','selection_file=','pool','dataonly','interpreteronly','deep','gccxmlpath=',
|
2523 |
|
|
+ 'capabilities=','rootmap=','rootmap-lib=','comments','iocomments','no_membertypedefs',
|
2524 |
|
|
'fail_on_warnings', 'quiet', 'gccxmlopt=', 'reflex', 'split','no_templatetypedefs'])
|
2525 |
|
|
except getopt.GetoptError, e:
|
2526 |
|
|
print "--->> genreflex: ERROR:",e
|
2527 |
|
|
@@ -129,6 +133,7 @@
|
2528 |
|
|
self.gccxmlpath = None
|
2529 |
|
|
self.cppopt = ''
|
2530 |
|
|
self.pool = 0
|
2531 |
|
|
+ self.interpreter = 0
|
2532 |
|
|
for o, a in opts:
|
2533 |
|
|
if o in ('-h', '--help'):
|
2534 |
|
|
self.help()
|
2535 |
|
|
@@ -142,6 +147,10 @@
|
2536 |
|
|
self.select = a
|
2537 |
|
|
if o in ('--pool',):
|
2538 |
|
|
self.opts['pool'] = True
|
2539 |
|
|
+ if o in ('--dataonly',):
|
2540 |
|
|
+ self.opts['pool'] = True
|
2541 |
|
|
+ if o in ('--interpreteronly',):
|
2542 |
|
|
+ self.opts['interpreter'] = True
|
2543 |
|
|
if o in ('--deep',):
|
2544 |
|
|
self.deep = True
|
2545 |
|
|
if o in ('--split',):
|
2546 |
|
|
@@ -150,6 +159,8 @@
|
2547 |
|
|
print '--->> genreflex: WARNING: --reflex option is obsolete'
|
2548 |
|
|
if o in ('--comments',):
|
2549 |
|
|
self.opts['comments'] = True
|
2550 |
|
|
+ if o in ('--iocomments',):
|
2551 |
|
|
+ self.opts['iocomments'] = True
|
2552 |
|
|
if o in ('--no_membertypedefs',):
|
2553 |
|
|
self.opts['no_membertypedefs'] = True
|
2554 |
|
|
if o in ('--fail_on_warnings',):
|
2555 |
|
|
@@ -168,7 +179,7 @@
|
2556 |
|
|
if o in ('--rootmap-lib',):
|
2557 |
|
|
self.rootmaplib = a
|
2558 |
|
|
if o in ('-I', '-U', '-D', '-P', '-C') :
|
2559 |
|
|
- self.cppopt += o + a +' '
|
2560 |
|
|
+ self.cppopt += '\'' + o + a + '\' '
|
2561 |
|
|
#----------------------------------------------------------------------------------
|
2562 |
|
|
def check_files_dirs(self):
|
2563 |
|
|
#---Check existance of input files--------------------
|
2564 |
|
|
@@ -278,7 +289,7 @@
|
2565 |
|
|
else :
|
2566 |
|
|
dicfile = os.path.join(self.outputDir,name+file_extension)
|
2567 |
|
|
#---------------Parse the header file with GCC_XML
|
2568 |
|
|
- cmd = '%s %s %s -fxml=%s %s -D__REFLEX__' %(self.gccxml, self.gccxmlopt, source, xmlfile, self.cppopt)
|
2569 |
|
|
+ cmd = '%s %s \'%s\' \'-fxml=%s\' %s -D__REFLEX__' %(self.gccxml, self.gccxmlopt, source, xmlfile, self.cppopt)
|
2570 |
|
|
if not self.quiet : print '--->> genreflex: INFO: Parsing file %s with GCC_XML' % source,
|
2571 |
|
|
status = os.system(cmd)
|
2572 |
|
|
if status :
|
2573 |
|
|
@@ -311,7 +322,7 @@
|
2574 |
|
|
else :
|
2575 |
|
|
mapfile = os.path.join(self.outputDir, self.rootmap)
|
2576 |
|
|
if not self.rootmaplib : self.rootmaplib = 'lib'+name+'.so'
|
2577 |
|
|
- genrootmap.genRootMap(mapfile, name, self.rootmaplib, cnames)
|
2578 |
|
|
+ genrootmap.genRootMap(mapfile, name, self.rootmaplib, cnames, classes)
|
2579 |
|
|
#------------Report unused class selections in selection
|
2580 |
|
|
if self.selector :
|
2581 |
|
|
warnings += self.selector.reportUnusedClasses()
|