3 //============================================================================
7 // The CdlConflict class
9 //============================================================================
10 //####COPYRIGHTBEGIN####
12 // ----------------------------------------------------------------------------
13 // Copyright (C) 1999, 2000 Red Hat, Inc.
15 // This file is part of the eCos host tools.
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)
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
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.
31 // ----------------------------------------------------------------------------
33 //####COPYRIGHTEND####
34 //============================================================================
35 //#####DESCRIPTIONBEGIN####
42 //####DESCRIPTIONEND####
43 //============================================================================
48 // ----------------------------------------------------------------------------
49 #include "cdlconfig.h"
51 // Get the infrastructure types, assertions, tracing and similar
53 #include <cyg/infra/cyg_ass.h>
54 #include <cyg/infra/cyg_trac.h>
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. It also brings
60 #include <cdlcore.hxx>
66 // ----------------------------------------------------------------------------
67 CYGDBG_DEFINE_MEMLEAK_COUNTER(CdlConflictBody);
68 CYGDBG_DEFINE_MEMLEAK_COUNTER(CdlConflict_UnresolvedBody);
69 CYGDBG_DEFINE_MEMLEAK_COUNTER(CdlConflict_IllegalValueBody);
70 CYGDBG_DEFINE_MEMLEAK_COUNTER(CdlConflict_EvalExceptionBody);
71 CYGDBG_DEFINE_MEMLEAK_COUNTER(CdlConflict_RequiresBody);
72 CYGDBG_DEFINE_MEMLEAK_COUNTER(CdlConflict_DataBody);
77 //{{{ Creation and destruction
79 // ----------------------------------------------------------------------------
80 // The basic conflicts. Conflicts are created in the context of a transaction.
81 // If the transaction gets committed then they are transferred to a toplevel.
82 // If the transaction gets cancelled then they just disappear.
84 // A conflict that is only part of a transaction may go away as that
85 // transaction proceeds, in which case it can be deleted immediately.
86 // A conflict that is already part of the toplevel cannot be
87 // destroyed, instead it gets marked in the transaction object. Only
88 // when the transaction is committed does the object get deleted.
89 // In addition within the context of a transaction old conflicts
90 // may hang around for a while.
93 CdlConflictBody::CdlConflictBody(CdlTransaction trans_arg, CdlNode node_arg, CdlProperty property_arg, bool structural_arg)
95 CYG_REPORT_FUNCNAME("CdlConflict:: constructor");
96 CYG_REPORT_FUNCARG4XV(this, trans_arg, node_arg, property_arg);
97 CYG_PRECONDITION_CLASSC(trans_arg);
98 CYG_PRECONDITION_CLASSC(node_arg);
99 CYG_PRECONDITION_CLASSC(property_arg);
102 property = property_arg;
103 transaction = trans_arg;
104 structural = structural_arg;
106 // The vectors take care of themselves
110 transaction->dirty = true;
111 if (structural_arg) {
112 transaction->new_structural_conflicts.push_back(this);
114 transaction->new_conflicts.push_back(this);
117 cdlconflictbody_cookie = CdlConflictBody_Magic;
118 CYGDBG_MEMLEAK_CONSTRUCTOR();
120 CYG_POSTCONDITION_THISC();
125 // ----------------------------------------------------------------------------
126 // The destructor can get invoked during a transaction commit, in the
127 // case of a global conflict, or from inside clear() for a per-transaction
128 // conflict. In all cases the calling code is responsible for removing
129 // the conflict from any STL containers.
131 CdlConflictBody::~CdlConflictBody()
133 CYG_REPORT_FUNCNAME("CdlConflict:: destructor");
134 CYG_REPORT_FUNCARG1XV(this);
135 CYG_PRECONDITION_THISC();
137 cdlconflictbody_cookie = CdlConflictBody_Invalid;
142 solution_references.clear();
147 CYGDBG_MEMLEAK_DESTRUCTOR();
153 //{{{ Solution support
155 // ----------------------------------------------------------------------------
157 CdlConflictBody::has_known_solution() const
159 CYG_REPORT_FUNCNAMETYPE("CdlConflict::has_solution", "result %d");
160 CYG_REPORT_FUNCARG1XV(this);
161 CYG_PRECONDITION_THISC();
163 bool result = (0 != solution.size());
165 CYG_REPORT_RETVAL(result);
170 CdlConflictBody::has_no_solution() const
172 CYG_REPORT_FUNCNAMETYPE("CdlConflict::has_no_solution", "result %d");
173 CYG_REPORT_FUNCARG1XV(this);
174 CYG_PRECONDITION_THISC();
176 bool result = no_solution;
178 CYG_REPORT_RETVAL(result);
182 const std::vector<std::pair<CdlValuable, CdlValue> >&
183 CdlConflictBody::get_solution() const
185 CYG_REPORT_FUNCNAME("CdlConflict::get_solution");
186 CYG_REPORT_FUNCARG1XV(this);
187 CYG_PRECONDITION_THISC();
193 const std::set<CdlValuable>&
194 CdlConflictBody::get_solution_references() const
196 CYG_REPORT_FUNCNAME("CdlConflict::get_solution_references");
197 CYG_REPORT_FUNCARG1XV(this);
198 CYG_PRECONDITION_THISC();
201 return solution_references;
204 // ----------------------------------------------------------------------------
205 // Try to resolve a conflict. If the conflict was created in a transaction,
206 // use that transaction. More commonly the conflict will be global and
207 // a new transaction will have to be created specially for it. Either
208 // way the conflict may cease to exist.
210 CdlConflictBody::resolve()
212 CYG_REPORT_FUNCNAME("CdlConflict::resolve");
213 CYG_REPORT_FUNCARG1XV(this);
214 CYG_PRECONDITION_THISC();
215 CYG_PRECONDITIONC(0 == transaction);
217 if (this->resolution_implemented()) {
218 CdlTransaction transact = CdlTransactionBody::make(this->get_node()->get_toplevel());
219 transact->resolve(this);
227 // ----------------------------------------------------------------------------
228 // A valuable has just been changed. If this value was relevant to the
229 // current solution (or lack thereof) then an update is necessary.
231 CdlConflictBody::update_solution_validity(CdlValuable valuable)
233 CYG_REPORT_FUNCNAME("CdlConflict::update_solution_validity");
234 CYG_REPORT_FUNCARG2XV(this, valuable);
235 CYG_PRECONDITION_THISC();
237 if (solution_references.find(valuable) != solution_references.end()) {
240 solution_references.clear();
246 // ----------------------------------------------------------------------------
247 // Default implementations of the inference engine do not do a lot...
249 CdlConflictBody::inner_resolve(CdlTransaction trans_arg, int level)
251 CYG_REPORT_FUNCNAMETYPE("CdlConflict::inner_resolve", "result false");
252 CYG_REPORT_FUNCARG3XV(this, trans_arg, level);
253 CYG_PRECONDITION_THISC();
254 CYG_PRECONDITION_CLASSC(trans_arg);
256 // Setting the no_solution flag while keeping a clear
257 // solution_accessed vector means that the no_solution flag should
258 // always remain set, and hence no further inference attempts will be made.
266 CdlConflictBody::resolution_implemented() const
268 CYG_REPORT_FUNCNAMETYPE("CdlConflict::resolution_implemented", "result %d");
269 CYG_REPORT_FUNCARG1XV(this);
270 CYG_PRECONDITION_THISC();
272 CYG_REPORT_RETVAL(false);
276 // ----------------------------------------------------------------------------
277 // Clearing a solution. This is needed if the inference engine has
278 // failed to find a complete solution, because in attempting this the
279 // solution_references vector will have been filled in anyway. It may
280 // have some other uses as well.
282 CdlConflictBody::clear_solution()
284 CYG_REPORT_FUNCNAME("CdlConflict::clear_solution");
285 CYG_REPORT_FUNCARG1XV(this);
286 CYG_PRECONDITION_THISC();
290 solution_references.clear();
298 // ----------------------------------------------------------------------------
301 CdlConflictBody::get_node() const
303 CYG_REPORT_FUNCNAMETYPE("CdlConflict::get_node", "result %p");
304 CYG_REPORT_FUNCARG1XV(this);
305 CYG_PRECONDITION_THISC();
307 CdlNode result = node;
308 CYG_REPORT_RETVAL(result);
313 CdlConflictBody::get_property() const
315 CYG_REPORT_FUNCNAMETYPE("CdlConflict::get_property", "result %p");
316 CYG_REPORT_FUNCARG1XV(this);
317 CYG_PRECONDITION_THISC();
319 CdlProperty result = property;
320 CYG_REPORT_RETVAL(result);
325 CdlConflictBody::is_structural() const
327 CYG_REPORT_FUNCNAMETYPE("CdlConflict::is_structural", "result %d");
328 CYG_REPORT_FUNCARG1XV(this);
329 CYG_PRECONDITION_THISC();
331 bool result = structural;
332 CYG_REPORT_RETVAL(result);
337 CdlConflictBody::get_transaction() const
339 CYG_REPORT_FUNCNAMETYPE("CdlConflict::get_transaction", "result %p");
340 CYG_REPORT_FUNCARG1XV(this);
341 CYG_PRECONDITION_THISC();
343 CdlTransaction result = transaction;
344 CYG_REPORT_RETVAL(result);
348 // FIXME: these are not currently implemented. It would be necessary
349 // to store the information in the savefile, which requires an
350 // unambiguous way of identifying a conflict that is likely to
351 // survice package version changes.
354 CdlConflictBody::is_enabled() const
356 CYG_REPORT_FUNCNAMETYPE("CdlConflict::is_enabled", "result %d");
357 CYG_REPORT_FUNCARG1XV(this);
358 CYG_PRECONDITION_THISC();
360 bool result = enabled;
361 CYG_REPORT_RETVAL(result);
366 CdlConflictBody::get_disabled_reason() const
368 CYG_REPORT_FUNCNAME("CdlConflict::get_disabled_reason");
369 CYG_REPORT_FUNCARG1XV(this);
370 CYG_PRECONDITION_THISC();
372 // Possibly there should be a check that the conflict is currently
373 // disabled, but it might be useful.
379 CdlConflictBody::disable(std::string reason_arg)
381 CYG_REPORT_FUNCNAME("CdlConflict::disable");
382 CYG_REPORT_FUNCARG1XV(this);
383 CYG_PRECONDITION_THISC();
392 CdlConflictBody::enable()
394 CYG_REPORT_FUNCNAME("CdlConflict::enable");
395 CYG_REPORT_FUNCARG1XV(this);
396 CYG_PRECONDITION_THISC();
399 // Leave "reason" alone, it may still be useful
407 // ----------------------------------------------------------------------------
409 CdlConflictBody::check_this(cyg_assert_class_zeal zeal) const
411 if (CdlConflictBody_Magic != cdlconflictbody_cookie) {
414 CYGDBG_MEMLEAK_CHECKTHIS();
415 if ((0 == node) || (0 == property)) {
419 case cyg_system_test :
422 if (!node->check_this(cyg_quick)) {
425 // Accessing the properties would involve a function call.
427 if (0 != transaction) {
428 if (!transaction->check_this(cyg_quick)) {
432 // The conflict should exist in the new_structural_conflicts vector
433 // deleted_structural_conflicts is for toplevel ones.
434 if (std::find(transaction->new_structural_conflicts.begin(),
435 transaction->new_structural_conflicts.end(), this) ==
436 transaction->new_structural_conflicts.end()) {
440 // The conflict may appear on the new_conflicts list
441 // or in the resolved_conflicts vector.
442 if (std::find(transaction->new_conflicts.begin(), transaction->new_conflicts.end(), this) ==
443 transaction->new_conflicts.end()) {
445 if (std::find(transaction->resolved_conflicts.begin(), transaction->resolved_conflicts.end(), this) ==
446 transaction->resolved_conflicts.end()) {
453 // Checking the toplevel lists would be good, but involves a
454 // further function call and hence nested assertions.
458 if (!node->check_this(cyg_quick)) {
461 if (!property->check_this(cyg_quick)) {
467 if (no_solution && (0 != solution.size())) {
483 //{{{ CdlConflict_Unresolved
485 // ----------------------------------------------------------------------------
486 // Unresolved references. Usually unresolved references occur inside
487 // expressions, but other properties that may be affected are parent,
488 // dialog and wizard.
490 // It is possible for a single expression to have multiple unresolved
491 // references, each of which will result in a separate conflict
492 // object. It is also possible for an expression to refer to the same
493 // unknown entity twice or more, in which case there would also be
494 // separate conflict objects. Unresolved references may also result in
495 // eval exceptions and in failed requires statements. Trying to cope
496 // with the various combinations as a single conflict seems too
500 CdlConflict_UnresolvedBody::make(CdlTransaction trans, CdlNode node_arg, CdlProperty prop_arg, std::string name_arg)
502 CdlConflict_Unresolved tmp = new CdlConflict_UnresolvedBody(trans, node_arg, prop_arg, name_arg);
503 CYG_UNUSED_PARAM(CdlConflict_Unresolved, tmp);
506 CdlConflict_UnresolvedBody::CdlConflict_UnresolvedBody(CdlTransaction trans_arg, CdlNode node_arg, CdlProperty prop_arg,
507 std::string target_name_arg)
508 : CdlConflictBody(trans_arg, node_arg, prop_arg, true)
510 CYG_REPORT_FUNCNAME("CdlConflict_Unresolved:: constructor");
511 CYG_REPORT_FUNCARG1XV(this);
512 CYG_PRECONDITIONC("" != target_name_arg);
514 target_name = target_name_arg;
515 cdlconflict_unresolvedbody_cookie = CdlConflict_UnresolvedBody_Magic;
516 CYGDBG_MEMLEAK_CONSTRUCTOR();
518 CYG_POSTCONDITION_THISC();
522 CdlConflict_UnresolvedBody::~CdlConflict_UnresolvedBody()
524 CYG_REPORT_FUNCNAME("CdlConflict_Unresolved:: destructor");
525 CYG_REPORT_FUNCARG1XV(this);
526 CYG_PRECONDITION_THISC();
528 cdlconflict_unresolvedbody_cookie = CdlConflict_UnresolvedBody_Invalid;
530 CYGDBG_MEMLEAK_DESTRUCTOR();
536 CdlConflict_UnresolvedBody::get_target_name() const
538 CYG_REPORT_FUNCNAME("CdlConflict_Unresolved::get_target_name");
539 CYG_REPORT_FUNCARG1XV(this);
540 CYG_PRECONDITION_THISC();
546 // For now, just report the node and property name, a brief text, and the
547 // entity being referenced.
549 // Eventually we can do clever things like looking up the name in a
553 CdlConflict_UnresolvedBody::get_explanation() const
555 CYG_REPORT_FUNCNAME("CdlConflict_Unresolved::get_explanation");
556 CYG_REPORT_FUNCARG1XV(this);
557 CYG_PRECONDITION_THISC();
560 result = node->get_name() + ", property " + property->get_property_name() +
561 ":\nReference to unknown object " + target_name;
568 CdlConflict_UnresolvedBody::check_this(cyg_assert_class_zeal zeal) const
570 if (CdlConflict_UnresolvedBody_Magic != cdlconflict_unresolvedbody_cookie) {
573 CYGDBG_MEMLEAK_CHECKTHIS();
575 // There is not a lot of checking that can be done on the name.
577 return CdlConflictBody::check_this(zeal);
581 CdlConflict_UnresolvedBody::test(CdlConflict conf)
583 CYG_REPORT_FUNCNAMETYPE("CdlConflict_Unresolved::test", "result %d");
584 CYG_REPORT_FUNCARG1XV(conf);
585 CYG_PRECONDITION_CLASSC(conf);
588 CdlConflict_Unresolved tmp = dynamic_cast<CdlConflict_Unresolved>(conf);
593 CYG_REPORT_RETVAL(result);
598 //{{{ CdlConflict_IllegalValue
600 // ----------------------------------------------------------------------------
601 // A valuable object has an illegal value. This can happen because the
602 // current value is not within the legal_values list, or because of a
603 // failure of check_proc or entry_proc. In the latter two cases the
604 // Tcl code should supply an explanation as to why the value is illegal.
606 // Note: if future variants of CDL implement some concept of a value
607 // that does not match the CdlValuable class then that will need a
608 // separate CdlConflict derived class.
611 CdlConflict_IllegalValueBody::make(CdlTransaction trans, CdlNode node_arg, CdlProperty prop_arg)
613 CdlConflict_IllegalValue tmp = new CdlConflict_IllegalValueBody(trans, node_arg, prop_arg);
614 CYG_UNUSED_PARAM(CdlConflict_IllegalValue, tmp);
617 CdlConflict_IllegalValueBody::CdlConflict_IllegalValueBody(CdlTransaction trans, CdlNode node_arg, CdlProperty prop_arg)
618 : CdlConflictBody(trans, node_arg, prop_arg, false)
620 CYG_REPORT_FUNCNAME("CdlConflict_IllegalValue:: constructor");
621 CYG_REPORT_FUNCARG1XV(this);
622 CYG_PRECONDITIONC(0 != dynamic_cast<CdlValuable>(node_arg));
625 cdlconflict_illegalvaluebody_cookie = CdlConflict_IllegalValueBody_Magic;
626 CYGDBG_MEMLEAK_CONSTRUCTOR();
628 CYG_POSTCONDITION_THISC();
632 CdlConflict_IllegalValueBody::~CdlConflict_IllegalValueBody()
634 CYG_REPORT_FUNCNAME("CdlConflict_IllegalValue:: destructor");
635 CYG_REPORT_FUNCARG1XV(this);
636 CYG_PRECONDITION_THISC();
638 cdlconflict_illegalvaluebody_cookie = CdlConflict_IllegalValueBody_Invalid;
640 CYGDBG_MEMLEAK_DESTRUCTOR();
645 // ----------------------------------------------------------------------------
646 // If the property is legal_values then it should be a list expression
647 // property. Display the current value and the original expression.
649 // If the property is check_proc or entry_proc, the Tcl code should
650 // have produced an explanation string and stored it in the conflict
653 CdlConflict_IllegalValueBody::get_explanation() const
655 CYG_REPORT_FUNCNAME("CdlConflict_IllegalValue::get_explanation()");
656 CYG_REPORT_FUNCARG1XV(this);
657 CYG_PRECONDITION_THISC();
659 CdlConstValuable valuable = dynamic_cast<CdlConstValuable>(node);
660 CYG_ASSERTC(0 != valuable);
662 std::string result = "";
664 // FIXME: analyse the current value and flavor a bit more
665 result += "Illegal current value " + valuable->get_value() + "\n";
667 if (CdlPropertyId_LegalValues == property->get_property_name()) {
669 CdlConstProperty_ListExpression expr = dynamic_cast<CdlConstProperty_ListExpression>(property);
670 CYG_ASSERTC(0 != expr);
671 result += "Legal values are: " + expr->get_original_string();
673 } else if (explanation != "") {
675 result += explanation;
678 CYG_FAIL("Inexplicable illegal value");
686 CdlConflict_IllegalValueBody::set_explanation(std::string explanation_arg)
688 CYG_REPORT_FUNCNAME("CdlConflict_IllegalValue::set_explanation");
689 CYG_REPORT_FUNCARG1XV(this);
690 CYG_PRECONDITION_THISC();
692 explanation = explanation_arg;
697 // ----------------------------------------------------------------------------
698 // Inference is implemented. The actual inference code is in infer.cxx
700 CdlConflict_IllegalValueBody::resolution_implemented() const
702 CYG_REPORT_FUNCNAME("CdlConflict_IllegalValue::resolution_implemented");
703 CYG_REPORT_FUNCARG1XV(this);
704 CYG_PRECONDITION_THISC();
710 // ----------------------------------------------------------------------------
712 CdlConflict_IllegalValueBody::check_this(cyg_assert_class_zeal zeal) const
714 if (CdlConflict_IllegalValueBody_Magic != cdlconflict_illegalvaluebody_cookie) {
717 CYGDBG_MEMLEAK_CHECKTHIS();
719 return CdlConflictBody::check_this(zeal);
723 CdlConflict_IllegalValueBody::test(CdlConflict conf)
725 CYG_REPORT_FUNCNAMETYPE("CdlConflict_IllegalValue::test", "result %d");
726 CYG_REPORT_FUNCARG1XV(conf);
727 CYG_PRECONDITION_CLASSC(conf);
730 CdlConflict_IllegalValue tmp = dynamic_cast<CdlConflict_IllegalValue>(conf);
735 CYG_REPORT_RETVAL(result);
740 //{{{ CdlConflict_EvalException
742 // ----------------------------------------------------------------------------
743 // Run-time expression failures are possible because of division by
744 // zero, if for no other reason. The evaluation code should have
745 // stored a suitable diagnostic with the conflict. This is not part
746 // of the constructor, allowing the conflict object to be re-used
747 // if the detailed reason changes
750 CdlConflict_EvalExceptionBody::make(CdlTransaction trans, CdlNode node_arg, CdlProperty prop_arg, std::string msg_arg)
752 CdlConflict_EvalException tmp = new CdlConflict_EvalExceptionBody(trans, node_arg, prop_arg, msg_arg);
753 CYG_UNUSED_PARAM(CdlConflict_EvalException, tmp);
756 CdlConflict_EvalExceptionBody::CdlConflict_EvalExceptionBody(CdlTransaction trans, CdlNode node_arg, CdlProperty prop_arg,
758 : CdlConflictBody(trans, node_arg, prop_arg, false)
760 CYG_REPORT_FUNCNAME("CdlConflict_EvalException");
761 CYG_REPORT_FUNCARG1XV(this);
763 explanation = msg_arg;
764 cdlconflict_evalexceptionbody_cookie = CdlConflict_EvalExceptionBody_Magic;
765 CYGDBG_MEMLEAK_CONSTRUCTOR();
767 CYG_POSTCONDITION_THISC();
771 CdlConflict_EvalExceptionBody::~CdlConflict_EvalExceptionBody()
773 CYG_REPORT_FUNCNAME("CdlConflict_EvalException");
774 CYG_REPORT_FUNCARG1XV(this);
775 CYG_PRECONDITION_THISC();
777 cdlconflict_evalexceptionbody_cookie = CdlConflict_EvalExceptionBody_Invalid;
779 CYGDBG_MEMLEAK_DESTRUCTOR();
784 // If there has been an eval exception then the property must be an
785 // ordinary expression, a list expression, or a goal expression
787 CdlConflict_EvalExceptionBody::get_explanation() const
789 CYG_REPORT_FUNCNAME("CdlConflict_EvalException::get_explanation");
790 CYG_REPORT_FUNCARG1XV(this);
791 CYG_PRECONDITION_THISC();
793 std::string result = node->get_name() + ", property " + property->get_property_name() + "\n";
794 result += "Error while evaluation expression: ";
795 if ("" != explanation) {
796 result += explanation;
800 if (CdlConstProperty_Expression expr = dynamic_cast<CdlConstProperty_Expression>(property)) {
802 result += "Expression: " + expr->get_original_string();
804 } else if (CdlConstProperty_ListExpression lexpr = dynamic_cast<CdlConstProperty_ListExpression>(property)) {
806 result += "List expression: " + lexpr->get_original_string();
808 } else if (CdlConstProperty_GoalExpression gexpr = dynamic_cast<CdlConstProperty_GoalExpression>(property)) {
810 result += "Goal expression: " + gexpr->get_original_string();
813 CYG_FAIL("Unknown expression type");
821 CdlConflict_EvalExceptionBody::set_explanation(std::string explanation_arg)
823 CYG_REPORT_FUNCNAME("CdlConflict_EvalException::set_explanation");
824 CYG_REPORT_FUNCARG1XV(this);
825 CYG_PRECONDITION_THISC();
827 explanation = explanation_arg;
833 CdlConflict_EvalExceptionBody::check_this(cyg_assert_class_zeal zeal) const
835 if (CdlConflict_EvalExceptionBody_Magic != cdlconflict_evalexceptionbody_cookie) {
838 CYGDBG_MEMLEAK_CHECKTHIS();
839 return CdlConflictBody::check_this(zeal);
843 CdlConflict_EvalExceptionBody::test(CdlConflict conf)
845 CYG_REPORT_FUNCNAMETYPE("CdlConflict_EvalException::test", "result %d");
846 CYG_REPORT_FUNCARG1XV(conf);
847 CYG_PRECONDITION_CLASSC(conf);
850 CdlConflict_EvalException tmp = dynamic_cast<CdlConflict_EvalException>(conf);
855 CYG_REPORT_RETVAL(result);
860 //{{{ CdlConflict_Requires
862 // ----------------------------------------------------------------------------
863 // A requires constraint is not satisfied. Producing a decent diagnostic
864 // here requires a detailed understanding of goal expressions. For now
865 // there is no extra data associated with goal expressions.
868 CdlConflict_RequiresBody::make(CdlTransaction trans, CdlNode node_arg, CdlProperty prop_arg)
870 CdlConflict_Requires tmp = new CdlConflict_RequiresBody(trans, node_arg, prop_arg);
871 CYG_UNUSED_PARAM(CdlConflict_Requires, tmp);
874 CdlConflict_RequiresBody::CdlConflict_RequiresBody(CdlTransaction trans, CdlNode node_arg, CdlProperty prop_arg)
875 : CdlConflictBody(trans, node_arg, prop_arg, false)
877 CYG_REPORT_FUNCNAME("CdlConflict_Requires:: constructor");
878 CYG_REPORT_FUNCARG1XV(this);
879 CYG_PRECONDITIONC(0 != dynamic_cast<CdlProperty_GoalExpression>(prop_arg));
881 cdlconflict_requiresbody_cookie = CdlConflict_RequiresBody_Magic;
882 CYGDBG_MEMLEAK_CONSTRUCTOR();
884 CYG_POSTCONDITION_THISC();
888 CdlConflict_RequiresBody::~CdlConflict_RequiresBody()
890 CYG_REPORT_FUNCNAME("CdlConflict_Requires:: destructor");
891 CYG_REPORT_FUNCARG1XV(this);
892 CYG_PRECONDITION_THISC();
894 cdlconflict_requiresbody_cookie = CdlConflict_RequiresBody_Invalid;
895 CYGDBG_MEMLEAK_DESTRUCTOR();
900 // FIXME: implement properly
902 CdlConflict_RequiresBody::get_explanation() const
904 CYG_REPORT_FUNCNAME("CdlConflict::get_explanation");
905 CYG_REPORT_FUNCARG1XV(this);
906 CYG_PRECONDITION_THISC();
908 CdlConstProperty_GoalExpression gexpr = dynamic_cast<CdlConstProperty_GoalExpression>(property);
909 CYG_ASSERTC(0 != gexpr);
911 std::string result = "";
912 result += "\"requires\" constraint not satisfied: " + gexpr->get_original_string();
918 // Inference is implemented, see infer.cxx
920 CdlConflict_RequiresBody::resolution_implemented() const
922 CYG_REPORT_FUNCNAME("CdlConflict_Requires");
923 CYG_REPORT_FUNCARG1XV(this);
924 CYG_PRECONDITION_THISC();
931 CdlConflict_RequiresBody::check_this(cyg_assert_class_zeal zeal) const
933 if (CdlConflict_RequiresBody_Magic != cdlconflict_requiresbody_cookie) {
936 CYGDBG_MEMLEAK_CHECKTHIS();
937 return CdlConflictBody::check_this(zeal);
941 CdlConflict_RequiresBody::test(CdlConflict conf)
943 CYG_REPORT_FUNCNAMETYPE("CdlConflict_Requires::test", "result %d");
944 CYG_REPORT_FUNCARG1XV(conf);
945 CYG_PRECONDITION_CLASSC(conf);
948 CdlConflict_Requires tmp = dynamic_cast<CdlConflict_Requires>(conf);
953 CYG_REPORT_RETVAL(result);
958 //{{{ CdlConflict_Data
960 // ----------------------------------------------------------------------------
961 // There is some strange problem in the configuration data, for example
962 // a parent property that is resolved but the target is not a container.
965 CdlConflict_DataBody::make(CdlTransaction trans, CdlNode node_arg, CdlProperty prop_arg, std::string message_arg)
967 CdlConflict_Data tmp = new CdlConflict_DataBody(trans, node_arg, prop_arg, message_arg);
968 CYG_UNUSED_PARAM(CdlConflict_Data, tmp);
971 CdlConflict_DataBody::CdlConflict_DataBody(CdlTransaction trans, CdlNode node_arg, CdlProperty prop_arg,
972 std::string message_arg)
973 : CdlConflictBody(trans, node_arg, prop_arg, true)
975 CYG_REPORT_FUNCNAME("CdlConflict_Data:: constructor");
976 CYG_REPORT_FUNCARG1XV(this);
977 CYG_PRECONDITIONC("" != message_arg);
979 message = message_arg;
980 cdlconflict_databody_cookie = CdlConflict_DataBody_Magic;
981 CYGDBG_MEMLEAK_CONSTRUCTOR();
983 CYG_POSTCONDITION_THISC();
987 CdlConflict_DataBody::~CdlConflict_DataBody()
989 CYG_REPORT_FUNCNAME("CdlConflict_ata: destructor");
990 CYG_REPORT_FUNCARG1XV(this);
991 CYG_PRECONDITION_THISC();
993 cdlconflict_databody_cookie = CdlConflict_DataBody_Invalid;
994 CYGDBG_MEMLEAK_DESTRUCTOR();
1000 CdlConflict_DataBody::get_explanation() const
1002 CYG_REPORT_FUNCNAME("CdlConflict_Data::get_explanation");
1003 CYG_REPORT_FUNCARG1XV(this);
1004 CYG_PRECONDITION_THISC();
1006 std::string result = message;
1008 CYG_REPORT_RETURN();
1013 CdlConflict_DataBody::check_this(cyg_assert_class_zeal zeal) const
1015 if (CdlConflict_DataBody_Magic != cdlconflict_databody_cookie) {
1018 CYGDBG_MEMLEAK_CHECKTHIS();
1019 return CdlConflictBody::check_this(zeal);
1023 CdlConflict_DataBody::test(CdlConflict conf)
1025 CYG_REPORT_FUNCNAMETYPE("CdlConflict_Data::test", "result %d");
1026 CYG_REPORT_FUNCARG1XV(conf);
1027 CYG_PRECONDITION_CLASSC(conf);
1029 bool result = false;
1030 CdlConflict_Data tmp = dynamic_cast<CdlConflict_Data>(conf);
1035 CYG_REPORT_RETVAL(result);