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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [ecos-3.0/] [host/] [tools/] [configtool/] [standalone/] [common/] [cdl_exec.cxx] - Blame information for rev 817

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

Line No. Rev Author Line
1 786 skrzyp
// ####ECOSHOSTGPLCOPYRIGHTBEGIN####                                        
2
// -------------------------------------------                              
3
// This file is part of the eCos host tools.                                
4
// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2005 Free Software Foundation, Inc.
5
//
6
// This program is free software; you can redistribute it and/or modify     
7
// it under the terms of the GNU General Public License as published by     
8
// the Free Software Foundation; either version 2 or (at your option) any   
9
// later version.                                                           
10
//
11
// This program is distributed in the hope that it will be useful, but      
12
// WITHOUT ANY WARRANTY; without even the implied warranty of               
13
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU        
14
// General Public License for more details.                                 
15
//
16
// You should have received a copy of the GNU General Public License        
17
// along with this program; if not, write to the                            
18
// Free Software Foundation, Inc., 51 Franklin Street,                      
19
// Fifth Floor, Boston, MA  02110-1301, USA.                                
20
// -------------------------------------------                              
21
// ####ECOSHOSTGPLCOPYRIGHTEND####                                          
22
//==========================================================================
23
//
24
//      cdl_exec.cxx
25
//
26
//      The implementation of each ecosconfig command
27
//
28
//==========================================================================
29
//==========================================================================
30
//#####DESCRIPTIONBEGIN####                                             
31
//
32
// Author(s):           jld
33
// Date:                1999-11-08
34
//
35
//####DESCRIPTIONEND####
36
//==========================================================================
37
 
38
#ifdef _MSC_VER
39
#include <direct.h> /* for getcwd() */
40
#else
41
#include <limits.h>
42
#include <unistd.h> /* for getcwd() */
43
#endif
44
#ifdef __CYGWIN__
45
#include <windows.h>
46
#include <sys/param.h>  /* for MAXPATHLEN */
47
#include <sys/cygwin.h> /* for cygwin_conv_to_win32_path() */
48
#endif
49
#include "build.hxx"
50
#include "cdl_exec.hxx"
51
 
52
// ----------------------------------------------------------------------------
53
bool cdl_exec::quiet            = false;
54
bool cdl_exec::verbose          = false;
55
bool cdl_exec::ignore_errors    = false;
56
bool cdl_exec::no_updates       = false;
57
bool cdl_exec::debug_level_set  = false;
58
int  cdl_exec::debug_level      = 0;
59
 
60
cdl_exec::cdl_exec (const std::string repository_arg, const std::string savefile_arg,
61
                    const std::string install_arg, bool no_resolve_arg)
62
    : repository(repository_arg),
63
      savefile(savefile_arg),
64
      install_prefix(install_arg),
65
      no_resolve(no_resolve_arg),
66
      pkgdata (NULL),
67
      interp (NULL),
68
      config (NULL)
69
{
70
 
71
    // The inference callback does not actually do anything at present.
72
    // In future it may be useful for diagnostic purposes.
73
    CdlTransactionBody::set_inference_callback_fn (&inference_callback);
74
 
75
    // Automatic inference is always disabled. The inference engine
76
    // only gets invoked explicitly, after a suitable transaction callback
77
    // has been invoked. The problem here is that the transaction callback
78
    // has to report changes made by the inference engine but there is
79
    // no way of distinguishing between inferred values that come out of
80
    // savefiles and inferred values determined by the inference engine.
81
    CdlTransactionBody::disable_automatic_inference ();
82
}
83
 
84
void
85
cdl_exec::set_quiet_mode(bool new_val)
86
{
87
    quiet = new_val;
88
}
89
 
90
void
91
cdl_exec::set_verbose_mode(bool new_val)
92
{
93
    verbose = new_val;
94
    CdlPackagesDatabaseBody::set_verbose(new_val);
95
}
96
 
97
void
98
cdl_exec::set_ignore_errors_mode(bool new_val)
99
{
100
    ignore_errors = new_val;
101
}
102
 
103
void
104
cdl_exec::set_no_updates_mode(bool new_val)
105
{
106
    no_updates = new_val;
107
}
108
 
