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

Subversion Repositories openrisc_me

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

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

Line No. Rev Author Line
1 26 unneback
//{{{  Banner                           
2
 
3
//============================================================================
4
//
5
//      conflict.cxx
6
//
7
//      The CdlConflict class
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/01/28
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. It also brings
59
// in <tcl.h>
60
#include <cdlcore.hxx>
61
 
62
//}}}
63
 
64
//{{{  Statics                          
65
 
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);
73
 
74
//}}}
75
//{{{  CdlConflict                      
76
 
77
//{{{  Creation and destruction                 
78
 
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.
83
//
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.
91
//
92
 
93
CdlConflictBody::CdlConflictBody(CdlTransaction trans_arg, CdlNode node_arg, CdlProperty property_arg, bool structural_arg)
94
{
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);
100
 
101
    node        = node_arg;
102
    property    = property_arg;
103
    transaction = trans_arg;
104
    structural  = structural_arg;
105
    no_solution = false;
106
    // The vectors take care of themselves
107
    enabled     = true;
108
    reason      = "";
109
 
110
    transaction->dirty = true;
111
    if (structural_arg) {
112
        transaction->new_structural_conflicts.push_back(this);
113
    } else {
114
        transaction->new_conflicts.push_back(this);
115
    }
116
 
117
    cdlconflictbody_cookie      = CdlConflictBody_Magic;
118
    CYGDBG_MEMLEAK_CONSTRUCTOR();
119
 
120
    CYG_POSTCONDITION_THISC();
121
    CYG_REPORT_RETURN();
122
}
123
 
124
 
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.
130
 
131
CdlConflictBody::~CdlConflictBody()
132
{
133
    CYG_REPORT_FUNCNAME("CdlConflict:: destructor");
134
    CYG_REPORT_FUNCARG1XV(this);
135
    CYG_PRECONDITION_THISC();
136
 
137
    cdlconflictbody_cookie      = CdlConflictBody_Invalid;
138
    reason                      = "";
139
    enabled                     = false;
140
    no_solution                 = false;
141
    solution.clear();
142
    solution_references.clear();
143
    structural                  = false;
144
    transaction                 = 0;
145
    property                    = 0;
146
    node                        = 0;
147
    CYGDBG_MEMLEAK_DESTRUCTOR();
148
 
149
    CYG_REPORT_RETURN();
150
}
151
 
152
//}}}
153
//{{{  Solution support                         
154
 
155
// ----------------------------------------------------------------------------
156
bool
157
CdlConflictBody::has_known_solution() const
158
{
159
    CYG_REPORT_FUNCNAMETYPE("CdlConflict::has_solution", "result %d");
160
    CYG_REPORT_FUNCARG1XV(this);
161
    CYG_PRECONDITION_THISC();
162
 
163
    bool result = (0 != solution.size());
164
 
165
    CYG_REPORT_RETVAL(result);
166
    return result;
167
}
168
 
169
bool
170
CdlConflictBody::has_no_solution() const
171
{
172
    CYG_REPORT_FUNCNAMETYPE("CdlConflict::has_no_solution", "result %d");
173
    CYG_REPORT_FUNCARG1XV(this);
174
    CYG_PRECONDITION_THISC();
175
 
176
    bool result = no_solution;
177
 
178
    CYG_REPORT_RETVAL(result);
179
    return result;
180
}
181
 
182
const std::vector<std::pair<CdlValuable, CdlValue> >&
183
CdlConflictBody::get_solution() const
184
{
185
    CYG_REPORT_FUNCNAME("CdlConflict::get_solution");
186
    CYG_REPORT_FUNCARG1XV(this);
187
    CYG_PRECONDITION_THISC();
188
 
189
    CYG_REPORT_RETURN();
190
    return solution;
191
}
192
 
