1#!/usr/bin/python
2
3import string
4import sys
5import os
6try:
7    import filecmp
8    filecmp = filecmp.cmp
9except ImportError:
10    import cmp
11    filecmp = cmp.cmp
12sys.path.append("../../../../protocols/atlas/spec")
13from types import *
14from ParseDef import read_all_defs
15
16copyright = \
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"
21
22# These are only used for description.
23descr_attrs = ['children', 'description', 'args_description', 'example', \
24               'long_description', 'specification', 'interface']
25# C++ equivalents of atlas types
26cpp_type = {'map':'Atlas::Message::Element::MapType',
27            'list':'Atlas::Message::Element::ListType',
28            'string':'std::string',
29            'int':'long',
30            'float':'double'}
31
32# Const references
33cpp_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']}
38
39# Non-const references
40cpp_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'] + '&'}
45
46# Turns some_thing into SomeThing
47def classize(id):
48    return string.join(map(lambda part:string.capitalize(part), \
49                       string.split(id, '_')), "")
50
51# Atlas equivalent of python type
52type2string={StringType:"string",
53             IntType:"int",
54             FloatType:"float"}
55
56def 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):
60            return 1
61        else:
62            if find_in_parents(parent.attr['parents'].value, attr_name) \
63               == 1:
64                return 1
65    return 0
66
67
68class GenerateCC:
69    def __init__(self, defs, outdir):
70        self.outdir = outdir
71        self.defs = defs
72    def __call__(self, id_list):
73        for id in id_list:
74            obj = self.defs.id_dict.get(id)
75            if not obj:
76                raise SyntaxError, 'no such id: "' + id + '"!'
77            self.classname = classize(id)
78            self.interface(obj)
79            self.implementation(obj)
80            children = obj.attr['children'].value
81            if children:
82                self(children)
83    def header(self, list):
84        self.out.write(copyright)
85        self.out.write("\n")
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 + " { ")
95        self.out.write("\n")
96    def ns_close(self, ns_list):
97        for i in range(0, len(ns_list)):
98            self.out.write("} ")
99        self.out.write("// namespace " + string.join(ns_list, "::"))
100        self.out.write("\n")
101    def doc(self, indent, text):
102        for i in range(0, indent):
103            self.out.write(" ")
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)
124            else:
125                self.out.write("%s" % sub.value)
126            self.out.write(");\n")
127    def default_list(self, name, obj):
128        i = 0
129        if len(obj.value) == 1:
130            self.out.write("    Element::ListType " + name + "(1,")
131            sub = obj.value[0]
132            sub_type = type2string[type(sub)]
133            if sub_type == "string":
134                self.out.write('std::string("%s")' % sub)
135            else:
136                self.out.write('%s' % sub)
137            self.out.write(");\n")
138        else:
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)
151                else:
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":
157                oid = sub_obj.value
158        args = ""
159        if oid:
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 = []
167        if len(statics) > 0:
168            for attr in statics:
169                if attr.type == "list":
170                    if len(attr.value) == 1:
171                        self.out.write(", ")
172                        self.out.write("attr_%s(1," % attr.name)
173                        sub = attr.value[0]
174                        sub_type = type2string[type(sub)]
175                        if sub_type == "string":
176                            self.out.write('std::string("%s"))' % sub)
177                        else:
178                            self.out.write('%s)' % sub)
179                        constructed_statics.append(attr.name)
180                elif attr.type == "string":
181                    if len(attr.value) > 1:
182                        self.out.write(", ")
183                        self.out.write("attr_%s(\"%s\")" % (attr.name, attr.value))
184                        constructed_statics.append(attr.name)
185                else:
186                    self.out.write(", ")
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
197                else:
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")')
209                            else:
210                                self.out.write('std::string("instance")')
211                        else:
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)
215                    else:
216                        self.out.write('%s' % sub_obj.value)
217                    self.out.write(');\n')
218        self.out.write("}\n")
219        self.out.write("\n")
220        args = "id, parent"
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 = []
226        if len(statics) > 0:
227            for attr in statics:
228                if attr.type == "list":
229                    if len(attr.value) == 1:
230                        self.out.write(", ")
231                        self.out.write("attr_%s(1," % attr.name)
232                        sub = attr.value[0]
233                        sub_type = type2string[type(sub)]
234                        if sub_type == "string":
235                            self.out.write('std::string("%s"))' % sub)
236                        else:
237                            self.out.write('%s)' % sub)
238                        constructed_statics.append(attr.name)
239                elif attr.type == "string":
240                    if len(attr.value) > 1:
241                        self.out.write(", ")
242                        self.out.write("attr_%s(\"%s\")" % (attr.name, attr.value))
243                        constructed_statics.append(attr.name)
244                else:
245                    self.out.write(", ")
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
256                else:
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")')
268                            else:
269                                self.out.write('std::string("instance")')
270                        else:
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)
274                    else:
275                        self.out.write('%s' % sub_obj.value)
276                    self.out.write(');\n')
277        self.out.write("}\n")
278        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)
304        for attr in statics:
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)
312        for attr in statics:
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)
325        for attr in statics:
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))
333            else:
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))
338            else:
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"
347                        % classname)
348        self.out.write("{\n")
349        for attr in statics:
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")
360        for attr in statics:
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")
371        for attr in statics:
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"
382                        % classname)
383        self.out.write("{\n")
384        for attr in statics:
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")
393        for attr in statics:
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))
404        for attr in statics:
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))
413        for attr in statics:
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))
424        for attr in statics:
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"
432        print outfile
433        self.out = open(outfile + ".tmp", "w")
434        if outdir != ".":
435            self.header(['Atlas', 'Objects', outdir, self.classname, "H"])
436        else:
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")
443        if outdir != ".":
444            self.ns_open(['Atlas', 'Objects', outdir])
445        else:
446            self.ns_open(['Atlas', 'Objects'])
447        self.out.write("\n")
448        self.out.write("/** " + obj.attr['description'].value + "\n")
449        self.out.write("\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")
463        self.out.write("\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")
468        self.out.write("\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)), \
471          obj.attr_list)
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)"\
475                           + "const;\n")
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' \
483                      + '"attr"')
484            self.out.write("    virtual void setAttr(const std::string& name,\n")
485            self.out.write("                         ")
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")
491            self.out.write("\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")
494            self.out.write("\n")
495            self.doc(4, 'Convert this object to a Message::Element.')
496            self.out.write("    virtual Atlas::Message::Element asObject() const;\n")
497            self.out.write("\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")
500            self.out.write("\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')
505            self.out.write('\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')
513            self.out.write('\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))
518            self.out.write('\n')
519            for attr in static_attrs:
520                self.out.write("    inline void send" + classize(attr.name))
521                self.out.write('(Atlas::Bridge*) const;\n')
522        self.out.write('\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)
529            self.out.write('\n')
530        if outdir != ".":
531            self.ns_close(['Atlas', 'Objects', outdir])
532            self.footer(['Atlas', 'Objects', outdir, self.classname, "H"])
533        else:
534            self.ns_close(['Atlas', 'Objects'])
535            self.footer(['Atlas', 'Objects', self.classname, "H"])
536        self.out.close()
537        if os.access(outfile, os.F_OK):
538            if filecmp(outfile + ".tmp", outfile) == 0:
539                os.remove(outfile)
540                os.rename(outfile + ".tmp", outfile)
541            else:
542                print "Output file same as existing one, not updating"
543                os.remove(outfile + ".tmp")
544        else:
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)
551        self.out.write("\n")
552    def implementation(self, obj):
553        print "Output of implementation for:"
554        #outfile = self.outdir + '/' + self.classname + ".cc"
555        print self.classname
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')
563        self.out.write("\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")
568        self.out.write("\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)), \
571          obj.attr_list)
572        if outdir != ".":
573            self.ns_open(['Atlas', 'Objects', outdir])
574        else:
575            self.ns_open(['Atlas', 'Objects'])
576        self.out.write("\n")
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)
589        if outdir != ".":
590            self.ns_close(['Atlas', 'Objects', outdir])
591        else:
592            self.ns_close(['Atlas', 'Objects'])
593        self.out.write("\n")
594        self.out = None
595    def implementation_close(self):
596        outfile = self.outdir + '/' + self.outdir + ".cc"
597        self.out = self.imp_out
598        print "Closing implementation file"
599        self.out.close()
600        if os.access(outfile, os.F_OK):
601            if filecmp(outfile + ".tmp", outfile) == 0:
602                os.remove(outfile)
603                os.rename(outfile + ".tmp", outfile)
604            else:
605                print "Output file same as existing one, not updating"
606                os.remove(outfile + ".tmp")
607        else:
608            os.rename(outfile + ".tmp", outfile)
609
610# Main program
611
612if len(sys.argv) < 2:
613    print "Syntax:"
614    print sys.argv[0] + " root [outdir]"
615    sys.exit()
616filelist = ["root","entity","operation","type","interface"]
617defs = read_all_defs(map(lambda file:"../../../../protocols/atlas/spec/" + file+".def", filelist))
618if len(sys.argv) >= 3:
619    outdir = sys.argv[2]
620else:
621    outdir = "."
622gen_header = GenerateCC(defs, outdir)
623gen_header.implementation_setup()
624gen_header([sys.argv[1]])
625gen_header.implementation_close()
626