109
void
110
cdl_exec::set_debug_level(int new_level)
111
{
112
    debug_level_set = true;
113
    debug_level = new_level;
114
}
115
 
116
// ----------------------------------------------------------------------------
117
void
118
cdl_exec::init(bool load_config)
119
{
120
    pkgdata = CdlPackagesDatabaseBody::make(repository, &diagnostic_handler, &diagnostic_handler);
121
    interp  = CdlInterpreterBody::make();
122
    if (load_config) {
123
        config = CdlConfigurationBody::load (savefile, pkgdata, interp, &diagnostic_handler, &diagnostic_handler);
124
    }
125
}
126
 
127
// ----------------------------------------------------------------------------
128
void
129
cdl_exec::delete_cdl_data ()
130
{
131
    if (0 != config) {
132
        delete config;
133
        config = 0;
134
    }
135
    if (0 != interp) {
136
        delete interp;
137
        interp = 0;
138
    }
139
    if (0 != pkgdata) {
140
        delete pkgdata;
141
        pkgdata = 0;
142
    }
143
}
144
 
145
// ----------------------------------------------------------------------------
146
bool cdl_exec::cmd_new (const std::string cdl_hardware,
147
                        const std::string cdl_template /* = "default" */,
148
                        const std::string cdl_version /* = "" */)
149
{
150
    bool status = false;
151
    try {
152
        init(false);
153
 
154
        config = CdlConfigurationBody::make ("eCos", pkgdata, interp);
155
 
156
        // The hardware and template should be loaded in a single transaction.
157
        // Validating the target name etc. can be left to libcdl.
158
        CdlLocalTransaction transact(config);
159
        config->set_hardware(transact.get(), resolve_hardware_alias(cdl_hardware), &diagnostic_handler, &diagnostic_handler);
160
        config->set_template(transact.get(), cdl_template, cdl_version, &diagnostic_handler, &diagnostic_handler);
161
        transact.body();
162
        transact.destroy();
163
 
164
        if (debug_level_set) {
165
            this->update_debug_level();
166
        }
167
 
168
        // Unless inference has been suppressed, make sure that the
169
        // inference engine gets invoked and that its results get
170
        // reported.
171
        if (!no_resolve) {
172
            CdlTransactionBody::set_callback_fn(&transaction_callback);
173
            config->resolve_all_conflicts();
174
        }
175
 
176
        // Now report any conflicts which the inference engine could not report. 
177
        report_conflicts();
178
 
179
        // A savefile should be generated/updated even if there are conflicts.
180
        // Otherwise the user does not have a chance to edit the savefile
181
        // and fix things.
182
        if (!no_updates) {
183
            config->save (savefile);
184
        }
185
        if (ignore_errors || (0 == config->get_all_conflicts().size())) {
186
            status = true;
187
        }
188
    } catch (CdlStringException exception) {
189
        exception_handler (exception);
190
    } catch (...) {
191
        exception_handler ();
192
    }
193
 
194
    delete_cdl_data ();
195
    return status;
196
}
197
 
198
// ----------------------------------------------------------------------------
199
bool
200
cdl_exec::cmd_target (const std::string cdl_target)
201
{
202
    bool status = false;
203
    try {
204
        init(true);
205
        config->set_hardware (resolve_hardware_alias (cdl_target), &diagnostic_handler, &diagnostic_handler);
206
        if (debug_level_set) {
207
            this->update_debug_level();
208
        }
209
        if (!no_resolve) {
210
            CdlTransactionBody::set_callback_fn(&transaction_callback);
211
            config->resolve_all_conflicts();
212
        }
213
        report_conflicts();
214
        if (!no_updates) {
215
            config->save (savefile);
216
        }
217
        if (ignore_errors || (0 == config->get_all_conflicts().size())) {
218
            status = true;
219
        }
220
    } catch (CdlStringException exception) {
221
        exception_handler (exception);
222
    } catch (...) {
223
        exception_handler ();
224
    }
225
 
226
    delete_cdl_data ();
227
    return status;
228
}
229
 
