OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [ecos-2.0/] [tools/] [src/] [libcdl/] [refer.cxx] - Blame information for rev 574

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 26 unneback
//{{{  Banner                           
2
 
3
//============================================================================
4
//
5
//      refer.cxx
6
//
7
//      Implementation of the CdlReference and CdlReferrer classes.
8
//
9
//============================================================================
10
//####COPYRIGHTBEGIN####
11
//                                                                          
12
// ----------------------------------------------------------------------------
13
// Copyright (C) 1999, 2000 Red Hat, Inc.
14
//
15
// This file is part of the eCos host tools.
16
//
17
// This program is free software; you can redistribute it and/or modify it 
18
// under the terms of the GNU General Public License as published by the Free 
19
// Software Foundation; either version 2 of the License, or (at your option) 
20
// any later version.
21
// 
22
// This program is distributed in the hope that it will be useful, but WITHOUT 
23
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
24
// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for 
25
// more details.
26
// 
27
// You should have received a copy of the GNU General Public License along with
28
// this program; if not, write to the Free Software Foundation, Inc., 
29
// 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
30
//
31
// ----------------------------------------------------------------------------
32
//                                                                          
33
//####COPYRIGHTEND####
34
//============================================================================
35
//#####DESCRIPTIONBEGIN####
36
//
37
// Author(s):   bartv
38
// Contact(s):  bartv
39
// Date:        1999/02/01
40
// Version:     0.02
41
//
42
//####DESCRIPTIONEND####
43
//============================================================================
44
 
45
//}}}
46
//{{{  #include's                       
47
 
48
// ----------------------------------------------------------------------------
49
#include "cdlconfig.h"
50
 
51
// Get the infrastructure types, assertions, tracing and similar
52
// facilities.
53
#include <cyg/infra/cyg_ass.h>
54
#include <cyg/infra/cyg_trac.h>
55
 
56
// <cdlcore.hxx> defines everything implemented in this module.
57
// It implicitly supplies <string>, <vector> and <map> because
58
// the class definitions rely on these headers.
59
#include <cdlcore.hxx>
60
 
61
//}}}
62
 
63
//{{{  Statics                          
64
 
65
// ----------------------------------------------------------------------------
66
CYGDBG_DEFINE_MEMLEAK_COUNTER(CdlReference);
67
CYGDBG_DEFINE_MEMLEAK_COUNTER(CdlReferrer);
68
 
69
//}}}
70
//{{{  CdlReference class               
71
 
72
// ----------------------------------------------------------------------------
73
// The default constructor. This should not normally get invoked, instead
74
// a string argument should be supplied. However it is occasionally useful
75
// to construct a reference and then set the name later.
76
 
77
CdlReference::CdlReference()
78
{
79
    CYG_REPORT_FUNCNAME("CdlReference:: default constructor");
80
    CYG_REPORT_FUNCARG1XV(this);
81
 
82
    dest_name           = "";
83
    dest                = 0;
84
    cdlreference_cookie = CdlReference_Magic;
85
    CYGDBG_MEMLEAK_CONSTRUCTOR();
86
 
87
    CYG_POSTCONDITION_THISC();
88
    CYG_REPORT_RETURN();
89
}
90
 
91
// This constructor typically gets used when parsing a property.
92
// The object may be created either on the stack or in the heap,
93
// depending on the requirements of the property. During a later
94
// phase in the parsing process the object may get bound.
95
CdlReference::CdlReference(const std::string dest_arg)
96
{
97
    CYG_REPORT_FUNCNAME("CdlReference:: constructor");
98
    CYG_REPORT_FUNCARG1("this %p", this);
99
 
100
    dest_name           = dest_arg;
101
    dest                = 0;
102
    cdlreference_cookie = CdlReference_Magic;
103
    CYGDBG_MEMLEAK_CONSTRUCTOR();
104
 
105
    CYG_POSTCONDITION_THISC();
106
    CYG_REPORT_RETURN();
107
}
108
 
