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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [ecos-3.0/] [host/] [libcdl/] [refer.cxx] - Blame information for rev 790

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

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

powered by: WebSVN 2.1.0

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