Skip to content

Commit

Permalink
Merge from eCos master repository on 2000-06-23-16:41:10-BST
Browse files Browse the repository at this point in the history
  • Loading branch information
jlarmour committed Jun 23, 2000
1 parent 8a51d2a commit 55d543e
Show file tree
Hide file tree
Showing 290 changed files with 54,359 additions and 1,090 deletions.
11 changes: 11 additions & 0 deletions host/libcdl/ChangeLog
Original file line number Diff line number Diff line change
@@ -1,3 +1,14 @@
2000-06-22 Bart Veer <[email protected]>

* value.cxx, interface.cxx:
Allow the flavor property to be used on interfaces. booldata
interfaces allow the use of #ifdef to determine whether or not
a feature is available. Clean up some of the value stuff to match,
especially when it comes to savefiles.

* build.cxx, cdlmisc.cxx, cdlcore.hxx:
Add version #define support.

2000-06-15 John Dallaway <[email protected]>

* cdl.dsp:
Expand Down
7 changes: 7 additions & 0 deletions host/libcdl/TODO
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,13 @@ Minor
20) make version comparison completely case insensitive, to avoid
problems on some file systems.

21) configure magic to cope with Debian TCL organization.
See http://sourceware.cygnus.com/ml/ecos-discuss/2000-06/msg00094.html

22) add version number #define's to pkgconf/system.h, to allow
application code to adapt to different versions of a package.
http://sourceware.cygnus.com/ml/ecos-discuss/2000-06/msg00140.html

Intermediate
------------

Expand Down
151 changes: 148 additions & 3 deletions host/libcdl/build.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -1113,6 +1113,143 @@ CdlBuildLoadableBody::update_all_build_info(CdlBuildInfo& build_info) const

//}}}

//}}}
//{{{ Version number #define's

// ----------------------------------------------------------------------------
// Given a package xxxPKG_A_B_C with a version V1_2_3, generate additional
// #define's of the form:
//
// #define xxxNUM_A_B_C_VERSION_MAJOR 1
// #define xxxNUM_A_B_C_VERSION_MINOR 2
// #define xxxNUM_A_B_C_VERSION_RELEASE 3
//
// The goal here is to allow application code to cope with API
// changes (which of course should be a rare event but cannot be
// eliminated completely). C preprocessor #if statements are
// essentially limited to numerical values, so there is no easy
// way of coping with V1_2_3 at the preprocessor level. However it
// is possible to cope with VERSION_NUMBER #define's.
//
// Note that only application code and third party packages are
// affected.
//
// These #define's go into system.h, alongside the main definition of
// the package. There seems to be little point in putting them in the
// package's own configuration header.
//
// There are three problems. First, what should be done for packages
// which do not follow the naming conventions? Given a completely
// random package rather than something like xxxPKG_..., what symbol
// names should be used? Basically, if the package does not follow the
// naming convention then there is no safe way of generating new
// symbols. Any names that are chosen might clash. Of course even for
// packages that do follow the naming convention a clash is still
// possible, just a lot less likely.
//
// Conclusion: if a package does not follow the naming convention, do
// not generate version #define's for it.
//
// Second, what happens if a different version numbering scheme is
// used? For example the release number might be absent. Version
// numbering schemes might change between releases, but application
// code may still check the #define's.
//
// Third and related, what should happen for "current" and anoncvs? Do
// we want to look at what other versions are installed and bump one
// of the numbers?
//
// Conclusion: the version #define's always have to be generated,
// even if they are not present in the version string, to allow
// application code to test these symbols anyway. A safe default is
// necessary, and -1 is probably the best bet. For example, if
// the version is bumped from 1.3.287 to 1.4 then the release number
// for the latter is set to -1. Another possible default would be
// 0, but that could cause problems for packages that start counting
// from 0 (not a common practice, but...)
//
// This leaves the question of what to do about "current". Chances are
// that "current" comes from anoncvs and is always more recent than
// any official release, so when comparing versions "current" should
// always be greater than anything else. This can be achieved by using
// a sufficiently large number for the major version. In practice
// it is cleaner to have another #define to indicate the current
// version, and then define package versions to match, i.e.:
//
// #define CYGNUM_VERSION_CURRENT 0x7fffff00
// ...
// #define xxxNUM_A_B_C_VERSION_MAJOR CYGNUM_VERSION_CURRENT
// #define xxxNUM_A_B_C_VERSION_MINOR -1
// #define xxxNUM_A_B_C_VERSION_RELEASE -1
//
// All comparisons should now work sensibly. Leaving a little bit
// of slack for VERSION_CURRENT seems like a good precaution.