193
const std::set<CdlValuable>&
194
CdlConflictBody::get_solution_references() const
195
{
196
    CYG_REPORT_FUNCNAME("CdlConflict::get_solution_references");
197
    CYG_REPORT_FUNCARG1XV(this);
198
    CYG_PRECONDITION_THISC();
199
 
200
    CYG_REPORT_RETURN();
201
    return solution_references;
202
}
203
 
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.
209
void
210
CdlConflictBody::resolve()
211
{
212
    CYG_REPORT_FUNCNAME("CdlConflict::resolve");
213
    CYG_REPORT_FUNCARG1XV(this);
214
    CYG_PRECONDITION_THISC();
215
    CYG_PRECONDITIONC(0 == transaction);
216
 
217
    if (this->resolution_implemented()) {
218
        CdlTransaction transact = CdlTransactionBody::make(this->get_node()->get_toplevel());
219
        transact->resolve(this);
220
        transact->body();
221
        delete transact;
222
    }
223
 
224
    CYG_REPORT_RETURN();
225
}
226
 
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.
230
void
231
CdlConflictBody::update_solution_validity(CdlValuable valuable)
232
{
233
    CYG_REPORT_FUNCNAME("CdlConflict::update_solution_validity");
234
    CYG_REPORT_FUNCARG2XV(this, valuable);
235
    CYG_PRECONDITION_THISC();
236
 
237
    if (solution_references.find(valuable) != solution_references.end()) {
238
        no_solution = false;
239
        solution.clear();
240
        solution_references.clear();
241
    }
242
 
243
    CYG_REPORT_RETURN();
244
}
245
 
246
// ----------------------------------------------------------------------------
247
// Default implementations of the inference engine do not do a lot...
248
bool
249
CdlConflictBody::inner_resolve(CdlTransaction trans_arg, int level)
250
{
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);
255
 
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.
259
    no_solution = true;
260
 
261
    CYG_REPORT_RETURN();
262
    return false;
263
}
264
 
265
bool
266
CdlConflictBody::resolution_implemented() const
267
{
268
    CYG_REPORT_FUNCNAMETYPE("CdlConflict::resolution_implemented", "result %d");
269
    CYG_REPORT_FUNCARG1XV(this);
270
    CYG_PRECONDITION_THISC();
271
 
272
    CYG_REPORT_RETVAL(false);
273
    return false;
274
}
275
 
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.
281
void
282
CdlConflictBody::clear_solution()
283
{
284
    CYG_REPORT_FUNCNAME("CdlConflict::clear_solution");
285
    CYG_REPORT_FUNCARG1XV(this);
286
    CYG_PRECONDITION_THISC();
287
 
288
    no_solution = false;
289
    solution.clear();
290
    solution_references.clear();
291
 
292
    CYG_REPORT_RETURN();
293
}
294
 
295
//}}}
296
//{{{  Basics                                   
297
 
298
// ----------------------------------------------------------------------------
299
 
300
CdlNode
301
CdlConflictBody::get_node() const
302
{
303
    CYG_REPORT_FUNCNAMETYPE("CdlConflict::get_node", "result %p");
304
    CYG_REPORT_FUNCARG1XV(this);
305
    CYG_PRECONDITION_THISC();
306
 
307
    CdlNode result = node;
308
    CYG_REPORT_RETVAL(result);
309
    return result;
310
}
311
 
312
CdlProperty
313
CdlConflictBody::get_property() const
314
{
315
    CYG_REPORT_FUNCNAMETYPE("CdlConflict::get_property", "result %p");
316
    CYG_REPORT_FUNCARG1XV(this);
317
    CYG_PRECONDITION_THISC();
318
 
319
    CdlProperty result  = property;
320
    CYG_REPORT_RETVAL(result);
321
    return result;
322
}
323
 
324
bool
325
CdlConflictBody::is_structural() const
326
{
327
    CYG_REPORT_FUNCNAMETYPE("CdlConflict::is_structural", "result %d");
328
    CYG_REPORT_FUNCARG1XV(this);
329
    CYG_PRECONDITION_THISC();
330
 
331
    bool result = structural;
332
    CYG_REPORT_RETVAL(result);
333
    return result;
334
}
335
 
336
CdlTransaction
337
CdlConflictBody::get_transaction() const
338
{
339
    CYG_REPORT_FUNCNAMETYPE("CdlConflict::get_transaction", "result %p");
340
    CYG_REPORT_FUNCARG1XV(this);
341
    CYG_PRECONDITION_THISC();
342
 
343
    CdlTransaction result = transaction;
344
    CYG_REPORT_RETVAL(result);
345
    return result;
346
}
347
 
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.
352
 
