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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [ecos-3.0/] [host/] [tools/] [ecostest/] [common/] [permtest.cxx] - Blame information for rev 790

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

Line No. Rev Author Line
1 786 skrzyp
// ####ECOSHOSTGPLCOPYRIGHTBEGIN####                                        
2
// -------------------------------------------                              
3
// This file is part of the eCos host tools.                                
4
// Copyright (C) 1998, 1999, 2000 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
//      permtest.cxx
25
//
26
//      Create a configuration based on a .ptest file                                                                
27
//
28
//==========================================================================
29
//==========================================================================
30
//#####DESCRIPTIONBEGIN####                                             
31
//
32
// Author(s):           bartv
33
// Contributors:        bartv
34
// Date:                1999-11-05
35
//
36
//####DESCRIPTIONEND####
37
//==========================================================================
38
 
39
#include <cdl.hxx>
40
#include <cstdio>
41
#include <cstdlib>
42
 
43
// ----------------------------------------------------------------------------
44
// Statics.
45
//
46
// The global configuration is created as the result of a pkgconf command
47
// when executing the .ptest file
48
static CdlConfiguration configuration = 0;
49
 
50
// The database is set up before the script is evaluated.
51
static CdlPackagesDatabase database = 0;
52
 
53
// The component repository can come from a command line argument or from
54
// an environment variable.
55
static char*            component_repository = 0;
56
 
57
// The name of the .ptest file. This is also the name used for the configuration.
58
static std::string      ptest_file = "";
59
 
60
// The target comes from a command line argument, and is needed by
61
// tcl_pkgconf_command()
62
std::string             target = "";
63
 
64
// The startup comes from a command line argument.
65
static char*            startup = 0;
66
 
67
// ----------------------------------------------------------------------------
68
// Diagnostics support
69
static void error_fn(std::string msg)
70
{
71
    fprintf(stderr, "%s\n", msg.c_str());
72
    exit(EXIT_FAILURE);
73
}
74
 
75
static void warn_fn(std::string msg)
76
{
77
    fprintf(stderr, "%s\n", msg.c_str());
78
}
79
 
80
// ----------------------------------------------------------------------------
81
// Given a database, output the known targets. This happens in response to
82
// the --targets flag or when the specified target is known.
83
// It is up to the calling code to exit with a suitable error code.
84
void
85
output_targets()
86
{
87
    if (0 == database) {
88
        fprintf(stderr, "Internal error, attempt to list targets when there is no database.\n");
89
        exit(EXIT_FAILURE);
90
    }
91
    const std::vector<std::string>& known_targets = database->get_targets();
92
    std::vector<std::string>::const_iterator target_i;
93
 
94
    printf("Known targets:\n");
95
    for (target_i = known_targets.begin(); target_i != known_targets.end(); target_i++) {
96
        printf("  %s\n", target_i->c_str());
97
    }
98
}
99
 
100
// ----------------------------------------------------------------------------
101
// Given a component repository and a permutation argument, find the
102
// corresponding .ptest file and store the result in the global ptest_file
103
static void find_ptest(CdlInterpreter interp, char* ptest_arg)
104
{
105
    if (interp->is_file(ptest_arg)) {
106
        ptest_file = ptest_arg;
107
        return;
108
    }
109
    std::string tmp = std::string(ptest_arg) + ".ptest";
110
    if (interp->is_file(tmp)) {
111
        ptest_file = tmp;
112
        return;
113
    }
114
    tmp = std::string(component_repository) + "/../testing/pkgtest/permtests/" + ptest_arg;
115
    if (interp->is_file(tmp)) {
116
        ptest_file = tmp;
117
        return;
118
    }
119
    tmp += ".ptest";
120
    if (interp->is_file(tmp)) {
121
        ptest_file = tmp;
122
        return;
123
    }
124
}
125
 