230
// ----------------------------------------------------------------------------
231
bool
232
cdl_exec::cmd_template (const std::string cdl_template, const std::string cdl_version /* = "" */)
233
{
234
    bool status = false;
235
    try {
236
        init(true);
237
        config->set_template (cdl_template, cdl_version, &diagnostic_handler, &diagnostic_handler);
238
        if (debug_level_set) {
239
            this->update_debug_level();
240
        }
241
        if (!no_resolve) {
242
            CdlTransactionBody::set_callback_fn(&transaction_callback);
243
            config->resolve_all_conflicts();
244
        }
245
        report_conflicts();
246
        if (!no_updates) {
247
            config->save (savefile);
248
        }
249
        if (ignore_errors || (0 == config->get_all_conflicts().size())) {
250
            status = true;
251
        }
252
    } catch (CdlStringException exception) {
253
        exception_handler (exception);
254
    } catch (...) {
255
        exception_handler ();
256
    }
257
 
258
    delete_cdl_data ();
259
    return status;
260
}
261
 
262
// ----------------------------------------------------------------------------
263
bool
264
cdl_exec::cmd_export (const std::string cdl_savefile)
265
{
266
    bool status = false;
267
    try {
268
        init(true);
269
        if (debug_level_set) {
270
            this->update_debug_level();
271
        }
272
        if (!no_resolve) {
273
            CdlTransactionBody::set_callback_fn(&transaction_callback);
274
            config->resolve_all_conflicts();
275
        }
276
        report_conflicts();
277
        // Exporting to another file should only happen if the
278
        // configuration is conflict-free. This is different from
279
        // updating the savefile.
280
        if (ignore_errors || (0 == config->get_all_conflicts().size())) {
281
            if (!no_updates) {
282
                config->save (cdl_savefile, /* minimal = */ true);
283
            }
284
            status = true;
285
        }
286
    } catch (CdlStringException exception) {
287
        exception_handler (exception);
288
    } catch (...) {
289
        exception_handler ();
290
    }
291
 
292
    delete_cdl_data ();
293
    return status;
294
}
295
 
296
// ----------------------------------------------------------------------------
297
bool
298
cdl_exec::cmd_import (const std::string cdl_savefile)
299
{
300
    bool status = false;
301
    try {
302
        init(true);
303
        config->add(cdl_savefile, &diagnostic_handler, &diagnostic_handler);
304
        if (debug_level_set) {
305
            this->update_debug_level();
306
        }
307
        if (!no_resolve) {
308
            CdlTransactionBody::set_callback_fn(&transaction_callback);
309
            config->resolve_all_conflicts();
310
        }
311
        report_conflicts();
312
        if (!no_updates) {
313
            config->save (savefile);
314
        }
315
        if (ignore_errors || (0 == config->get_all_conflicts().size())) {
316
            status = true;
317
        }
318
    } catch (CdlStringException exception) {
319
        exception_handler (exception);
320
    } catch (...) {
321
        exception_handler ();
322
    }
323
 
324
    delete_cdl_data ();
325
    return status;
326
}
327
 
328
// ----------------------------------------------------------------------------
329
bool
330
cdl_exec::cmd_add (const std::vector<std::string> cdl_packages)
331
{
332
    bool status = false;
333
    try {
334
        init(true);
335
        for (unsigned int n = 0; n < cdl_packages.size (); n++) {
336
            config->load_package (resolve_package_alias (cdl_packages [n]), "", &diagnostic_handler, &diagnostic_handler);
337
        }
338
        if (debug_level_set) {
339
            this->update_debug_level();
340
        }
341
        if (!no_resolve) {
342
            CdlTransactionBody::set_callback_fn(&transaction_callback);
343
            config->resolve_all_conflicts();
344
        }
345
        report_conflicts();
346
        if (!no_updates) {
347
            config->save (savefile);
348
        }
349
        if (ignore_errors || (0 == config->get_all_conflicts().size())) {
350
            status = true;
351
        }
352
    } catch (CdlStringException exception) {
353
        exception_handler (exception);
354
    } catch (...) {
355
        exception_handler ();
356
    }
357
 
358
    delete_cdl_data ();
359
    return status;
360
}
361
 