353
bool
354
CdlConflictBody::is_enabled() const
355
{
356
    CYG_REPORT_FUNCNAMETYPE("CdlConflict::is_enabled", "result %d");
357
    CYG_REPORT_FUNCARG1XV(this);
358
    CYG_PRECONDITION_THISC();
359
 
360
    bool result = enabled;
361
    CYG_REPORT_RETVAL(result);
362
    return result;
363
}
364
 
365
std::string
366
CdlConflictBody::get_disabled_reason() const
367
{
368
    CYG_REPORT_FUNCNAME("CdlConflict::get_disabled_reason");
369
    CYG_REPORT_FUNCARG1XV(this);
370
    CYG_PRECONDITION_THISC();
371
 
372
    // Possibly there should be a check that the conflict is currently
373
    // disabled, but it might be useful. 
374
    CYG_REPORT_RETURN();
375
    return reason;
376
}
377
 
378
void
379
CdlConflictBody::disable(std::string reason_arg)
380
{
381
    CYG_REPORT_FUNCNAME("CdlConflict::disable");
382
    CYG_REPORT_FUNCARG1XV(this);
383
    CYG_PRECONDITION_THISC();
384
 
385
    reason      = reason_arg;
386
    enabled     = false;
387
 
388
    CYG_REPORT_RETURN();
389
}
390
 
391
void
392
CdlConflictBody::enable()
393
{
394
    CYG_REPORT_FUNCNAME("CdlConflict::enable");
395
    CYG_REPORT_FUNCARG1XV(this);
396
    CYG_PRECONDITION_THISC();
397
 
398
    enabled     = true;
399
    // Leave "reason" alone, it may still be useful
400
 
401
    CYG_REPORT_RETURN();
402
}
403
 
404
//}}}
405
//{{{  check_this()                             
406
 
407
// ----------------------------------------------------------------------------
408
bool
409
CdlConflictBody::check_this(cyg_assert_class_zeal zeal) const
410
{
411
    if (CdlConflictBody_Magic != cdlconflictbody_cookie) {
412
        return false;
413
    }
414
    CYGDBG_MEMLEAK_CHECKTHIS();
415
    if ((0 == node) || (0 == property)) {
416
        return false;
417
    }
418
    switch(zeal) {
419
      case cyg_system_test :
420
      case cyg_extreme :
421
      {
422
          if (!node->check_this(cyg_quick)) {
423
              return false;
424
          }
425
          // Accessing the properties would involve a function call.
426
 
427
          if (0 != transaction) {
428
              if (!transaction->check_this(cyg_quick)) {
429
                  return false;
430
              }
431
              if (structural) {
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()) {
437
                      return false;
438
                  }
439
              } else {
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()) {
444
 
445
                      if (std::find(transaction->resolved_conflicts.begin(), transaction->resolved_conflicts.end(), this) ==
446
                          transaction->resolved_conflicts.end()) {
447
 
448
                          return false;
449
                      }
450
                  }
451
              }
452
          }
453
          // Checking the toplevel lists would be good, but involves a
454
          // further function call and hence nested assertions.
455
      }
456
      case cyg_thorough :
457
      {
458
          if (!node->check_this(cyg_quick)) {
459
              return false;
460
          }
461
          if (!property->check_this(cyg_quick)) {
462
              return false;
463
          }
464
      }
465
      case cyg_quick :
466
      {
467
          if (no_solution && (0 != solution.size())) {
468
              return false;
469
          }
470
      }
471
      case cyg_trivial :
472
      case cyg_none :
473
      default:
474
          break;
475
    }
476
 
477
    return true;
478
}
479
 
480
//}}}
481
 
482
//}}}
483
//{{{  CdlConflict_Unresolved           
484
 
485
// ----------------------------------------------------------------------------
486
// Unresolved references. Usually unresolved references occur inside
487
// expressions, but other properties that may be affected are parent,
488
// dialog and wizard.
489
//
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
497
// error-prone.
498
 