126
// ----------------------------------------------------------------------------
127
// Given an alias for a target or package, turn it into the canonical name.
128
std::string
129
get_target_canonical_name(std::string alias)
130
{
131
    if (0 == database) {
132
        fprintf(stderr, "Internal error, attempt to get target canonical name when there is no database.\n");
133
        exit(EXIT_FAILURE);
134
    }
135
 
136
    std::string result = "";
137
    const std::vector<std::string>& known_targets = database->get_targets();
138
    std::vector<std::string>::const_iterator target_i;
139
    for (target_i = known_targets.begin(); ("" == result) && (target_i != known_targets.end()); target_i++) {
140
        if (alias == *target_i) {
141
            result = alias;
142
            break;
143
        }
144
 
145
        const std::vector<std::string>& aliases = database->get_target_aliases(*target_i);
146
        std::vector<std::string>::const_iterator alias_i;
147
        for (alias_i = aliases.begin(); alias_i != aliases.end(); alias_i++) {
148
            if (alias == *alias_i) {
149
                result = *target_i;
150
                break;
151
            }
152
        }
153
    }
154
 
155
    return result;
156
}
157
 
158
std::string
159
get_package_canonical_name(std::string alias)
160
{
161
    if (0 == database) {
162
        fprintf(stderr, "Internal error, attempt to get package canonical name when there is no database.\n");
163
        exit(EXIT_FAILURE);
164
    }
165
 
166
    std::string result = "";
167
    const std::vector<std::string>& known_packages = database->get_packages();
168
    std::vector<std::string>::const_iterator package_i;
169
    for (package_i = known_packages.begin(); ("" == result) && (package_i != known_packages.end()); package_i++) {
170
        if (alias == *package_i) {
171
            result = alias;
172
            break;
173
        }
174
 
175
        const std::vector<std::string>& aliases = database->get_package_aliases(*package_i);
176
        std::vector<std::string>::const_iterator alias_i;
177
        for (alias_i = aliases.begin(); alias_i != aliases.end(); alias_i++) {
178
            if (alias == *alias_i) {
179
                result = *package_i;
180
                break;
181
            }
182
        }
183
    }
184
 
185
    return result;
186
}
187
 
188
// ----------------------------------------------------------------------------
189
// The pkgconf command is responsible for creating the initial
190
// configuration. This should use the hardware as per the command-line
191
// target argument, either the default template or the uITRON package
192
// depending on the presence of an explicit -disable-uitron or
193
// --disable-uitron argument, and any additional packages added
194
// or removed.
195
 