109
// For some properties, notably LocalReference ones, it is convenient
110
// to create a temporary reference object on the stack and then
111
// derive the property from the temporary. This requires the
112
// copy constructor. When this operation is used the object
113
// should still be unbound.
114
CdlReference::CdlReference(const CdlReference& orig)
115
{
116
    CYG_REPORT_FUNCNAME("CdlReference:: copy constructor");
117
    CYG_REPORT_FUNCARG2("this %p, orig %p", this, &orig);
118
    CYG_INVARIANT_CLASSC(CdlReference, orig);
119
    CYG_PRECONDITIONC(0 == orig.dest);
120
 
121
    dest_name           = orig.dest_name;
122
    dest                = 0;
123
    cdlreference_cookie = CdlReference_Magic;
124
    CYGDBG_MEMLEAK_CONSTRUCTOR();
125
 
126
    CYG_POSTCONDITION_THISC();
127
    CYG_REPORT_RETURN();
128
}
129
 
130
// The assignment operator may be needed for similar reasons.
131
CdlReference&
132
CdlReference::operator=(const CdlReference& orig)
133
{
134
    CYG_REPORT_FUNCNAME("CdlReference:: assignment operator");
135
    CYG_REPORT_FUNCARG2("this %p, orig %p", this, &orig);
136
    CYG_INVARIANT_CLASSC(CdlReference, orig);
137
    CYG_PRECONDITIONC(0 == orig.dest);
138
 
139
    if (this != &orig) {
140
        dest_name               = orig.dest_name;
141
        dest                    = 0;
142
        cdlreference_cookie     = CdlReference_Magic;
143
    }
144
 
145
    CYG_POSTCONDITION_THISC();
146
    CYG_REPORT_RETURN();
147
    return *this;
148
}
149
 
150
// The destructor should only get invoked when a package is unloaded.
151
// All appropriate clean-ups should have happened already, in particular
152
// the reference should not currently be bound.
153
CdlReference::~CdlReference()
154
{
155
    CYG_REPORT_FUNCNAME("CdlReference:: destructor");
156
    CYG_REPORT_FUNCARG1("this %p", this);
157
    CYG_PRECONDITION_THISC();
158
    CYG_PRECONDITIONC(0 == dest);
159
 
160
    cdlreference_cookie = CdlReference_Invalid;
161
    dest_name           = "";
162
    CYGDBG_MEMLEAK_DESTRUCTOR();
163
 
164
    CYG_REPORT_RETURN();
165
}
166
 
167
// ----------------------------------------------------------------------------
168
// Accessing the fields.
169
 
170
void
171
CdlReference::set_destination_name(const std::string name)
172
{
173
    CYG_REPORT_FUNCNAME("CdlReference::set_destination_name");
174
    CYG_REPORT_FUNCARG1XV(this);
175
    CYG_PRECONDITION_THISC();
176
    CYG_PRECONDITIONC((0 == dest) && ("" == dest_name));
177
 
178
    dest_name = name;
179
 
180
    CYG_REPORT_RETURN();
181
}
182
 
183
const std::string&
184
CdlReference::get_destination_name(void) const
185
{
186
    CYG_REPORT_FUNCNAME("CdlReference::get_destination_name");
187
    CYG_REPORT_FUNCARG1("this %p", this);
188
    CYG_PRECONDITION_THISC();
189
 
190
    CYG_REPORT_RETURN();
191
    return dest_name;
192
}
193
 
194
CdlNode
195
CdlReference::get_destination() const
196
{
197
    CYG_REPORT_FUNCNAMETYPE("CdlReference::get_destination", "result %p");
198
    CYG_REPORT_FUNCARG1XV(this);
199
    CYG_PRECONDITION_THISC();
200
 
201
    CdlNode result = dest;
202
    CYG_REPORT_RETVAL(result);
203
    return result;
204
}
205
 