499
void
500
CdlConflict_UnresolvedBody::make(CdlTransaction trans, CdlNode node_arg, CdlProperty prop_arg, std::string name_arg)
501
{
502
    CdlConflict_Unresolved tmp = new CdlConflict_UnresolvedBody(trans, node_arg, prop_arg, name_arg);
503
    CYG_UNUSED_PARAM(CdlConflict_Unresolved, tmp);
504
}
505
 
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)
509
{
510
    CYG_REPORT_FUNCNAME("CdlConflict_Unresolved:: constructor");
511
    CYG_REPORT_FUNCARG1XV(this);
512
    CYG_PRECONDITIONC("" != target_name_arg);
513
 
514
    target_name = target_name_arg;
515
    cdlconflict_unresolvedbody_cookie = CdlConflict_UnresolvedBody_Magic;
516
    CYGDBG_MEMLEAK_CONSTRUCTOR();
517
 
518
    CYG_POSTCONDITION_THISC();
519
    CYG_REPORT_RETURN();
520
}
521
 
522
CdlConflict_UnresolvedBody::~CdlConflict_UnresolvedBody()
523
{
524
    CYG_REPORT_FUNCNAME("CdlConflict_Unresolved:: destructor");
525
    CYG_REPORT_FUNCARG1XV(this);
526
    CYG_PRECONDITION_THISC();
527
 
528
    cdlconflict_unresolvedbody_cookie = CdlConflict_UnresolvedBody_Invalid;
529
    target_name = "";
530
    CYGDBG_MEMLEAK_DESTRUCTOR();
531
 
532
    CYG_REPORT_RETURN();
533
}
534
 
535
std::string
536
CdlConflict_UnresolvedBody::get_target_name() const
537
{
538
    CYG_REPORT_FUNCNAME("CdlConflict_Unresolved::get_target_name");
539
    CYG_REPORT_FUNCARG1XV(this);
540
    CYG_PRECONDITION_THISC();
541
 
542
    CYG_REPORT_RETURN();
543
    return target_name;
544
}
545
 
546
// For now, just report the node and property name, a brief text, and the
547
// entity being referenced. 
548
//
549
// Eventually we can do clever things like looking up the name in a
550
// database.
551
 
552
std::string
553
CdlConflict_UnresolvedBody::get_explanation() const
554
{
555
    CYG_REPORT_FUNCNAME("CdlConflict_Unresolved::get_explanation");
556
    CYG_REPORT_FUNCARG1XV(this);
557
    CYG_PRECONDITION_THISC();
558
 
559
    std::string result;
560
    result = node->get_name() + ", property " + property->get_property_name() +
561
        ":\nReference to unknown object " + target_name;
562
 
563
    CYG_REPORT_RETURN();
564
    return result;
565
}
566
 
567
bool
568
CdlConflict_UnresolvedBody::check_this(cyg_assert_class_zeal zeal) const
569
{
570
    if (CdlConflict_UnresolvedBody_Magic != cdlconflict_unresolvedbody_cookie) {
571
        return false;
572
    }
573
    CYGDBG_MEMLEAK_CHECKTHIS();
574
 
575
    // There is not a lot of checking that can be done on the name.
576
 
577
    return CdlConflictBody::check_this(zeal);
578
}
579
 
580
bool
581
CdlConflict_UnresolvedBody::test(CdlConflict conf)
582
{
583
    CYG_REPORT_FUNCNAMETYPE("CdlConflict_Unresolved::test", "result %d");
584
    CYG_REPORT_FUNCARG1XV(conf);
585
    CYG_PRECONDITION_CLASSC(conf);
586
 
587
    bool result = false;
588
    CdlConflict_Unresolved tmp = dynamic_cast<CdlConflict_Unresolved>(conf);
589
    if (0 != tmp) {
590
        result = true;
591
    }
592
 
593
    CYG_REPORT_RETVAL(result);
594
    return result;
595
}
596
 
597
//}}}
598
//{{{  CdlConflict_IllegalValue         
599
 
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.
605
//
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.
609
 
610
void
611
CdlConflict_IllegalValueBody::make(CdlTransaction trans, CdlNode node_arg, CdlProperty prop_arg)
612
{
613
    CdlConflict_IllegalValue tmp = new CdlConflict_IllegalValueBody(trans, node_arg, prop_arg);
614
    CYG_UNUSED_PARAM(CdlConflict_IllegalValue, tmp);
615
}
616
 