196
static int
197
tcl_pkgconf_command(CdlInterpreter interp, int argc, char** argv)
198
{
199
    if (0 != configuration) {
200
        interp->set_result("Invalid `pkgconf' command, the configuration already exists.");
201
        return TCL_ERROR;
202
    }
203
    if ("" == target) {
204
        interp->set_result("Internal error, attempt to create a configuration with no known target.");
205
        return TCL_ERROR;
206
    }
207
    if (0 == database) {
208
        interp->set_result("Internal error, attempt to create a configuration before the database has been initialized.");
209
        return TCL_ERROR;
210
    }
211
    if ("" == ptest_file) {
212
        interp->set_result("Internal error, attempt to create a configuration when the .ptest file is unknown.");
213
        return TCL_ERROR;
214
    }
215
 
216
    // Create a new interpreter for the configuration. Re-using the one
217
    // being used for evaluating the .ptest file could cause problems.
218
    CdlInterpreter new_interp = CdlInterpreterBody::make();
219
    if (0 == new_interp) {
220
        interp->set_result("Unable to create a new Tcl interpreter, out of memory?");
221
        return TCL_ERROR;
222
    }
223
 
224
    configuration = CdlConfigurationBody::make(ptest_file, database, new_interp);
225
    if (0 == configuration) {
226
        interp->set_result("Unable to create a new configuration, out of memory?");
227
        return TCL_ERROR;
228
    }
229
 
230
    bool uitron = true;
231
    int  i;
232
    for (i = 1; i < argc; i++) {
233
        if ((0 == strcmp(argv[i], "-disable-uitron")) || (0 == strcmp(argv[i], "--disable-uitron"))) {
234
            uitron = false;
235
            break;
236
        }
237
    }
238
 
239
    try {
240
        configuration->set_hardware(target, &error_fn, &warn_fn);
241
        if (uitron) {
242
            configuration->set_template("uitron", "", &error_fn, &warn_fn);
243
        } else {
244
            configuration->set_template("default", "", &error_fn, &warn_fn);
245
        }
246
 
247
        for (i = 1; i < argc; i++) {
248
            char* disable = 0;
249
            char* enable  = 0;
250
 
251
            if (0 == strncmp(argv[i], "-disable-", 9)) {
252
                disable = &(argv[i][9]);
253
            } else if (0 == strncmp(argv[i], "--disable-", 10)) {
254
                disable = &(argv[i][10]);
255
            } else if (0 == strncmp(argv[i], "-enable-", 8)) {
256
                enable = &(argv[i][8]);
257
            } else if (0 == strncmp(argv[i], "--enable-", 9)) {
258
                enable = &(argv[i][9]);
259
            } else {
260
                interp->set_result(std::string("Invalid pkgconf argument `") + argv[i] + "'");
261
                return TCL_ERROR;
262
            }
263
 
264
            if ((0 != disable) && (0 != strcmp(disable, "uitron"))) {
265
                std::string package = get_package_canonical_name(disable);
266
                if ("" == package) {
267
                    interp->set_result(std::string("Error in pkgconf command, attempt to disable unknown package `") +
268
                                       disable + "'");
269
                    return TCL_ERROR;
270
                }
271
                const std::vector<CdlLoadable>& loadables = configuration->get_loadables();
272
                std::vector<CdlLoadable>::const_iterator package_i;
273
                for (package_i = loadables.begin(); package_i != loadables.end(); package_i++) {
274
                    if (package == (*package_i)->get_name()) {
275
                        break;
276
                    }
277
                }
278
                if (package_i == loadables.end()) {
279
                    printf("Warning, pkgconf command, cannot disable %s because it is not loaded in the current configuration",
280
                           disable);
281
                } else {
282
                    configuration->unload_package(package, false);
283
                }
284
            }
285
 
286
            if (0 != enable) {
287
                std::string package = get_package_canonical_name(enable);
288
                if ("" == package) {
289
                    interp->set_result(std::string("Error in pkgconf command, attempt to enable unknown package `") +
290
                                       enable + "'");
291
                    return TCL_ERROR;
292
                }
293
                const std::vector<CdlLoadable>& loadables = configuration->get_loadables();
294
                std::vector<CdlLoadable>::const_iterator package_i;
295
                for (package_i = loadables.begin(); package_i != loadables.end(); package_i++) {
296
                    if (package == (*package_i)->get_name()) {
297
                        break;
298
                    }
299
                }
300
                if (package_i != loadables.end()) {
301
                    interp->set_result(std::string("Error in pkgconf command, cannot enable `") + enable +
302
                                       "' because it is already loaded in the current configuration.");
303
                    return TCL_ERROR;
304
                }
305
                configuration->load_package(package, "", &error_fn, &warn_fn, false);
306
            }
307
        }
308
    } catch(std::bad_alloc) {
309
        interp->set_result(std::string("Unexpected error, out of memory?"));
310
        return TCL_ERROR;
311
    } catch(CdlInputOutputException e) {
312
        interp->set_result(std::string("File I/O exception: ") + e.get_message());
313
        return TCL_ERROR;
314
    } catch(CdlParseException e) {
315
        interp->set_result(std::string("Parse error: ") + e.get_message());
316
        return TCL_ERROR;
317
    } catch(...) {
318
        interp->set_result("Internal error, an unexpected C++ exception was raised");
319
        return TCL_ERROR;
320
    }
321
 
322
    return TCL_OK;
323
}
324
 
325
// ----------------------------------------------------------------------------
326
// Other Tcl commands, on the whole these are straightforward.
327
static int
328
tcl_header_command(CdlInterpreter interp, int argc, char** argv)
329
{
330
    // Modifying a configuration no longer involves editing
331
    // a header file. Instead a single overall configuration
332
    // is updated, and then a savefile is generated. All that
333
    // is necessary is to evaluate the second argument, which
334
    // should be a Tcl script containing enable/disable/value
335
    // commands.
336
    if (3 != argc) {
337
        interp->set_result("Invalid `header' command, expecting two arguments.");
338
        return TCL_ERROR;
339
    }
340
    if (0 == configuration) {
341
        interp->set_result("`header' command detected before the configuration was created.");
342
        return TCL_ERROR;
343
    }
344
    std::string str_result;
345
    int result = interp->eval(argv[2], str_result);
346
    return result;
347
}
348
 