362
// ----------------------------------------------------------------------------
363
bool
364
cdl_exec::cmd_remove (const std::vector<std::string> cdl_packages)
365
{
366
    unsigned int n;
367
    bool status = false;
368
    try {
369
        init(true);
370
        for (n = 0; n < cdl_packages.size (); n++) {
371
            CdlNode     base = config->lookup(resolve_package_alias (cdl_packages [n]));
372
            if (0 == base ) {
373
                throw CdlStringException ("Unknown package " + cdl_packages [n]);
374
            }
375
            CdlPackage pkg = dynamic_cast<CdlPackage>(base);
376
            if (0 == pkg) {
377
                CdlLoadable     owner       = base->get_owner();
378
                std::string     owner_name  = owner ? owner->get_name() : "<unknown>";
379
                CdlOption       option      = dynamic_cast<CdlOption>(base);
380
                CdlComponent    component   = dynamic_cast<CdlComponent>(base);
381
                CdlInterface    iface       = dynamic_cast<CdlInterface>(base);
382
                if (0 != option) {
383
                    throw CdlStringException (cdl_packages [n] + " is an option within " + owner_name + ", not a loadable package");
384
                } else if (0 != component) {
385
                    throw CdlStringException (cdl_packages [n] + " is a component of " + owner_name + ", not a loadable package");
386
                } else if (0 != iface) {
387
                    throw CdlStringException (cdl_packages [n] + " is an interface within " + owner_name + ", not a loadable package");
388
                } else {
389
                    throw CdlStringException (cdl_packages [n] + " is not a loadable package");
390
                }
391
            }
392
        }
393
        for (n = 0; n < cdl_packages.size (); n++) {
394
            config->unload_package (resolve_package_alias (cdl_packages [n]));
395
        }
396
        if (debug_level_set) {
397
            this->update_debug_level();
398
        }
399
        if (!no_resolve) {
400
            CdlTransactionBody::set_callback_fn(&transaction_callback);
401
            config->resolve_all_conflicts();
402
        }
403
        report_conflicts();
404
        if (!no_updates) {
405
            config->save (savefile);
406
        }
407
        if (ignore_errors || (0 == config->get_all_conflicts().size())) {
408
            status = true;
409
        }
410
    } catch (CdlStringException exception) {
411
        exception_handler (exception);
412
    } catch (...) {
413
        exception_handler ();
414
    }
415
 
416
    delete_cdl_data ();
417
    return status;
418
}
419
 
420
// ----------------------------------------------------------------------------
421
bool
422
cdl_exec::cmd_version (const std::string cdl_version, const std::vector<std::string> cdl_packages)
423
{
424
    bool status = false;
425
    try {
426
        init(true);
427
        for (unsigned int n = 0; n < cdl_packages.size (); n++) {
428
            config->change_package_version(resolve_package_alias (cdl_packages [n]), cdl_version,
429
                                           &diagnostic_handler, &diagnostic_handler, true);
430
        }
431
        if (debug_level_set) {
432
            this->update_debug_level();
433
        }
434
        if (!no_resolve) {
435
            CdlTransactionBody::set_callback_fn(&transaction_callback);
436
            config->resolve_all_conflicts();
437
        }
438
        report_conflicts();
439
        if (!no_updates) {
440
            config->save (savefile);
441
        }
442
        if (ignore_errors || (0 == config->get_all_conflicts().size())) {
443
            status = true;
444
        }
445
    } catch (CdlStringException exception) {
446
        exception_handler (exception);
447
    } catch (...) {
448
        exception_handler ();
449
    }
450
 
451
    delete_cdl_data ();
452
    return status;
453
}
454
 
455
// ----------------------------------------------------------------------------
456
bool
457
cdl_exec::cmd_tree ()
458
{
459
    bool status = false;
460
    try {
461
        init(true);
462
        if (debug_level_set) {
463
            this->update_debug_level();
464
        }
465
        if (!no_resolve) {
466
            CdlTransactionBody::set_callback_fn(&transaction_callback);
467
            config->resolve_all_conflicts();
468
        }
469
        report_conflicts();
470
        if (!no_updates) {
471
            config->save (savefile);
472
        }
473
        // A build tree should only be generated if there are no conflicts,
474
        // and suppressed if -n is given.
475
        if (no_updates) {
476
            // Do nothing
477
        }
478
        else if (ignore_errors || (0 == config->get_all_conflicts().size())) {
479
#ifdef _MSC_VER
480
            char cwd [_MAX_PATH + 1];
481
#else
482
            char cwd [PATH_MAX + 1];
483
#endif
484
            getcwd (cwd, sizeof cwd);
485
            generate_build_tree (config, cwd, install_prefix);
486
            config->generate_config_headers (install_prefix.empty () ? "install/include/pkgconf" : install_prefix + "/include/pkgconf");
487
            status = true;
488
        } else {
489
            printf("\nUnable to generate build tree, this configuration still contains conflicts.\n");
490
            printf("Either resolve the conflicts or use --ignore-errors\n");
491
        }
492
    } catch (CdlStringException exception) {
493
        exception_handler (exception);
494
    } catch (...) {
495
        exception_handler ();
496
    }
497
 
498
    delete_cdl_data ();
499
    return status;
500
}
501
 