617
CdlConflict_IllegalValueBody::CdlConflict_IllegalValueBody(CdlTransaction trans, CdlNode node_arg, CdlProperty prop_arg)
618
    : CdlConflictBody(trans, node_arg, prop_arg, false)
619
{
620
    CYG_REPORT_FUNCNAME("CdlConflict_IllegalValue:: constructor");
621
    CYG_REPORT_FUNCARG1XV(this);
622
    CYG_PRECONDITIONC(0 != dynamic_cast<CdlValuable>(node_arg));
623
 
624
    explanation = "";
625
    cdlconflict_illegalvaluebody_cookie = CdlConflict_IllegalValueBody_Magic;
626
    CYGDBG_MEMLEAK_CONSTRUCTOR();
627
 
628
    CYG_POSTCONDITION_THISC();
629
    CYG_REPORT_RETURN();
630
}
631
 
632
CdlConflict_IllegalValueBody::~CdlConflict_IllegalValueBody()
633
{
634
    CYG_REPORT_FUNCNAME("CdlConflict_IllegalValue:: destructor");
635
    CYG_REPORT_FUNCARG1XV(this);
636
    CYG_PRECONDITION_THISC();
637
 
638
    cdlconflict_illegalvaluebody_cookie = CdlConflict_IllegalValueBody_Invalid;
639
    explanation = "";
640
    CYGDBG_MEMLEAK_DESTRUCTOR();
641
 
642
    CYG_REPORT_RETURN();
643
}
644
 
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.
648
//
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
651
// object.
652
std::string
653
CdlConflict_IllegalValueBody::get_explanation() const
654
{
655
    CYG_REPORT_FUNCNAME("CdlConflict_IllegalValue::get_explanation()");
656
    CYG_REPORT_FUNCARG1XV(this);
657
    CYG_PRECONDITION_THISC();
658
 
659
    CdlConstValuable valuable = dynamic_cast<CdlConstValuable>(node);
660
    CYG_ASSERTC(0 != valuable);
661
 
662
    std::string result = "";
663
 
664
    // FIXME: analyse the current value and flavor a bit more
665
    result += "Illegal current value " + valuable->get_value() + "\n";
666
 
667
    if (CdlPropertyId_LegalValues == property->get_property_name()) {
668
 
669
        CdlConstProperty_ListExpression expr = dynamic_cast<CdlConstProperty_ListExpression>(property);
670
        CYG_ASSERTC(0 != expr);
671
        result += "Legal values are: " + expr->get_original_string();
672
 
673
    } else if (explanation != "") {
674
 
675
        result += explanation;
676
    } else {
677
 
678
        CYG_FAIL("Inexplicable illegal value");
679
    }
680
 
681
    CYG_REPORT_RETURN();
682
    return result;
683
}
684
 
685
void
686
CdlConflict_IllegalValueBody::set_explanation(std::string explanation_arg)
687
{
688
    CYG_REPORT_FUNCNAME("CdlConflict_IllegalValue::set_explanation");
689
    CYG_REPORT_FUNCARG1XV(this);
690
    CYG_PRECONDITION_THISC();
691
 
692
    explanation = explanation_arg;
693
 
694
    CYG_REPORT_RETURN();
695
}
696
 
697
// ----------------------------------------------------------------------------
698
// Inference is implemented. The actual inference code is in infer.cxx
699
bool
700
CdlConflict_IllegalValueBody::resolution_implemented() const
701
{
702
    CYG_REPORT_FUNCNAME("CdlConflict_IllegalValue::resolution_implemented");
703
    CYG_REPORT_FUNCARG1XV(this);
704
    CYG_PRECONDITION_THISC();
705
 
706
    CYG_REPORT_RETURN();
707
    return true;
708
}
709
 
710
// ----------------------------------------------------------------------------
711
bool
712
CdlConflict_IllegalValueBody::check_this(cyg_assert_class_zeal zeal) const
713
{
714
    if (CdlConflict_IllegalValueBody_Magic != cdlconflict_illegalvaluebody_cookie) {
715
        return false;
716
    }
717
    CYGDBG_MEMLEAK_CHECKTHIS();
718
 
719
    return CdlConflictBody::check_this(zeal);
720
}
721
 
