]> git.kernelconcepts.de Git - karo-tx-redboot.git/blob - tools/src/libcdl/property.cxx
unified MX27, MX25, MX37 trees
[karo-tx-redboot.git] / tools / src / libcdl / property.cxx
1 //{{{  Banner                           
2
3 //============================================================================
4 //
5 //     property.cxx
6 //
7 //     Implementation of the CdlProperty class and derived classes.
8 //
9 //============================================================================
10 //####COPYRIGHTBEGIN####
11 //                                                                          
12 // ----------------------------------------------------------------------------
13 // Copyright (C) 2002 Bart Veer
14 // Copyright (C) 1999, 2000 Red Hat, Inc.
15 //
16 // This file is part of the eCos host tools.
17 //
18 // This program is free software; you can redistribute it and/or modify it 
19 // under the terms of the GNU General Public License as published by the Free 
20 // Software Foundation; either version 2 of the License, or (at your option) 
21 // any later version.
22 // 
23 // This program is distributed in the hope that it will be useful, but WITHOUT 
24 // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
25 // FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for 
26 // more details.
27 // 
28 // You should have received a copy of the GNU General Public License along with
29 // this program; if not, write to the Free Software Foundation, Inc., 
30 // 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
31 //
32 // ----------------------------------------------------------------------------
33 //                                                                          
34 //####COPYRIGHTEND####
35 //============================================================================
36 //#####DESCRIPTIONBEGIN####
37 //
38 // Author(s):   bartv
39 // Contact(s):  bartv
40 // Date:        1999/01/29
41 // Version:     0.02
42 // Description: The CdlProperty class is used to hold the bulk of the
43 //              actual data in a CDL script. The CdlOption and other
44 //              higher-level classes are essentially just named containers
45 //              of properties.
46 //
47 //####DESCRIPTIONEND####
48 //============================================================================
49
50 //}}}
51 //{{{  #include's                       
52
53 // ----------------------------------------------------------------------------
54 #include "cdlconfig.h"
55
56 // Get the infrastructure types, assertions, tracing and similar
57 // facilities.
58 #include <cyg/infra/cyg_ass.h>
59 #include <cyg/infra/cyg_trac.h>
60
61 // <cdl.hxx> defines everything implemented in this module.
62 // It implicitly supplies <string>, <vector> and <map> because
63 // the class definitions rely on these headers.
64 #include <cdlcore.hxx>
65
66 //}}}
67
68 //{{{  Statics                          
69
70 // ----------------------------------------------------------------------------
71 CYGDBG_DEFINE_MEMLEAK_COUNTER(CdlPropertyBody);
72 CYGDBG_DEFINE_MEMLEAK_COUNTER(CdlProperty_MinimalBody);
73 CYGDBG_DEFINE_MEMLEAK_COUNTER(CdlProperty_StringBody);
74 CYGDBG_DEFINE_MEMLEAK_COUNTER(CdlProperty_TclCodeBody);
75 CYGDBG_DEFINE_MEMLEAK_COUNTER(CdlProperty_ReferenceBody);
76 CYGDBG_DEFINE_MEMLEAK_COUNTER(CdlProperty_StringVectorBody);
77 CYGDBG_DEFINE_MEMLEAK_COUNTER(CdlProperty_ExpressionBody);
78 CYGDBG_DEFINE_MEMLEAK_COUNTER(CdlProperty_ListExpressionBody);
79 CYGDBG_DEFINE_MEMLEAK_COUNTER(CdlProperty_GoalExpressionBody);
80
81 //}}}
82 //{{{  CdlProperty base class           
83
84 // ----------------------------------------------------------------------------
85
86 CdlPropertyBody::CdlPropertyBody(CdlNode node, std::string name_arg, int argc, const char* argv_arg[],
87                                  std::vector<std::pair<std::string,std::string> >& options_arg)
88 {
89     CYG_REPORT_FUNCNAME("CdlProperty:: constructor");
90     CYG_REPORT_FUNCARG3XV(this, node, argc);
91     CYG_PRECONDITIONC(argc > 0);
92     CYG_PRECONDITION_CLASSC(node);
93
94     name = name_arg;
95     argv.push_back(CdlParse::get_tcl_cmd_name(argv_arg[0]));
96     for (int i = 1; i < argc; i++) {
97         argv.push_back(argv_arg[i]);
98     }
99     options = options_arg;
100     node->properties.push_back(this);
101     cdlpropertybody_cookie = CdlPropertyBody_Magic;
102     CYGDBG_MEMLEAK_CONSTRUCTOR();
103     
104     CYG_POSTCONDITION_THISC();
105     CYG_REPORT_RETURN();
106 }
107
108 CdlPropertyBody::~CdlPropertyBody()
109 {
110     CYG_REPORT_FUNCNAME("CdlProperty:: destructor");
111     CYG_REPORT_FUNCARG1("this %p", this);
112     CYG_PRECONDITION_THISC();
113     
114     cdlpropertybody_cookie      = CdlPropertyBody_Invalid;
115     name                        = "";
116     argv.clear();
117     CYGDBG_MEMLEAK_DESTRUCTOR();
118     
119     CYG_REPORT_RETURN();
120 }
121
122 std::string
123 CdlPropertyBody::get_property_name(void) const
124 {
125     CYG_REPORT_FUNCNAME("CdlProperty::get_property_id");
126     CYG_REPORT_FUNCARG1("this %p", this);
127     CYG_PRECONDITION_THISC();
128
129     CYG_REPORT_RETURN();
130     return name;
131 }
132
133 int
134 CdlPropertyBody::get_argc(void) const
135 {
136     CYG_REPORT_FUNCNAMETYPE("CdlProperty::get_argc", "argc %d");
137     CYG_REPORT_FUNCARG1("this %p", this);
138     CYG_PRECONDITION_THISC();
139
140     int result = argv.size();
141     CYG_REPORT_RETVAL(result);
142     return result;
143 }
144
145 const std::vector<std::string>&
146 CdlPropertyBody::get_argv(void) const
147 {
148     CYG_REPORT_FUNCNAME("CdlProperty::get_argv");
149     CYG_REPORT_FUNCARG1("this %p", this);
150     CYG_PRECONDITION_THISC();
151     CYG_REPORT_RETURN();
152     return argv;
153 }
154
155 const std::vector<std::pair<std::string,std::string> >&
156 CdlPropertyBody::get_options() const
157 {
158     CYG_REPORT_FUNCNAME("CdlProperty::get_options");
159     CYG_REPORT_FUNCARG1XV(this);
160     CYG_PRECONDITION_THISC();
161     CYG_REPORT_RETURN();
162     return options;
163 }
164
165 bool
166 CdlPropertyBody::has_option(std::string name) const
167 {
168     CYG_REPORT_FUNCNAMETYPE("CdlProperty::has_option", "result %d");
169     CYG_REPORT_FUNCARG1XV(this);
170     CYG_PRECONDITION_THISC();
171
172     bool result = false;
173     std::vector<std::pair<std::string,std::string> >::const_iterator opt_i;
174     for (opt_i = options.begin(); opt_i != options.end(); opt_i++) {
175         if (name == opt_i->first) {
176             result = true;
177             break;
178         }
179     }
180
181     CYG_REPORT_RETVAL(result);
182     return result;
183 }
184
185 std::string
186 CdlPropertyBody::get_option(std::string name) const
187 {
188     CYG_REPORT_FUNCNAME("CdlProperty::get_option");
189     CYG_REPORT_FUNCARG1XV(this);
190     CYG_PRECONDITION_THISC();
191
192     std::string result = "";
193     std::vector<std::pair<std::string,std::string> >::const_iterator opt_i;
194     for (opt_i = options.begin(); opt_i != options.end(); opt_i++) {
195         if (name == opt_i->first) {
196             result = opt_i->second;
197             break;
198         }
199     }
200
201     CYG_REPORT_RETURN();
202     return result;
203 }
204
205 // ----------------------------------------------------------------------------
206 // Handling updates. This is a virtual function. The default
207 // implementation does nothing because not all properties contain
208 // references to other CDL entities.
209
210 void
211 CdlPropertyBody::update(CdlTransaction transact, CdlNode source, CdlNode dest, CdlUpdate change)
212 {
213     CYG_REPORT_FUNCNAME("CdlProperty::update");
214     CYG_REPORT_FUNCARG5XV(this, transact, source, dest, change);
215     CYG_PRECONDITION_THISC();
216
217     CYG_UNUSED_PARAM(CdlTransaction, transact);
218     CYG_UNUSED_PARAM(CdlNode, source);
219     CYG_UNUSED_PARAM(CdlNode, dest);
220     CYG_UNUSED_PARAM(CdlUpdate, change);
221     
222     CYG_REPORT_RETURN();
223 }
224
225 // ----------------------------------------------------------------------------
226 bool
227 CdlPropertyBody::check_this(cyg_assert_class_zeal zeal) const
228 {
229     if (CdlPropertyBody_Magic != cdlpropertybody_cookie) {
230         return false;
231     }
232     CYGDBG_MEMLEAK_CHECKTHIS();
233     CYG_UNUSED_PARAM(cyg_assert_class_zeal, zeal);
234     return true;
235 }
236
237 //}}}
238 //{{{  CdlProperty_Minimal class        
239
240 // ----------------------------------------------------------------------------
241
242 CdlProperty_Minimal
243 CdlProperty_MinimalBody::make(CdlNode node_arg, std::string name_arg, int argc_arg, const char* argv_arg[],
244                               std::vector<std::pair<std::string,std::string> >& options_arg)
245 {
246     return new CdlProperty_MinimalBody(node_arg, name_arg, argc_arg, argv_arg, options_arg);
247 }
248
249 CdlProperty_MinimalBody::CdlProperty_MinimalBody(CdlNode node_arg, std::string name_arg, int argc_arg, const char* argv_arg[],
250                                                  std::vector<std::pair<std::string,std::string> >& options_arg)
251     : inherited(node_arg, name_arg, argc_arg, argv_arg, options_arg)
252 {
253     CYG_REPORT_FUNCNAME("CdlProperty_Minimal:: constructor");
254     CYG_REPORT_FUNCARG1("this %p", this);
255
256     cdlproperty_minimalbody_cookie = CdlProperty_MinimalBody_Magic;
257     CYGDBG_MEMLEAK_CONSTRUCTOR();
258     
259     CYG_POSTCONDITION_THISC();
260     CYG_REPORT_RETURN();
261 }
262
263 CdlProperty_MinimalBody::~CdlProperty_MinimalBody()
264 {
265     CYG_REPORT_FUNCNAME("CdlProperty_Minimal:: destructor");
266     CYG_REPORT_FUNCARG1("this %p", this);
267     CYG_PRECONDITION_THISC();
268
269     cdlproperty_minimalbody_cookie = CdlProperty_MinimalBody_Invalid;
270     CYGDBG_MEMLEAK_DESTRUCTOR();
271     
272     CYG_REPORT_RETURN();
273 }
274
275 bool
276 CdlProperty_MinimalBody::check_this(cyg_assert_class_zeal zeal) const
277 {
278     if (CdlProperty_MinimalBody_Magic != cdlproperty_minimalbody_cookie) {
279         return false;
280     }
281     CYGDBG_MEMLEAK_CHECKTHIS();
282     return inherited::check_this(zeal);
283 }
284
285 //}}}
286 //{{{  CdlProperty_String class         
287
288 // ----------------------------------------------------------------------------
289
290 CdlProperty_String
291 CdlProperty_StringBody::make(CdlNode node_arg, std::string name_arg, std::string value_arg, int argc_arg, const char* argv_arg[],
292                              std::vector<std::pair<std::string,std::string> >& options_arg)
293 {
294     return new CdlProperty_StringBody(node_arg, name_arg, value_arg, argc_arg, argv_arg, options_arg);
295 }
296
297 CdlProperty_StringBody::CdlProperty_StringBody(CdlNode node_arg, std::string name_arg, std::string value_arg,
298                                                int argc_arg, const char* argv_arg[],
299                                                std::vector<std::pair<std::string,std::string> >& options_arg)
300     : inherited(node_arg, name_arg, argc_arg, argv_arg, options_arg)
301 {
302     CYG_REPORT_FUNCNAME("CdlProperty_String:: constructor");
303     CYG_REPORT_FUNCARG1("this %p", this);
304
305     data = value_arg;
306     cdlproperty_stringbody_cookie = CdlProperty_StringBody_Magic;
307     CYGDBG_MEMLEAK_CONSTRUCTOR();
308     
309     CYG_POSTCONDITION_THISC();
310     CYG_REPORT_RETURN();
311 }
312
313 CdlProperty_StringBody::~CdlProperty_StringBody()
314 {
315     CYG_REPORT_FUNCNAME("CdlProperty_String:: destructor");
316     CYG_REPORT_FUNCARG1("this %p", this);
317     CYG_PRECONDITION_THISC();
318
319     cdlproperty_stringbody_cookie = CdlProperty_StringBody_Invalid;
320     data = "";
321     CYGDBG_MEMLEAK_DESTRUCTOR();
322     
323     CYG_REPORT_RETURN();
324 }
325
326 std::string
327 CdlProperty_StringBody::get_string(void) const
328 {
329     CYG_REPORT_FUNCNAME("CdlProperty_String::get_string");
330     CYG_REPORT_FUNCARG1("this %p", this);
331     CYG_PRECONDITION_THISC();
332
333     CYG_REPORT_RETURN();
334     return data;
335 }
336
337 bool
338 CdlProperty_StringBody::check_this(cyg_assert_class_zeal zeal) const
339 {
340     if (CdlProperty_StringBody_Magic != cdlproperty_stringbody_cookie) {
341         return false;
342     }
343     CYGDBG_MEMLEAK_CHECKTHIS();
344     return inherited::check_this(zeal);
345 }
346
347 //}}}`
348 //{{{  CdlProperty_TclCode class        
349
350 // ----------------------------------------------------------------------------
351
352 CdlProperty_TclCode
353 CdlProperty_TclCodeBody::make(CdlNode node_arg, std::string name_arg, cdl_tcl_code code_arg,
354                               int argc_arg, const char* argv_arg[],
355                               std::vector<std::pair<std::string,std::string> >& options_arg)
356 {
357     return new CdlProperty_TclCodeBody(node_arg, name_arg, 0, code_arg, argc_arg, argv_arg, options_arg);
358 }
359
360 CdlProperty_TclCode
361 CdlProperty_TclCodeBody::make(CdlNode node_arg, std::string name_arg, cdl_int number_arg, cdl_tcl_code code_arg,
362                               int argc_arg, const char* argv_arg[],
363                               std::vector<std::pair<std::string,std::string> >& options_arg)                              
364 {
365     return new CdlProperty_TclCodeBody(node_arg, name_arg, number_arg, code_arg, argc_arg, argv_arg, options_arg);
366 }
367
368
369 CdlProperty_TclCodeBody::CdlProperty_TclCodeBody(CdlNode node_arg, std::string name_arg,
370                                                  cdl_int number_arg, cdl_tcl_code code_arg,
371                                                  int argc_arg, const char* argv_arg[],
372                                                  std::vector<std::pair<std::string,std::string> >& options_arg)
373     : inherited(node_arg, name_arg, argc_arg, argv_arg, options_arg)
374 {
375     CYG_REPORT_FUNCNAME("CdlProperty_TclCode:: constructor");
376     CYG_REPORT_FUNCARG2("this %p, number_arg %d", this, number_arg);
377
378     code   = code_arg;
379     number = number_arg;
380     cdlproperty_tclcodebody_cookie = CdlProperty_TclCodeBody_Magic;
381     CYGDBG_MEMLEAK_CONSTRUCTOR();
382     
383     CYG_POSTCONDITION_THISC();
384     CYG_REPORT_RETURN();
385 }
386
387 CdlProperty_TclCodeBody::~CdlProperty_TclCodeBody()
388 {
389     CYG_REPORT_FUNCNAME("CdlProperty_TclCode:: destructor");
390     CYG_REPORT_FUNCARG1("this %p", this);
391     CYG_PRECONDITION_THISC();
392
393     cdlproperty_tclcodebody_cookie = CdlProperty_TclCodeBody_Invalid;
394     code = cdl_tcl_code("");
395     CYGDBG_MEMLEAK_DESTRUCTOR();
396     
397     CYG_REPORT_RETURN();
398 }
399
400 const cdl_tcl_code&
401 CdlProperty_TclCodeBody::get_code(void) const
402 {
403     CYG_REPORT_FUNCNAME("CdlProperty_TclCode::get_code");
404     CYG_REPORT_FUNCARG1("this %p", this);
405     CYG_PRECONDITION_THISC();
406
407     CYG_REPORT_RETURN();
408     return code;
409 }
410
411 cdl_int
412 CdlProperty_TclCodeBody::get_number(void) const
413 {
414     CYG_REPORT_FUNCNAMETYPE("CdlProperty_TclCode::get_number", "result %d");
415     CYG_REPORT_FUNCARG1("this %p", this);
416     CYG_PRECONDITION_THISC();
417
418     cdl_int result = number;
419     CYG_REPORT_RETVAL(result);
420     return result;
421 }
422
423 bool
424 CdlProperty_TclCodeBody::check_this(cyg_assert_class_zeal zeal) const
425 {
426     if (CdlProperty_TclCodeBody_Magic != cdlproperty_tclcodebody_cookie) {
427         return false;
428     }
429     CYGDBG_MEMLEAK_CHECKTHIS();
430     return inherited::check_this(zeal);
431 }
432
433 //}}}
434 //{{{  CdlProperty_StringVector class   
435
436 // ----------------------------------------------------------------------------
437
438 CdlProperty_StringVector
439 CdlProperty_StringVectorBody::make(CdlNode node_arg, std::string name_arg, const std::vector<std::string>& data_arg,
440                                    int argc_arg, const char* argv_arg[],
441                                    std::vector<std::pair<std::string,std::string> >& options_arg)
442 {
443     return new CdlProperty_StringVectorBody(node_arg, name_arg, data_arg, argc_arg, argv_arg, options_arg);
444 }
445
446 CdlProperty_StringVectorBody::CdlProperty_StringVectorBody(CdlNode node_arg, std::string name_arg,
447                                                            const std::vector<std::string>& data_arg,
448                                                            int argc_arg, const char* argv_arg[],
449                                                            std::vector<std::pair<std::string,std::string> >& options_arg)
450     : inherited(node_arg, name_arg, argc_arg, argv_arg, options_arg)
451 {
452     CYG_REPORT_FUNCNAME("CdlProperty_StringVector:: constructor");
453     CYG_REPORT_FUNCARG1("this %p", this);
454     
455     data = data_arg;
456     cdlproperty_stringvectorbody_cookie = CdlProperty_StringVectorBody_Magic;
457     CYGDBG_MEMLEAK_CONSTRUCTOR();
458     
459     CYG_POSTCONDITION_THISC();
460     CYG_REPORT_RETURN();
461 }
462
463 CdlProperty_StringVectorBody::~CdlProperty_StringVectorBody()
464 {
465     CYG_REPORT_FUNCNAME("CdlProperty_StringVector:: destructor");
466     CYG_REPORT_FUNCARG1("this %p", this);
467     CYG_PRECONDITION_THISC();
468
469     cdlproperty_stringvectorbody_cookie = CdlProperty_StringVectorBody_Invalid;
470     data.clear();
471     CYGDBG_MEMLEAK_DESTRUCTOR();
472     
473     CYG_REPORT_RETURN();
474 }
475
476 std::string
477 CdlProperty_StringVectorBody::get_first_string(void) const
478 {
479     CYG_REPORT_FUNCNAME("CdlProperty_StringVector::get_first_string");
480     CYG_REPORT_FUNCARG1("this %p", this);
481     CYG_PRECONDITION_THISC();
482
483     std::string result;
484     if (0 == data.size()) {
485         result = "";
486     } else {
487         result = data[0];
488     }
489     CYG_REPORT_RETURN();
490     return result;
491 }
492
493 unsigned int
494 CdlProperty_StringVectorBody::get_number_of_strings() const
495 {
496     CYG_REPORT_FUNCNAMETYPE("CdlProperty_StringVector::get_number_of_strings", "result %d");
497     CYG_REPORT_FUNCARG1XV(this);
498     CYG_PRECONDITION_THISC();
499
500     unsigned int result = data.size();
501     CYG_REPORT_RETVAL(result);
502     return result;
503 }
504
505 std::string
506 CdlProperty_StringVectorBody::get_string(unsigned int index) const
507 {
508     CYG_REPORT_FUNCNAME("CdlProperty_StringVector::get_string");
509     CYG_REPORT_FUNCARG2XV(this, index);
510     CYG_PRECONDITION_THISC();
511     CYG_PRECONDITIONC(index < data.size());
512
513     std::string result = data[index];
514     CYG_REPORT_RETURN();
515     return result;
516 }
517
518 const std::vector<std::string>&
519 CdlProperty_StringVectorBody::get_strings(void) const
520 {
521     CYG_REPORT_FUNCNAME("CdlProperty_StringVector::get_strings");
522     CYG_REPORT_FUNCARG1("this %p", this);
523     CYG_PRECONDITION_THISC();
524
525     CYG_REPORT_RETURN();
526     return data;
527 }
528
529 bool
530 CdlProperty_StringVectorBody::check_this(cyg_assert_class_zeal zeal) const
531 {
532     if (CdlProperty_StringVectorBody_Magic != cdlproperty_stringvectorbody_cookie) {
533         return false;
534     }
535     CYGDBG_MEMLEAK_CHECKTHIS();
536     return inherited::check_this(zeal);
537 }
538
539 //}}}`
540 //{{{  CdlProperty_Reference class      
541
542 // ----------------------------------------------------------------------------
543 // This is pretty simple since most of the functionality is provided by the
544 // reference class.
545
546 CdlProperty_Reference
547 CdlProperty_ReferenceBody::make(CdlNode node_arg, std::string name_arg, std::string ref_arg, CdlUpdateHandler update_handler,
548                                 int argc_arg, const char* argv_arg[],
549                                 std::vector<std::pair<std::string,std::string> >& options_arg)
550 {
551     return new CdlProperty_ReferenceBody(node_arg, name_arg, ref_arg, update_handler, argc_arg, argv_arg, options_arg);
552 }
553
554 CdlProperty_ReferenceBody::CdlProperty_ReferenceBody(CdlNode node_arg, std::string name_arg, std::string ref_arg,
555                                                      CdlUpdateHandler update_handler_arg,
556                                                      int argc_arg, const char* argv_arg[],
557                                                      std::vector<std::pair<std::string,std::string> >& options_arg)
558     : CdlPropertyBody(node_arg, name_arg, argc_arg, argv_arg, options_arg),
559       CdlReference(ref_arg),
560       update_handler(update_handler_arg)
561 {
562     CYG_REPORT_FUNCNAME("CdlProperty_Reference:: constructor");
563     CYG_REPORT_FUNCARG1("this %p", this);
564
565     cdlproperty_referencebody_cookie = CdlProperty_ReferenceBody_Magic;
566     CYGDBG_MEMLEAK_CONSTRUCTOR();
567     
568     CYG_POSTCONDITION_THISC();
569     CYG_REPORT_RETURN();
570 }
571
572 CdlProperty_ReferenceBody::~CdlProperty_ReferenceBody()
573 {
574     CYG_REPORT_FUNCNAME("CdlProperty_Reference:: destructor");
575     CYG_REPORT_FUNCARG1("this %p", this);
576     CYG_PRECONDITION_THISC();
577
578     cdlproperty_referencebody_cookie = CdlProperty_ReferenceBody_Invalid;
579     CYGDBG_MEMLEAK_DESTRUCTOR();
580
581     CYG_REPORT_RETURN();
582 }
583
584 // ----------------------------------------------------------------------------
585 // Reference handling. It is useful at this level to cope with the
586 // four cases of Loaded, Unloaded, Created, and Destroyed. In addition
587 // the property-specific update handler needs to be invoked.
588
589 void
590 CdlProperty_ReferenceBody::update(CdlTransaction transact, CdlNode source, CdlNode dest, CdlUpdate change)
591 {
592     CYG_REPORT_FUNCNAME("CdlProperty_Reference::update");
593     CYG_REPORT_FUNCARG5XV(this, transact, source, dest, change);
594     CYG_PRECONDITION_THISC();
595
596     switch(change) {
597         
598       case CdlUpdate_Loaded :
599       {
600         // The source has just been loaded, try to resolve the reference.
601         // Note that e.g. the parent property allow for a reference to ""
602         // The necessary validation will have happened during parsing.
603         CYG_ASSERTC(0 == dest);
604         CdlToplevel toplevel = source->get_toplevel();
605         std::string dest_name = get_destination_name();
606         if ("" != dest_name) {
607             dest = toplevel->lookup(dest_name);
608             if (0 == dest) {
609                 CdlConflict_UnresolvedBody::make(transact, source, this, get_destination_name());
610             } else {
611                 bind(source, this, dest);
612             }
613         }
614         break;
615       }
616
617       case CdlUpdate_Unloading:
618       {
619         // The source is being unloaded. If the reference is currently bound,
620         // unbind it. There is no point in creating a new conflict object.
621         CYG_ASSERTC(0 == dest);
622         dest = get_destination();
623         if (0 != dest) {
624             unbind(source, this);
625         }
626         break;
627       }
628       
629       case CdlUpdate_Created:
630       {
631         // There is an existing conflict object, but the destination has
632         // just been created. The old conflict object should be eliminated,
633         // and the reference can now be bound.
634         CYG_ASSERT_CLASSC(dest);
635         
636         bind(source, this, dest);
637
638         CdlConflict conflict = transact->get_structural_conflict(source, this, &CdlConflict_UnresolvedBody::test);
639         CYG_ASSERTC(0 != conflict);
640         transact->clear_conflict(conflict);
641         break;
642       }
643       case CdlUpdate_Destroyed :
644       {
645         // The destination is about to be destroyed. Eliminate the existing
646         // binding and create a new conflict object.
647         CYG_ASSERT_CLASSC(dest);
648         unbind(source, this);
649         CdlConflict_UnresolvedBody::make(transact, source, this, get_destination_name());
650         break;
651       }
652
653       // Init, ValueChange and ActiveChange are of no interest.
654       default:
655         break;
656     }
657
658     (*update_handler)(transact, source, this, dest, change);
659     
660     CYG_REPORT_RETURN();
661 }
662
663 // ----------------------------------------------------------------------------
664 bool
665 CdlProperty_ReferenceBody::check_this(cyg_assert_class_zeal zeal) const
666 {
667     if (CdlProperty_ReferenceBody_Magic != cdlproperty_referencebody_cookie) {
668         return false;
669     }
670     CYGDBG_MEMLEAK_CHECKTHIS();
671     return inherited_property::check_this(zeal) && inherited_reference::check_this(zeal);
672 }
673
674 //}}}
675 //{{{  CdlProperty_Expression class     
676
677 // ----------------------------------------------------------------------------
678 // This is pretty simple since most of the functionality is provided by the
679 // base expression class.
680
681 CdlProperty_Expression
682 CdlProperty_ExpressionBody::make(CdlNode node_arg, std::string name_arg, CdlExpression expr_arg,
683                                  CdlUpdateHandler update_handler_arg,
684                                  int argc_arg, const char* argv_arg[],
685                                  std::vector<std::pair<std::string,std::string> >& options_arg)
686 {
687     return new CdlProperty_ExpressionBody(node_arg, name_arg, expr_arg, update_handler_arg, argc_arg, argv_arg, options_arg);
688 }
689
690 CdlProperty_ExpressionBody::CdlProperty_ExpressionBody(CdlNode node_arg, std::string name_arg, CdlExpression expr_arg,
691                                                        CdlUpdateHandler update_handler_arg,
692                                                        int argc_arg, const char* argv_arg[],
693                                                        std::vector<std::pair<std::string,std::string> >& options_arg)
694     : CdlPropertyBody(node_arg, name_arg, argc_arg, argv_arg, options_arg),
695       CdlExpressionBody(*expr_arg),
696       update_handler(update_handler_arg)
697 {
698     CYG_REPORT_FUNCNAME("CdlProperty_Expression:: constructor");
699     CYG_REPORT_FUNCARG1("this %p", this);
700     
701     cdlproperty_expressionbody_cookie = CdlProperty_ExpressionBody_Magic;
702     CYGDBG_MEMLEAK_CONSTRUCTOR();
703     
704     CYG_POSTCONDITION_THISC();
705     CYG_REPORT_RETURN();
706 }
707
708 CdlProperty_ExpressionBody::~CdlProperty_ExpressionBody()
709 {
710     CYG_REPORT_FUNCNAME("CdlProperty_Expression:: destructor");
711     CYG_REPORT_FUNCARG1("this %p", this);
712     CYG_PRECONDITION_THISC();
713
714     cdlproperty_expressionbody_cookie = CdlProperty_ExpressionBody_Invalid;
715     CYGDBG_MEMLEAK_DESTRUCTOR();
716
717     CYG_REPORT_RETURN();
718 }
719
720 void
721 CdlProperty_ExpressionBody::update(CdlTransaction transact, CdlNode source, CdlNode dest, CdlUpdate change)
722 {
723     CYG_REPORT_FUNCNAME("CdlProperty_Expression::update");
724     CYG_REPORT_FUNCARG5XV(this, transact, source, dest, change);
725     CYG_PRECONDITION_THISC();
726
727     // The CdlExpression update() member will take care of binding
728     // and unbinding, as needed.
729     if ((change & (CdlUpdate_Loaded | CdlUpdate_Unloading | CdlUpdate_Created | CdlUpdate_Destroyed)) != 0) {
730         (void) CdlExpressionBody::update(transact, source, this, dest, change);
731     }
732
733     // Now invoke the per-property update handler to re-evaluate the
734     // expression etc., as needed
735     (*update_handler)(transact, source, this, dest, change);
736     
737     CYG_REPORT_RETURN();
738 }
739
740 bool
741 CdlProperty_ExpressionBody::check_this(cyg_assert_class_zeal zeal) const
742 {
743     if (CdlProperty_ExpressionBody_Magic != cdlproperty_expressionbody_cookie) {
744         return false;
745     }
746     CYGDBG_MEMLEAK_CHECKTHIS();
747     return inherited_property::check_this(zeal) && inherited_expression::check_this(zeal);
748 }
749
750 //}}}
751 //{{{  CdlProperty_ListExpression class 
752
753 // ----------------------------------------------------------------------------
754 // This is pretty simple since most of the functionality is provided by the
755 // base expression class.
756
757 CdlProperty_ListExpression
758 CdlProperty_ListExpressionBody::make(CdlNode node_arg, std::string name_arg, CdlListExpression expr_arg,
759                                      CdlUpdateHandler update_handler_arg, 
760                                      int argc_arg, const char* argv_arg[],
761                                      std::vector<std::pair<std::string,std::string> >& options_arg)
762 {
763     return new CdlProperty_ListExpressionBody(node_arg, name_arg, expr_arg, update_handler_arg,
764                                               argc_arg, argv_arg, options_arg);
765 }
766
767 CdlProperty_ListExpressionBody::CdlProperty_ListExpressionBody(CdlNode node_arg, std::string name_arg,
768                                                                CdlListExpression expr_arg,
769                                                                CdlUpdateHandler update_handler_arg,
770                                                                int argc_arg, const char* argv_arg[],
771                                                                std::vector<std::pair<std::string,std::string> >& options_arg)
772     : CdlPropertyBody(node_arg, name_arg, argc_arg, argv_arg, options_arg),
773       CdlListExpressionBody(*expr_arg),
774       update_handler(update_handler_arg)
775 {
776     CYG_REPORT_FUNCNAME("CdlProperty_ListExpression:: constructor");
777     CYG_REPORT_FUNCARG1("this %p", this);
778     
779     cdlproperty_listexpressionbody_cookie = CdlProperty_ListExpressionBody_Magic;
780     CYGDBG_MEMLEAK_CONSTRUCTOR();
781     
782     CYG_POSTCONDITION_THISC();
783     CYG_REPORT_RETURN();
784 }
785
786 CdlProperty_ListExpressionBody::~CdlProperty_ListExpressionBody()
787 {
788     CYG_REPORT_FUNCNAME("CdlProperty_ListExpression:: destructor");
789     CYG_REPORT_FUNCARG1("this %p", this);
790     CYG_PRECONDITION_THISC();
791
792     cdlproperty_listexpressionbody_cookie = CdlProperty_ListExpressionBody_Invalid;
793     CYGDBG_MEMLEAK_DESTRUCTOR();
794
795     CYG_REPORT_RETURN();
796 }
797
798 void
799 CdlProperty_ListExpressionBody::update(CdlTransaction transact, CdlNode source, CdlNode dest, CdlUpdate change)
800 {
801     CYG_REPORT_FUNCNAME("CdlProperty_ListExpression::update");
802     CYG_REPORT_FUNCARG4XV(this, source, dest, change);
803     CYG_PRECONDITION_THISC();
804
805     if ((change & (CdlUpdate_Loaded | CdlUpdate_Unloading | CdlUpdate_Created | CdlUpdate_Destroyed)) != 0) {
806         bool handled = CdlListExpressionBody::update(transact, source, this, dest, change);
807         CYG_UNUSED_PARAM(bool, handled);
808         CYG_ASSERTC(handled);
809     }
810
811     // Now invoke the per-property update handler to re-evaluate
812     // the lexpr as appropriate.
813     (*update_handler)(transact, source, this, dest, change);
814     
815     CYG_REPORT_RETURN();
816 }
817
818 bool
819 CdlProperty_ListExpressionBody::check_this(cyg_assert_class_zeal zeal) const
820 {
821     if (CdlProperty_ListExpressionBody_Magic != cdlproperty_listexpressionbody_cookie) {
822         return false;
823     }
824     CYGDBG_MEMLEAK_CHECKTHIS();
825     return inherited_property::check_this(zeal) && inherited_expression::check_this(zeal);
826 }
827
828 //}}}
829 //{{{  CdlProperty_GoalExpression class 
830
831 // ----------------------------------------------------------------------------
832 // This is pretty simple since most of the functionality is provided by the
833 // base expression class.
834
835 CdlProperty_GoalExpression
836 CdlProperty_GoalExpressionBody::make(CdlNode node_arg, std::string name_arg, CdlGoalExpression expr_arg,
837                                      CdlUpdateHandler update_handler_arg,
838                                      int argc_arg, const char* argv_arg[],
839                                      std::vector<std::pair<std::string,std::string> >& options_arg)
840 {
841     return new CdlProperty_GoalExpressionBody(node_arg, name_arg, expr_arg, update_handler_arg,
842                                               argc_arg, argv_arg, options_arg);
843 }
844
845 CdlProperty_GoalExpressionBody::CdlProperty_GoalExpressionBody(CdlNode node_arg, std::string name_arg,
846                                                                CdlGoalExpression expr_arg,
847                                                                CdlUpdateHandler update_handler_arg,
848                                                                int argc_arg, const char* argv_arg[],
849                                                                std::vector<std::pair<std::string,std::string> >& options_arg)
850     : CdlPropertyBody(node_arg, name_arg, argc_arg, argv_arg, options_arg),
851       CdlGoalExpressionBody(*expr_arg),
852       update_handler(update_handler_arg)
853 {
854     CYG_REPORT_FUNCNAME("CdlProperty_GoalExpression:: constructor");
855     CYG_REPORT_FUNCARG1("this %p", this);
856     
857     cdlproperty_goalexpressionbody_cookie = CdlProperty_GoalExpressionBody_Magic;
858     CYGDBG_MEMLEAK_CONSTRUCTOR();
859     
860     CYG_POSTCONDITION_THISC();
861     CYG_REPORT_RETURN();
862 }
863
864 CdlProperty_GoalExpressionBody::~CdlProperty_GoalExpressionBody()
865 {
866     CYG_REPORT_FUNCNAME("CdlProperty_GoalExpression:: destructor");
867     CYG_REPORT_FUNCARG1("this %p", this);
868     CYG_PRECONDITION_THISC();
869
870     cdlproperty_goalexpressionbody_cookie = CdlProperty_GoalExpressionBody_Invalid;
871     CYGDBG_MEMLEAK_DESTRUCTOR();
872
873     CYG_REPORT_RETURN();
874 }
875
876 void
877 CdlProperty_GoalExpressionBody::update(CdlTransaction transact, CdlNode source, CdlNode dest, CdlUpdate change)
878 {
879     CYG_REPORT_FUNCNAME("CdlProperty_GoalExpression::update");
880     CYG_REPORT_FUNCARG4XV(this, source, dest, change);
881     CYG_PRECONDITION_THISC();
882
883     // The CdlExpression update() member will take care of binding and
884     // unbinding, as needed.
885     if ((change & (CdlUpdate_Loaded | CdlUpdate_Unloading | CdlUpdate_Created | CdlUpdate_Destroyed)) != 0) {
886         CdlExpression expr = get_expression();
887         bool handled = expr->update(transact, source, this, dest, change);
888         CYG_UNUSED_PARAM(bool, handled);
889         CYG_ASSERTC(handled);
890     }
891
892     // Now invoke the per-property update handler to re-evaluate
893     // the gexpr as appropriate
894     (*update_handler)(transact, source, this, dest, change);
895     
896     CYG_REPORT_RETURN();
897 }
898
899 bool
900 CdlProperty_GoalExpressionBody::check_this(cyg_assert_class_zeal zeal) const
901 {
902     if (CdlProperty_GoalExpressionBody_Magic != cdlproperty_goalexpressionbody_cookie) {
903         return false;
904     }
905     CYGDBG_MEMLEAK_CHECKTHIS();
906     return inherited_property::check_this(zeal) && inherited_expression::check_this(zeal);
907 }
908
909 //}}}