static void
system_h_add_version_header(Tcl_Channel system_h)
{
CYG_REPORT_FUNCNAME("system_h_add_version_header");
Tcl_Write(system_h, "#define CYGNUM_VERSION_CURRENT 0x7fffff00\n", -1);
CYG_REPORT_RETURN();
}

static void
system_h_add_package_versioning(Tcl_Channel system_h, std::string name, std::string value)
{
CYG_REPORT_FUNCNAME("system_h_add_package_versioning");

char name_buf[256];
char line_buf[512];

// The first thing to check is that the package name can be used
// as the basis for the version symbols.
bool ok = false;
unsigned int i;
for (i = 0; i < name.size(); i++) {
if ('_' == name[i]) {
if (3 < i) {
if ((name[i-3] == 'P') && (name[i-2] == 'K') && (name[i-1] == 'G')) {
ok = true;
}
}
break;
}
}
if (name.size() >= 256) {
ok = false;
}
if (!ok) {
CYG_REPORT_RETURN();
return;
}

strcpy(name_buf, name.c_str());

// Change from xxxPKG to xxxNUM
name_buf[i - 3] = 'N';
name_buf[i - 2] = 'U';
name_buf[i - 1] = 'M';

// Now determine the version strings.
std::string major = "-1";
std::string minor = "-1";
std::string release = "-1";
if ("current" == value) {
major = "CYGNUM_VERSION_CURRENT";
} else {
Cdl::split_version_string(value, major, minor, release);
}

sprintf(line_buf, "#define %s_VERSION_MAJOR %s\n", name_buf, major.c_str());
Tcl_Write(system_h, line_buf, -1);
sprintf(line_buf, "#define %s_VERSION_MINOR %s\n", name_buf, minor.c_str());
Tcl_Write(system_h, line_buf, -1);
sprintf(line_buf, "#define %s_VERSION_RELEASE %s\n", name_buf, release.c_str());
Tcl_Write(system_h, line_buf, -1);

CYG_REPORT_RETURN();
}

//}}}
//{{{ CdlDefinableBody

Expand Down Expand Up @@ -1468,6 +1605,11 @@ CdlDefinableBody::generate_config_header(Tcl_Channel this_hdr, Tcl_Channel syste
tmp = "#define "+ tmp + "\n";
Tcl_Write(chan, const_cast<char*>(tmp.c_str()), -1);
}

// For loadables, add additional version information to system_h
if (dynamic_cast<CdlConstLoadable>((CdlConstNode)this) == loadable) {
system_h_add_package_versioning(system_h, name, value);
}
}
}

Expand Down Expand Up @@ -1956,11 +2098,14 @@ CdlToplevelBody::generate_config_headers(std::string directory)
sprintf(local_buf, banner_format, "SYSTEM_H", "SYSTEM_H", "system.h");
Tcl_Write(system_h, local_buf, -1);

// Add generic version information
system_h_add_version_header(system_h);

// The rest of system.h will be filled in by the following loop.
//
// Next, walk down the previously constructed headers vector,
// create appropriate files, and let each DefineLoadable fill
// in the file for itself.
// Walk down the previously constructed headers vector, create
// appropriate files, and let each DefineLoadable fill in the
// file for itself.
std::vector<std::pair<CdlDefineLoadable, std::string> >::iterator outer_i;
std::vector<std::pair<CdlDefineLoadable, std::string> >::iterator inner_i;
for (outer_i = headers.begin(); outer_i != headers.end(); outer_i++) {
Expand Down
4 changes: 4 additions & 0 deletions host/libcdl/cdlcore.hxx
Original file line number Diff line number Diff line change
Expand Up @@ -985,6 +985,10 @@ class Cdl {
}
};

// Split a version string into major, minor and release numbers.
static void split_version_string(const std::string&, std::string& /* major */,
std::string& /* minor */, std::string& /* release */);

// It is occasionally useful to take a full CDL name such as CYGPKG_KERNEL
// and turn it into a short form, i.e. kernel.
static std::string get_short_form(const std::string&);
Expand Down
45 changes: 44 additions & 1 deletion host/libcdl/cdlmisc.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -846,7 +846,7 @@ Cdl::is_interactive(void)
}

//}}}
//{{{ Cdl::compare_versions()
//{{{ version support()

// ----------------------------------------------------------------------------
// Packages may need to impose constraints on which versions of other
Expand Down Expand Up @@ -1013,6 +1013,49 @@ Cdl::compare_versions(std::string arg1, std::string arg2)
// Not reachable.
}

// ----------------------------------------------------------------------------
// Given a version string, extract major, minor and release numbers.
// Some or all of these may be absent. Basically the code just
// iterates through the string looking for sequences of numbers.