722
bool
723
CdlConflict_IllegalValueBody::test(CdlConflict conf)
724
{
725
    CYG_REPORT_FUNCNAMETYPE("CdlConflict_IllegalValue::test", "result %d");
726
    CYG_REPORT_FUNCARG1XV(conf);
727
    CYG_PRECONDITION_CLASSC(conf);
728
 
729
    bool result = false;
730
    CdlConflict_IllegalValue tmp = dynamic_cast<CdlConflict_IllegalValue>(conf);
731
    if (0 != tmp) {
732
        result = true;
733
    }
734
 
735
    CYG_REPORT_RETVAL(result);
736
    return result;
737
}
738
 
739
//}}}
740
//{{{  CdlConflict_EvalException        
741
 
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
748
 
749
void
750
CdlConflict_EvalExceptionBody::make(CdlTransaction trans, CdlNode node_arg, CdlProperty prop_arg, std::string msg_arg)
751
{
752
    CdlConflict_EvalException tmp = new CdlConflict_EvalExceptionBody(trans, node_arg, prop_arg, msg_arg);
753
    CYG_UNUSED_PARAM(CdlConflict_EvalException, tmp);
754
}
755
 
756
CdlConflict_EvalExceptionBody::CdlConflict_EvalExceptionBody(CdlTransaction trans, CdlNode node_arg, CdlProperty prop_arg,
757
                                                             std::string msg_arg)
758
    : CdlConflictBody(trans, node_arg, prop_arg, false)
759
{
760
    CYG_REPORT_FUNCNAME("CdlConflict_EvalException");
761
    CYG_REPORT_FUNCARG1XV(this);
762
 
763
    explanation = msg_arg;
764
    cdlconflict_evalexceptionbody_cookie = CdlConflict_EvalExceptionBody_Magic;
765
    CYGDBG_MEMLEAK_CONSTRUCTOR();
766
 
767
    CYG_POSTCONDITION_THISC();
768
    CYG_REPORT_RETURN();
769
}
770
 
771
CdlConflict_EvalExceptionBody::~CdlConflict_EvalExceptionBody()
772
{
773
    CYG_REPORT_FUNCNAME("CdlConflict_EvalException");
774
    CYG_REPORT_FUNCARG1XV(this);
775
    CYG_PRECONDITION_THISC();
776
 
777
    cdlconflict_evalexceptionbody_cookie = CdlConflict_EvalExceptionBody_Invalid;
778
    explanation = "";
779
    CYGDBG_MEMLEAK_DESTRUCTOR();
780
 
781
    CYG_REPORT_RETURN();
782
}
783
 
784
// If there has been an eval exception then the property must be an
785
// ordinary expression, a list expression, or a goal expression
786
std::string
787
CdlConflict_EvalExceptionBody::get_explanation() const
788
{
789
    CYG_REPORT_FUNCNAME("CdlConflict_EvalException::get_explanation");
790
    CYG_REPORT_FUNCARG1XV(this);
791
    CYG_PRECONDITION_THISC();
792
 
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;
797
    }
798
    result += "\n";
799
 
800
    if (CdlConstProperty_Expression expr = dynamic_cast<CdlConstProperty_Expression>(property)) {
801
 
802
        result += "Expression: " + expr->get_original_string();
803
 
804
    } else if (CdlConstProperty_ListExpression lexpr = dynamic_cast<CdlConstProperty_ListExpression>(property)) {
805
 
806
        result += "List expression: " + lexpr->get_original_string();
807
 
808
    } else if (CdlConstProperty_GoalExpression gexpr = dynamic_cast<CdlConstProperty_GoalExpression>(property)) {
809
 
810
        result += "Goal expression: " + gexpr->get_original_string();
811
 
812
    } else {
813
        CYG_FAIL("Unknown expression type");
814
    }
815
 
816
    CYG_REPORT_RETURN();
817
    return result;
818
}
819
 
820
void
821
CdlConflict_EvalExceptionBody::set_explanation(std::string explanation_arg)
822
{
823
    CYG_REPORT_FUNCNAME("CdlConflict_EvalException::set_explanation");
824
    CYG_REPORT_FUNCARG1XV(this);
825
    CYG_PRECONDITION_THISC();
826
 
827
    explanation = explanation_arg;
828
 
829
    CYG_REPORT_RETURN();
830
}
831
 