206
bool
207
CdlReference::check_this(cyg_assert_class_zeal zeal) const
208
{
209
    if (CdlReference_Magic != cdlreference_cookie) {
210
        return false;
211
    }
212
    CYGDBG_MEMLEAK_CHECKTHIS();
213
    switch(zeal) {
214
      case cyg_system_test:
215
      case cyg_extreme:
216
          // There is not enough information in the reference
217
          // object itself to allow for a check for a corresponding
218
          // referrer object. If more debugability is needed
219
          // then extra data will have to be stored.
220
          //
221
          // However, it is possible to do a basic check of dest itself.
222
          if (0 != dest) {
223
              if (!dest->check_this(cyg_quick)) {
224
                  return false;
225
              }
226
          }
227
      case cyg_thorough:
228
          if (0 != dest) {
229
              if (dest_name != dest->get_name()) {
230
                  return false;
231
              }
232
          }
233
      case cyg_quick:
234
      case cyg_trivial:
235
      case cyg_none   :
236
      default         :
237
          break;
238
    }
239
    return true;
240
}
241
 
242
// ----------------------------------------------------------------------------
243
// Binding. This is simply a case of filling in some fields in the reference
244
// object and pushing a new referrer object. Binding generally happens as
245
// a result of calling reference update handlers when a package gets loaded.
246
 
247
void
248
CdlReference::bind(CdlNode src_arg, CdlProperty src_prop_arg, CdlNode dest_arg)
249
{
250
    CYG_REPORT_FUNCNAME("CdlReference::bind");
251
    CYG_REPORT_FUNCARG4XV(this, src_arg, src_prop_arg, dest_arg);
252
    CYG_INVARIANT_THISC(CdlReference);
253
    CYG_PRECONDITION_CLASSC(src_arg);
254
    CYG_PRECONDITION_CLASSC(src_prop_arg);
255
    CYG_PRECONDITION_CLASSC(dest_arg);
256
 
257
    CYG_ASSERTC(dest_name == dest_arg->get_name());
258
 
259
    CdlReferrer local_copy;
260
    local_copy.source           = src_arg;
261
    local_copy.source_property  = src_prop_arg;
262
 
263
    dest_arg->referrers.push_back(local_copy);
264
    dest = dest_arg;
265
 
266
    CYG_REPORT_RETURN();
267
}
268
 
269
// Unbinding involves finding and removing the appropriate referrer object (there
270
// may be several, but each will result in a separate unbind() call.)
271
void
272
CdlReference::unbind(CdlNode src_arg, CdlProperty src_prop_arg)
273
{
274
    CYG_REPORT_FUNCNAME("CdlReference::unbind");
275
    CYG_REPORT_FUNCARG3XV(this, src_arg, src_prop_arg);
276
    CYG_PRECONDITION_THISC();
277
    CYG_PRECONDITION_CLASSC(src_arg);
278
    CYG_PRECONDITION_CLASSC(src_prop_arg);
279
 
280
    if (0 != dest) {
281
        std::vector<CdlReferrer>::iterator ref_i;
282
        for (ref_i = dest->referrers.begin(); ref_i != dest->referrers.end(); ref_i++) {
283
            if ((ref_i->source == src_arg) && (ref_i->source_property == src_prop_arg)) {
284
                dest->referrers.erase(ref_i);
285
                break;
286
            }
287
        }
288
    }
289
 
290
    dest = 0;
291
 
292
    CYG_REPORT_RETURN();
293
}
294
 
295
//}}}
296
//{{{  CdlReferrer class                
297
 
298
// ----------------------------------------------------------------------------
299
// The constructors etc. should only get invoked from
300
// CdlReference::bind() and unbind(). However because Referrer objects
301
// get held in  STL vectors/lists/whatever it is hard to know exactly
302
// what will happen when, so assertions are a bit thin on the ground.
303
 
304
CdlReferrer::CdlReferrer()
305
{
306
    CYG_REPORT_FUNCNAME("CdlReferrer:: default constructor");
307
    CYG_REPORT_FUNCARG1XV(this);
308
 
309
    source              = 0;
310
    source_property     = 0;
311
    cdlreferrer_cookie  = CdlReferrer_Magic;
312
    CYGDBG_MEMLEAK_CONSTRUCTOR();
313
 
314
    CYG_POSTCONDITION_THISC();
315
    CYG_REPORT_RETURN();
316
}
317
 