349
static int
350
tcl_makefile_command(CdlInterpreter interp, int argc, char** argv)
351
{
352
    // The makefile command was used to modify the compiler flags.
353
    // This happens very differently in the CDL world, and the
354
    // best solution for now is to ignore this command completely.
355
    if (3 != argc) {
356
        interp->set_result("Invalid `makefile' command, expecting two arguments.");
357
        return TCL_ERROR;
358
    }
359
    if (0 == configuration) {
360
        interp->set_result("`header' command detected before the configuration was created.");
361
        return TCL_ERROR;
362
    }
363
    return TCL_OK;
364
}
365
 
366
static int
367
tcl_enable_command(CdlInterpreter interp, int argc, char** argv)
368
{
369
    // There should be one argument, the name of a configuration option.
370
    if (2 != argc) {
371
        interp->set_result("Invalid `enable' command, expecting one argument.");
372
        return TCL_ERROR;
373
    }
374
    if (0 == configuration) {
375
        interp->set_result("`enable' command detected before the configuration was created.");
376
        return TCL_ERROR;
377
    }
378
 
379
    CdlNode node = configuration->lookup(argv[1]);
380
    if (0 == node) {
381
        printf("Warning, attempt to enable unknown option %s\n", argv[1]);
382
        return TCL_OK;
383
    }
384
    CdlValuable valuable = dynamic_cast<CdlValuable>(node);
385
    if ((0 == valuable) || !valuable->is_modifiable()) {
386
        printf("Warning, attempt to disable non-modifiable option %s\n", argv[1]);
387
        return TCL_OK;
388
    }
389
    CdlValueFlavor flavor = valuable->get_flavor();
390
    if ((CdlValueFlavor_Bool != flavor) && (CdlValueFlavor_BoolData != flavor)) {
391
        printf("Warning, attempt to disable non-boolean option %s\n", argv[1]);
392
        return TCL_OK;
393
    }
394
 
395
    valuable->enable(CdlValueSource_User);
396
    return TCL_OK;
397
}
398
 
399
static int
400
tcl_disable_command(CdlInterpreter interp, int argc, char** argv)
401
{
402
    // There should be one argument, the name of a configuration option.
403
    if (2 != argc) {
404
        interp->set_result("Invalid `disable' command, expecting one argument.");
405
        return TCL_ERROR;
406
    }
407
    if (0 == configuration) {
408
        interp->set_result("`header' command detected before the configuration was created.");
409
        return TCL_ERROR;
410
    }
411
 
412
    CdlNode node = configuration->lookup(argv[1]);
413
    if (0 == node) {
414
        printf("Warning, attempt to disable unknown option %s\n", argv[1]);
415
        return TCL_OK;
416
    }
417
    CdlValuable valuable = dynamic_cast<CdlValuable>(node);
418
    if ((0 == valuable) || !valuable->is_modifiable()) {
419
        printf("Warning, attempt to disable non-modifiable option %s\n", argv[1]);
420
        return TCL_OK;
421
    }
422
    CdlValueFlavor flavor = valuable->get_flavor();
423
    if ((CdlValueFlavor_Bool != flavor) && (CdlValueFlavor_BoolData != flavor)) {
424
        printf("Warning, attempt to disable non-boolean option %s\n", argv[1]);
425
        return TCL_OK;
426
    }
427
 
428
    valuable->disable(CdlValueSource_User);
429
    return TCL_OK;
430
}
431
 