832
bool
833
CdlConflict_EvalExceptionBody::check_this(cyg_assert_class_zeal zeal) const
834
{
835
    if (CdlConflict_EvalExceptionBody_Magic != cdlconflict_evalexceptionbody_cookie) {
836
        return false;
837
    }
838
    CYGDBG_MEMLEAK_CHECKTHIS();
839
    return CdlConflictBody::check_this(zeal);
840
}
841
 
842
bool
843
CdlConflict_EvalExceptionBody::test(CdlConflict conf)
844
{
845
    CYG_REPORT_FUNCNAMETYPE("CdlConflict_EvalException::test", "result %d");
846
    CYG_REPORT_FUNCARG1XV(conf);
847
    CYG_PRECONDITION_CLASSC(conf);
848
 
849
    bool result = false;
850
    CdlConflict_EvalException tmp = dynamic_cast<CdlConflict_EvalException>(conf);
851
    if (0 != tmp) {
852
        result = true;
853
    }
854
 
855
    CYG_REPORT_RETVAL(result);
856
    return result;
857
}
858
 
859
//}}}
860
//{{{  CdlConflict_Requires             
861
 
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.
866
 
867
void
868
CdlConflict_RequiresBody::make(CdlTransaction trans, CdlNode node_arg, CdlProperty prop_arg)
869
{
870
    CdlConflict_Requires tmp = new CdlConflict_RequiresBody(trans, node_arg, prop_arg);
871
    CYG_UNUSED_PARAM(CdlConflict_Requires, tmp);
872
}
873
 
874
CdlConflict_RequiresBody::CdlConflict_RequiresBody(CdlTransaction trans, CdlNode node_arg, CdlProperty prop_arg)
875
    : CdlConflictBody(trans, node_arg, prop_arg, false)
876
{
877
    CYG_REPORT_FUNCNAME("CdlConflict_Requires:: constructor");
878
    CYG_REPORT_FUNCARG1XV(this);
879
    CYG_PRECONDITIONC(0 != dynamic_cast<CdlProperty_GoalExpression>(prop_arg));
880
 
881
    cdlconflict_requiresbody_cookie = CdlConflict_RequiresBody_Magic;
882
    CYGDBG_MEMLEAK_CONSTRUCTOR();
883
 
884
    CYG_POSTCONDITION_THISC();
885
    CYG_REPORT_RETURN();
886
}
887
 
888
CdlConflict_RequiresBody::~CdlConflict_RequiresBody()
889
{
890
    CYG_REPORT_FUNCNAME("CdlConflict_Requires:: destructor");
891
    CYG_REPORT_FUNCARG1XV(this);
892
    CYG_PRECONDITION_THISC();
893
 
894
    cdlconflict_requiresbody_cookie = CdlConflict_RequiresBody_Invalid;
895
    CYGDBG_MEMLEAK_DESTRUCTOR();
896
 
897
    CYG_REPORT_RETURN();
898
}
899
 
900
// FIXME: implement properly
901
std::string
902
CdlConflict_RequiresBody::get_explanation() const
903
{
904
    CYG_REPORT_FUNCNAME("CdlConflict::get_explanation");
905
    CYG_REPORT_FUNCARG1XV(this);
906
    CYG_PRECONDITION_THISC();
907
 
908
    CdlConstProperty_GoalExpression gexpr = dynamic_cast<CdlConstProperty_GoalExpression>(property);
909
    CYG_ASSERTC(0 != gexpr);
910
 
911
    std::string result = "";
912
    result += "\"requires\" constraint not satisfied: " + gexpr->get_original_string();
913
 
914
    CYG_REPORT_RETURN();
915
    return result;
916
}
917
 
918
// Inference is implemented, see infer.cxx
919
bool
920
CdlConflict_RequiresBody::resolution_implemented() const
921
{
922
    CYG_REPORT_FUNCNAME("CdlConflict_Requires");
923
    CYG_REPORT_FUNCARG1XV(this);
924
    CYG_PRECONDITION_THISC();
925
 
926
    CYG_REPORT_RETURN();
927
    return true;
928
}
929
 