502
// ----------------------------------------------------------------------------
503
bool
504
cdl_exec::cmd_list ()
505
{
506
    bool status = false;
507
    try {
508
        init(false);
509
 
510
        // list the installed packages
511
        std::vector<std::string> packages = pkgdata->get_packages ();
512
        std::sort (packages.begin (), packages.end ());
513
        for (unsigned int package = 0; package < packages.size (); package++) {
514
            const std::vector<std::string> & aliases = pkgdata->get_package_aliases (packages [package]);
515
            printf ("Package %s (%s):\n aliases:", packages [package].c_str (), aliases [0].c_str ());
516
            for (unsigned int alias = 1; alias < aliases.size (); alias++) {
517
                printf (" %s", aliases [alias].c_str ());
518
            }
519
            const std::vector<std::string> & versions = pkgdata->get_package_versions (packages [package]);
520
            printf ("\n versions:");
521
            for (unsigned int version = 0; version < versions.size (); version++) {
522
                printf (" %s", versions [version].c_str ());
523
            }
524
            printf ("\n");
525
        }
526
 
527
        // list the available targets
528
        std::vector<std::string> targets = pkgdata->get_targets ();
529
        std::sort (targets.begin (), targets.end ());
530
        for (unsigned int target = 0; target < targets.size (); target++) {
531
            const std::vector<std::string> & aliases = pkgdata->get_target_aliases (targets [target]);
532
            printf ("Target %s (%s):\n aliases:", targets [target].c_str (), aliases [0].c_str ());
533
            for (unsigned int alias = 1; alias < aliases.size (); alias++) {
534
                printf (" %s", aliases [alias].c_str ());
535
            }
536
            printf ("\n");
537
        }
538
 
539
        // list the available templates
540
        std::vector<std::string> templates = pkgdata->get_templates ();
541
        std::sort (templates.begin (), templates.end ());
542
        for (unsigned int templ = 0; templ < templates.size (); templ++) {
543
            const std::vector<std::string> & versions = pkgdata->get_template_versions (templates [templ]);
544
            printf ("Template %s:\n versions:", templates [templ].c_str ());
545
            for (unsigned int version = 0; version < versions.size (); version++) {
546
                printf (" %s", versions [version].c_str ());
547
            }
548
            printf ("\n");
549
        }
550
 
551
        status = true;
552
    } catch (CdlStringException exception) {
553
        exception_handler (exception);
554
    } catch (...) {
555
        exception_handler ();
556
    }
557
 
558
    delete_cdl_data ();
559
    return status;
560
}
561
 
