~ubuntu-branches/ubuntu/breezy/atlas-cpp/breezy

« back to all changes in this revision

Viewing changes to Atlas/Objects/gen_cpp.py

  • Committer: Bazaar Package Importer
  • Author(s): Michael Koch
  • Date: 2005-10-02 11:41:44 UTC
  • mfrom: (1.1.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20051002114144-8qmn4d1cdn9g27ta
Tags: 0.5.98-1
New upstream release

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#!/usr/local/bin/python
 
2
#This file is distributed under the terms of 
 
3
#the GNU Lesser General Public license (See the file COPYING for details).
 
4
#Copyright (C) 2000 Stefanus Du Toit and Aloril
 
5
 
 
6
from common import *
 
7
from AttributeInfo import *
 
8
from GenerateObjectFactory import GenerateObjectFactory
 
9
from GenerateDecoder import GenerateDecoder
 
10
from GenerateDispatcher import GenerateDispatcher
 
11
from GenerateForward import GenerateForward
 
12
 
 
13
class_serial_no = 1
 
14
 
 
15
class GenerateCC(GenerateObjectFactory, GenerateDecoder, GenerateDispatcher, GenerateForward):
 
16
    def __init__(self, objects, outdir):
 
17
        self.objects = objects
 
18
        #self.outdir = outdir
 
19
        self.outdir = "."
 
20
        if outdir != ".":
 
21
            self.base_list = ['Atlas', 'Objects', outdir]
 
22
            self.name_space = outdir + "::"
 
23
        else:
 
24
            self.base_list = ['Atlas', 'Objects']
 
25
            self.name_space = ""
 
26
 
 
27
    def __call__(self, obj, class_only_files):
 
28
        self.classname = classize(obj.id, data=1)
 
29
        self.classname_pointer = classize(obj.id)
 
30
        self.generic_class_name = capitalize_only(string.split(obj.id, "_")[-1])
 
31
        self.interface_file(obj)
 
32
        self.implementation_file(obj)
 
33
        if class_only_files:
 
34
            self.find_progeny(obj, class_only_files)
 
35
            self.children_interface_file(obj)
 
36
            self.children_implementation_file(obj)
 
37
            res = [obj] + self.progeny
 
38
            #self.decoder()
 
39
        else:
 
40
            res = [obj]
 
41
        return map(lambda o,n=self.name_space:(o,n), res)
 
42
    
 
43
    def find_attr_class(self, obj):
 
44
        name = obj.id
 
45
        if attr_name2class.has_key(name):
 
46
            return name, attr_name2class[name]
 
47
        for parent in obj.parents:
 
48
            res = self.find_attr_class(parent)
 
49
            if res: return res
 
50
 
 
51
    def get_name_value_type(self, obj, first_definition = 0,
 
52
                            real_attr_only = 0, include_desc_attrs = 0):
 
53
        lst = []
 
54
        for name, value in obj.items():
 
55
            if not include_desc_attrs and name in descr_attrs:
 
56
                continue
 
57
            #required that no parent has this attribute?
 
58
            if first_definition:
 
59
                if find_in_parents(obj, name):
 
60
                    continue
 
61
            #basic type
 
62
            otype, attr_class_lst = self.find_attr_class(self.objects[name])
 
63
            # print 'Attr ', attr_class_lst, name, value, otype
 
64
            if real_attr_only:
 
65
                lst.append(apply(attr_class_lst[0],
 
66
                                 (name, value, otype)))
 
67
            else:
 
68
                for attr_class in attr_class_lst:
 
69
                    lst.append(apply(attr_class,
 
70
                                     (name, value, otype)))
 
71
        return lst
 
72
 
 
73
    def set_attributes(self, obj, include_desc_attrs, lst, used_attributes):
 
74
        for name, value in obj.items():
 
75
            if not include_desc_attrs and name in descr_attrs:
 
76
                continue
 
77
            if name in ['id', 'parents']:
 
78
                continue
 
79
            if name == 'objtype':
 
80
                if value == 'op_definition':
 
81
                    value = 'op'
 
82
                else:
 
83
                    value = 'obj'
 
84
            otype, attr_class_lst = self.find_attr_class(self.objects[name])
 
85
            if name not in used_attributes:
 
86
                lst.append(apply(attr_class_lst[0],
 
87
                                 (name, value, otype)))
 
88
                used_attributes.append(name)
 
89
        for parent in obj.parents:
 
90
            self.set_attributes(parent, include_desc_attrs, lst, used_attributes)
 
91
 
 
92
    def get_default_name_value_type(self, obj, include_desc_attrs = 0):
 
93
        lst = []
 
94
        used_attributes = []
 
95
        self.set_attributes(obj, include_desc_attrs, lst, used_attributes)
 
96
        if obj.has_key('id'):
 
97
            parent = obj['id']
 
98
            otype,attr_class_lst = self.find_attr_class(self.objects['parents'])
 
99
            lst.append(apply(attr_class_lst[0],
 
100
                             ('parents', [parent], 'string_list')))
 
101
        return lst
 
102
 
 
103
    def get_cpp_parent(self, obj):
 
104
        if len(obj.parents) == 0:
 
105
            parent = "BaseObject"
 
106
        elif len(obj.parents) == 1:
 
107
            parent = obj.parents[0].id
 
108
        else:
 
109
            raise ValueError, "Multiple parents needs supporting code"
 
110
        return classize(parent, data=1)
 
111
 
 
112
    def write(self, str):
 
113
        self.out.write(str)
 
114
 
 
115
    def header(self, list, copyright = copyright):
 
116
        self.write(copyright)
 
117
        self.write("\n")
 
118
        guard = string.join(map(string.upper, list), "_")
 
119
        self.write("#ifndef " + guard + "\n")
 
120
        self.write("#define " + guard + "\n\n")
 
121
    def footer(self, list):
 
122
        guard = string.join(map(string.upper, list), "_")
 
123
        self.write("\n#endif // " + guard + "\n")
 
124
 
 
125
    #namespace
 
126
    def ns_open(self, ns_list):
 
127
        for namespace in ns_list:
 
128
            self.write("namespace " + namespace + " { ")
 
129
        self.write("\n")
 
130
    def ns_close(self, ns_list):
 
131
        for i in range(0, len(ns_list)):
 
132
            self.write("} ")
 
133
        self.write("// namespace " + string.join(ns_list, "::"))
 
134
        self.write("\n")
 
135
 
 
136
    def doc(self, indent, text):
 
137
        self.write(doc(indent, text))
 
138
 
 
139
    def update_outfile(self, outfile):
 
140
        if os.access(outfile, os.F_OK):
 
141
            if filecmp(outfile + ".tmp", outfile) == 0:
 
142
                os.remove(outfile)
 
143
                os.rename(outfile + ".tmp", outfile)
 
144
                print "Generated:", outfile
 
145
            else:
 
146
                #print "Output file same as existing one, not updating"
 
147
                os.remove(outfile + ".tmp")
 
148
        else:
 
149
            os.rename(outfile + ".tmp", outfile)
 
150
            print "Generated:", outfile
 
151
 
 
152
    def constructors_if(self, obj, static_attrs):
 
153
        self.doc(4, "Construct a " + self.classname + " class definition.")
 
154
        classname_base = self.get_cpp_parent(obj)
 
155
        classname = self.classname
 
156
        serialno_name = string.upper(obj.id) + "_NO"
 
157
        self.write("""    %(classname)s(%(classname)s *defaults = NULL) : 
 
158
        %(classname_base)s((%(classname_base)s*)defaults)
 
159
    {
 
160
        m_class_no = %(serialno_name)s;
 
161
    }
 
162
""" % vars()) #"for xemacs syntax highlighting
 
163
 
 
164
    def static_inline_sets(self, obj, statics):
 
165
        classname = classize(obj.id, data=1)
 
166
        for attr in statics:
 
167
            self.write("const int %s = 1 << %i;\n" %
 
168
                       (attr.flag_name, attr.enum))
 
169
            self.write(attr.inline_set(classname))
 
170
 
 
171
    def static_inline_gets(self, obj, statics):
 
172
        classname = classize(obj.id, data=1)
 
173
        for attr in statics:
 
174
            self.write(attr.inline_get(classname))
 
175
 
 
176
    def static_inline_is_defaults(self, obj, statics):
 
177
        classname = classize(obj.id, data=1)
 
178
        for attr in statics:
 
179
            self.write(attr.inline_is_default(classname))
 
180
 
 
181
    def static_inline_sends(self, obj, statics):
 
182
        classname = classize(obj.id, data=1)
 
183
        for attr in statics:
 
184
            self.write(attr.inline_send(classname))
 
185
 
 
186
    def static_default_assigns(self, obj, defaults):
 
187
        classname = classize(obj.id, data=1)
 
188
        for attr in defaults:
 
189
            self.write(attr.default_assign(classname))
 
190
 
 
191
    def static_attr_flag_inserts(self, obj, static_attrs):
 
192
        classname = classize(obj.id, data=1)
 
193
        self.write("        attr_flags_%s = new std::map<std::string, int>;\n" % (classname))
 
194
        for attr in static_attrs:
 
195
            self.write("        (*attr_flags_%s)[\"%s\"] = %s;\n" % (classname, attr.name, attr.flag_name)) #"for xamacs syntax highlighting
 
196
 
 
197
    def getattrclass_im(self, obj, statics):
 
198
        classname = classize(obj.id, data=1)
 
199
        serialno_name = string.upper(obj.id) + "_NO"
 
200
        self.write("int %s::getAttrClass(const std::string& name) const\n"
 
201
                        % classname)
 
202
        self.write("{\n")
 
203
        # for attr in statics:
 
204
        #     self.write('    if (name == "%s")' % attr.name)
 
205
        #     self.write(' return %s;\n' % serialno_name)
 
206
        self.write("""    if (attr_flags_%s->find(name) != attr_flags_%s->end()) {
 
207
        return %s;
 
208
    }
 
209
""" % (classname, classname, serialno_name))
 
210
        parent = self.get_cpp_parent(obj)
 
211
        self.write("    return %s::getAttrClass(name);\n" % parent)
 
212
        self.write("}\n\n")
 
213
 
 
214
    def getattrflag_im(self, obj):
 
215
        classname = classize(obj.id, data=1)
 
216
        self.write("int %s::getAttrFlag(const std::string& name) const\n"
 
217
                        % classname)
 
218
        self.write("{\n")
 
219
        self.write("""    std::map<std::string, int>::const_iterator I = attr_flags_%s->find(name);
 
220
    if (I != attr_flags_%s->end()) {
 
221
        return I->second;
 
222
    }
 
223
""" % (classname, classname))
 
224
        parent = self.get_cpp_parent(obj)
 
225
        self.write("    return %s::getAttrFlag(name);\n" % parent)
 
226
        self.write("}\n\n")
 
227
 
 
228
    def getattr_im(self, obj, statics):
 
229
        classname = classize(obj.id, data=1)
 
230
        # This is no longer required, as its base is no virtual, and just
 
231
        # calls getAttr(name, attr)
 
232
        #self.write("const Element %s::getAttr" % classname)
 
233
        #self.write("(const std::string& name) const\n")
 
234
        #self.write("    throw (NoSuchAttrException)\n")
 
235
        #self.write("{\n")
 
236
        #for attr in statics:
 
237
            #self.write(attr.getattr_im())
 
238
        #parent = self.get_cpp_parent(obj)
 
239
        #self.write("    return %s::getAttr(name);\n" % parent)
 
240
        #self.write("}\n\n")
 
241
        self.write("int %s::copyAttr" % classname)
 
242
        self.write("(const std::string& name, Element & attr) const\n")
 
243
        self.write("{\n")
 
244
        for attr in statics:
 
245
            self.write(attr.getattr_im2())
 
246
        parent = self.get_cpp_parent(obj)
 
247
        self.write("    return %s::copyAttr(name, attr);\n" % parent)
 
248
        self.write("}\n\n")
 
249
 
 
250
    def setattr_im(self, obj, statics):
 
251
        classname = classize(obj.id, data=1)
 
252
        self.write("void %s::setAttr" % classname)
 
253
        self.write("(const std::string& name, const Element& attr)\n")
 
254
        self.write("{\n")
 
255
        for attr in statics:
 
256
            self.write(attr.setattr_im())
 
257
        parent = self.get_cpp_parent(obj)
 
258
        self.write("    %s::setAttr(name, attr);\n" % parent)
 
259
        self.write("}\n\n")
 
260
 
 
261
    def remattr_im(self, obj, statics):
 
262
        classname = classize(obj.id, data=1)
 
263
        self.write("void %s::removeAttr(const std::string& name)\n"
 
264
                        % classname)
 
265
        self.write("{\n")
 
266
        for attr in statics:
 
267
            self.write('    if (name == "%s")\n' % attr.name)
 
268
            self.write('        { m_attrFlags &= ~%s; return;}\n' % attr.flag_name)
 
269
        parent = self.get_cpp_parent(obj)
 
270
        self.write("    %s::removeAttr(name);\n" % parent)
 
271
        self.write("}\n\n")
 
272
 
 
273
    def sendcontents_im(self, obj, statics):
 
274
        classname = classize(obj.id, data=1)
 
275
        self.write("void %s::sendContents(Bridge & b) const\n" % classname)
 
276
        self.write("{\n")
 
277
        for attr in statics:
 
278
            self.write('    send%s(b);\n' % classize(attr.name))
 
279
        parent = self.get_cpp_parent(obj)
 
280
        self.write("    %s::sendContents(b);\n" % parent)
 
281
        self.write("}\n\n")
 
282
 
 
283
    def asobject_im(self, obj, statics):
 
284
        classname = classize(obj.id, data=1)
 
285
        self.write("const MapType %s::asMessage() const\n" % classname)
 
286
        self.write("{\n")
 
287
        parent = self.get_cpp_parent(obj)
 
288
        self.write("    MapType m = %s::asMessage();\n" % parent)
 
289
        for attr in statics:
 
290
            self.write('    if(m_attrFlags & %s)\n' % attr.flag_name)
 
291
            self.write('        m["%s"] = get%s%s();\n' % \
 
292
                    (attr.name, attr.cname, attr.as_object))
 
293
        self.write('    return m;\n')
 
294
        self.write("}\n\n")
 
295
 
 
296
    def addtoobject_im(self, obj, statics):
 
297
        classname = classize(obj.id, data=1)
 
298
        self.write("void %s::addToMessage(MapType & m) const\n" % classname)
 
299
        self.write("{\n")
 
300
        parent = self.get_cpp_parent(obj)
 
301
        self.write("    %s::addToMessage(m);\n" % parent)
 
302
        for attr in statics:
 
303
            if attr.name not in ["parents", "objtype"]:
 
304
                self.write('    if(m_attrFlags & %s)\n' % attr.flag_name)
 
305
                # If we can get the attribute without having to check the
 
306
                # flag twice, do it.
 
307
                if attr.as_object:
 
308
                    self.write('        m["%s"] = get%s%s();\n' % \
 
309
                           (attr.name, attr.cname, attr.as_object))
 
310
                else:
 
311
                    self.write('        m["%s"] = attr_%s;\n' % \
 
312
                           (attr.name, attr.name))
 
313
            else:
 
314
                # This code only handles "parents" and "objtype", both
 
315
                # of which can be checked with .empty().
 
316
                if attr.as_object:
 
317
                    self.write('    %s l_attr_%s = get%s%s();\n' % \
 
318
                        (attr.cpp_param_type_as_object, attr.name, attr.cname, attr.as_object))
 
319
                    self.write('    if (!l_attr_%s.empty())\n' % \
 
320
                        (attr.name))
 
321
                    self.write('        m["%s"] = l_attr_%s;\n' % \
 
322
                        (attr.name, attr.name))
 
323
                else:
 
324
                    self.write('    %s l_attr_%s = get%s();\n' % \
 
325
                        (attr.cpp_param_type, attr.name, attr.cname))
 
326
                    self.write('    if (!l_attr_%s.empty())\n' % \
 
327
                        (attr.name))
 
328
                    self.write('        m["%s"] = l_attr_%s;\n' % \
 
329
                        (attr.name, attr.name))
 
330
        self.write('    return;\n')
 
331
        self.write("}\n\n")
 
332
 
 
333
    def smart_ptr_if(self, name_addition=""):
 
334
        self.write("\nclass %s;\n" % (self.classname + name_addition))
 
335
        self.write("typedef SmartPtr<%s> %s;\n" %
 
336
                   (self.classname + name_addition,
 
337
                    self.classname_pointer + name_addition))
 
338
        self.write("\n")
 
339
 
 
340
    def freelist_if(self, name_addition=""):
 
341
        classname = self.classname + name_addition
 
342
        self.write("""
 
343
    //freelist related things
 
344
public:
 
345
    static %(classname)s *alloc();
 
346
    virtual void free();
 
347
 
 
348
    /// \\brief Get the reference object that contains the default values for
 
349
    /// attributes of instances of the same class as this object.
 
350
    ///
 
351
    /// @return a pointer to the default object.
 
352
    virtual %(classname)s *getDefaultObject();
 
353
 
 
354
    /// \\brief Get the reference object that contains the default values for
 
355
    /// attributes of instances of this class.
 
356
    ///
 
357
    /// @return a pointer to the default object.
 
358
    static %(classname)s *getDefaultObjectInstance();
 
359
private:
 
360
    static %(classname)s *defaults_%(classname)s;
 
361
    static %(classname)s *begin_%(classname)s;
 
362
""" % vars()) #"for xemacs syntax highlighting
 
363
    def freelist_im(self, name_addition=""):
 
364
        classname = self.classname + name_addition
 
365
        self.write("""
 
366
//freelist related methods specific to this class
 
367
%(classname)s *%(classname)s::defaults_%(classname)s = 0;
 
368
%(classname)s *%(classname)s::begin_%(classname)s = 0;
 
369
 
 
370
%(classname)s *%(classname)s::alloc()
 
371
{
 
372
    if(begin_%(classname)s) {
 
373
        %(classname)s *res = begin_%(classname)s;
 
374
        assert( res->m_refCount == 0 );
 
375
        res->m_attrFlags = 0;
 
376
        res->m_attributes.clear();
 
377
        begin_%(classname)s = (%(classname)s *)begin_%(classname)s->m_next;
 
378
        return res;
 
379
    }
 
380
    return new %(classname)s(%(classname)s::getDefaultObjectInstance());
 
381
}
 
382
 
 
383
void %(classname)s::free()
 
384
{
 
385
    m_next = begin_%(classname)s;
 
386
    begin_%(classname)s = this;
 
387
}
 
388
 
 
389
""" % vars()) #"for xemacs syntax highlighting
 
390
 
 
391
    def default_object_im(self, obj, default_attrs, static_attrs):
 
392
        classname = self.classname
 
393
        self.write("""
 
394
%(classname)s *%(classname)s::getDefaultObjectInstance()
 
395
{
 
396
    if (defaults_%(classname)s == 0) {
 
397
        defaults_%(classname)s = new %(classname)s;
 
398
""" % vars()) #"for xemacs syntax highlighting
 
399
        self.static_default_assigns(obj, default_attrs)
 
400
        if len(static_attrs) > 0:
 
401
            self.static_attr_flag_inserts(obj, static_attrs)
 
402
        if len(obj.parents) > 0:
 
403
            self.write("        %s::getDefaultObjectInstance();\n" % (classize(obj.parents[0], data=1)))
 
404
        self.write("""    }
 
405
    return defaults_%(classname)s;
 
406
}
 
407
 
 
408
%(classname)s *%(classname)s::getDefaultObject()
 
409
{
 
410
    return %(classname)s::getDefaultObjectInstance();
 
411
}
 
412
 
 
413
""" % vars()) #"for xemacs syntax highlighting
 
414
 
 
415
    def destructor_im(self, obj):
 
416
        classname = self.classname
 
417
        self.write("""%(classname)s::~%(classname)s()
 
418
{
 
419
}
 
420
 
 
421
""" % vars()) #"for xemacs syntax highlighting
 
422
 
 
423
    def settype_im(self, obj):
 
424
        classname = self.classname
 
425
        self.write("""void %(classname)s::setType(const std::string & name, int no)
 
426
{
 
427
    setParents(std::list<std::string>(1, name));
 
428
    m_class_no = no;
 
429
}
 
430
 
 
431
""" % vars()) #"for xemacs syntax highlighting
 
432
    def copy_im(self, obj):
 
433
        self.write("""%s * %s::copy() const
 
434
{
 
435
    %s * copied = %s::alloc();
 
436
    *copied = *this;
 
437
    copied->m_refCount = 0;
 
438
    return copied;
 
439
}
 
440
 
 
441
""" % (self.classname, self.classname, self.classname, self.classname))
 
442
    def instanceof_im(self, obj):
 
443
        classname_base = self.get_cpp_parent(obj)
 
444
        classname = self.classname
 
445
        serialno_name = string.upper(obj.id) + "_NO"
 
446
        self.write("""bool %(classname)s::instanceOf(int classNo) const
 
447
{
 
448
    if(%(serialno_name)s == classNo) return true;
 
449
    return %(classname_base)s::instanceOf(classNo);
 
450
}
 
451
""" % vars()) #"for xemacs syntax highlighting
 
452
 
 
453
    def iterate_im(self, obj, statics):
 
454
        classname_base = self.get_cpp_parent(obj)
 
455
        classname = self.classname
 
456
        serialno_name = string.upper(obj.id) + "_NO"
 
457
        self.write("""void %(classname)s::iterate(int& current_class, std::string& attr) const
 
458
{
 
459
    // If we've already finished this class, chain to the parent
 
460
    if(current_class >= 0 && current_class != %(serialno_name)s) {
 
461
        %(classname_base)s::iterate(current_class, attr);
 
462
        return;
 
463
    }
 
464
 
 
465
    static const char *attr_list[] = {""" % vars()) #"for xemacs syntax highlighting
 
466
        for attr in statics:
 
467
            self.write('"%s",' % attr.name)
 
468
        self.write("""};
 
469
    static const unsigned n_attr = sizeof(attr_list) / sizeof(const char*);
 
470
 
 
471
    unsigned next_attr = n_attr; // so we chain to the parent if we don't find attr
 
472
 
 
473
    if(attr.empty()) // just staring on this class
 
474
        next_attr = 0;
 
475
    else {
 
476
      for(unsigned i = 0; i < n_attr; ++i) {
 
477
         if(attr == attr_list[i]) {
 
478
             next_attr = i + 1;
 
479
             break;
 
480
         }
 
481
      }
 
482
    }
 
483
 
 
484
    if(next_attr == n_attr) { // last one on the list
 
485
        current_class = -1;
 
486
        attr = "";
 
487
        %(classname_base)s::iterate(current_class, attr); // chain to parent
 
488
    }
 
489
    else {
 
490
        current_class = %(serialno_name)s;
 
491
        attr = attr_list[next_attr];
 
492
    }
 
493
}
 
494
 
 
495
""" % vars()) #"for xemacs syntax highlighting 
 
496
 
 
497
    def interface_file(self, obj):
 
498
        #print "Output of interface for:",
 
499
        outfile = self.outdir + '/' + self.classname_pointer + ".h"
 
500
        #print outfile
 
501
        self.out = open(outfile + ".tmp", "w")
 
502
        self.header(self.base_list + [self.classname_pointer, "H"])
 
503
        for parent in obj.parents:
 
504
            parent = parent.id
 
505
            self.write('#include <Atlas/Objects/')
 
506
            #if parent == "root": self.write('../')
 
507
            self.write(classize(parent) + '.h>\n')
 
508
        if not obj.parents:
 
509
            self.write('#include <Atlas/Objects/BaseObject.h>\n\n')
 
510
            self.write('#include <Atlas/Message/Element.h>\n\n')
 
511
        else:
 
512
            self.write('#include <Atlas/Objects/SmartPtr.h>\n\n')
 
513
        if obj.id=="root_operation":
 
514
            self.write('#include <Atlas/Objects/objectFactory.h>\n\n')
 
515
        self.ns_open(self.base_list)
 
516
        if not obj.parents:
 
517
            self.write('\ntemplate <class T> class SmartPtr;\n')
 
518
        static_attrs = self.get_name_value_type(obj, first_definition=1)
 
519
        self.interface(obj, static_attrs)
 
520
        self.ns_close(self.base_list)
 
521
        self.footer(self.base_list + [self.classname_pointer, "H"])
 
522
        self.out.close()
 
523
        self.update_outfile(outfile)
 
524
 
 
525
    def interface(self, obj, static_attrs=[], default_attrs=[]):
 
526
        self.write("\n")
 
527
        self.write("/** " + obj.description + "\n")
 
528
        self.write("\n")
 
529
        self.write(obj.long_description + "\n\n")
 
530
        self.write("*/\n")
 
531
        self.smart_ptr_if()
 
532
        global class_serial_no
 
533
        self.write("static const int %s_NO = %i;\n\n" % (
 
534
            string.upper(obj.id), class_serial_no))
 
535
        class_serial_no = class_serial_no + 1
 
536
        self.write("/// \\brief " + obj.description  + ".\n")
 
537
        if hasattr(obj, 'long_description'):
 
538
            self.write("///\n/** " + obj.long_description + "\n */\n")
 
539
        self.write("class " + self.classname)
 
540
        parentlist = obj.parents
 
541
        if not parentlist: parentlist = ["BaseObject"]
 
542
        parentlist = map(lambda parent:"public " + classize(parent, data=1), \
 
543
                         parentlist)
 
544
        if len(parentlist) > 0:
 
545
            self.write(" : ")
 
546
            self.write(string.join(parentlist, ", "))
 
547
        self.write("\n{\n")
 
548
 
 
549
        self.write("protected:\n")
 
550
        self.constructors_if(obj, static_attrs)
 
551
        self.doc(4, "Default destructor.")
 
552
        self.write("    virtual ~" + self.classname + "();\n")
 
553
        self.write("\n")
 
554
        self.write("public:\n")
 
555
        if obj.id in ['anonymous', 'generic']:
 
556
            self.doc(4, 'Set the type of this object.')
 
557
            self.write("    void setType(const std::string &, int);\n\n")
 
558
        self.doc(4, 'Copy this object.')
 
559
        self.write("    virtual %s * copy() const;\n" % (self.classname))
 
560
        self.write("\n")
 
561
        self.doc(4, 'Is this instance of some class?')
 
562
        self.write("    virtual bool instanceOf(int classNo) const;\n")
 
563
        self.write("\n")
 
564
 
 
565
        if len(static_attrs) > 0:
 
566
            #generic access/etc.. methods
 
567
            # self.doc(4, 'Retrieve the attribute "name". Throws ' \
 
568
            #          + 'NoSuchAttrException if it does')
 
569
            # self.doc(4, 'not exist.')
 
570
            # self.write("    virtual const Atlas::Message::Element getAttr(")
 
571
            # self.write("const std::string& name)\n")
 
572
            # self.write("            const throw (NoSuchAttrException);\n")
 
573
            self.doc(4, 'Retrieve the attribute "name". Return ' \
 
574
                      + 'non-zero if it does')
 
575
            self.doc(4, 'not exist.')
 
576
            self.write("    virtual int copyAttr(")
 
577
            self.write("const std::string& name, ")
 
578
            self.write("Atlas::Message::Element & attr) const;\n")
 
579
            self.doc(4, 'Set the attribute "name" to the value given by' \
 
580
                      + '"attr"')
 
581
            self.write("    virtual void setAttr(const std::string& name,\n")
 
582
            self.write("                         ")
 
583
            self.write("const Atlas::Message::Element& attr);\n")
 
584
            self.doc(4, 'Remove the attribute "name". This will not work for '\
 
585
                      + 'static attributes.')
 
586
            self.write("    virtual void removeAttr(")
 
587
            self.write("const std::string& name);\n")
 
588
            self.write("\n")
 
589
            self.doc(4, 'Send the contents of this object to a Bridge.')
 
590
            self.write("    virtual void sendContents(Atlas::Bridge & b) const;\n")
 
591
            self.write("\n")
 
592
            # self.doc(4, 'Convert this object to a Element.')
 
593
            # self.write("    virtual const Atlas::Message::MapType asMessage() const;\n")
 
594
            # self.write("\n")
 
595
            self.doc(4, 'Write this object to an existing Element.')
 
596
            self.write("    virtual void addToMessage(Atlas::Message::MapType &) const;\n")
 
597
            self.write("\n")
 
598
            for attr in static_attrs:
 
599
                self.write(attr.set_if())
 
600
            self.write('\n')
 
601
            for attr in static_attrs:
 
602
                self.write(attr.get_if())
 
603
            self.write('\n')
 
604
            for attr in static_attrs:
 
605
                self.write(attr.is_default_if())
 
606
            self.write('\n')
 
607
 
 
608
            self.write("protected:\n")
 
609
 
 
610
            self.doc(4, 'Find the class which contains the attribute "name".')
 
611
            self.write("    virtual int getAttrClass(const std::string& name)"\
 
612
                           + "const;\n")
 
613
 
 
614
            self.doc(4, 'Find the flag for the attribute "name".')
 
615
            self.write("    virtual int getAttrFlag(const std::string& name)"\
 
616
                           + "const;\n")
 
617
 
 
618
            for attr in static_attrs:
 
619
                if self.objects.has_key(attr.name):
 
620
                    attr_object = self.objects[attr.name]
 
621
                    if hasattr(attr_object, 'description'):
 
622
                        self.doc(4, attr_object.description)
 
623
                self.write('    %s attr_%s;\n' %
 
624
                               (cpp_type[attr.type], attr.name))
 
625
            self.write('\n')
 
626
            for attr in static_attrs:
 
627
                self.doc(4, 'Send the "%s" attribute to an Atlas::Bridge.' %
 
628
                            (attr.name))
 
629
                self.write("    void send" + attr.cname)
 
630
                self.write('(Atlas::Bridge&) const;\n')
 
631
 
 
632
        self.write("\n    virtual void iterate(int& current_class, std::string& attr) const")
 
633
        if len(static_attrs) == 0:
 
634
            self.write("\n        {if(current_class == " + string.upper(obj.id) + "_NO) current_class = -1; " + self.get_cpp_parent(obj) + "::iterate(current_class, attr);}\n")
 
635
        else:
 
636
            self.write(";\n")
 
637
 
 
638
        self.freelist_if()
 
639
        if len(static_attrs) > 0:
 
640
            self.write("""
 
641
    static std::map<std::string, int> * attr_flags_%s;
 
642
""" % (self.classname)) #"for xemacs syntax highlighting
 
643
        self.write("};\n\n")
 
644
 
 
645
        #inst# self.instance_if(obj)
 
646
 
 
647
        if len(static_attrs) > 0:
 
648
            self.write('//\n// Inlined member functions follow.\n//\n\n')
 
649
            self.static_inline_sets(obj, static_attrs)
 
650
            self.static_inline_gets(obj, static_attrs)
 
651
            self.static_inline_is_defaults(obj, static_attrs)
 
652
            # self.static_inline_sends(obj, static_attrs)
 
653
            self.write('\n')
 
654
 
 
655
    def implementation_file (self, obj):
 
656
        #print "Output of implementation for:",
 
657
        outfile = self.outdir + '/' + self.classname_pointer + ".cpp"
 
658
        #print outfile
 
659
        self.out = open(outfile + ".tmp", "w")
 
660
        self.write(copyright)
 
661
        self.write("\n")
 
662
        self.write('#include <Atlas/Objects/' + self.classname_pointer + '.h>\n')
 
663
        self.write("\n")
 
664
        #self.write("using namespace std;\n")
 
665
        #self.write("using namespace Atlas;\n")
 
666
        #self.write("using namespace Atlas::Message;\n")
 
667
        self.write("using Atlas::Message::Element;\n")
 
668
        self.write("using Atlas::Message::MapType;\n")
 
669
        self.write("\n")
 
670
        self.ns_open(self.base_list)
 
671
        self.write("\n")
 
672
        static_attrs = self.get_name_value_type(obj, first_definition=1,
 
673
                                                real_attr_only=1)
 
674
        default_attrs = self.get_default_name_value_type(obj)
 
675
        self.implementation(obj, static_attrs, default_attrs)
 
676
        self.ns_close(self.base_list)
 
677
        self.out.close()
 
678
        self.update_outfile(outfile)
 
679
 
 
680
    def implementation(self, obj, static_attrs=[], default_attrs=[]):
 
681
        if len(static_attrs) > 0:
 
682
            #self.constructors_im(obj)
 
683
            self.getattrclass_im(obj, static_attrs)
 
684
            self.getattrflag_im(obj)
 
685
            self.getattr_im(obj, static_attrs)
 
686
            self.setattr_im(obj, static_attrs)
 
687
            self.remattr_im(obj, static_attrs)
 
688
            self.static_inline_sends(obj, static_attrs)
 
689
            self.sendcontents_im(obj, static_attrs)
 
690
            #self.asobject_im(obj, static_attrs)
 
691
            self.addtoobject_im(obj, static_attrs)
 
692
            self.iterate_im(obj, static_attrs)
 
693
        self.destructor_im(obj)
 
694
        if obj.id in ['anonymous', 'generic']:
 
695
            self.settype_im(obj)
 
696
        self.copy_im(obj)
 
697
        self.instanceof_im(obj)
 
698
        self.freelist_im()
 
699
        if len(static_attrs) > 0:
 
700
            self.write("std::map<std::string, int> * %s::attr_flags_%s = 0;\n"
 
701
                       % (self.classname, self.classname))
 
702
        self.default_object_im(obj, default_attrs, static_attrs)
 
703
 
 
704
        #inst# self.instance_im()
 
705
        
 
706
    def instance_if(self, obj):
 
707
        self.smart_ptr_if("Instance")
 
708
        classname_base = self.classname
 
709
        classname = classname_base + "Instance"
 
710
        serialno_name = string.upper(obj.id) + "_INSTANCE_NO"
 
711
        global class_serial_no
 
712
        cs_no = class_serial_no
 
713
        self.write("""
 
714
const int %(serialno_name)s = %(cs_no)s;
 
715
 
 
716
class %(classname)s : public %(classname_base)s
 
717
{
 
718
public:
 
719
    %(classname)s(%(classname)s *defaults = NULL) : 
 
720
        %(classname_base)s((%(classname_base)s*)defaults)
 
721
    {
 
722
        m_class_no = %(serialno_name)s;
 
723
    }
 
724
""" % vars()) #"for xemacs syntax highlighting
 
725
        class_serial_no = class_serial_no + 1
 
726
        self.freelist_if("Instance")
 
727
        self.write("};\n\n")
 
728
 
 
729
    def instance_im(self):
 
730
        self.freelist_im("Instance")
 
731
 
 
732
    def for_progeny(self, progeny, func):
 
733
        for child in progeny:
 
734
            bak_classname = self.classname
 
735
            bak_classname_pointer = self.classname_pointer
 
736
            self.classname = classize(child.id, data=1)
 
737
            self.classname_pointer = classize(child.id)
 
738
            static_attrs = self.get_name_value_type(child, first_definition=1,
 
739
                                                         real_attr_only=1)
 
740
            default_attrs = self.get_default_name_value_type(child)
 
741
 
 
742
            func(child, static_attrs, default_attrs)
 
743
            self.classname = bak_classname
 
744
            self.classname_pointer = bak_classname_pointer
 
745
 
 
746
    def find_progeny(self, obj, class_only_files):
 
747
        self.progeny = []
 
748
        for child in obj.children:
 
749
            self.find_progeny_recursive(child, class_only_files)
 
750
 
 
751
    def find_progeny_recursive(self, obj, class_only_files):
 
752
        if obj.specification_file.filename not in class_only_files:
 
753
            return
 
754
        self.progeny.append(obj)
 
755
        for child in obj.children:
 
756
            self.find_progeny_recursive(child, class_only_files)
 
757
 
 
758
    def children_interface_file(self, obj):
 
759
        #print "Output of interface for:",
 
760
        outfile = self.outdir + '/' + self.generic_class_name + ".h"
 
761
        #print outfile
 
762
        self.out = open(outfile + ".tmp", "w")
 
763
        self.header(self.base_list + [self.generic_class_name, "H"])
 
764
        self.write('#include <Atlas/Objects/%s.h>\n' % self.classname_pointer)
 
765
        if obj.id == "root_entity":
 
766
            self.write('#include <Atlas/Objects/Anonymous.h>\n')
 
767
        if obj.id == "root_operation":
 
768
            self.write('#include <Atlas/Objects/Generic.h>\n')
 
769
        self.write("\n\n")
 
770
        self.ns_open(self.base_list)
 
771
        self.for_progeny(self.progeny, self.interface)
 
772
        self.ns_close(self.base_list)
 
773
        self.footer(self.base_list + [self.generic_class_name, "H"])
 
774
        self.out.close()
 
775
        self.update_outfile(outfile)
 
776
 
 
777
    def children_implementation_file(self, obj):
 
778
        size_limit = 6
 
779
        if len(self.progeny)<=size_limit:
 
780
            self.children_implementation_one_file(obj, "", self.progeny)
 
781
        else:
 
782
            for i in range(0, len(self.progeny), size_limit):
 
783
                self.children_implementation_one_file(
 
784
                    obj, i/size_limit+1, self.progeny[i:i+size_limit])
 
785
 
 
786
    def children_implementation_one_file(self, obj, serial, progeny):
 
787
        #print "Output of implementation for:",
 
788
        outfile = self.outdir + '/' + self.classname_pointer + \
 
789
                  "Children%s.cpp" % serial
 
790
        #print outfile
 
791
        self.out = open(outfile + ".tmp", "w")
 
792
        self.write(copyright)
 
793
        self.write("\n")
 
794
        self.write('#include <Atlas/Objects/' + self.generic_class_name + '.h>\n')
 
795
        self.write("\n")
 
796
        #self.write("using namespace std;\n")
 
797
        #self.write("using namespace Atlas;\n")
 
798
        #self.write("using namespace Atlas::Message;\n")
 
799
        self.write("using Atlas::Message::Element;\n")
 
800
        self.write("using Atlas::Message::MapType;\n")
 
801
        self.write("\n")
 
802
        self.ns_open(self.base_list)
 
803
        self.write("\n")
 
804
        self.for_progeny(progeny, self.implementation)
 
805
        self.ns_close(self.base_list)
 
806
        self.out.close()
 
807
        self.update_outfile(outfile)
 
808
 
 
809
        
 
810
 
 
811
 
 
812
# Main program
 
813
if __name__=="__main__":
 
814
##     if len(sys.argv) < 2:
 
815
##         print "Syntax:"
 
816
##         print sys.argv[0] + " root [outdir]"
 
817
##         sys.argv.append("root")
 
818
##         sys.exit()
 
819
 
 
820
    #read XML spec
 
821
    parseXML=parse_xml.get_decoder()
 
822
    parseXML.set_stream_mode()
 
823
    spec_xml_string = open("../../../../protocols/atlas/spec/atlas.xml").read()
 
824
#    spec_xml_string = open("../../../../protocols/atlas/spec/core_atlas.xml").read()
 
825
    #convert list into dictionary
 
826
    objects = {}
 
827
    for obj in parseXML(spec_xml_string):
 
828
        objects[obj.id] = obj
 
829
    find_parents_children_objects(objects)
 
830
    objects["anonymous"] = Object(id="anonymous", parents=[objects["root_entity"]])
 
831
    objects["generic"] = Object(id="generic", parents=[objects["root_operation"]])
 
832
 
 
833
    print "Loaded atlas.xml"
 
834
 
 
835
##     if len(sys.argv) >= 3:
 
836
##         outdir = sys.argv[2]
 
837
##     else:
 
838
##         outdir = "."
 
839
    object_enum = 0
 
840
    all_objects = []
 
841
    # print objects["pos"].description
 
842
    for name, outdir, class_only_files in (
 
843
                ("root", ".", []),
 
844
                ("root_entity", "Entity", ["entity.def"]),
 
845
                ("root_operation", "Operation", ["operation.def"]),
 
846
                ("anonymous", "Entity", []),
 
847
                ("generic", "Operation", [])):
 
848
        object_enum = object_enum + 1
 
849
        gen_code = GenerateCC(objects, outdir) #, object_enum)
 
850
        all_objects = all_objects + gen_code(objects[name], class_only_files)
 
851
    #generate code common to all objects
 
852
    gen_code = GenerateCC(objects, ".") #, object_enum)
 
853
    gen_code.generate_object_factory(all_objects,class_serial_no)
 
854
    gen_code.generate_decoder(all_objects)
 
855
    gen_code.generate_dispatcher(all_objects)
 
856
    gen_code.generate_forward(all_objects)