432
static int
433
tcl_value_command(CdlInterpreter interp, int argc, char** argv)
434
{
435
    // There should be two argument, the name of a configuration option and the new value
436
    if (3 != argc) {
437
        interp->set_result("Invalid `value' command, expecting two arguments.");
438
        return TCL_ERROR;
439
    }
440
    if (0 == configuration) {
441
        interp->set_result("`value' command detected before the configuration was created.");
442
        return TCL_ERROR;
443
    }
444
 
445
    CdlNode node = configuration->lookup(argv[1]);
446
    if (0 == node) {
447
        printf("Warning, attempt to change the value of an unknown option %s\n", argv[1]);
448
        return TCL_OK;
449
    }
450
    CdlValuable valuable = dynamic_cast<CdlValuable>(node);
451
    if ((0 == valuable) || !valuable->is_modifiable()) {
452
        printf("Warning, attempt to change the value of non-modifiable option %s\n", argv[1]);
453
        return TCL_OK;
454
    }
455
    CdlValueFlavor flavor = valuable->get_flavor();
456
    if ((CdlValueFlavor_BoolData != flavor) && (CdlValueFlavor_Data != flavor)) {
457
        printf("Warning, attempt to change the value of non-data option %s\n", argv[1]);
458
        return TCL_OK;
459
    }
460
 
461
    valuable->set_value(argv[2], CdlValueSource_User);
462
 
463
    // There's no point setting the value for a BoolData but keeping it disabled
464
    if (CdlValueFlavor_BoolData == flavor) {
465
        valuable->enable(CdlValueSource_User);
466
    }
467
 
468
    return TCL_OK;
469
}
470
 
471
// ----------------------------------------------------------------------------
472
// Specifying the startup. There should be an option CYGHWR_HAL_STARTUP
473
// or CYG_HAL_STARTUP which can be set to the appropriate value.
474
static void
475
process_startup()
476
{
477
    if (0 == configuration) {
478
        fprintf(stderr, "Error: attempting to set the startup before a configuration has been created.\n");
479
        exit(EXIT_FAILURE);
480
    }
481
    if (0 == startup) {
482
        fprintf(stderr, "Error: no startup has been specified.\n");
483
        exit(EXIT_FAILURE);
484
    }
485
 
486
    CdlNode node = configuration->lookup("CYGHWR_HAL_STARTUP");
487
    if (0 == node) {
488
        node = configuration->lookup("CYG_HAL_STARTUP");
489
    }
490
    if (0 == node) {
491
        printf("Warning, there is no option CYGHWR_HAL_STARTUP in the current configuration.\n");
492
        return;
493
    }
494
    CdlValuable valuable = dynamic_cast<CdlValuable>(node);
495
    if (0 == valuable) {
496
        fprintf(stderr, "Error: CYGHWR_HAL_STARTUP exists but is not an option in the current configuration.\n");
497
        exit(EXIT_FAILURE);
498
    }
499
    valuable->set_value(startup, CdlValueSource_User);
500
}
501
 
502
// ----------------------------------------------------------------------------
503
static void
504
usage(void)
505
{
506
    printf("Usage: permtest [options] -target <target> -startup <startup> <ptest>\n");
507
    printf("       permtest --help\n");
508
    printf("       permtest --targets\n");
509
    printf("\n");
510
    printf("  Valid options are:\n");
511
    printf("    -srcdir     <component repository>\n");
512
 
513
    // It is up to the calling code to exit with a suitable exit code.
514
}
515
 