static void
version_extract_number(const std::string& version, unsigned int& index, std::string& result)
{
CYG_REPORT_FUNCNAME("version_extract_number");

// The calling code is expected to supply a sensible default.
// Search for a digit
for ( ; index < version.size(); index++) {
if (isdigit(version[index])) {
break;
}
}
if (index != version.size()) {
result = "";
if ((index > 0) && ('-' == version[index-1])) {
result = "-";
}
do {
result += version[index++];
} while ((index < version.size()) && isdigit(version[index]));
}

CYG_REPORT_RETURN();
}

void
Cdl::split_version_string(const std::string& version, std::string& major, std::string& minor, std::string& release)
{
CYG_REPORT_FUNCNAME("CdlMisc::split_version_string");

unsigned int index = 0;
version_extract_number(version, index, major);
version_extract_number(version, index, minor);
version_extract_number(version, index, release);

CYG_REPORT_RETURN();
}

//}}}
//{{{ Cdl::get_short_form()

Expand Down
59 changes: 51 additions & 8 deletions host/libcdl/interface.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -231,12 +231,17 @@ CdlInterfaceBody::parse_interface(CdlInterpreter interp, int argc, char** argv)
new_interface->CdlBuildableBody::check_properties(interp);
new_interface->CdlDefinableBody::check_properties(interp);

// A few properties do not make sense for interfaces.
// Start with the value-related ones. Interfaces always
// have the flavor Data.
// The flavor "none" makes no sense for interfaces.
// The flavor "bool" makes very little sense, but may be useful
// in weird cases. Both booldata and data make sense.
// The default flavor is "data", because interfaces are
// essentially just counters.
if (new_interface->has_property(CdlPropertyId_Flavor)) {
CdlParse::report_error(interp, "", "An interface should not have a `flavor' property.");
if (CdlValueFlavor_None == new_interface->get_flavor()) {
CdlParse::report_error(interp, "", "An interface should not have the `none' flavor.");
}
}

// Interfaces cannot be modified directly by the user, so
// there is no point in entry_proc, check_proc, dialog or
// wizard
Expand Down Expand Up @@ -342,17 +347,22 @@ CdlInterfaceBody::save(CdlInterpreter interp, Tcl_Channel chan, int indentation,
if (!minimal) {
const std::vector<CdlReferrer>& referrers = this->get_referrers();
std::vector<CdlReferrer>::const_iterator ref_i;
int real_referrers = 0;
for (ref_i = referrers.begin(); ref_i != referrers.end(); ref_i++) {
CdlNode node = ref_i->get_source();
CdlProperty prop = ref_i->get_source_property();

CdlValuable valuable = dynamic_cast<CdlValuable>(node);
if ((0 != valuable) && (CdlPropertyId_Implements == prop->get_property_name())) {
real_referrers++;
data += std::string(indentation, ' ') + " # Implemented by " + valuable->get_name() + ", " +
(valuable->is_active() ? "active" : "inactive") + ", " +
(valuable->is_enabled() ? "enabled" : "disabled") + '\n';
}
}
if (0 == real_referrers) {
data += std::string(indentation, ' ') + " # No options implement this inferface\n";
}
}
interp->write_data(chan, data);

Expand Down Expand Up @@ -469,10 +479,43 @@ CdlInterfaceBody::recalculate(CdlTransaction transaction)
}
}
}
if (count != old_value.get_integer_value()) {
CdlValue new_value = old_value;
new_value.set_integer_value(count, CdlValueSource_Default);
transaction->set_whole_value(this, old_value, new_value);

// What to do with the count depends on the flavor.
switch(this->get_flavor()) {
case CdlValueFlavor_Bool :
{
bool new_bool = (count > 0);
if (new_bool != old_value.is_enabled()) {
CdlValue new_value = old_value;
new_value.set_enabled(new_bool, CdlValueSource_Default);
transaction->set_whole_value(this, old_value, new_value);
}
break;
}
case CdlValueFlavor_BoolData:
{
// The only thing that actually needs checking is the count value.
// Iff that has changed then the boolean part may need changing as well.
if (count != old_value.get_integer_value()) {
CdlValue new_value = old_value;
new_value.set_enabled_and_value(count > 0, count, CdlValueSource_Default);
transaction->set_whole_value(this, old_value, new_value);
}

break;
}
case CdlValueFlavor_Data:
{
if (count != old_value.get_integer_value()) {
CdlValue new_value = old_value;
new_value.set_integer_value(count, CdlValueSource_Default);
transaction->set_whole_value(this, old_value, new_value);
}
break;
}

default:
break;
}

CYG_REPORT_RETURN();
Expand Down
Loading

0 comments on commit 55d543e

Please sign in to comment.