930
bool
931
CdlConflict_RequiresBody::check_this(cyg_assert_class_zeal zeal) const
932
{
933
    if (CdlConflict_RequiresBody_Magic != cdlconflict_requiresbody_cookie) {
934
        return false;
935
    }
936
    CYGDBG_MEMLEAK_CHECKTHIS();
937
    return CdlConflictBody::check_this(zeal);
938
}
939
 
940
bool
941
CdlConflict_RequiresBody::test(CdlConflict conf)
942
{
943
    CYG_REPORT_FUNCNAMETYPE("CdlConflict_Requires::test", "result %d");
944
    CYG_REPORT_FUNCARG1XV(conf);
945
    CYG_PRECONDITION_CLASSC(conf);
946
 
947
    bool result = false;
948
    CdlConflict_Requires tmp = dynamic_cast<CdlConflict_Requires>(conf);
949
    if (0 != tmp) {
950
        result = true;
951
    }
952
 
953
    CYG_REPORT_RETVAL(result);
954
    return result;
955
}
956
 
957
//}}}
958
//{{{  CdlConflict_Data                 
959
 
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.
963
 
964
void
965
CdlConflict_DataBody::make(CdlTransaction trans, CdlNode node_arg, CdlProperty prop_arg, std::string message_arg)
966
{
967
    CdlConflict_Data tmp = new CdlConflict_DataBody(trans, node_arg, prop_arg, message_arg);
968
    CYG_UNUSED_PARAM(CdlConflict_Data, tmp);
969
}
970
 
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)
974
{
975
    CYG_REPORT_FUNCNAME("CdlConflict_Data:: constructor");
976
    CYG_REPORT_FUNCARG1XV(this);
977
    CYG_PRECONDITIONC("" != message_arg);
978
 
979
    message = message_arg;
980
    cdlconflict_databody_cookie = CdlConflict_DataBody_Magic;
981
    CYGDBG_MEMLEAK_CONSTRUCTOR();
982
 
983
    CYG_POSTCONDITION_THISC();
984
    CYG_REPORT_RETURN();
985
}
986
 
987
CdlConflict_DataBody::~CdlConflict_DataBody()
988
{
989
    CYG_REPORT_FUNCNAME("CdlConflict_ata: destructor");
990
    CYG_REPORT_FUNCARG1XV(this);
991
    CYG_PRECONDITION_THISC();
992
 
993
    cdlconflict_databody_cookie = CdlConflict_DataBody_Invalid;
994
    CYGDBG_MEMLEAK_DESTRUCTOR();
995
 
996
    CYG_REPORT_RETURN();
997
}
998
 
999
std::string
1000
CdlConflict_DataBody::get_explanation() const
1001
{
1002
    CYG_REPORT_FUNCNAME("CdlConflict_Data::get_explanation");
1003
    CYG_REPORT_FUNCARG1XV(this);
1004
    CYG_PRECONDITION_THISC();
1005
 
1006
    std::string result = message;
1007
 
1008
    CYG_REPORT_RETURN();
1009
    return result;
1010
}
1011
 
1012
bool
1013
CdlConflict_DataBody::check_this(cyg_assert_class_zeal zeal) const
1014
{
1015
    if (CdlConflict_DataBody_Magic != cdlconflict_databody_cookie) {
1016
        return false;
1017
    }
1018
    CYGDBG_MEMLEAK_CHECKTHIS();
1019
    return CdlConflictBody::check_this(zeal);
1020
}
1021
 
1022
bool
1023
CdlConflict_DataBody::test(CdlConflict conf)
1024
{
1025
    CYG_REPORT_FUNCNAMETYPE("CdlConflict_Data::test", "result %d");
1026
    CYG_REPORT_FUNCARG1XV(conf);
1027
    CYG_PRECONDITION_CLASSC(conf);
1028
 
1029
    bool result = false;
1030
    CdlConflict_Data tmp = dynamic_cast<CdlConflict_Data>(conf);
1031
    if (0 != tmp) {
1032
        result = true;
1033
    }
1034
 
1035
    CYG_REPORT_RETVAL(result);
1036
    return result;
1037
}
1038
 
1039
//}}}

powered by: WebSVN 2.1.0

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