516
// ----------------------------------------------------------------------------
517
int
518
main(int argc, char** argv)
519
{
520
    bool        list_targets = false;
521
    bool        show_help    = false;
522
    char*       target_arg   = 0;
523
    char*       ptest_arg    = 0;
524
 
525
    // Time to process all the arguments.
526
    int i;
527
    for (i = 1; i < argc; i++) {
528
 
529
        // If there are any -- arguments, ignore the first -
530
        char* arg = argv[i];
531
        if (('-' == arg[0]) && ('-' == arg[1])) {
532
            arg = &(arg[1]);
533
        }
534
 
535
        if ((0 == strcmp("-help", arg)) || (0 == strcmp("-H", arg))) {
536
            show_help = true;
537
            continue;
538
        }
539
 
540
        if (0 == strcmp("-targets",  arg)) {
541
            list_targets = true;
542
            continue;
543
        }
544
 
545
        if (0 == strncmp("-target", arg, 7)) {
546
            if (0 != target_arg) {
547
                fprintf(stderr, "Only one target should be specified.\n");
548
                usage();
549
                exit(EXIT_FAILURE);
550
            }
551
            if ('=' == arg[7]) {
552
                target_arg = &(arg[8]);
553
            } else {
554
                if (++i == argc) {
555
                    fprintf(stderr, "Missing argument after -target\n");
556
                    usage();
557
                    exit(EXIT_FAILURE);
558
                }
559
                target_arg = argv[i];
560
            }
561
            continue;
562
        }
563
        if (0 == strncmp("-srcdir", arg, 7)) {
564
            if (0 != component_repository) {
565
                fprintf(stderr, "The component repository should be specified only once.\n");
566
                usage();
567
                exit(EXIT_FAILURE);
568
            }
569
            if ('=' == arg[7]) {
570
                component_repository = &(arg[8]);
571
            } else {
572
                if (++i == argc) {
573
                    fprintf(stderr, "Missing argument after -srcdir\n");
574
                    usage();
575
                    exit(EXIT_FAILURE);
576
                }
577
                component_repository = argv[i];
578
            }
579
            continue;
580
        }
581
        if (0 == strncmp("-startup", argv[i], 8)) {
582
            if (0 != startup) {
583
                fprintf(stderr, "The startup mode should be specified only once.\n");
584
                usage();
585
                exit(EXIT_FAILURE);
586
            }
587
            if ('=' == arg[8]) {
588
                startup = &(arg[9]);
589
            } else {
590
                if (++i == argc) {
591
                    fprintf(stderr, "Missing argument after -startup\n");
592
                    usage();
593
                    exit(EXIT_FAILURE);
594
                }
595
                startup = argv[i];
596
            }
597
            continue;
598
        }
599
 
600
        // None of the standard arguments, this had better be a ptest
601
        if (0 == ptest_arg) {
602
            ptest_arg = argv[i];
603
            continue;
604
        } else {
605
            fprintf(stderr, "Invalid argument %s, only one permutation file should be specified.\n", argv[i]);
606
            usage();
607
            exit(EXIT_FAILURE);
608
        }
609
    }
610
 
611
    // That takes care of the argument processing, time to do
612
    // something interesting.
613
    if (show_help) {
614
        usage();
615
        return EXIT_SUCCESS;
616
    }
617
 
618
    // Locate the component repository. This can come from either a
619
    // command-line argument or from an environment variable. The
620
    // component repository is validated by creating a database.
621
    if ((0 == component_repository) || ('\0' == component_repository[0])) {
622
        component_repository = getenv("ECOS_REPOSITORY");
623
        if (0 == component_repository) {
624
            fprintf(stderr, "The eCos repository location is unknown.\n");
625
            fprintf(stderr, "Please use a --srcdir command line argument, or set\n");
626
            fprintf(stderr, "the ECOS_REPOSITORY environment variable.\n");
627
            exit(EXIT_FAILURE);
628
        }
629
    }
630
 
631
    // Create the Tcl interpreter, to provide ready access to the file
632
    // system and for processing the permutation file itself.
633
    CdlInterpreter interp = CdlInterpreterBody::make();
634
    if (0 == interp) {
635
        fprintf(stderr, "Internal error, unable to create a Tcl interpreter.\n");
636
        exit(EXIT_FAILURE);
637
    }
638
    interp->push_context("permtest");
639
    interp->push_error_fn_ptr(&error_fn);
640
    interp->push_warning_fn_ptr(&warn_fn);
641
 
642
    // Now look for the ptest file.
643
    if ((0 == ptest_arg) || ('\0' == ptest_arg[0])) {
644
        fprintf(stderr, "Please specify a permutation to be tested, e.g. default.ptest\n");
645
        usage();
646
        exit(EXIT_FAILURE);
647
    }
648
    find_ptest(interp, ptest_arg);
649
    if ("" == ptest_file) {
650
        fprintf(stderr, "Unable to locate a permutation file corresponding to %s\n", ptest_arg);
651
        exit(EXIT_FAILURE);
652
    }
653
 
654
    try {
655
        database = CdlPackagesDatabaseBody::make(component_repository, &error_fn, &warn_fn);
656
    } catch(std::bad_alloc) {
657
        fprintf(stderr, "Failed to initialize the component repository database, out of memory?\n");
658
        exit(EXIT_FAILURE);
659
    } catch(CdlInputOutputException e) {
660
        fprintf(stderr, "Failed to initialize the component repository database.\n");
661
        fprintf(stderr, "    %s\n", e.get_message().c_str());
662
        exit(EXIT_FAILURE);
663
    } catch(...) {
664
        fprintf(stderr, "Internal error, unexpected C++ exception while initializing the component repository database.\n");
665
        exit(EXIT_FAILURE);
666
    }
667
 
668
    // Once we have a database we can process the target.
669
    if (list_targets) {
670
        output_targets();
671
        exit(EXIT_SUCCESS);
672
    }
673
    if ((0 == target_arg) || ('\0' == target_arg[0])) {
674
        fprintf(stderr, "Please specify a target using e.g. --target=xyz\n");
675
        usage();
676
        exit(EXIT_FAILURE);
677
    }
678
    target = get_target_canonical_name(target_arg);
679
    if ("" == target) {
680
        fprintf(stderr, "Invalid target %s\n", target_arg);
681
        output_targets();
682
        exit(EXIT_FAILURE);
683
    }
684
 
685
    if ((0 == startup) || ('\0' == startup[0])) {
686
        fprintf(stderr, "Please specify a startup for this target, e.g. rom or ram\n");
687
        usage();
688
        exit(EXIT_FAILURE);
689
    }
690
 
691
    interp->add_command("pkgconf",  &tcl_pkgconf_command);
692
    interp->add_command("header",   &tcl_header_command);
693
    interp->add_command("makefile", &tcl_makefile_command);
694
    interp->add_command("enable",   &tcl_enable_command);
695
    interp->add_command("disable",  &tcl_disable_command);
696
    interp->add_command("value",    &tcl_value_command);
697
 
698
    std::string str_result;
699
    int result =  interp->eval_file(ptest_file, str_result);
700
    if (TCL_OK != result) {
701
        fprintf(stderr, "An error occurred while processing the permutation file.\n");
702
        fprintf(stderr, "%s\n", str_result.c_str());
703
        exit(EXIT_FAILURE);
704
    }
705
 
706
    // Take care of the startup argument as well.
707
    process_startup();
708
 
709
    // Perform global conflict resolution, in case some of the
710
    // conflicts were caused by the order in which packages were
711
    // loaded.
712
    configuration->resolve_all_conflicts();
713
 
714
    // We now have a configuration. Is it valid?
715
    bool valid = true;
716
    const std::list<CdlConflict>& all_conflicts = configuration->get_all_conflicts();
717
    std::list<CdlConflict>::const_iterator conf_i;
718
    for (conf_i = all_conflicts.begin(); conf_i != all_conflicts.end(); conf_i++) {
719
        // HACK: ignore any conflicts inside interfaces.
720
        CdlNode node = (*conf_i)->get_node();
721
        CdlInterface interface = dynamic_cast<CdlInterface>(node);
722
        if (0 != interface) {
723
            continue;
724
        }
725
        CdlProperty prop = (*conf_i)->get_property();
726
        fprintf(stderr, "Conflict: %s %s, property %s\n    %s\n", node->get_class_name().c_str(), node->get_name().c_str(),
727
                prop->get_property_name().c_str(), (*conf_i)->get_explanation().c_str());
728
        valid = false;
729
    }
730
    if (!valid) {
731
        printf("This configuration is invalid and cannot be built.\n");
732
        exit(EXIT_FAILURE);
733
    }
734
 
735
    // It appears we have a valid configuration. Generate the savefile.
736
    try {
737
        configuration->save("ecos.ecc");
738
    } catch(std::bad_alloc) {
739
        fprintf(stderr, "Unexpected error while saving configuration, out of memory?\n");
740
        exit(EXIT_FAILURE);
741
    } catch(CdlInputOutputException e) {
742
        fprintf(stderr, "I/O error while saving configuration.\n");
743
        fprintf(stderr, "%s\n", e.get_message().c_str());
744
        exit(EXIT_FAILURE);
745
    }
746
 
747
    // Time to invoke ecosconfig. This needs a component repository environment variable
748
    interp->set_variable("env(ECOS_REPOSITORY)", component_repository);
749
    result = interp->eval("exec ecosconfig tree", str_result);
750
    if (TCL_OK != result) {
751
        fprintf(stderr, "Error when invoking ecosconfig\n");
752
        fprintf(stderr, "%s\n", str_result.c_str());
753
        exit(EXIT_FAILURE);
754
    }
755
 
756
    return EXIT_SUCCESS;
757
}

powered by: WebSVN 2.1.0

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