562
// ----------------------------------------------------------------------------
563
bool
564
cdl_exec::cmd_check ()
565
{
566
    bool status = false;
567
    unsigned int n;
568
 
569
    try {
570
        init(true);
571
        // check() should never invoke the inference engine. The user
572
        // wants to determine the current status, which should not
573
        // change.
574
        // However, updating the savefile is worthwhile because it
575
        // will now contain more accurate information about the state.
576
        // Enabling/disabling debugs is allowed for now because that
577
        // is unlikely to introduce conflicts.
578
        if (debug_level_set) {
579
            this->update_debug_level();
580
        }
581
        if (!no_updates) {
582
            config->save (savefile);
583
        }
584
 
585
        // report current target and template
586
        printf ("Target: %s\n", config->get_hardware ().c_str ());
587
        printf ("Template: %s\n", config->get_template ().c_str ());
588
        std::vector<std::string> template_packages = pkgdata->get_template_packages (config->get_template ());
589
        const std::vector<std::string> & hardware_packages = pkgdata->get_target_packages (config->get_hardware ());
590
        for (n = 0; n < hardware_packages.size (); n++) {
591
            template_packages.push_back (hardware_packages [n]);
592
        }
593
 
594
        // report loaded packages not in the templates
595
        const std::vector<CdlLoadable> & loadables = config->get_loadables ();
596
        std::vector<std::string> added_packages;
597
        std::vector<CdlLoadable>::const_iterator loadable_i;
598
        for (loadable_i = loadables.begin (); loadable_i != loadables.end (); loadable_i++) {
599
            const CdlNode & node = dynamic_cast<CdlNode> (* loadable_i);
600
            if (template_packages.end () == std::find (template_packages.begin (), template_packages.end (), node->get_name ())) {
601
                added_packages.push_back (node->get_name ());
602
            }
603
        }
604
        if (added_packages.size ()) {
605
            printf ("Added:\n");
606
        }
607
        for (n = 0; n < added_packages.size (); n++) {
608
            printf (" %s\n", added_packages [n].c_str ());
609
        }
610
 
611
        // report template packages not in the configuration
612
        std::vector<std::string> removed_packages;
613
        for (n = 0; n < template_packages.size (); n++) {
614
            if (! config->lookup (template_packages [n])) {
615
                removed_packages.push_back (template_packages [n]);
616
            }
617
        }
618
        if (removed_packages.size ()) {
619
            printf ("Removed:\n");
620
        }
621
        for (n = 0; n < removed_packages.size (); n++) {
622
            printf (" %s\n", removed_packages [n].c_str ());
623
        }
624
 
625
        // report packages of non-default version
626
        std::vector<CdlValuable> version_packages;
627
        for (loadable_i = loadables.begin (); loadable_i != loadables.end (); loadable_i++) {
628
            const CdlValuable & valuable = dynamic_cast<CdlValuable> (* loadable_i);
629
            if (pkgdata->get_package_versions (valuable->get_name ()) [0] != valuable->get_value ()) {
630
                version_packages.push_back (valuable);
631
            }
632
        }
633
        if (version_packages.size ()) {
634
            printf ("Version(s):\n");
635
        }
636
        for (n = 0; n < version_packages.size (); n++) {
637
            printf (" %s %s\n", version_packages [n]->get_name ().c_str (), version_packages [n]->get_value ().c_str ());
638
        }
639
 
640
        // report conflicts
641
        const std::list<CdlConflict> & conflicts = config->get_all_conflicts ();
642
        if (conflicts.size ()) {
643
            printf ("%u conflict(s):\n", conflicts.size ());
644
        } else {
645
            printf ("No conflicts\n");
646
        }
647
        report_conflicts();
648
 
649
        status = true;
650
    } catch (CdlStringException exception) {
651
        exception_handler (exception);
652
    } catch (...) {
653
        exception_handler ();
654
    }
655
 
656
    delete_cdl_data ();
657
    return status;
658
}
659
 
660
// ----------------------------------------------------------------------------
661
bool
662
cdl_exec::cmd_resolve ()
663
{
664
    bool status = false;
665
 
666
    try {
667
        init(true);
668
        if (debug_level_set) {
669
            this->update_debug_level();
670
        }
671
        CdlTransactionBody::set_callback_fn(&transaction_callback);
672
        config->resolve_all_conflicts ();
673
        report_conflicts();
674
        if (!no_updates) {
675
            config->save (savefile);
676
        }
677
        if (ignore_errors || (0 == config->get_all_conflicts().size())) {
678
            status = true;
679
        }
680
    } catch (CdlStringException exception) {
681
        exception_handler (exception);
682
    } catch (...) {
683
        exception_handler ();
684
    }
685
 
686
    delete_cdl_data ();
687
    return status;
688
}
689
 
690
// ----------------------------------------------------------------------------
691
// The inference callback. This could give some useful diagnostics, or it
692
// could do useful things when running in some interactive mode. In batch
693
// mode it should not do anything.
694
 
695
CdlInferenceCallbackResult
696
cdl_exec::inference_callback (CdlTransaction transaction)
697
{
698
    return CdlInferenceCallbackResult_Continue;
699
}
700
 