318
CdlReferrer::CdlReferrer(const CdlReferrer& original)
319
{
320
    CYG_REPORT_FUNCNAME("CdlReferrer:: copy constructor");
321
    CYG_REPORT_FUNCARG2XV(this, &original);
322
    CYG_PRECONDITION_CLASSOC(original);
323
 
324
    source              = original.source;
325
    source_property     = original.source_property;
326
    cdlreferrer_cookie  = CdlReferrer_Magic;
327
    CYGDBG_MEMLEAK_CONSTRUCTOR();
328
 
329
    CYG_POSTCONDITION_THISC();
330
    CYG_REPORT_RETURN();
331
}
332
 
333
CdlReferrer&
334
CdlReferrer::operator=(const CdlReferrer& original)
335
{
336
    CYG_REPORT_FUNCNAME("CdlReferrer:: assignment operator");
337
    CYG_REPORT_FUNCARG2XV(this, &original);
338
    CYG_PRECONDITION_CLASSOC(original);
339
 
340
    if (this != &original) {
341
        source                  = original.source;
342
        source_property         = original.source_property;
343
        cdlreferrer_cookie      = CdlReferrer_Magic;
344
    }
345
 
346
    CYG_POSTCONDITION_THISC();
347
    CYG_REPORT_RETURN();
348
    return *this;
349
}
350
 
351
CdlReferrer::~CdlReferrer()
352
{
353
    CYG_REPORT_FUNCNAME("CdlReferrer:: destructor");
354
    CYG_REPORT_FUNCARG1XV(this);
355
    CYG_PRECONDITION_THISC();
356
 
357
    cdlreferrer_cookie  = CdlReferrer_Magic;
358
    source              = 0;
359
    source_property     = 0;
360
    CYGDBG_MEMLEAK_DESTRUCTOR();
361
 
362
    CYG_REPORT_RETURN();
363
}
364
 
365
// ----------------------------------------------------------------------------
366
// This routine is the main reason for having reference and referrer
367
// objects around in the first place. It allows changes to an entity
368
// to be propagated back to anything else interested in the entity.
369
 
370
void
371
CdlReferrer::update(CdlTransaction transact, CdlNode dest_arg, CdlUpdate change)
372
{
373
    CYG_REPORT_FUNCNAME("CdlReferrer::update");
374
    CYG_REPORT_FUNCARG4XV(this, transact, dest_arg, change);
375
    CYG_PRECONDITION_THISC();
376
 
377
    source_property->update(transact, source, dest_arg, change);
378
 
379
    CYG_REPORT_RETURN();
380
}
381
 
382
CdlNode
383
CdlReferrer::get_source() const
384
{
385
    CYG_REPORT_FUNCNAMETYPE("CdlReferrer::get_source", "result %p");
386
    CYG_REPORT_FUNCARG1XV(this);
387
    CYG_PRECONDITION_THISC();
388
 
389
    CdlNode result = source;
390
    CYG_REPORT_RETVAL(result);
391
    return result;
392
}
393
 
394
CdlProperty
395
CdlReferrer::get_source_property() const
396
{
397
    CYG_REPORT_FUNCNAMETYPE("CdlReferrer::get_source_property", "result %p");
398
    CYG_REPORT_FUNCARG1XV(this);
399
    CYG_PRECONDITION_THISC();
400
 
401
    CdlProperty result = source_property;
402
    CYG_REPORT_RETVAL(result);
403
    return result;
404
}
405
 
406
bool
407
CdlReferrer::check_this(cyg_assert_class_zeal zeal) const
408
{
409
    if (CdlReferrer_Magic != cdlreferrer_cookie) {
410
        return false;
411
    }
412
    CYGDBG_MEMLEAK_CHECKTHIS();
413
    switch(zeal) {
414
      case cyg_system_test :
415
      case cyg_extreme:
416
      case cyg_thorough:
417
          if (0 != source) {
418
              if (!source->check_this(cyg_quick)) {
419
                  return false;
420
              }
421
          }
422
          if (0 != source_property) {
423
              if (!source_property->check_this(cyg_quick)) {
424
                  return false;
425
              }
426
          }
427
      case cyg_quick:
428
      case cyg_trivial:
429
      case cyg_none:
430
        break;
431
    }
432
    return true;
433
}
434
 
435
//}}}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.