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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [ecos-3.0/] [host/] [libcdl/] [database.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
//{{{  Banner                                                   
2
 
3
//============================================================================
4
//
5
//      database.cxx
6
//
7
//      Temporary implementation of the CdlPackagesDatabase class
8
//      Implementations of the temporary CdlTargetsDatabase and
9
//      CdlTemplatesDatabase classes.
10
//
11
//============================================================================
12
// ####ECOSHOSTGPLCOPYRIGHTBEGIN####                                        
13
// -------------------------------------------                              
14
// This file is part of the eCos host tools.                                
15
// Copyright (C) 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
16
//
17
// This program is free software; you can redistribute it and/or modify     
18
// it under the terms of the GNU General Public License as published by     
19
// the Free Software Foundation; either version 2 or (at your option) any   
20
// later version.                                                           
21
//
22
// This program is distributed in the hope that it will be useful, but      
23
// WITHOUT ANY WARRANTY; without even the implied warranty of               
24
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU        
25
// General Public License for more details.                                 
26
//
27
// You should have received a copy of the GNU General Public License        
28
// along with this program; if not, write to the                            
29
// Free Software Foundation, Inc., 51 Franklin Street,                      
30
// Fifth Floor, Boston, MA  02110-1301, USA.                                
31
// -------------------------------------------                              
32
// ####ECOSHOSTGPLCOPYRIGHTEND####                                          
33
//============================================================================
34
//#####DESCRIPTIONBEGIN####
35
//
36
// Author(s):   bartv
37
// Contact(s):  bartv
38
// Date:        1999/01/21
39
// Version:     0.02
40
//
41
//####DESCRIPTIONEND####
42
//============================================================================
43
 
44
//}}}
45
//{{{  #include's                                               
46
 
47
// ----------------------------------------------------------------------------
48
#include "cdlconfig.h"
49
 
50
// Get the infrastructure types, assertions, tracing and similar
51
// facilities.
52
#include <cyg/infra/cyg_ass.h>
53
#include <cyg/infra/cyg_trac.h>
54
 
55
// <cdl.hxx> defines everything implemented in this module.
56
// It implicitly supplies <string>, <vector> and <map> because
57
// the class definitions rely on these headers.
58
#include <cdl.hxx>
59
 
60
// strcmp() is useful when dealing with Tcl strings.
61
#include <cstring>
62
 
63
//}}}
64
 
65
//{{{  Statics                                                  
66
 
67
// ----------------------------------------------------------------------------
68
// Some test cases may want to read in a file other than
69
// "ecos.db", e.g. to facilitate testing the error conditions.
70
const char*
71
CdlPackagesDatabaseBody::database_name = "ecos.db";
72
 
73
// Should warnings be issued for minor database inconsistencies?
74
bool CdlPackagesDatabaseBody::verbose_mode      = false;
75
 
76
// The new_package etc. commands need to store the name of the
77
// current package so that subsequent commands can do the right thing.
78
// Using constant strings as the key avoids typo problems.
79
const char*     dbparser_pkgname                = "::dbparser_pkgname";
80
const char*     dbparser_pkgdata                = "__cdl_dbparser_pkgdata";
81
const char*     dbparser_targetname             = "::dbparser_targetname";
82
const char*     dbparser_targetdata             = "__cdl_dbparser_targetdata";
83
const char*     dbparser_component_repository   = "::component_repository";
84
const char*     dbparser_database_key           = "__dbparser_key";       // for assoc data
85
const char*     template_description_key        = "__cdl_extract_template_description"; // ditto
86
const char*     template_packages_key           = "__cdl_extract_template_packages";
87
 
88
// These are useful for generating diagnostics.
89
static std::string diag_package = std::string("package ");
90
static std::string diag_target  = std::string("target ");
91
 
92
CYGDBG_DEFINE_MEMLEAK_COUNTER(CdlPackagesDatabaseBody);
93
 
94
//}}}
95
//{{{  Tcl commands for the parser                              
96
 
97
//{{{  CdlDbParser class                                
98
 
99
// ----------------------------------------------------------------------------
100
// Commands that get invoked from inside the Tcl interpreter. These
101
// need access to the internals of the database objects, which can be
102
// achieved by making them static members of a CdlDbParser class.
103
 
104
class CdlDbParser {
105
  public:
106
    static int new_package(CdlInterpreter, int, const char*[]);
107
    static int package_description(CdlInterpreter, int, const char*[]);
108
    static int package_alias(CdlInterpreter, int, const char*[]);
109
    static int package_directory(CdlInterpreter, int, const char*[]);
110
    static int package_script(CdlInterpreter, int, const char*[]);
111
    static int package_hardware(CdlInterpreter, int, const char*[]);
112
 
113
    static int new_target(CdlInterpreter, int, const char*[]);
114
    static int target_description(CdlInterpreter, int, const char*[]);
115
    static int target_alias(CdlInterpreter, int, const char*[]);
116
    static int target_packages(CdlInterpreter, int, const char*[]);
117
    static int target_enable(CdlInterpreter, int, const char*[]);
118
    static int target_disable(CdlInterpreter, int, const char*[]);
119
    static int target_set_value(CdlInterpreter, int, const char*[]);
120
};
121
 
122
//}}}
123
//{{{  CdlDbParser::package-related                     
124
 
125
// ----------------------------------------------------------------------------
126
// package <name> <body>
127
 
128
int
129
CdlDbParser::new_package(CdlInterpreter interp, int argc, const char* argv[])
130
{
131
    CYG_REPORT_FUNCNAMETYPE("CdlDbParser::new_package", "result %d");
132
    CYG_REPORT_FUNCARG1XV(argc);
133
    CYG_PRECONDITION_CLASSC(interp);
134
 
135
    CdlPackagesDatabase db      = static_cast<CdlPackagesDatabase>(interp->get_assoc_data(dbparser_database_key));
136
    CYG_INVARIANT_CLASSC(CdlPackagesDatabaseBody, db);
137
 
138
    if (3 != argc) {
139
        if (argc < 2) {
140
            CdlParse::report_error(interp, "", "Invalid package command, missing name and contents.");
141
        } else if (argc == 2) {
142
            CdlParse::report_error(interp, diag_package + argv[1], "Invalid package command, missing body.");
143
        } else {
144
            CdlParse::report_error(interp, diag_package + argv[1],
145
                                   "Invalid package command, expecting just name and body.");
146
        }
147
        CYG_REPORT_RETVAL(TCL_OK);
148
        return TCL_OK;
149
    }
150
    std::string pkg_name        = argv[1];
151
 
152
    // The package data is constructed locally. It only gets added to
153
    // the database in the absence of errors.
154
    bool package_ok      = true;
155
    int  old_error_count = CdlParse::get_error_count(interp);
156
 
157
    CdlPackagesDatabaseBody::package_data package;
158
    package.description = "";
159
    package.directory   = "";
160
    package.script      = "";
161
    package.hardware    = false;
162
 
163
    // aliases and versions are vectors and will take care of themselves
164
    // And the name had better be valid as well.
165
    if (!Cdl::is_valid_cdl_name(pkg_name)) {
166
        CdlParse::report_error(interp, diag_package + pkg_name, "This is not a valid CDL name.");
167
    }
168
 
169
    // Sort out the commands, then invoke the script in argv[2]. There is
170
    // no need to worry about error recovery here, any errors will be
171
    // fatal anyway.
172
    CdlInterpreterCommandEntry commands[] = {
173
        CdlInterpreterCommandEntry("description", &CdlDbParser::package_description ),
174
        CdlInterpreterCommandEntry("alias",       &CdlDbParser::package_alias       ),
175
        CdlInterpreterCommandEntry("directory",   &CdlDbParser::package_directory   ),
176
        CdlInterpreterCommandEntry("script",      &CdlDbParser::package_script      ),
177
        CdlInterpreterCommandEntry("hardware",    &CdlDbParser::package_hardware    ),
178
        CdlInterpreterCommandEntry("",            0                                 )
179
    };
180
    CdlInterpreterBody::CommandSupport  cmds(interp, commands);
181
    CdlInterpreterBody::VariableSupport interp_name(interp, dbparser_pkgname, pkg_name);
182
    CdlInterpreterBody::AssocSupport    interp_data(interp, dbparser_pkgdata, static_cast<ClientData>(&package));
183
    int result = interp->eval(argv[2]);
184
    if (TCL_OK == result) {
185
 
186
        // The body has been parsed OK. Check that it is valid.
187
        if ("" == package.directory) {
188
            CdlParse::report_error(interp, diag_package + pkg_name, "Missing directory specification.");
189
        }
190
        if ("" == package.script) {
191
            CdlParse::report_error(interp, diag_package + pkg_name, "Missing script specification.");
192
        }
193
        if (0 == package.aliases.size()) {
194
            CdlParse::report_error(interp, diag_package + pkg_name, "At least one alias should be supplied.");
195
        }
196
 
197
        // Additional checks. Is the package directory actually present?
198
        // Note that there are scenarios where a package may be listed
199
        // in the database but not installed, e.g. an anoncvs checkout
200
        // of selected modules.
201
        if ("" != package.directory) {
202
            std::string repo = interp->get_variable(dbparser_component_repository);
203
            CYG_ASSERTC("" != repo);
204
 
205
            std::string pkgdir = repo + "/" + package.directory;
206
            if (!interp->is_directory(pkgdir)) {
207
                if (CdlPackagesDatabaseBody::verbose_mode) {
208
                    CdlParse::report_warning(interp, diag_package + pkg_name,
209
                                             std::string("This package is not present in the component repository.\n"
210
                                                         "There is no directory `") + pkgdir + "'.");
211
                }
212
                package_ok = false;
213
            } else {
214
 
215
                // Now look for version subdirectories. There should be at least one.
216
                std::vector<std::string> subdirs;
217
                unsigned int i;
218
                interp->locate_subdirs(pkgdir, subdirs);
219
                for (i = 0; i < subdirs.size(); i++) {
220
                    if (("CVS" == subdirs[i]) || ("cvs" == subdirs[i])) {
221
                        continue;
222
                    }
223
                    if ("" != package.script) {
224
                        if (!(interp->is_file(pkgdir + "/" + subdirs[i] + "/cdl/" + package.script) ||
225
                              interp->is_file(pkgdir + "/" + subdirs[i] + "/" + package.script))) {
226
                            CdlParse::report_warning(interp, diag_package + pkg_name,
227
                                                     std::string("Version subdirectory `") + subdirs[i] +
228
                                                     "' does not have a CDL script `" + package.script + "'.");
229
                            continue;
230
                        }
231
                    }
232
                    package.versions.push_back(subdirs[i]);
233
                    package.repositories[subdirs[i]] = repo;
234
                }
235
                if (0 == package.versions.size()) {
236
                    CdlParse::report_warning(interp, diag_package + pkg_name,
237
                                             "This package does not have any valid version subdirectories.");
238
                    package_ok = false;
239
                }
240
            }
241
        }
242
    }
243
 
244
    // If the package is still ok, now is the time to add it to the database.
245
    // It may be a new package, or there may already be an entry from a previous
246
    // repository.
247
    if (package_ok && (old_error_count == CdlParse::get_error_count(interp))) {
248
        if ( std::find(db->package_names.begin(), db->package_names.end(), pkg_name) == db->package_names.end()) {
249
            db->package_names.push_back(pkg_name);
250
            db->packages[pkg_name] = package;
251
        } else {
252
            // Only add versions which are not already present.
253
            std::vector<std::string>::const_iterator version_i;
254
            for (version_i = package.versions.begin(); version_i != package.versions.end(); version_i++) {
255
                if (std::find(db->packages[pkg_name].versions.begin(), db->packages[pkg_name].versions.end(),
256
                              *version_i) == db->packages[pkg_name].versions.end()) {
257
                    db->packages[pkg_name].versions.push_back(*version_i);
258
                    db->packages[pkg_name].repositories[*version_i] = package.repositories[*version_i];
259
                }
260
            }
261
        }
262
    }
263
 
264
    CYG_REPORT_RETVAL(result);
265
    return result;
266
}
267
 
268
// Syntax: description <text>
269
int
270
CdlDbParser::package_description(CdlInterpreter interp, int argc, const char* argv[])
271
{
272
    CYG_REPORT_FUNCNAMETYPE("CdlDbParser::package_description", "result %d");
273
    CYG_REPORT_FUNCARG1XV(argc);
274
    CYG_PRECONDITION_CLASSC(interp);
275
 
276
    std::string name = interp->get_variable(dbparser_pkgname);
277
    CYG_ASSERTC("" != name);
278
    CdlPackagesDatabaseBody::package_data* package =
279
        static_cast<CdlPackagesDatabaseBody::package_data*>(interp->get_assoc_data(dbparser_pkgdata));
280
 
281
    if (2 != argc) {
282
        CdlParse::report_error(interp, diag_package + name, "Invalid description, expecting a single string.");
283
    } else if ("" != package->description) {
284
        CdlParse::report_warning(interp, diag_package + name, "A package should have only one description.");
285
    } else {
286
        package->description = argv[1];
287
    }
288
 
289
    CYG_REPORT_RETVAL(TCL_OK);
290
    return TCL_OK;
291
}
292
 
293
// Syntax: alias <list>
294
// For example: alias { "This is an alias" another_alias dummy_name }
295
int
296
CdlDbParser::package_alias(CdlInterpreter interp, int argc, const char* argv[])
297
{
298
    CYG_REPORT_FUNCNAMETYPE("CdlDbParser::package_alias", "result %d");
299
    CYG_REPORT_FUNCARG1XV(argc);
300
    CYG_PRECONDITION_CLASSC(interp);
301
 
302
    std::string name = interp->get_variable(dbparser_pkgname);
303
    CYG_ASSERTC("" != name);
304
    CdlPackagesDatabaseBody::package_data* package =
305
        static_cast<CdlPackagesDatabaseBody::package_data*>(interp->get_assoc_data(dbparser_pkgdata));
306
 
307
    // There should be one argument, a list of valid packages.
308
    // Also, the alias command should be used only once
309
    if (2 != argc) {
310
        CdlParse::report_error(interp, diag_package + name,
311
                               "The alias command should be followed by a list of known aliases.");
312
    } else if (0 < package->aliases.size()) {
313
        CdlParse::report_warning(interp, diag_package + name, "There should be only one list of aliases.");
314
    } else {
315
        int          list_count     = 0;
316
        const char** list_entries   = 0;
317
        Tcl_Interp* tcl_interp      = interp->get_tcl_interpreter();
318
        if (TCL_OK != Tcl_SplitList(tcl_interp, CDL_TCL_CONST_CAST(char*, argv[1]), &list_count, CDL_TCL_CONST_CAST(char***, &list_entries))) {
319
            CdlParse::report_error(interp, diag_package + name, Tcl_GetStringResult(tcl_interp));
320
        } else {
321
            if (0 == list_count) {
322
                CdlParse::report_error(interp, diag_package + name, "At least one alias should be supplied.");
323
            } else {
324
                for (int i = 0; i < list_count; i++) {
325
                    package->aliases.push_back(list_entries[i]);
326
                }
327
            }
328
            Tcl_Free((char*)list_entries);
329
        }
330
    }
331
 
332
    CYG_REPORT_RETVAL(TCL_OK);
333
    return TCL_OK;
334
}
335
 
336
// Syntax: directory <path>
337
// The path is of course relative to the component repository.
338
int
339
CdlDbParser::package_directory(CdlInterpreter interp, int argc, const char* argv[])
340
{
341
    CYG_REPORT_FUNCNAMETYPE("CdlDbParser::package_directory", "result %d");
342
    CYG_REPORT_FUNCARG1XV(argc);
343
    CYG_PRECONDITION_CLASSC(interp);
344
 
345
    std::string name = interp->get_variable(dbparser_pkgname);
346
    CYG_ASSERTC("" != name);
347
    CdlPackagesDatabaseBody::package_data* package =
348
        static_cast<CdlPackagesDatabaseBody::package_data*>(interp->get_assoc_data(dbparser_pkgdata));
349
 
350
    // There should be exactly one argument, and the directory command
351
    // should be used only once.
352
    if (2 != argc) {
353
        CdlParse::report_error(interp, diag_package + name, "Only one directory can be specified.");
354
    } else if ("" != package->directory) {
355
        CdlParse::report_warning(interp, diag_package + name, "A package can be located in only one directory.");
356
    } else {
357
        package->directory = argv[1];
358
    }
359
    CYG_REPORT_RETVAL(TCL_OK);
360
    return TCL_OK;
361
}
362
 
363
// Syntax: hardware
364
// There are no arguments.
365
int
366
CdlDbParser::package_hardware(CdlInterpreter interp, int argc, const char* argv[])
367
{
368
    CYG_REPORT_FUNCNAMETYPE("CdlDbParser::package_hardware", "result %d");
369
    CYG_REPORT_FUNCARG1XV(argc);
370
    CYG_PRECONDITION_CLASSC(interp);
371
 
372
    std::string name = interp->get_variable(dbparser_pkgname);
373
    CYG_ASSERTC("" != name);
374
    CdlPackagesDatabaseBody::package_data* package =
375
        static_cast<CdlPackagesDatabaseBody::package_data*>(interp->get_assoc_data(dbparser_pkgdata));
376
 
377
    if (1 != argc) {
378
        CdlParse::report_error(interp, diag_package + name, "There should be no further data after hardware.");
379
    } else if (package->hardware) {
380
        CdlParse::report_warning(interp, diag_package + name, "The hardware property should be specified only once");
381
    } else {
382
        package->hardware    = true;
383
    }
384
 
385
    CYG_REPORT_RETVAL(TCL_OK);
386
    return TCL_OK;
387
}
388
 
389
// Syntax: script <filename>
390
int
391
CdlDbParser::package_script(CdlInterpreter interp, int argc, const char* argv[])
392
{
393
    CYG_REPORT_FUNCNAMETYPE("CdlDbParser::package_script", "result %d");
394
    CYG_REPORT_FUNCARG1XV(argc);
395
    CYG_PRECONDITION_CLASSC(interp);
396
 
397
    std::string name = interp->get_variable(dbparser_pkgname);
398
    CYG_ASSERTC("" != name);
399
    CdlPackagesDatabaseBody::package_data* package =
400
        static_cast<CdlPackagesDatabaseBody::package_data*>(interp->get_assoc_data(dbparser_pkgdata));
401
 
402
    // There should be exactly one argument, and the script command
403
    // should be used only once
404
    if (2 != argc) {
405
        CdlParse::report_error(interp, diag_package + name, "Only one CDL script can be specified.");
406
    } else if ("" != package->script) {
407
        CdlParse::report_warning(interp, diag_package + name, "A package can have only one starting CDL script.");
408
    } else {
409
        package->script = argv[1];
410
    }
411
 
412
    CYG_REPORT_RETVAL(TCL_OK);
413
    return TCL_OK;
414
}
415
 
416
//}}}
417
//{{{  CdlDbParser::target-related                      
418
 
419
// ----------------------------------------------------------------------------
420
// target <name> <body>
421
 
422
int
423
CdlDbParser::new_target(CdlInterpreter interp, int argc, const char* argv[])
424
{
425
    CYG_REPORT_FUNCNAMETYPE("CdlDbParser::new_target", "result %d");
426
    CYG_REPORT_FUNCARG1XV(argc);
427
    CYG_PRECONDITION_CLASSC(interp);
428
 
429
    CdlPackagesDatabase db      = static_cast<CdlPackagesDatabase>(interp->get_assoc_data(dbparser_database_key));
430
    CYG_INVARIANT_CLASSC(CdlPackagesDatabaseBody, db);
431
 
432
    if (3 != argc) {
433
        if (argc < 2) {
434
            CdlParse::report_error(interp, "", "Invalid target command, missing name and contents.");
435
        } else if (argc == 2) {
436
            CdlParse::report_error(interp, diag_target + argv[1], "Invalid target command, missing body.");
437
        } else {
438
            CdlParse::report_error(interp, diag_target + argv[1], "Invalid target command, expecting just name and body.");
439
        }
440
        CYG_REPORT_RETVAL(TCL_OK);
441
        return TCL_OK;
442
    }
443
 
444
    std::string target_name     = argv[1];
445
 
446
    // This may be a duplicate definition if the target was defined in an
447
    // earlier repository
448
    if (std::find(db->target_names.begin(), db->target_names.end(), target_name) != db->target_names.end()) {
449
        CYG_REPORT_RETVAL(TCL_OK);
450
        return TCL_OK;
451
    }
452
 
453
    // The target data is constructed locally. It only gets added to the
454
    // database in the absence of errors.
455
    bool target_ok = true;
456
    int old_error_count = CdlParse::get_error_count(interp);
457
 
458
    CdlPackagesDatabaseBody::target_data target;
459
    target.description = "";
460
    // aliases, packages and compiler_flags are vectors and will take care of themselves
461
 
462
    // Sort out the commands, then invoke the script in argv[2]. There is
463
    // no need to worry about error recovery here, any errors will be
464
    // fatal anyway.
465
    CdlInterpreterCommandEntry commands[] = {
466
        CdlInterpreterCommandEntry("description",    &CdlDbParser::target_description    ),
467
        CdlInterpreterCommandEntry("alias",          &CdlDbParser::target_alias          ),
468
        CdlInterpreterCommandEntry("packages",       &CdlDbParser::target_packages       ),
469
        CdlInterpreterCommandEntry("enable",         &CdlDbParser::target_enable         ),
470
        CdlInterpreterCommandEntry("disable",        &CdlDbParser::target_disable        ),
471
        CdlInterpreterCommandEntry("set_value",      &CdlDbParser::target_set_value      ),
472
        CdlInterpreterCommandEntry("",               0                                   )
473
    };
474
    CdlInterpreterBody::CommandSupport  interp_cmds(interp, commands);
475
    CdlInterpreterBody::VariableSupport interp_name(interp, dbparser_targetname, target_name);
476
    CdlInterpreterBody::AssocSupport    interp_data(interp, dbparser_targetdata, static_cast<ClientData>(&target));
477
    int result = interp->eval(argv[2]);
478
    if (TCL_OK == result) {
479
 
480
        if (0 == target.aliases.size()) {
481
            CdlParse::report_error(interp, diag_target + target_name, "At least one alias should be supplied.");
482
        }
483
 
484
        // There is no check for > 0 hardware packages. This is an unlikely
485
        // scenario but should be allowed for.
486
        // Add this target to the list.
487
    }
488
 
489
    if (target_ok && (old_error_count == CdlParse::get_error_count(interp))) {
490
        db->target_names.push_back(target_name);
491
        db->targets[target_name] = target;
492
    }
493
 
494
    CYG_REPORT_RETVAL(result);
495
    return result;
496
}
497
 
498
// Syntax: description <text>
499
int
500
CdlDbParser::target_description(CdlInterpreter interp, int argc, const char* argv[])
501
{
502
    CYG_REPORT_FUNCNAMETYPE("CdlDbParser::target_description", "result %d");
503
    CYG_REPORT_FUNCARG1XV(argc);
504
    CYG_PRECONDITION_CLASSC(interp);
505
 
506
    std::string name = interp->get_variable(dbparser_targetname);
507
    CYG_ASSERTC("" != name);
508
    CdlPackagesDatabaseBody::target_data* target =
509
        static_cast<CdlPackagesDatabaseBody::target_data*>(interp->get_assoc_data(dbparser_targetdata));
510
 
511
    if (2 != argc) {
512
        CdlParse::report_error(interp, diag_target + name, "The target description should be a single string.");
513
    } else if ("" != target->description) {
514
        CdlParse::report_warning(interp, diag_target + name, "A target should have only one description.");
515
    } else {
516
        target->description = argv[1];
517
    }
518
 
519
    CYG_REPORT_RETVAL(TCL_OK);
520
    return TCL_OK;
521
}
522
 
523
// Syntax: alias <list>
524
// For example: alias { "This is an alias" another_alias dummy_name }
525
int
526
CdlDbParser::target_alias(CdlInterpreter interp, int argc, const char* argv[])
527
{
528
    CYG_REPORT_FUNCNAMETYPE("CdlDbParser::target_alias", "result %d");
529
    CYG_REPORT_FUNCARG1XV(argc);
530
    CYG_PRECONDITION_CLASSC(interp);
531
 
532
    std::string name = interp->get_variable(dbparser_targetname);
533
    CYG_ASSERTC("" != name);
534
    CdlPackagesDatabaseBody::target_data* target =
535
        static_cast<CdlPackagesDatabaseBody::target_data*>(interp->get_assoc_data(dbparser_targetdata));
536
 
537
    // There should be one argument, a list of valid aliases
538
    // The alias command should be used only once
539
    if (2 != argc) {
540
        CdlParse::report_error(interp, diag_target + name, "The alias command should be followed by a list of known aliases");
541
    } else if (0 < target->aliases.size()) {
542
        CdlParse::report_warning(interp, diag_target + name, "There should be only one list of aliases.");
543
    } else {
544
        int          list_count     = 0;
545
        const char** list_entries   = 0;
546
        Tcl_Interp* tcl_interp      = interp->get_tcl_interpreter();
547
        if (TCL_OK != Tcl_SplitList(tcl_interp, CDL_TCL_CONST_CAST(char*, argv[1]), &list_count, CDL_TCL_CONST_CAST(char***, &list_entries))) {
548
            CdlParse::report_error(interp, diag_target + name, Tcl_GetStringResult(tcl_interp));
549
        } else {
550
            if (0 == list_count) {
551
                CdlParse::report_error(interp, diag_target + name, "At least one alias should be supplied.");
552
            } else {
553
                for (int i = 0; i < list_count; i++) {
554
                    target->aliases.push_back(list_entries[i]);
555
                }
556
            }
557
            Tcl_Free((char*)list_entries);
558
        }
559
    }
560
 
561
    CYG_REPORT_RETVAL(TCL_OK);
562
    return TCL_OK;
563
}
564
 
565
// Syntax: packages <list> ...
566
// For example: packages { CYGPKG_HAL_XXX CYGPKG_HAL_YYY }
567
int
568
CdlDbParser::target_packages(CdlInterpreter interp, int argc, const char* argv[])
569
{
570
    CYG_REPORT_FUNCNAMETYPE("CdlDbParser::target_packages", "result %d");
571
    CYG_REPORT_FUNCARG1XV(argc);
572
    CYG_PRECONDITION_CLASSC(interp);
573
 
574
    std::string name = interp->get_variable(dbparser_targetname);
575
    CYG_ASSERTC("" != name);
576
    CdlPackagesDatabaseBody::target_data* target =
577
        static_cast<CdlPackagesDatabaseBody::target_data*>(interp->get_assoc_data(dbparser_targetdata));
578
 
579
    // There should be one argument, a list of valid packages.
580
    // The packages command should be used only once
581
    if (2 != argc) {
582
        CdlParse::report_error(interp, diag_target + name, "`packages' should be followed by a list of known packages.");
583
    } else if (0 < target->packages.size()) {
584
        CdlParse::report_warning(interp, diag_target + name, "There should be only one list of packages.");
585
    } else {
586
        int          list_count     = 0;
587
        const char** list_entries   = 0;
588
        Tcl_Interp* tcl_interp      = interp->get_tcl_interpreter();
589
        if (TCL_OK != Tcl_SplitList(tcl_interp, CDL_TCL_CONST_CAST(char*, argv[1]), &list_count, CDL_TCL_CONST_CAST(char***, &list_entries))) {
590
            CdlParse::report_error(interp, diag_target + name, Tcl_GetStringResult(tcl_interp));
591
        } else {
592
            // Allow for a dummy target spec, just in case it proves useful.
593
            if (0 != list_count) {
594
                for (int i = 0; i < list_count; i++) {
595
                    target->packages.push_back(list_entries[i]);
596
                }
597
            }
598
            Tcl_Free((char*)list_entries);
599
        }
600
    }
601
 
602
    CYG_REPORT_RETVAL(TCL_OK);
603
    return TCL_OK;
604
}
605
 
606
// Syntax: enable { opt1 opt2 ... }
607
// For example: enable { CYGPKG_HAL_ARM_CL7xxx_7211 }
608
int
609
CdlDbParser::target_enable(CdlInterpreter interp, int argc, const char* argv[])
610
{
611
    CYG_REPORT_FUNCNAMETYPE("CdlDbParser::target_enable", "result %d");
612
    CYG_REPORT_FUNCARG1XV(argc);
613
    CYG_PRECONDITION_CLASSC(interp);
614
 
615
    std::string name = interp->get_variable(dbparser_targetname);
616
    CYG_ASSERTC("" != name);
617
    CdlPackagesDatabaseBody::target_data* target =
618
        static_cast<CdlPackagesDatabaseBody::target_data*>(interp->get_assoc_data(dbparser_targetdata));
619
 
620
    // There should be one argument, a list of valid flags.
621
    if (2 != argc) {
622
        CdlParse::report_error(interp, diag_target + name, "`enable' should be followed by a list of CDL options.");
623
    } else {
624
        int          list_count     = 0;
625
        const char** list_entries   = 0;
626
        Tcl_Interp* tcl_interp      = interp->get_tcl_interpreter();
627
        if (TCL_OK != Tcl_SplitList(tcl_interp, CDL_TCL_CONST_CAST(char*, argv[1]), &list_count, CDL_TCL_CONST_CAST(char***, &list_entries))) {
628
            CdlParse::report_error(interp, diag_target + name, Tcl_GetStringResult(tcl_interp));
629
        } else {
630
            for (int i = 0; i < list_count; i++) {
631
                target->enable.push_back(list_entries[i]);
632
            }
633
            Tcl_Free((char *) list_entries);
634
        }
635
    }
636
 
637
    CYG_REPORT_RETVAL(TCL_OK);
638
    return TCL_OK;
639
}
640
 
641
 
642
// Syntax: disable { opt1 opt2 ... }
643
// For example: disable { CYGPKG_HAL_ARM_CL7xxx_7111 }
644
int
645
CdlDbParser::target_disable(CdlInterpreter interp, int argc, const char* argv[])
646
{
647
    CYG_REPORT_FUNCNAMETYPE("CdlDbParser::target_disable", "result %d");
648
    CYG_REPORT_FUNCARG1XV(argc);
649
    CYG_PRECONDITION_CLASSC(interp);
650
 
651
    std::string name = interp->get_variable(dbparser_targetname);
652
    CYG_ASSERTC("" != name);
653
    CdlPackagesDatabaseBody::target_data* target =
654
        static_cast<CdlPackagesDatabaseBody::target_data*>(interp->get_assoc_data(dbparser_targetdata));
655
 
656
    // There should be one argument, a list of valid flags.
657
    if (2 != argc) {
658
        CdlParse::report_error(interp, diag_target + name, "`disable' should be followed by a list of CDL options.");
659
    } else {
660
        int          list_count     = 0;
661
        const char** list_entries   = 0;
662
        Tcl_Interp* tcl_interp      = interp->get_tcl_interpreter();
663
        if (TCL_OK != Tcl_SplitList(tcl_interp, CDL_TCL_CONST_CAST(char*, argv[1]), &list_count, CDL_TCL_CONST_CAST(char***, &list_entries))) {
664
            CdlParse::report_error(interp, diag_target + name, Tcl_GetStringResult(tcl_interp));
665
        } else {
666
            for (int i = 0; i < list_count; i++) {
667
                target->disable.push_back(list_entries[i]);
668
            }
669
            Tcl_Free((char *) list_entries);
670
        }
671
    }
672
 
673
    CYG_REPORT_RETVAL(TCL_OK);
674
    return TCL_OK;
675
}
676
 
677
// Syntax: set_value <option> <value>
678
// For example: set_value CYGHWR_MEMSIZE 0x100000
679
int
680
CdlDbParser::target_set_value(CdlInterpreter interp, int argc, const char* argv[])
681
{
682
    CYG_REPORT_FUNCNAMETYPE("CdlDbParser::target_set_value", "result %d");
683
    CYG_REPORT_FUNCARG1XV(argc);
684
    CYG_PRECONDITION_CLASSC(interp);
685
 
686
    std::string name = interp->get_variable(dbparser_targetname);
687
    CYG_ASSERTC("" != name);
688
    CdlPackagesDatabaseBody::target_data* target =
689
        static_cast<CdlPackagesDatabaseBody::target_data*>(interp->get_assoc_data(dbparser_targetdata));
690
 
691
    // There should be one argument, a list of valid flags.
692
    if (3 != argc) {
693
        CdlParse::report_error(interp, diag_target + name, "`set_value' should be followed by an option name and its value.");
694
    } else {
695
        target->set_values.push_back(std::make_pair(std::string(argv[1]), std::string(argv[2])));
696
    }
697
 
698
    CYG_REPORT_RETVAL(TCL_OK);
699
    return TCL_OK;
700
}
701
 
702
//}}}
703
 
704
//}}}
705
//{{{  CdlPackagesDatabase:: creation                           
706
 
707
// ----------------------------------------------------------------------------
708
// The exported interface is make(). The hard work is done inside the
709
// constructor.
710
 
711
CdlPackagesDatabase
712
CdlPackagesDatabaseBody::make(std::string repo, CdlDiagnosticFnPtr error_fn, CdlDiagnosticFnPtr warn_fn)
713
{
714
    CYG_REPORT_FUNCNAMETYPE("CdlPackagesDatabase::make", "database %p");
715
 
716
    // Where is the component repository? The location may come from the
717
    // parent or from an environment variable ECOS_REPOSITORY
718
    if ("" == repo) {
719
        char *env = getenv("ECOS_REPOSITORY");
720
        if (0 == env) {
721
            throw CdlInputOutputException(std::string("No component repository specified and no ") +
722
                                          std::string("ECOS_REPOSITORY environment variable"));
723
        } else {
724
            repo = env;
725
        }
726
    }
727
 
728
    // Replace any backslashes in the repository with forward slashes.
729
    // The latter are used throughout the library
730
    // NOTE: this is not i18n-friendly.
731
    for (unsigned int i = 0; i < repo.size(); i++) {
732
        if ('\\' == repo[i]) {
733
            repo[i] = '/';
734
        }
735
    }
736
    CdlPackagesDatabase result = new CdlPackagesDatabaseBody(repo, error_fn, warn_fn);
737
    CYG_REPORT_RETVAL(result);
738
    return result;
739
}
740
 
741
// ----------------------------------------------------------------------------
742
 
743
CdlPackagesDatabaseBody::CdlPackagesDatabaseBody(std::string repo, CdlDiagnosticFnPtr error_fn, CdlDiagnosticFnPtr warn_fn)
744
{
745
    CYG_REPORT_FUNCNAME("CdlPackagesDatabase:: constructor");
746
    CYG_PRECONDITIONC("" != repo);
747
 
748
    // There will be calls to check_this() while the database is evaluated,
749
    // so make sure that the database is valid first.
750
    component_repository                = repo;
751
    cdlpackagesdatabasebody_cookie      = CdlPackagesDatabaseBody_Magic;
752
 
753
    // We want to read in the entire packages file. Portability problems
754
    // can be largely eliminated by using a Tcl interpreter for this, but
755
    // under Windows there is a problem if the pathname is a cygwin one.
756
    // For now it is assumed that the supplied pathname is acceptable to
757
    // Tcl.
758
    //
759
    // No attempt is made at this stage to use a safe interpreter.
760
    // Some file I/O operations are needed while processing the data,
761
    // for example to check that a package is actually installed.
762
    // Additional file I/O may prove useful in future, e.g. to create
763
    // some or all of a database on the fly. Obviously some
764
    // restrictions are desirable (no modify access to the repository,
765
    // no network capabilities, and so on.) These have to be added
766
    // in future.
767
 
768
    CdlInterpreter interp = CdlInterpreterBody::make();
769
 
770
    try {
771
 
772
        CdlInterpreterBody::ContextSupport context(interp, database_name);
773
        CdlInterpreterCommandEntry commands[] =
774
        {
775
            CdlInterpreterCommandEntry("package",  &CdlDbParser::new_package  ),
776
            CdlInterpreterCommandEntry("target",   &CdlDbParser::new_target   ),
777
            CdlInterpreterCommandEntry("",         0                          )
778
        };
779
        CdlInterpreterBody::CommandSupport cmds(interp, commands);
780
        CdlInterpreterBody::DiagSupport diag(interp, error_fn, warn_fn);
781
        CdlInterpreterBody::AssocSupport assoc(interp, dbparser_database_key, static_cast<ClientData>(this));
782
        interp->add_command("unknown", &CdlParse::unknown_command);
783
        CdlParse::clear_error_count(interp);
784
 
785
        unsigned int index, search;
786
        for ( index = 0; index < repo.size(); ) {
787
 
788
            // Get the next entry in the search path. In a normal world
789
            // the separator is :, but in a VC++ Windows world it is ;
790
            for ( search = index; search < repo.size(); search++) {
791
#ifdef _MSC_VER
792
                if ( ';' == repo[search]) {
793
                    break;
794
                }
795
#else
796
                if ( ':' == repo[search]) {
797
                    break;
798
                }
799
#endif                
800
            }
801
            std::string this_repo   = repo.substr(index, search - index);
802
            index = search + 1;
803
 
804
            // Ignore errors at this stage, instead check error count at the end.
805
            interp->set_variable(std::string(dbparser_component_repository), this_repo);
806
            (void) interp->eval_file(this_repo + "/" + database_name);
807
 
808
            // Now start looking for templates. These should reside in the
809
            // templates subdirectory of the component repository. Each template
810
            // should be in its own directory, and inside each directory should
811
            // be versioned template files with a .ect extension.
812
            std::string templates_dir = this_repo + "/" + "templates";
813
            std::vector<std::string> subdirs;
814
            interp->locate_subdirs(templates_dir, subdirs);
815
 
816
            unsigned int i;
817
            for (i = 0; i < subdirs.size(); i++) {
818
                // Do not add the template to the known ones until we are sure there is
819
                // at least one valid template.
820
                std::vector<std::string> files;
821
                interp->locate_files(templates_dir + "/" + subdirs[i], files);
822
                unsigned int j;
823
                for (j = 0; j < files.size(); j++) {
824
                    if ((4 < files[j].size()) && (".ect" == files[j].substr(files[j].size() - 4))) {
825
                        break;
826
                    }
827
                }
828
                if (j != files.size()) {
829
                    std::string tmplt = subdirs[i];
830
                    if  (std::find(this->template_names.begin(), this->template_names.end(), tmplt) == this->template_names.end()) {
831
                        this->template_names.push_back(tmplt);
832
                    }
833
                    for ( ; j < files.size(); j++) {
834
                        if ((4 < files[j].size()) && (".ect" == files[j].substr(files[j].size() - 4))) {
835
                            std::string version = files[j].substr(0, files[j].size() - 4);
836
                            if (std::find(templates[tmplt].versions.begin(), templates[tmplt].versions.end(), version) == templates[tmplt].versions.end()) {
837
                                templates[tmplt].versions.push_back(version);
838
                                templates[tmplt].files[version] = templates_dir + "/" + tmplt + "/" + files[j] ;
839
                            }
840
                        }
841
                    }
842
                }
843
            }
844
        }
845
 
846
        // The package and template version should be sorted
847
        std::vector<std::string>::const_iterator pkg_i;
848
        for (pkg_i = package_names.begin(); pkg_i != package_names.end(); pkg_i++) {
849
            std::sort(packages[*pkg_i].versions.begin(), packages[*pkg_i].versions.end(), Cdl::version_cmp());
850
        }
851
        std::vector<std::string>::const_iterator tmpl_i;
852
        for (tmpl_i = template_names.begin(); tmpl_i != template_names.end(); tmpl_i++) {
853
            std::sort(templates[*tmpl_i].versions.begin(), templates[*tmpl_i].versions.end(), Cdl::version_cmp());
854
        }
855
 
856
        // Consistency checks. All target-specific packages should
857
        // have the hardware attribute. Also, all the packages should
858
        // exist. Problems only result in warnings and only when
859
        // operating in verbose mode, to allow for somewhat
860
        // inconsistent repositories e.g. an anoncvs tree.
861
        if (CdlPackagesDatabaseBody::verbose_mode) {
862
            std::vector<std::string>::const_iterator name_i;
863
            std::vector<std::string>::const_iterator name_j;
864
            for (name_i = target_names.begin(); name_i != target_names.end(); name_i++) {
865
                for (name_j = targets[*name_i].packages.begin(); name_j != targets[*name_i].packages.end(); name_j++) {
866
                    if (std::find(package_names.begin(), package_names.end(), *name_j) == package_names.end()) {
867
                        CdlParse::report_warning(interp, diag_target + *name_i,
868
                                                 std::string("This target refers to an unknown package `") + *name_j + "'.");
869
                        }
870
                    if (!packages[*name_j].hardware) {
871
                        CdlParse::report_warning(interp, diag_target + *name_i,
872
                                                 std::string("This target refers to a package `") + *name_j +
873
                                                 "' that is not hardware-specific.");
874
                    }
875
                }
876
            }
877
        }
878
 
879
        // Now, were there any errors while reading in the database?
880
        // If so it is necessary to throw an exception here, to make sure
881
        // that things get cleaned up properly.
882
        int error_count = CdlParse::get_error_count(interp);
883
        if (0 != error_count) {
884
            throw CdlInputOutputException("Invalid package database.");
885
        }
886
    } catch(...) {
887
        // Something has gone wrong. Clear out all of the data accumulated so far, as well
888
        // as the interpreter.
889
        delete interp;
890
        package_names.clear();
891
        target_names.clear();
892
        template_names.clear();
893
        packages.clear();
894
        targets.clear();
895
        templates.clear();
896
        throw;
897
    }
898
 
899
    delete interp;
900
    CYGDBG_MEMLEAK_CONSTRUCTOR();
901
 
902
    CYG_REPORT_RETURN();
903
}
904
 
905
//}}}
906
//{{{  CdlPackagesDatabase:: destructor                         
907
 
908
// ----------------------------------------------------------------------------
909
CdlPackagesDatabaseBody::~CdlPackagesDatabaseBody()
910
{
911
    CYG_REPORT_FUNCNAME("CdlPackagesDatabase:: default destructor");
912
    CYG_REPORT_FUNCARG1XV(this);
913
    CYG_PRECONDITION_THISC();
914
 
915
    cdlpackagesdatabasebody_cookie      = CdlPackagesDatabaseBody_Invalid;
916
    component_repository                = "";
917
    package_names.clear();
918
    target_names.clear();
919
    template_names.clear();
920
    packages.clear();
921
    targets.clear();
922
    templates.clear();
923
 
924
    CYGDBG_MEMLEAK_DESTRUCTOR();
925
 
926
    CYG_REPORT_RETURN();
927
}
928
 
929
//}}}
930
//{{{  CdlPackagesDatabase:: check_this()                       
931
 
932
// ----------------------------------------------------------------------------
933
 
934
bool
935
CdlPackagesDatabaseBody::check_this(cyg_assert_class_zeal zeal) const
936
{
937
    if (CdlPackagesDatabaseBody_Magic != cdlpackagesdatabasebody_cookie) {
938
        return false;
939
    }
940
    CYGDBG_MEMLEAK_CHECKTHIS();
941
 
942
    switch(zeal) {
943
      case cyg_system_test :
944
      case cyg_extreme :
945
      {
946
          std::vector<std::string>::const_iterator              names_i;
947
          std::map<std::string,package_data>::const_iterator    pkgs_i;
948
 
949
          // Every entry in the names vector should have an entry in the packages vector.
950
          for (names_i = package_names.begin(); names_i != package_names.end(); names_i++) {
951
              if (packages.find(*names_i) == packages.end()) {
952
                  return false;
953
              }
954
          }
955
          // The inverse should be true as well
956
          for (pkgs_i = packages.begin(); pkgs_i != packages.end(); pkgs_i++) {
957
              if (std::find(package_names.begin(), package_names.end(), pkgs_i->first) == package_names.end()) {
958
                  return false;
959
              }
960
          }
961
 
962
          // Repeat for targets.
963
          std::map<std::string,target_data>::const_iterator     targets_i;
964
          for (names_i = target_names.begin(); names_i != target_names.end(); names_i++) {
965
              if (targets.find(*names_i) == targets.end()) {
966
                  return false;
967
              }
968
          }
969
          for (targets_i = targets.begin(); targets_i != targets.end(); targets_i++) {
970
              if (std::find(target_names.begin(), target_names.end(), targets_i->first) == target_names.end()) {
971
                  return false;
972
              }
973
          }
974
 
975
          // And for templates
976
          std::map<std::string,template_data>::const_iterator    templates_i;
977
          for (names_i = template_names.begin(); names_i != template_names.end(); names_i++) {
978
              if (templates.find(*names_i) == templates.end()) {
979
                  return false;
980
              }
981
          }
982
          // The inverse should be true as well
983
          for (templates_i = templates.begin(); templates_i != templates.end(); templates_i++) {
984
              if (std::find(template_names.begin(), template_names.end(), templates_i->first) == template_names.end()) {
985
                  return false;
986
              }
987
          }
988
 
989
          // Possibly the package directories should be validated as
990
          // well, not to mention the various version subdirectories,
991
          // but doing file I/O inside an assertion is excessive.
992
      }
993
      case cyg_thorough :
994
      case cyg_quick:
995
          if ("" == component_repository) {
996
              return false;
997
          }
998
      case cyg_trivial:
999
      case cyg_none :
1000
        break;
1001
    }
1002
 
1003
    return true;
1004
}
1005
 
1006
//}}}
1007
//{{{  CdlPackagesDatabase:: misc                               
1008
 
1009
// ----------------------------------------------------------------------------
1010
 
1011
std::string
1012
CdlPackagesDatabaseBody::get_component_repository() const
1013
{
1014
    CYG_REPORT_FUNCNAME("CdlPackagesDatabase::get_component_repository");
1015
    CYG_REPORT_FUNCARG1XV(this);
1016
    CYG_PRECONDITION_THISC();
1017
 
1018
    CYG_REPORT_RETURN();
1019
    return component_repository;
1020
}
1021
 
1022
void
1023
CdlPackagesDatabaseBody::set_verbose(bool new_mode)
1024
{
1025
    CYG_REPORT_FUNCNAME("CdlPackagesDatabase::set_verbose");
1026
    CYG_REPORT_FUNCARG1XV(new_mode);
1027
 
1028
    verbose_mode = new_mode;
1029
 
1030
    CYG_REPORT_RETURN();
1031
}
1032
 
1033
//}}}
1034
//{{{  CdlPackagesDatabase:: get package information            
1035
 
1036
// ----------------------------------------------------------------------------
1037
 
1038
const std::vector<std::string>&
1039
CdlPackagesDatabaseBody::get_packages(void) const
1040
{
1041
    CYG_REPORT_FUNCNAME("CdlPackagesDatabase::get_packages");
1042
    CYG_REPORT_FUNCARG1XV(this);
1043
    CYG_PRECONDITION_THISC();
1044
 
1045
    CYG_REPORT_RETURN();
1046
    return package_names;
1047
}
1048
 
1049
bool
1050
CdlPackagesDatabaseBody::is_known_package(std::string name) const
1051
{
1052
    CYG_REPORT_FUNCNAMETYPE("CdlPackagesDatabase::is_known_package", "result %d");
1053
    CYG_REPORT_FUNCARG1XV(this);
1054
    CYG_PRECONDITION_THISC();
1055
 
1056
    bool result = false;
1057
    if (std::find(package_names.begin(), package_names.end(), name) != package_names.end()) {
1058
        result = true;
1059
    }
1060
 
1061
    CYG_REPORT_RETVAL(result);
1062
    return result;
1063
}
1064
 
1065
const std::string&
1066
CdlPackagesDatabaseBody::get_package_description(std::string pkg_name) const
1067
{
1068
    CYG_REPORT_FUNCNAME("CdlPackagesDatabase::get_package_description");
1069
    CYG_REPORT_FUNCARG1XV(this);
1070
    CYG_PRECONDITION_THISC();
1071
 
1072
    std::map<std::string,package_data>::const_iterator pkgs_i = packages.find(pkg_name);
1073
    if (pkgs_i != packages.end()) {
1074
        CYG_REPORT_RETURN();
1075
        return pkgs_i->second.description;
1076
    }
1077
 
1078
    CYG_FAIL("Invalid package name passed to CdlPackagesDatabase::get_package_description()");
1079
    static std::string dummy = "";
1080
    return dummy;
1081
}
1082
 
1083
const std::vector<std::string>&
1084
CdlPackagesDatabaseBody::get_package_aliases(std::string pkg_name) const
1085
{
1086
    CYG_REPORT_FUNCNAME("CdlPackagesDatabase::get_package_aliases");
1087
    CYG_REPORT_FUNCARG1XV(this);
1088
    CYG_PRECONDITION_THISC();
1089
 
1090
    std::map<std::string,package_data>::const_iterator pkgs_i = packages.find(pkg_name);
1091
    if (pkgs_i != packages.end()) {
1092
        CYG_REPORT_RETURN();
1093
        return pkgs_i->second.aliases;
1094
    }
1095
 
1096
    CYG_FAIL("Invalid package name passed to CdlPackagesDatabase::get_package_aliases()");
1097
    static std::vector<std::string> dummy;
1098
    return dummy;
1099
}
1100
 
1101
const std::vector<std::string>&
1102
CdlPackagesDatabaseBody::get_package_versions(std::string pkg_name) const
1103
{
1104
    CYG_REPORT_FUNCNAME("CdlPackagesDatabase::get_package_versions");
1105
    CYG_REPORT_FUNCARG1XV(this);
1106
    CYG_PRECONDITION_THISC();
1107
 
1108
    std::map<std::string,package_data>::const_iterator pkgs_i = packages.find(pkg_name);
1109
    if (pkgs_i != packages.end()) {
1110
        CYG_REPORT_RETURN();
1111
        return pkgs_i->second.versions;
1112
    }
1113
 
1114
    CYG_FAIL("Invalid package name passed to CdlPackagesDatabase::get_package_versions()");
1115
    static std::vector<std::string> dummy;
1116
    return dummy;
1117
}
1118
 
1119
const std::string&
1120
CdlPackagesDatabaseBody::get_package_directory(std::string pkg_name) const
1121
{
1122
    CYG_REPORT_FUNCNAME("CdlPackagesDatabase::get_package_directory");
1123
    CYG_REPORT_FUNCARG1XV(this);
1124
    CYG_PRECONDITION_THISC();
1125
 
1126
    std::map<std::string,package_data>::const_iterator pkgs_i = packages.find(pkg_name);
1127
    if (pkgs_i != packages.end()) {
1128
        CYG_REPORT_RETURN();
1129
        return pkgs_i->second.directory;
1130
    }
1131
 
1132
    CYG_FAIL("Invalid package name passed to CdlPackagesDatabase::get_package_directory()");
1133
    static std::string dummy = "";
1134
    return dummy;
1135
}
1136
 
1137
const std::string&
1138
CdlPackagesDatabaseBody::get_package_repository(std::string pkg_name, std::string vsn) const
1139
{
1140
    CYG_REPORT_FUNCNAME("CdlPackagesDatabase::get_package_repository");
1141
    CYG_REPORT_FUNCARG1XV(this);
1142
    CYG_PRECONDITION_THISC();
1143
 
1144
    static std::string dummy = "";
1145
 
1146
    std::map<std::string,package_data>::const_iterator pkgs_i = packages.find(pkg_name);
1147
    if (pkgs_i == packages.end()) {
1148
        CYG_FAIL("Invalid package name passed to CdlPackagesDatabase::get_package_repository()");
1149
        CYG_REPORT_RETURN();
1150
        return dummy;
1151
    }
1152
 
1153
    std::map<std::string,std::string>::const_iterator repo_i;
1154
    if (("" == vsn) && (0 == pkgs_i->second.versions.size())) {
1155
        CYG_REPORT_RETURN();
1156
        return dummy;
1157
    }
1158
 
1159
    if ("" == vsn) {
1160
        vsn = *(pkgs_i->second.versions.begin());
1161
    }
1162
    repo_i = pkgs_i->second.repositories.find(vsn);
1163
    if (repo_i == pkgs_i->second.repositories.end()) {
1164
        CYG_FAIL("Invalid package version passed to CdlPackagesDatabase::get_package_repository()");
1165
        CYG_REPORT_RETURN();
1166
        return dummy;
1167
    }
1168
 
1169
    CYG_REPORT_RETURN();
1170
    return repo_i->second;
1171
}
1172
 
1173
const std::string&
1174
CdlPackagesDatabaseBody::get_package_script(std::string pkg_name) const
1175
{
1176
    CYG_REPORT_FUNCNAME("CdlPackagesDatabase::get_package_script");
1177
    CYG_REPORT_FUNCARG1XV(this);
1178
    CYG_PRECONDITION_THISC();
1179
 
1180
    std::map<std::string,package_data>::const_iterator pkgs_i = packages.find(pkg_name);
1181
    if (pkgs_i != packages.end()) {
1182
        CYG_REPORT_RETURN();
1183
        return pkgs_i->second.script;
1184
    }
1185
 
1186
    CYG_FAIL("Invalid package name passed to CdlPackagesDatabase::get_package_script()");
1187
    static std::string dummy = "";
1188
    return dummy;
1189
}
1190
 
1191
bool
1192
CdlPackagesDatabaseBody::is_hardware_package(std::string pkg_name) const
1193
{
1194
    CYG_REPORT_FUNCNAME("CdlPackagesDatabase::is_hardware_package");
1195
    CYG_REPORT_FUNCARG1XV(this);
1196
    CYG_PRECONDITION_THISC();
1197
 
1198
    std::map<std::string,package_data>::const_iterator pkgs_i = packages.find(pkg_name);
1199
    if (pkgs_i != packages.end()) {
1200
        CYG_REPORT_RETURN();
1201
        return pkgs_i->second.hardware;
1202
    }
1203
 
1204
    CYG_FAIL("Invalid package name passed to CdlPackagesDatabase::is_hardware_package()");
1205
    return false;
1206
}
1207
 
1208
//}}}
1209
//{{{  CdlPackagesDatabase:: get target information             
1210
 
1211
// ----------------------------------------------------------------------------
1212
 
1213
const std::vector<std::string>&
1214
CdlPackagesDatabaseBody::get_targets(void) const
1215
{
1216
    CYG_REPORT_FUNCNAME("CdlPackagesDatabase::get_targets");
1217
    CYG_PRECONDITION_THISC();
1218
 
1219
    CYG_REPORT_RETURN();
1220
    return target_names;
1221
}
1222
 
1223
bool
1224
CdlPackagesDatabaseBody::is_known_target(std::string name) const
1225
{
1226
    CYG_REPORT_FUNCNAMETYPE("CdlPackagesDatabase::is_known_target", "result %d");
1227
    CYG_REPORT_FUNCARG1XV(this);
1228
    CYG_PRECONDITION_THISC();
1229
 
1230
    bool result = false;
1231
    if (std::find(target_names.begin(), target_names.end(), name) != target_names.end()) {
1232
        result = true;
1233
    }
1234
 
1235
    CYG_REPORT_RETVAL(result);
1236
    return result;
1237
}
1238
 
1239
const std::string&
1240
CdlPackagesDatabaseBody::get_target_description(std::string target_name) const
1241
{
1242
    CYG_REPORT_FUNCNAME("CdlPackagesDatabase::get_target_description");
1243
    CYG_PRECONDITION_THISC();
1244
 
1245
    std::map<std::string,target_data>::const_iterator target_i = targets.find(target_name);
1246
    if (target_i != targets.end()) {
1247
        CYG_REPORT_RETURN();
1248
        return target_i->second.description;
1249
    }
1250
 
1251
    CYG_FAIL("Invalid target name passed to CdlPackagesDatabase::get_target_description()");
1252
    static std::string dummy = "";
1253
    return dummy;
1254
}
1255
 
1256
const std::vector<std::string>&
1257
CdlPackagesDatabaseBody::get_target_aliases(std::string target_name) const
1258
{
1259
    CYG_REPORT_FUNCNAME("CdlPackagesDatabase::get_target_aliases");
1260
    CYG_PRECONDITION_THISC();
1261
 
1262
    std::map<std::string,target_data>::const_iterator target_i = targets.find(target_name);
1263
    if (target_i != targets.end()) {
1264
        CYG_REPORT_RETURN();
1265
        return target_i->second.aliases;
1266
    }
1267
 
1268
    CYG_FAIL("Invalid target name passed to CdlPackagesDatabase::get_target_aliases()");
1269
    static std::vector<std::string> dummy;
1270
    return dummy;
1271
}
1272
 
1273
const std::vector<std::string>&
1274
CdlPackagesDatabaseBody::get_target_packages(std::string target_name) const
1275
{
1276
    CYG_REPORT_FUNCNAME("CdlPackagesDatabase::get_target_packages");
1277
    CYG_PRECONDITION_THISC();
1278
 
1279
    std::map<std::string,target_data>::const_iterator target_i = targets.find(target_name);
1280
    if (target_i != targets.end()) {
1281
        CYG_REPORT_RETURN();
1282
        return target_i->second.packages;
1283
    }
1284
 
1285
    CYG_FAIL("Invalid target name passed to CdlPackagesDatabase::get_target_packages()");
1286
    static std::vector<std::string> dummy;
1287
    return dummy;
1288
}
1289
 
1290
const std::vector<std::string>&
1291
CdlPackagesDatabaseBody::get_target_enables(std::string target_name) const
1292
{
1293
    CYG_REPORT_FUNCNAME("CdlPackagesDatabase::get_target_enables");
1294
    CYG_PRECONDITION_THISC();
1295
 
1296
    std::map<std::string,target_data>::const_iterator target_i = this->targets.find(target_name);
1297
    if (target_i != this->targets.end()) {
1298
        CYG_REPORT_RETURN();
1299
        return target_i->second.enable;
1300
    }
1301
 
1302
    CYG_FAIL("Invalid target name passed to CdlPackagesDatabase::get_target_enables()");
1303
    static std::vector<std::string> dummy;
1304
    return dummy;
1305
}
1306
 
1307
const std::vector<std::string>&
1308
CdlPackagesDatabaseBody::get_target_disables(std::string target_name) const
1309
{
1310
    CYG_REPORT_FUNCNAME("CdlPackagesDatabase::get_target_disables");
1311
    CYG_PRECONDITION_THISC();
1312
 
1313
    std::map<std::string,target_data>::const_iterator target_i = this->targets.find(target_name);
1314
    if (target_i != this->targets.end()) {
1315
        CYG_REPORT_RETURN();
1316
        return target_i->second.disable;
1317
    }
1318
 
1319
    CYG_FAIL("Invalid target name passed to CdlPackagesDatabase::get_target_disables()");
1320
    static std::vector<std::string> dummy;
1321
    return dummy;
1322
}
1323
 
1324
const std::vector<std::pair<std::string, std::string> >&
1325
CdlPackagesDatabaseBody::get_target_set_values(std::string target_name) const
1326
{
1327
    CYG_REPORT_FUNCNAME("CdlPackagesDatabase::get_target_set_values");
1328
    CYG_PRECONDITION_THISC();
1329
 
1330
    std::map<std::string,target_data>::const_iterator target_i = this->targets.find(target_name);
1331
    if (target_i != this->targets.end()) {
1332
        CYG_REPORT_RETURN();
1333
        return target_i->second.set_values;
1334
    }
1335
 
1336
    CYG_FAIL("Invalid target name passed to CdlPackagesDatabase::get_target_values()");
1337
    static std::vector<std::pair<std::string, std::string> > dummy;
1338
    return dummy;
1339
}
1340
 
1341
//}}}
1342
//{{{  CdlPackagesDatabase:: get template information           
1343
 
1344
// ----------------------------------------------------------------------------
1345
// Templates are different from packages and targets. The ecos.db file
1346
// does not contain all the information in one convenient file, instead
1347
// it is necessary to trawl through a templates sub-directory of the
1348
// component repository. There are no aliases. Descriptions can be obtained
1349
// only by executing the template file in a suitable interpreter.
1350
 
1351
const std::vector<std::string>&
1352
CdlPackagesDatabaseBody::get_templates(void) const
1353
{
1354
    CYG_REPORT_FUNCNAME("CdlPackagesDatabase::get_templates");
1355
    CYG_PRECONDITION_THISC();
1356
 
1357
    CYG_REPORT_RETURN();
1358
    return template_names;
1359
}
1360
 
1361
bool
1362
CdlPackagesDatabaseBody::is_known_template(std::string name) const
1363
{
1364
    CYG_REPORT_FUNCNAMETYPE("CdlPackagesDatabase::is_known_template", "result %d");
1365
    CYG_REPORT_FUNCARG1XV(this);
1366
    CYG_PRECONDITION_THISC();
1367
 
1368
    bool result = false;
1369
    if (std::find(template_names.begin(), template_names.end(), name) != template_names.end()) {
1370
        result = true;
1371
    }
1372
 
1373
    CYG_REPORT_RETVAL(result);
1374
    return result;
1375
}
1376
 
1377
const std::vector<std::string>&
1378
CdlPackagesDatabaseBody::get_template_versions(std::string template_name) const
1379
{
1380
    CYG_REPORT_FUNCNAME("CdlPackagesDatabase::get_template_versions");
1381
    CYG_REPORT_FUNCARG1XV(this);
1382
    CYG_PRECONDITION_THISC();
1383
 
1384
    std::map<std::string,template_data>::const_iterator template_i = templates.find(template_name);
1385
    if (template_i != templates.end()) {
1386
        CYG_REPORT_RETURN();
1387
        return template_i->second.versions;
1388
    }
1389
 
1390
    CYG_FAIL("Invalid template name passed to CdlPackagesDatabase::get_template_versions()");
1391
    static std::vector<std::string> dummy;
1392
    return dummy;
1393
}
1394
 
1395
std::string
1396
CdlPackagesDatabaseBody::get_template_filename(std::string template_name, std::string version) const
1397
{
1398
    CYG_REPORT_FUNCNAME("CdlPackagesDatabase::get_template_filename");
1399
    CYG_REPORT_FUNCARG1XV(this);
1400
    CYG_PRECONDITION_THISC();
1401
 
1402
    // Given the way templates are identified, the filename can be determined
1403
    // easily by concatenating a few strings. The only complication is that
1404
    // version_name may be an empty string, indicating that the most recent
1405
    // version should be used.
1406
    std::map<std::string,template_data>::const_iterator template_i = templates.find(template_name);
1407
    if (template_i == templates.end()) {
1408
        CYG_FAIL("Invalid template name passed to CdlPackagesDatabase::get_template_filename");
1409
        CYG_REPORT_RETURN();
1410
        return "";
1411
    }
1412
    if ("" == version) {
1413
        CYG_ASSERTC(0 != template_i->second.versions.size());
1414
        version = template_i->second.versions[0];
1415
    } else {
1416
        std::vector<std::string>::const_iterator vsn_i = std::find(template_i->second.versions.begin(),
1417
                                                                   template_i->second.versions.end(), version);
1418
        if (vsn_i == template_i->second.versions.end()) {
1419
            CYG_FAIL("Invalid template version passed to CdlPackagesDatabase::get_template_filename");
1420
            CYG_REPORT_RETURN();
1421
            return "";
1422
        }
1423
    }
1424
 
1425
    std::map<std::string,std::string>::const_iterator file_i = template_i->second.files.find(version);
1426
    std::string result = file_i->second;
1427
    CYG_REPORT_RETURN();
1428
    return result;
1429
}
1430
 
1431
// ----------------------------------------------------------------------------
1432
// The descriptions now live in an eCos savefile, i.e. a Tcl script, so
1433
// extracting them can be relatively expensive and needs to happen on
1434
// a just-in-time basis.
1435
 
1436
const std::string
1437
CdlPackagesDatabaseBody::get_template_description(std::string template_name, std::string version_name)
1438
{
1439
    CYG_REPORT_FUNCNAME("CdlPackagesDatabase::get_template_description");
1440
    CYG_REPORT_FUNCARG1XV(this);
1441
    CYG_PRECONDITION_THISC();
1442
 
1443
    // Is this a known template?
1444
    std::map<std::string, struct template_data>::iterator template_i = templates.find(template_name);
1445
    if (template_i == templates.end()) {
1446
        CYG_FAIL("Invalid template name passed to CdlPackagesDatabase::get_template_description");
1447
        CYG_REPORT_RETURN();
1448
        return "";
1449
    }
1450
 
1451
    // Is it a known version of the template?
1452
    if ("" == version_name) {
1453
        CYG_ASSERTC(0 != template_i->second.versions.size());
1454
        version_name = template_i->second.versions[0];
1455
    } else {
1456
        if (std::find(template_i->second.versions.begin(), template_i->second.versions.end(), version_name) ==
1457
            template_i->second.versions.end()) {
1458
 
1459
            CYG_FAIL("Invalid template version passed to CdlPackagesDatabase::get_template_description");
1460
            CYG_REPORT_RETURN();
1461
            return "";
1462
        }
1463
    }
1464
 
1465
    // We have a valid template and version. Has the version file in
1466
    // question been read in yet?
1467
    std::map<std::string, struct template_version_data>::iterator version_i;
1468
    version_i = template_i->second.version_details.find(version_name);
1469
    if (version_i != template_i->second.version_details.end()) {
1470
        CYG_REPORT_RETURN();
1471
        return version_i->second.description;
1472
    }
1473
 
1474
    std::string filename = this->get_template_filename(template_name, version_name);
1475
    if ("" == filename) {
1476
        CYG_REPORT_RETURN();
1477
        return "";
1478
    }
1479
    extract_template_details(filename, template_i->second.version_details[version_name].description,
1480
                             template_i->second.version_details[version_name].packages);
1481
    CYG_REPORT_RETURN();
1482
    return template_i->second.version_details[version_name].description;
1483
}
1484
 
1485
// ----------------------------------------------------------------------------
1486
// Similarly extracting package information needs to happen on a
1487
// just-in-time basis.
1488
const std::vector<std::string>&
1489
CdlPackagesDatabaseBody::get_template_packages(std::string template_name, std::string version_name)
1490
{
1491
    CYG_REPORT_FUNCNAME("CdlPackagesDatabase::get_template_packages");
1492
    CYG_REPORT_FUNCARG1XV(this);
1493
    CYG_PRECONDITION_THISC();
1494
 
1495
    static std::vector<std::string> dummy;
1496
 
1497
    // Is this a known template?
1498
    std::map<std::string, struct template_data>::iterator template_i = templates.find(template_name);
1499
    if (template_i == templates.end()) {
1500
        CYG_FAIL("Invalid template name passed to CdlPackagesDatabase::get_template_packages");
1501
        CYG_REPORT_RETURN();
1502
        return dummy;
1503
    }
1504
 
1505
    // Is it a known version of the template?
1506
    if ("" == version_name) {
1507
        CYG_ASSERTC(0 != template_i->second.versions.size());
1508
        version_name = template_i->second.versions[0];
1509
    } else {
1510
        if (std::find(template_i->second.versions.begin(), template_i->second.versions.end(), version_name) ==
1511
            template_i->second.versions.end()) {
1512
 
1513
            CYG_FAIL("Invalid template version passed to CdlPackagesDatabase::get_packages");
1514
            CYG_REPORT_RETURN();
1515
            return dummy;
1516
        }
1517
    }
1518
 
1519
    // We have a valid template and version. Has the version file in
1520
    // question been read in yet?
1521
    std::map<std::string, struct template_version_data>::iterator version_i;
1522
    version_i = template_i->second.version_details.find(version_name);
1523
    if (version_i != template_i->second.version_details.end()) {
1524
        CYG_REPORT_RETURN();
1525
        return version_i->second.packages;
1526
    }
1527
 
1528
    std::string filename = this->get_template_filename(template_name, version_name);
1529
    if ("" == filename) {
1530
        CYG_REPORT_RETURN();
1531
        return dummy;
1532
    }
1533
    extract_template_details(filename, template_i->second.version_details[version_name].description,
1534
                             template_i->second.version_details[version_name].packages);
1535
    CYG_REPORT_RETURN();
1536
    return template_i->second.version_details[version_name].packages;
1537
}
1538
 
1539
// ----------------------------------------------------------------------------
1540
// Extracting the description and package information involves running
1541
// the script through a Tcl interpreter extended with the appropriate
1542
// commands. Most of the savefile information is irrelevant and is handled
1543
// by extract_ignore(). The commands of interest are cdl_configuration and
1544
// its sub-commands description and package.
1545
 
1546
static int
1547
extract_ignore(CdlInterpreter interp, int argc, const char* argv[])
1548
{
1549
    return TCL_OK;
1550
}
1551
 
1552
static int
1553
extract_cdl_configuration(CdlInterpreter interp, int argc, const char* argv[])
1554
{
1555
    CYG_REPORT_FUNCNAMETYPE("extract_cdl_configuration", "result %d");
1556
    CYG_REPORT_FUNCARG2XV(interp, argc);
1557
    CYG_PRECONDITION_CLASSC(interp);
1558
 
1559
    int result = TCL_OK;
1560
 
1561
    // usage: cdl_configuration <name> <body>
1562
    if (3 != argc) {
1563
        interp->set_result("Invalid cdl_configuration command in template, expecting two arguments");
1564
        result = TCL_ERROR;
1565
    } else {
1566
        // Ignore the first argument for now.
1567
        std::string tmp;
1568
        result = interp->eval(argv[2], tmp);
1569
 
1570
        // After processing the cdl_configuration command the description and
1571
        // package information should be known. There is no point in processing
1572
        // the rest of the file.
1573
        if (TCL_OK == result) {
1574
            interp->set_result("OK");
1575
            result = TCL_ERROR;
1576
        }
1577
    }
1578
 
1579
    CYG_REPORT_RETVAL(result);
1580
    return result;
1581
}
1582
 
1583
static int
1584
extract_cdl_description(CdlInterpreter interp, int argc, const char* argv[])
1585
{
1586
    CYG_REPORT_FUNCNAMETYPE("extract_cdl_description", "result %d");
1587
    CYG_REPORT_FUNCARG2XV(interp, argc);
1588
    CYG_PRECONDITION_CLASSC(interp);
1589
 
1590
    int result = TCL_OK;
1591
 
1592
    // usage: package <name>
1593
    if (2 != argc) {
1594
        interp->set_result("Invalid description command in template, expecting just one argument");
1595
        result = TCL_ERROR;
1596
    } else {
1597
        ClientData client_data = interp->get_assoc_data(template_description_key);
1598
        CYG_ASSERTC(0 != client_data);
1599
        std::string* result_ptr = static_cast<std::string*>(client_data);
1600
        *result_ptr = argv[1];
1601
    }
1602
 
1603
    CYG_REPORT_RETVAL(result);
1604
    return result;
1605
}
1606
 
1607
static int
1608
extract_cdl_package(CdlInterpreter interp, int argc, const char* argv[])
1609
{
1610
    CYG_REPORT_FUNCNAMETYPE("extract_cdl_package", "result %d");
1611
    CYG_REPORT_FUNCARG2XV(interp, argc);
1612
    CYG_PRECONDITION_CLASSC(interp);
1613
 
1614
    int result = TCL_OK;
1615
 
1616
    // usage: package <name> <version>
1617
    if (2 > argc) {
1618
        interp->set_result("Invalid package command in template, expecting two arguments");
1619
        result = TCL_ERROR;
1620
    } else {
1621
        ClientData client_data = interp->get_assoc_data(template_packages_key);
1622
        CYG_ASSERTC(0 != client_data);
1623
        std::vector<std::string>* result_ptr = static_cast<std::vector<std::string>*>(client_data);
1624
        result_ptr->push_back(argv[1]);
1625
    }
1626
    CYG_REPORT_RETVAL(result);
1627
    return result;
1628
}
1629
 
1630
 
1631
void
1632
CdlPackagesDatabaseBody::extract_template_details(std::string filename, std::string& description,
1633
                                                      std::vector<std::string>& packages)
1634
{
1635
    CYG_REPORT_FUNCNAME("CdlPackagesDatabase::extract_template_description");
1636
 
1637
    CdlInterpreter interp = CdlInterpreterBody::make();
1638
    interp->set_assoc_data(template_description_key, static_cast<ClientData>(&description));
1639
    interp->set_assoc_data(template_packages_key,    static_cast<ClientData>(&packages));
1640
    static CdlInterpreterCommandEntry extract_commands[] =
1641
    {
1642
        CdlInterpreterCommandEntry("cdl_savefile_version",  &extract_ignore                 ),
1643
        CdlInterpreterCommandEntry("cdl_savefile_command",  &extract_ignore                 ),
1644
        CdlInterpreterCommandEntry("cdl_configuration",     &extract_cdl_configuration      ),
1645
        CdlInterpreterCommandEntry("hardware",              &extract_ignore                 ),
1646
        CdlInterpreterCommandEntry("template",              &extract_ignore                 ),
1647
        CdlInterpreterCommandEntry("description",           &extract_cdl_description        ),
1648
        CdlInterpreterCommandEntry("package",               &extract_cdl_package            ),
1649
        CdlInterpreterCommandEntry("unknown",               &extract_ignore                 ),
1650
        CdlInterpreterCommandEntry("",                      0                               )
1651
    };
1652
    std::vector<CdlInterpreterCommandEntry> new_commands;
1653
    for (int i = 0; 0 != extract_commands[i].command; i++) {
1654
        new_commands.push_back(extract_commands[i]);
1655
    }
1656
    interp->push_commands(new_commands);
1657
 
1658
    std::string tmp;
1659
    int result = interp->eval_file(filename, tmp);
1660
    // Special escape mechanism, see extract_cdl_configuration() above
1661
    if ((TCL_ERROR == result) && ("OK" == tmp)) {
1662
        result = TCL_OK;
1663
    }
1664
#if 0    
1665
    if (TCL_OK != result) {
1666
        // No obvious way of recovering just yet
1667
    }
1668
#endif
1669
    delete interp;
1670
 
1671
    CYG_REPORT_RETURN();
1672
}
1673
 
1674
//}}}
1675
//{{{  CdlPackagesDatabase:: get_valid_cflags()                 
1676
 
1677
// ----------------------------------------------------------------------------
1678
 
1679
const std::vector<std::string>&
1680
CdlPackagesDatabaseBody::get_valid_cflags()
1681
{
1682
    CYG_REPORT_FUNCNAME("CdlPackagesDatabase::get_valid_compiler_flags");
1683
 
1684
    static std::vector<std::string> result_vec;
1685
    static const char* valid_flags[] = {
1686
        "ARCHFLAGS",  "CARCHFLAGS",  "CXXARCHFLAGS",  "LDARCHFLAGS",
1687
        "ERRFLAGS",   "CERRFLAGS",   "CXXERRFLAGS",   "LDERRFLAGS",
1688
        "LANGFLAGS",  "CLANGFLAGS",  "CXXLANGFLAGS",  "LDLANGFLAGS",
1689
        "DBGFLAGS",   "CDBGFLAGS",   "CXXDBGFLAGS",   "LDDBGFLAGS",
1690
        "EXTRAFLAGS", "CEXTRAFLAGS", "CXXEXTRAFLAGS", "LDEXTRAFLAGS",
1691
 
1692
    };
1693
 
1694
    if (0 == result_vec.size()) {
1695
        for (int i = 0; 0 != valid_flags[i]; i++) {
1696
            result_vec.push_back(valid_flags[i]);
1697
        }
1698
    }
1699
    CYG_REPORT_RETURN();
1700
    return result_vec;
1701
}
1702
 
1703
//}}}

powered by: WebSVN 2.1.0

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