701
// ----------------------------------------------------------------------------
702
// Output a message with indentation after newlines.
703
static void
704
dump_string(unsigned int indent, const std::string& str)
705
{
706
    bool newline_pending = false;
707
    unsigned int i, j;
708
    for (i = 0; i < str.size(); i++) {
709
        if (newline_pending) {
710
            putchar('\n');
711
            if ('\n' != str[i]) {
712
                for (j = 0; j < indent; j++) {
713
                    putchar(' ');
714
                }
715
            }
716
            newline_pending = false;
717
        }
718
        if ('\n' == str[i]) {
719
            newline_pending = true;
720
        } else {
721
            putchar(str[i]);
722
        }
723
    }
724
    if (newline_pending) {
725
        putchar('\n');  // But not the indentation.
726
    }
727
}
728
 
729
// ----------------------------------------------------------------------------
730
// The transaction callback. This should report any changes that have been
731
// made to the configuration. The amount of output depends on the verbosity
732
// level selected by the user.
733
//
734
// 1) quiet     - no output at all
735
// 2) default   - list updates done by the inference engine.
736
// 3) verbose   - this does not currently add anything.
737
// 
738
// There is no reporting of new or resolved conflicts. Resolved
739
// conflicts are probably of no interest in batch mode. New conflicts
740
// will be handled by report_conflicts(). There is also no information
741
// given about active state changes, although arguably there should be
742
// especially in the case of containers.
743
 
744
void
745
cdl_exec::transaction_callback(const CdlTransactionCallback& callback_data)
746
{
747
    if (quiet) {
748
        return;
749
    }
750
 
751
    unsigned int i;
752
    for (i = 0; i < callback_data.value_changes.size(); i++) {
753
        CdlValuable valuable = callback_data.value_changes[i];
754
        if (CdlValueSource_Inferred == valuable->get_source()) {
755
            CdlEvalContext context(0, valuable, 0);
756
            CdlSimpleValue simple_val;
757
            CdlSimpleValue::eval_valuable(context, valuable, simple_val);
758
            std::string msg = std::string("U ") + valuable->get_name() + ", new inferred value ";
759
            std::string value = simple_val.get_value();
760
            if ("" == value) {
761
                msg += "\"\"";
762
            } else {
763
                msg += value;
764
            }
765
            msg += "\n";
766
            dump_string(4, msg);
767
        }
768
    }
769
}
770
 
771
// ----------------------------------------------------------------------------
772
// Report the remaining conflicts in the configuration. These indicate
773
// problems that the user should fix before going further with the
774
// configuration, e.g. before generating a build tree.
775
//
776
// Quiet verbosity level has no effect on this, but at the verbose level
777
// it is a good idea to look for a possible solution to the conflict.
778
 
779
 
780
void
781
cdl_exec::report_conflicts()
782
{
783
    const std::list<CdlConflict>& all_conflicts = config->get_all_conflicts();
784
    std::list<CdlConflict>::const_iterator conf_i;
785
    for (conf_i = all_conflicts.begin(); conf_i != all_conflicts.end(); conf_i++) {
786
        CdlNode     node = (*conf_i)->get_node();
787
 
788
        std::string msg = std::string("C ") + node->get_name() + ", " + (*conf_i)->get_explanation() + "\n";
789
        dump_string(2, msg);
790
 
791
        if (verbose && (*conf_i)->resolution_implemented()) {
792
            // See if there is a possible solution to this conflict.
793
            // This involves creating a transaction, invoking the
794
            // inference engine, and cancelling the transaction
795
            // (thus making sure that nothing actually changes).
796
            //
797
            // NOTE: at some stage libcdl may keep track of solutions
798
            // globally. However, although it will know when a solution
799
            // becomes invalid it will not necessarily try to resolve
800
            // all global conflicts after every change, so attempting
801
            // to do this in a transaction may still be necessary.
802
            CdlTransaction transact = CdlTransactionBody::make(config);
803
            transact->resolve(*conf_i);
804
            if ((*conf_i)->has_known_solution()) {
805
                std::string soln_msg = "  Possible solution:\n";
806
                const std::vector<std::pair<CdlValuable, CdlValue> > & soln = (*conf_i)->get_solution();
807
                unsigned int i;
808
                for (i = 0; i < soln.size(); i++) {
809
                    CdlValuable valuable = soln[i].first;
810
                    soln_msg += valuable->get_name();
811
                    soln_msg += " -> ";
812
                    switch(valuable->get_flavor()) {
813
                      case CdlValueFlavor_Bool :
814
                        if (!soln[i].second.is_enabled()) {
815
                            soln_msg += "0 (disabled)";
816
                        } else {
817
                            soln_msg += "1 (enabled)";
818
                        }
819
                        break;
820
                      case CdlValueFlavor_Data:
821
                        soln_msg += soln[i].second.get_value();
822
                        break;
823
                      case CdlValueFlavor_BoolData:
824
                        if (!soln[i].second.is_enabled()) {
825
                            soln_msg += "0 " + soln[i].second.get_value();
826
                        } else {
827
                            soln_msg += "1 " + soln[i].second.get_value();
828
                        }
829
                        break;
830
                        // An option with flavor none cannot be involved
831
                        // in a solution.
832
                      default:
833
                        soln_msg += "<internal error>";
834
                        break;
835
                    }
836
                    soln_msg += "\n";
837
                }
838
 
839
#if 0
840
                // FIXME: currently this member only works for nested sub-transactions.
841
                if (transact->user_confirmation_required()) {
842
                    msg += "This change affects previous user settings.\n";
843
                }
844
#endif                
845
                dump_string(4, soln_msg);
846
            }
847
            transact->cancel();
848
            delete transact;
849
        }
850
    }
851
}
852
 
