12
sys.path.append("../../../../protocols/atlas/spec")
14
from ParseDef import read_all_defs
17
"// This file may be redistributed and modified only under the terms of\n\
18
// the GNU Lesser General Public License (See COPYING for details).\n\
19
// Copyright 2000-2001 Stefanus Du Toit and Alistair Riddoch.\n\
20
// Automatically generated using gen_cc.py.\n"
22
# These are only used for description.
23
descr_attrs = ['children', 'description', 'args_description', 'example', \
24
'long_description', 'specification', 'interface']
25
# C++ equivalents of atlas types
26
cpp_type = {'map':'Atlas::Message::Element::MapType',
27
'list':'Atlas::Message::Element::ListType',
28
'string':'std::string',
33
cpp_param_type = {'map':'const ' + cpp_type['map'] + '&',
34
'list':'const ' + cpp_type['list'] + '&',
35
'string':'const ' + cpp_type['string'] + '&',
36
'int':cpp_type['int'],
37
'float':cpp_type['float']}
39
# Non-const references
40
cpp_param_type2 = {'map':cpp_type['map'] + '&',
41
'list':cpp_type['list'] + '&',
42
'string':cpp_type['string'] + '&',
43
'int':cpp_type['int'] + '&',
44
'float':cpp_type['float'] + '&'}
46
# Turns some_thing into SomeThing
48
return string.join(map(lambda part:string.capitalize(part), \
49
string.split(id, '_')), "")
51
# Atlas equivalent of python type
52
type2string={StringType:"string",
56
def find_in_parents(parents, attr_name):
57
for parent_name in parents:
58
parent = defs.id_dict.get(parent_name)
59
if attr_name in map(lambda attr: attr.name, parent.attr_list):
62
if find_in_parents(parent.attr['parents'].value, attr_name) \
69
def __init__(self, defs, outdir):
72
def __call__(self, id_list):
74
obj = self.defs.id_dict.get(id)
76
raise SyntaxError, 'no such id: "' + id + '"!'
77
self.classname = classize(id)
79
self.implementation(obj)
80
children = obj.attr['children'].value
83
def header(self, list):
84
self.out.write(copyright)
86
guard = string.join(map(lambda part:string.upper(part), list), "_")
87
self.out.write("#ifndef " + guard + "\n")
88
self.out.write("#define " + guard + "\n\n")
89
def footer(self, list):
90
guard = string.join(map(lambda part:string.upper(part), list), "_")
91
self.out.write("\n#endif // " + guard + "\n")
92
def ns_open(self, ns_list):
93
for namespace in ns_list:
94
self.out.write("namespace " + namespace + " { ")
96
def ns_close(self, ns_list):
97
for i in range(0, len(ns_list)):
99
self.out.write("// namespace " + string.join(ns_list, "::"))
101
def doc(self, indent, text):
102
for i in range(0, indent):
104
self.out.write("/// %s\n" % text)
105
def constructors_if(self, obj):
106
self.out.write(" public:\n")
107
self.doc(4, "Construct a " + self.classname + " instance.")
108
self.out.write(" " + self.classname + "();\n")
109
self.out.write(" protected:\n")
110
self.doc(4, "Constructor for sub-classes.")
111
self.out.write(" " + self.classname + "(const char *,const char *);\n")
112
def default_map(self, name, obj):
113
self.out.write(" Element::MapType " + name + ";\n")
114
for sub in obj.attr_list:
115
if sub.type == "list":
116
self.default_list("%s_%d" % (name, sub.name), sub)
117
if sub.type == "map":
118
self.default_map("%s_%d" % (name, sub.name), sub)
119
self.out.write(" %s.push_back(" % name)
120
if sub.type == "list" or sub_type == "map":
121
self.out.write("%s_%d" % (name, sub.name))
122
elif sub.type == "string":
123
self.out.write('std::string("%s")' % sub.value)
125
self.out.write("%s" % sub.value)
126
self.out.write(");\n")
127
def default_list(self, name, obj):
129
if len(obj.value) == 1:
130
self.out.write(" Element::ListType " + name + "(1,")
132
sub_type = type2string[type(sub)]
133
if sub_type == "string":
134
self.out.write('std::string("%s")' % sub)
136
self.out.write('%s' % sub)
137
self.out.write(");\n")
139
self.out.write(" Element::ListType " + name + ";\n")
140
for sub in obj.value:
141
sub_type = type2string[type(sub)]
142
if sub_type == "list":
143
self.default_list("%s_%d" % (name, ++i), sub)
144
elif sub_type == "map":
145
self.default_map("%s_%d" % (name, ++i), sub)
146
self.out.write(" %s.push_back(" % name)
147
if sub_type == "list" or sub_type == "map":
148
self.out.write("%s_%d" % (name, i))
149
elif sub_type == "string":
150
self.out.write('std::string("%s")' % sub)
152
self.out.write('%s' % sub)
153
self.out.write(");\n")
154
def constructors_im(self, obj, statics):
155
for sub_obj in obj.attr_list:
156
if sub_obj.name == "id":
160
args = "\"\", \""+oid+"\""
161
print "Got parent init ", args
162
self.out.write(self.classname + "::" + self.classname + "()\n")
163
self.out.write(" : ")
164
self.out.write(string.join(map(lambda parent,a=args:classize(parent)+"("+a+")", \
165
obj.attr['parents'].value), ", "))
166
constructed_statics = []
169
if attr.type == "list":
170
if len(attr.value) == 1:
172
self.out.write("attr_%s(1," % attr.name)
174
sub_type = type2string[type(sub)]
175
if sub_type == "string":
176
self.out.write('std::string("%s"))' % sub)
178
self.out.write('%s)' % sub)
179
constructed_statics.append(attr.name)
180
elif attr.type == "string":
181
if len(attr.value) > 1:
183
self.out.write("attr_%s(\"%s\")" % (attr.name, attr.value))
184
constructed_statics.append(attr.name)
187
self.out.write("attr_%s(%s)" % (attr.name, attr.value))
188
constructed_statics.append(attr.name)
189
self.out.write("\n{\n")
190
for sub_obj in obj.attr_list:
191
if sub_obj.attr_container_obj == obj and \
192
sub_obj.name != "id" and sub_obj.name != "parents" and \
193
sub_obj.name not in constructed_statics and \
194
sub_obj.name not in descr_attrs:
195
if (sub_obj.type == "list" or sub_obj.type == "map") and len(sub_obj.value) == 0: pass
196
elif sub_obj.type == "string" and len(sub_obj.value) == 0: pass
198
if sub_obj.type == "list":
199
self.default_list(sub_obj.name, sub_obj)
200
if sub_obj.type == "map":
201
self.default_map(sub_obj.name, sub_obj)
202
self.out.write(' set' + classize(sub_obj.name) + '(')
203
if sub_obj.type == "string":
204
if sub_obj.name == "objtype":
205
if sub_obj.value == "op_definition":
206
self.out.write('std::string("op")')
207
elif sub_obj.value == "class":
208
self.out.write('std::string("object")')
210
self.out.write('std::string("instance")')
212
self.out.write('std::string("' + sub_obj.value + '")')
213
elif sub_obj.type == "list" or sub_obj.type == "map":
214
self.out.write(sub_obj.name)
216
self.out.write('%s' % sub_obj.value)
217
self.out.write(');\n')
218
self.out.write("}\n")
221
self.out.write(self.classname + "::" + self.classname + "(const char * id, const char * parent)\n")
222
self.out.write(" : ")
223
self.out.write(string.join(map(lambda parent,a=args:classize(parent)+"("+a+")", \
224
obj.attr['parents'].value), ", "))
225
constructed_statics = []
228
if attr.type == "list":
229
if len(attr.value) == 1:
231
self.out.write("attr_%s(1," % attr.name)
233
sub_type = type2string[type(sub)]
234
if sub_type == "string":
235
self.out.write('std::string("%s"))' % sub)
237
self.out.write('%s)' % sub)
238
constructed_statics.append(attr.name)
239
elif attr.type == "string":
240
if len(attr.value) > 1:
242
self.out.write("attr_%s(\"%s\")" % (attr.name, attr.value))
243
constructed_statics.append(attr.name)
246
self.out.write("attr_%s(%s)" % (attr.name, attr.value))
247
constructed_statics.append(attr.name)
248
self.out.write("\n{\n")
249
for sub_obj in obj.attr_list:
250
if sub_obj.attr_container_obj == obj and \
251
sub_obj.name != "id" and sub_obj.name != "parents" and \
252
sub_obj.name not in constructed_statics and \
253
sub_obj.name not in descr_attrs:
254
if (sub_obj.type == "list" or sub_obj.type == "map") and len(sub_obj.value) == 0: pass
255
elif sub_obj.type == "string" and len(sub_obj.value) == 0: pass
257
if sub_obj.type == "list":
258
self.default_list(sub_obj.name, sub_obj)
259
if sub_obj.type == "map":
260
self.default_map(sub_obj.name, sub_obj)
261
self.out.write(' set' + classize(sub_obj.name) + '(')
262
if sub_obj.type == "string":
263
if sub_obj.name == "objtype":
264
if sub_obj.value == "op_definition":
265
self.out.write('std::string("op")')
266
elif sub_obj.value == "class":
267
self.out.write('std::string("object")')
269
self.out.write('std::string("instance")')
271
self.out.write('std::string("' + sub_obj.value + '")')
272
elif sub_obj.type == "list" or sub_obj.type == "map":
273
self.out.write(sub_obj.name)
275
self.out.write('%s' % sub_obj.value)
276
self.out.write(');\n')
277
self.out.write("}\n")
279
def destructor_im(self, obj):
280
self.out.write("%s::~%s()\n{\n}\n\n" % (self.classname, self.classname))
281
def class_instance(self, obj):
282
id = obj.attr['id'].value
283
parent = obj.attr['parents'].value[0]
284
objtype = obj.attr['objtype'].value
285
self.out.write("%s %s::Class()\n{\n" \
286
% (self.classname, self.classname))
287
self.out.write(" " + self.classname + " value(\"" + id + "\", \"" + parent + "\");\n\n")
288
self.out.write(" value.setObjtype(std::string(\"%s\"));\n" % (objtype))
289
self.out.write(" \n")
290
self.out.write(" return value;\n")
291
self.out.write("}\n\n")
292
def instantiation(self, obj):
293
id = obj.attr['id'].value
294
self.out.write("%s %s::Instantiate()\n{\n" \
295
% (self.classname, self.classname))
296
self.out.write(" " + self.classname + " value;\n\n")
297
#self.out.write(" Element::ListType parents;\n")
298
#self.out.write(' parents.push_back(std::string("%s"));\n' % id)
299
#self.out.write(' value.setParents(Element::ListType(1,std::string("%s")));\n' % id)
300
self.out.write(" return value;\n")
301
self.out.write("}\n\n")
302
def static_inline_sets(self, obj, statics):
303
classname = classize(obj.attr['id'].value)
305
self.out.write('void %s::set%s' % (classname, classize(attr.name)))
306
self.out.write('(%s val)\n' % cpp_param_type[attr.type])
307
self.out.write('{\n')
308
self.out.write(' attr_%s = val;\n' % attr.name)
309
self.out.write('}\n\n')
310
def static_inline_gets(self, obj, statics):
311
classname = classize(obj.attr['id'].value)
313
self.out.write('%s %s::get%s() const\n' % (cpp_param_type[attr.type], \
314
classname, classize(attr.name)))
315
self.out.write('{\n')
316
self.out.write(' return attr_%s;\n' % attr.name)
317
self.out.write('}\n\n')
318
self.out.write('%s %s::get%s()\n' % (cpp_param_type2[attr.type], \
319
classname, classize(attr.name)))
320
self.out.write('{\n')
321
self.out.write(' return attr_%s;\n' % attr.name)
322
self.out.write('}\n\n')
323
def static_inline_sends(self, obj, statics):
324
classname = classize(obj.attr['id'].value)
326
self.out.write('void %s::send%s' % (classname, classize(attr.name)))
327
self.out.write('(Atlas::Bridge* b) const\n')
328
self.out.write('{\n')
329
if attr.type == 'int':
330
self.out.write(' if (attr_%s != 0) {\n' % (attr.name))
331
elif attr.type == 'float':
332
self.out.write(' if (attr_%s != 0.0) {\n' % (attr.name))
334
self.out.write(' if (!attr_%s.empty()) {\n' % (attr.name))
335
if attr.type in ('int', 'float', 'string'):
336
self.out.write(' b->mapItem("%s", attr_%s);\n' \
337
% (attr.name, attr.name))
339
self.out.write(' Atlas::Message::Encoder e(b);\n')
340
self.out.write(' e.mapItem("%s", attr_%s);\n' \
341
% (attr.name, attr.name))
342
self.out.write(' }\n')
343
self.out.write('}\n\n')
344
def hasattr_im(self, obj, statics):
345
classname = classize(obj.attr['id'].value)
346
self.out.write("bool %s::hasAttr(const std::string& name) const\n"
348
self.out.write("{\n")
350
self.out.write(' if (name == "%s") return true;\n' % attr.name)
351
parent = obj.attr['parents'].value[0]
352
self.out.write(" return %s::hasAttr(name);\n" % classize(parent))
353
self.out.write("}\n\n")
354
def getattr_im(self, obj, statics):
355
classname = classize(obj.attr['id'].value)
356
self.out.write("Element %s::getAttr" % classname)
357
self.out.write("(const std::string& name) const\n")
358
self.out.write(" throw (NoSuchAttrException)\n")
359
self.out.write("{\n")
361
self.out.write(' if (name == "%s") return attr_%s;\n' \
362
% (attr.name, attr.name))
363
parent = obj.attr['parents'].value[0]
364
self.out.write(" return %s::getAttr(name);\n" % classize(parent))
365
self.out.write("}\n\n")
366
def setattr_im(self, obj, statics):
367
classname = classize(obj.attr['id'].value)
368
self.out.write("void %s::setAttr" % classname)
369
self.out.write("(const std::string& name, const Element& attr)\n")
370
self.out.write("{\n")
372
self.out.write(' if (name == "%s") {' % attr.name)
373
self.out.write(' set%s(attr.as%s()); ' % \
374
(classize(attr.name), classize(attr.type)))
375
self.out.write('return; }\n')
376
parent = obj.attr['parents'].value[0]
377
self.out.write(" %s::setAttr(name, attr);\n" % classize(parent))
378
self.out.write("}\n\n")
379
def remattr_im(self, obj, statics):
380
classname = classize(obj.attr['id'].value)
381
self.out.write("void %s::removeAttr(const std::string& name)\n"
383
self.out.write("{\n")
385
self.out.write(' if (name == "%s") return;\n' % attr.name)
386
parent = obj.attr['parents'].value[0]
387
self.out.write(" %s::removeAttr(name);\n" % classize(parent))
388
self.out.write("}\n\n")
389
def sendcontents_im(self, obj, statics):
390
classname = classize(obj.attr['id'].value)
391
self.out.write("void %s::sendContents(Bridge* b) const\n" % classname)
392
self.out.write("{\n")
394
self.out.write(' send%s(b);\n' % classize(attr.name))
395
parent = obj.attr['parents'].value[0]
396
self.out.write(" %s::sendContents(b);\n" % classize(parent))
397
self.out.write("}\n\n")
398
def asobject_im(self, obj, statics):
399
classname = classize(obj.attr['id'].value)
400
self.out.write("Element %s::asObject() const\n" % classname)
401
self.out.write("{\n")
402
parent = obj.attr['parents'].value[0]
403
self.out.write(" Element::MapType m = %s::asObject().asMap();\n" % classize(parent))
405
self.out.write(' m["%s"] = Element(attr_%s);\n' % \
406
(attr.name, attr.name))
407
self.out.write(' return Element(m);\n')
408
self.out.write("}\n\n")
409
self.out.write("Element::MapType %s::asMap() const\n" % classname)
410
self.out.write("{\n")
411
parent = obj.attr['parents'].value[0]
412
self.out.write(" Element::MapType m = %s::asObject().asMap();\n" % classize(parent))
414
self.out.write(' m["%s"] = Element(attr_%s);\n' % \
415
(attr.name, attr.name))
416
self.out.write(' return m;\n')
417
self.out.write("}\n\n")
418
def asmap_im(self, obj, statics):
419
classname = classize(obj.attr['id'].value)
420
self.out.write("Element::MapType %s::asMap() const\n" % classname)
421
self.out.write("{\n")
422
parent = obj.attr['parents'].value[0]
423
self.out.write(" Element::MapType m = %s::asMap();\n" % classize(parent))
425
self.out.write(' m["%s"] = Element(attr_%s);\n' % \
426
(attr.name, attr.name))
427
self.out.write(' return m;\n')
428
self.out.write("}\n\n")
429
def interface(self, obj):
430
print "Output of interface for:"
431
outfile = self.outdir + '/' + self.classname + ".h"
433
self.out = open(outfile + ".tmp", "w")
435
self.header(['Atlas', 'Objects', outdir, self.classname, "H"])
437
self.header(['Atlas', 'Objects', self.classname, "H"])
438
for parent in obj.attr['parents'].value:
439
self.out.write('#include <Atlas/Objects/')
440
if parent != "root": self.out.write(outdir + '/')
441
self.out.write(classize(parent) + '.h>\n')
442
self.out.write("\n\n")
444
self.ns_open(['Atlas', 'Objects', outdir])
446
self.ns_open(['Atlas', 'Objects'])
448
self.out.write("/** " + obj.attr['description'].value + "\n")
450
self.out.write(obj.attr['long_description'].value + "\n\n")
451
self.out.write("*/\n")
452
self.out.write("class " + self.classname)
453
parentlist = map(lambda parent:"public " + classize(parent), \
454
obj.attr['parents'].value)
455
if len(parentlist) > 0:
456
self.out.write(" : ")
457
self.out.write(string.join(parentlist, ", "))
458
self.out.write("\n{\n")
459
self.constructors_if(obj)
460
self.out.write(" public:\n")
461
self.doc(4, "Default destructor.")
462
self.out.write(" virtual ~" + self.classname + "();\n")
464
self.doc(4, "Create a new class for " + self.classname + ".")
465
self.out.write(" static " + self.classname + " Class();\n")
466
# self.doc(4, "Create a new instance of " + self.classname + ".")
467
# self.out.write(" static " + self.classname + " Instantiate();\n")
469
static_attrs = filter(lambda attr,obj=obj:(not attr.name in descr_attrs) \
470
and (not find_in_parents(obj.attr['parents'].value, attr.name)), \
472
if len(static_attrs) > 0:
473
self.doc(4, 'Check whether the attribute "name" exists.')
474
self.out.write(" virtual bool hasAttr(const std::string& name)"\
476
self.doc(4, 'Retrieve the attribute "name". Throws ' \
477
+'NoSuchAttrException if it does')
478
self.doc(4, 'not exist.')
479
self.out.write(" virtual Atlas::Message::Element getAttr(")
480
self.out.write("const std::string& name)\n")
481
self.out.write(" const throw (NoSuchAttrException);\n")
482
self.doc(4, 'Set the attribute "name" to the value given by' \
484
self.out.write(" virtual void setAttr(const std::string& name,\n")
486
self.out.write("const Atlas::Message::Element& attr);\n")
487
self.doc(4, 'Remove the attribute "name". This will not work for '\
488
+ 'static attributes.')
489
self.out.write(" virtual void removeAttr(")
490
self.out.write("const std::string& name);\n")
492
self.doc(4, 'Send the contents of this object to a Bridge.')
493
self.out.write(" virtual void sendContents(Atlas::Bridge* b) const;\n")
495
self.doc(4, 'Convert this object to a Message::Element.')
496
self.out.write(" virtual Atlas::Message::Element asObject() const;\n")
498
self.doc(4, 'Convert this object to a Message::Element::MapType.')
499
self.out.write(" virtual Atlas::Message::Element::MapType asMap() const;\n")
501
for attr in static_attrs:
502
self.doc(4, 'Set the "%s" attribute.' % attr.name)
503
self.out.write(" inline void set" + classize(attr.name))
504
self.out.write('(' + cpp_param_type[attr.type] + ' val);\n')
506
for attr in static_attrs:
507
self.doc(4, 'Retrieve the "%s" attribute.' % attr.name)
508
self.out.write(' inline %s get' % cpp_param_type[attr.type])
509
self.out.write(classize(attr.name) + '() const;\n')
510
self.doc(4, 'Retrieve the "%s" attribute as a non-const reference.' % attr.name)
511
self.out.write(' inline %s get' % cpp_param_type2[attr.type])
512
self.out.write(classize(attr.name) + '();\n')
514
self.out.write("protected:\n")
515
if len(static_attrs) > 0:
516
for attr in static_attrs:
517
self.out.write(' %s attr_%s;\n' % (cpp_type[attr.type], attr.name))
519
for attr in static_attrs:
520
self.out.write(" inline void send" + classize(attr.name))
521
self.out.write('(Atlas::Bridge*) const;\n')
523
self.out.write("};\n\n")
524
if len(static_attrs) > 0:
525
self.out.write('//\n// Inlined member functions follow.\n//\n\n')
526
self.static_inline_sets(obj, static_attrs)
527
self.static_inline_gets(obj, static_attrs)
528
# self.static_inline_sends(obj, static_attrs)
531
self.ns_close(['Atlas', 'Objects', outdir])
532
self.footer(['Atlas', 'Objects', outdir, self.classname, "H"])
534
self.ns_close(['Atlas', 'Objects'])
535
self.footer(['Atlas', 'Objects', self.classname, "H"])
537
if os.access(outfile, os.F_OK):
538
if filecmp(outfile + ".tmp", outfile) == 0:
540
os.rename(outfile + ".tmp", outfile)
542
print "Output file same as existing one, not updating"
543
os.remove(outfile + ".tmp")
545
os.rename(outfile + ".tmp", outfile)
546
def implementation_setup(self):
547
outfile = self.outdir + '/' + self.outdir + ".cc"
548
self.imp_out = open(outfile + ".tmp", "w")
549
self.out = self.imp_out
550
self.out.write(copyright)
552
def implementation(self, obj):
553
print "Output of implementation for:"
554
#outfile = self.outdir + '/' + self.classname + ".cc"
556
# self.out = open(outfile + ".tmp", "w")
557
self.out = self.imp_out
558
#self.out.write(copyright)
559
#self.out.write("\n")
560
self.out.write('#include <Atlas/Objects/')
561
if self.outdir != ".": self.out.write(self.outdir + '/')
562
self.out.write(self.classname + '.h>\n')
564
#self.out.write("using namespace std;\n")
565
#self.out.write("using namespace Atlas;\n")
566
#self.out.write("using namespace Atlas::Message;\n")
567
self.out.write("using Atlas::Message::Element;\n")
569
static_attrs = filter(lambda attr,obj=obj:(not attr.name in descr_attrs) \
570
and (not find_in_parents(obj.attr['parents'].value, attr.name)), \
573
self.ns_open(['Atlas', 'Objects', outdir])
575
self.ns_open(['Atlas', 'Objects'])
577
self.constructors_im(obj, static_attrs)
578
self.destructor_im(obj)
579
self.class_instance(obj)
580
# self.instantiation(obj)
581
if len(static_attrs) > 0:
582
self.hasattr_im(obj, static_attrs)
583
self.getattr_im(obj, static_attrs)
584
self.setattr_im(obj, static_attrs)
585
self.remattr_im(obj, static_attrs)
586
self.static_inline_sends(obj, static_attrs)
587
self.sendcontents_im(obj, static_attrs)
588
self.asobject_im(obj, static_attrs)
590
self.ns_close(['Atlas', 'Objects', outdir])
592
self.ns_close(['Atlas', 'Objects'])
595
def implementation_close(self):
596
outfile = self.outdir + '/' + self.outdir + ".cc"
597
self.out = self.imp_out
598
print "Closing implementation file"
600
if os.access(outfile, os.F_OK):
601
if filecmp(outfile + ".tmp", outfile) == 0:
603
os.rename(outfile + ".tmp", outfile)
605
print "Output file same as existing one, not updating"
606
os.remove(outfile + ".tmp")
608
os.rename(outfile + ".tmp", outfile)
612
if len(sys.argv) < 2:
614
print sys.argv[0] + " root [outdir]"
616
filelist = ["root","entity","operation","type","interface"]
617
defs = read_all_defs(map(lambda file:"../../../../protocols/atlas/spec/" + file+".def", filelist))
618
if len(sys.argv) >= 3:
622
gen_header = GenerateCC(defs, outdir)
623
gen_header.implementation_setup()
624
gen_header([sys.argv[1]])
625
gen_header.implementation_close()