853
// ----------------------------------------------------------------------------
854
void
855
cdl_exec::diagnostic_handler (std::string message)
856
{
857
    printf ("%s\n", message.c_str ());
858
}
859
 
860
void cdl_exec::exception_handler (CdlStringException exception) {
861
    printf ("%s\n", exception.get_message ().c_str ());
862
}
863
 
864
void
865
cdl_exec::exception_handler ()
866
{
867
    printf ("Unknown error\n");
868
}
869
 
870
 
871
// ----------------------------------------------------------------------------
872
std::string
873
cdl_exec::resolve_package_alias (const std::string alias)
874
{
875
    std::string package = alias;
876
 
877
    if (! pkgdata->is_known_package (alias)) { // if the alias is not a package name
878
        const std::vector<std::string> & packages = pkgdata->get_packages (); // get packages
879
        for (unsigned int n = 0; n < packages.size (); n++) { // for each package
880
            const std::vector<std::string> & aliases = pkgdata->get_package_aliases (packages [n]); // get package aliases
881
            if (aliases.end () != std::find (aliases.begin (), aliases.end (), alias)) { // if alias is found
882
                package = packages [n]; // note the package
883
                break;
884
            }
885
        }
886
    }
887
    return package;
888
}
889
 
890
std::string
891
cdl_exec::resolve_hardware_alias (const std::string alias)
892
{
893
    std::string target = alias;
894
 
895
    if (! pkgdata->is_known_target (alias)) { // if the alias is not a target name
896
        const std::vector<std::string> & targets = pkgdata->get_targets (); // get targets
897
        for (unsigned int n = 0; n < targets.size (); n++) { // for each target
898
            const std::vector<std::string> & aliases = pkgdata->get_target_aliases (targets [n]); // get target aliases
899
            if (aliases.end () != std::find (aliases.begin (), aliases.end (), alias)) { // if alias is found
900
                target = targets [n]; // note the target
901
                break;
902
            }
903
        }
904
    }
905
    return target;
906
}
907
 
908
// ----------------------------------------------------------------------------
909
// Enable or disable debugging in a configuration.
910
void
911
cdl_exec::update_debug_level()
912
{
913
    CdlNode node = config->lookup("CYGPKG_INFRA_DEBUG");
914
    CdlValuable valuable = 0;
915
    if (0 != node) {
916
        valuable = dynamic_cast<CdlValuable>(node);
917
    }
918
    if (0 == valuable) {
919
        throw CdlStringException("Cannot enable or disable debugging, the infrastructure package is absent");
920
    }
921
 
922
    if (debug_level > 0) {
923
        valuable->enable(CdlValueSource_User);
924
    } else {
925
        valuable->disable(CdlValueSource_User);
926
    }
927
}

powered by: WebSVN 2.1.0

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