⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cdlmisc.cxx

📁 eCos1.31版
💻 CXX
📖 第 1 页 / 共 2 页
字号:
        CYG_REPORT_RETURN();    return;}//}}}//{{{  double_to_string()                       // ----------------------------------------------------------------------------std::stringCdl::double_to_string(double value, CdlValueFormat format){    std::string result;    Cdl::double_to_string(value, result, format);    return result;}voidCdl::double_to_string(double value, std::string& result, CdlValueFormat format){    CYG_REPORT_FUNCNAME("Cdl::double_to_String");    char buf[256];      // This should be plenty :-)    sprintf(buf, "%.*G", DBL_DIG, value);    result = buf;    CYG_UNUSED_PARAM(CdlValueFormat, format);    CYG_REPORT_RETURN();}//}}}//{{{  bool_to_string()                         // ----------------------------------------------------------------------------// Should the string results be 1/0 or true/false? Not that// it really matters. The testcase in cdl1.cxx expects 1/0.std::stringCdl::bool_to_string(bool value){    std::string result;    Cdl::bool_to_string(value, result);    return result;}voidCdl::bool_to_string(bool value, std::string& target){    CYG_REPORT_FUNCNAME("Cdl::bool_to_string");    CYG_REPORT_FUNCARG1( "value arg %ld", (long) value);    if (value)        target = "1";    else        target = "0";    CYG_REPORT_RETURN();}//}}}//{{{  integer_to_double()                      // ----------------------------------------------------------------------------// Currently integer to double cannot fail, although there may well be loss// of accurary. Eventually cdl_int may be an arbitrary precision integer// in which case conversion to double is not guaranteed.doubleCdl::integer_to_double(cdl_int value){    CYG_REPORT_FUNCNAME("Cdl::integer_to_double");    double result = (double) value;    CYG_REPORT_RETURN();    return result;}voidCdl::integer_to_double(cdl_int value, double& target){    CYG_REPORT_FUNCNAME("Cdl::integer_to_double");    target = (double) value;    CYG_REPORT_RETURN();}//}}}//{{{  double_to_integer()                      // Conversion from double to integer is only allowed if there is no loss// of data. modf() is useful hereboolCdl::double_to_integer(double value, cdl_int& target){    CYG_REPORT_FUNCNAMETYPE("Cdl::double_to_integer", "result %d");    bool   result = false;        double integral;    double frac;    frac = modf(value, &integral);    if (0.0 == frac) {        // Looking good, but integral may still be too big.        cdl_int tmp = (cdl_int) integral;        if (tmp == value) {            // No fraction, no loss of data, everything looking good            target = tmp;            result = true;        }    }    CYG_REPORT_RETVAL(result);    return result;}//}}}//}}}//{{{  Cdl::xxx_to_yyy() - CDL-specific data types              // ----------------------------------------------------------------------------// Conversions between strings and flavors.static struct {    char*               name;    CdlValueFlavor      flavor;} valid_flavors[] = {    { "none",           CdlValueFlavor_None     },    { "bool",           CdlValueFlavor_Bool     },    { "booldata",       CdlValueFlavor_BoolData },    { "data",           CdlValueFlavor_Data     },    { 0,                CdlValueFlavor_Invalid  }};boolCdl::string_to_flavor(std::string name, CdlValueFlavor& target){    CYG_REPORT_FUNCNAMETYPE("Cdl::string_to_flavor", "success %d");    bool result = false;    // First convert the argument to lower case. Arguably this is incorrect,    // Tcl is a case-sensitive language, but the conversion is unlikely ever    // to be harmfull.    for (std::string::iterator str_i = name.begin(); str_i != name.end(); str_i++) {        if (isupper(*str_i)) {            *str_i = tolower(*str_i);        }    }               // Now look for a match in the table.    int match           = -1;    int i;    const char* c_str   = name.c_str();    int len             = strlen(c_str);    for (i = 0; 0 != valid_flavors[i].name; i++) {        if (0 == strncmp(c_str, valid_flavors[i].name, len)) {            // Check for an ambiguous string match.            // This cannot actually happen with the current flavor names.            if ( -1 != match) {                break;            }            match = i;        }            }    if (-1 != match) {        target = valid_flavors[match].flavor;        result = true;    }    CYG_REPORT_RETVAL(result);    return result;}boolCdl::flavor_to_string(CdlValueFlavor flavor, std::string& target){    CYG_REPORT_FUNCNAMETYPE("Cdl::flavor_to_string", "success %d");    bool result = false;    for (int i = 0; 0 != valid_flavors[i].name; i++) {        if (flavor == valid_flavors[i].flavor) {            target = valid_flavors[i].name;            result = true;            break;        }    }        CYG_REPORT_RETVAL(result);    return result;}// ----------------------------------------------------------------------------// Similar support for value sources.static struct {    char*               name;    CdlValueSource      source;} valid_sources[] = {    { "default",        CdlValueSource_Default  },    { "inferred",       CdlValueSource_Inferred },    { "wizard",         CdlValueSource_Wizard   },    { "user",           CdlValueSource_User     },    { 0,                CdlValueSource_Invalid  }};boolCdl::string_to_source(std::string name, CdlValueSource& target){    CYG_REPORT_FUNCNAMETYPE("Cdl::string_to_source", "success %d");    bool result = false;    // First convert the argument to lower case. Arguably this is incorrect,    // Tcl is a case-sensitive language, but the conversion is unlikely ever    // to be harmfull.    for (std::string::iterator str_i = name.begin(); str_i != name.end(); str_i++) {        if (isupper(*str_i)) {            *str_i = tolower(*str_i);        }    }               // Now look for a match in the table.    int match           = -1;    int i;    const char* c_str   = name.c_str();    int len             = strlen(c_str);    for (i = 0; 0 != valid_sources[i].name; i++) {        if (0 == strncmp(c_str, valid_sources[i].name, len)) {            // Check for an ambiguous string match.            // This cannot actually happen with the current source names.            if ( -1 != match) {                break;            }            match = i;        }            }    if (-1 != match) {        target = valid_sources[match].source;        result = true;    }    CYG_REPORT_RETVAL(result);    return result;}boolCdl::source_to_string(CdlValueSource source, std::string& target){    CYG_REPORT_FUNCNAMETYPE("Cdl::source_to_string", "success %d");    bool result = false;    for (int i = 0; 0 != valid_sources[i].name; i++) {        if (source == valid_sources[i].source) {            target = valid_sources[i].name;            result = true;            break;        }    }        CYG_REPORT_RETVAL(result);    return result;}//}}}//{{{  Cdl::get_library_version()                               // ----------------------------------------------------------------------------// The version of the library actually lives inside configure.in. It gets// exported into cdlconfig.hstd::stringCdl::get_library_version(void){    return std::string(CYGNUM_LIBCDL_VERSION);}//}}}//{{{  Cdl::set_interactive()                                   // ----------------------------------------------------------------------------// Some CDL scripts and some bits of the library may want to adapt depending// on whether or not the application is running fully interactively or in// batch mode. The primary distinction is that a batch program should never// attempt to obtain user input, whether via Tk widgets or by other means.bool Cdl::interactive   = false;voidCdl::set_interactive(bool value){    CYG_REPORT_FUNCNAME("Cdl::set_interactive");    CYG_REPORT_FUNCARG1D(value);    interactive = value;}boolCdl::is_interactive(void){    CYG_REPORT_FUNCNAMETYPE("Cdl::is_interactive", "interactive %d");    CYG_REPORT_RETVAL(interactive);    return interactive;}//}}}//{{{  Cdl::compare_versions()                                  // ----------------------------------------------------------------------------// Packages may need to impose constraints on which versions of other// packages they can coexist with. This requires some way of achieving// a partial ordering of version numbers. Unfortunately there are many// different ways of specifying a version number, and we cannot impose// a single model on all third party package developers. Instead this// routine performs some semi-intelligent comparisons of two version// strings which should work in the vast majority of cases.//// The return value is as per strcmp(), -1 if the first entry is// smaller (i.e. the more recent and hence hopefully the first in// a list), +1 if the second entry is smaller, 0 if the two are// identical.//// There is a big ambiguity between "derived" versions and "experimental"// versions. Something like v0.3beta is experimental, i.e. it is older// than the full release v0.3. On the other hand v0.3.p1 is a patched// version of v0.3 and hence newer. This code uses the presence or otherwise// of a separator to decide between the two cases.// A utility routine which checks whether or not a character counts// as a separator. Currently the characters . - and _ are all accepted// as field separators.//// Arguably - should not be accepted as a separator. Instead if it preceeds// a digit it could be interpreted as part of a prerelease number.static boolis_separator(int ch){    return ('.' == ch) || ('-' == ch) || ('_' == ch);}    intCdl::compare_versions(std::string arg1, std::string arg2){    CYG_REPORT_FUNCNAMETYPE("Cdl::compare_versions", "result %d");    if (arg1 == arg2) {        CYG_REPORT_RETVAL(0);        return 0;    }    // The version number "current" is special, it always indicates the most    // recent version e.g. as checked out from a CVS repository.    if ("current" == arg1) {        CYG_REPORT_RETVAL(-1);        return -1;    }    if ("current" == arg2) {        CYG_REPORT_RETVAL(1);        return 1;    }    const char* ptr1 = arg1.c_str();    const char* ptr2 = arg2.c_str();          int num1    = 0;    int num2    = 0;    // If both strings start with 'v' or 'V', skip this. A minor variation in    // case at the start of a string should be ignored.    if ((('v' == *ptr1) || ('V' == *ptr1)) &&        (('v' == *ptr2) || ('V' == *ptr2))) {        ptr1++;        ptr2++;    }    // Now process the rest of the version string, one unit at a time.    while (1) {        if (('\0' == *ptr1) && ('\0' == *ptr2)) {            // Both strings have terminated at the same time. There            // may have been some spurious leading zeroes in numbers,            // or irrelevant differences in the separators.            CYG_REPORT_RETVAL(0);            return 0;        }                if ('\0' == *ptr1) {            // The first string has ended first. If the second string currently            // points at a separator then arg2 is a derived version, e.g.            // v0.3.p1, and hence newer. Otherwise arg2 is an experimental            // version v0.3beta and hence older.            if (is_separator(*ptr2)) {                CYG_REPORT_RETVAL(1);                return 1;            } else {                CYG_REPORT_RETVAL(-1);                return -1;            }        }        if ('\0' == *ptr2) {            // As per the previous test.            if (is_separator(*ptr1)) {                CYG_REPORT_RETVAL(-1);                return -1;            } else {                CYG_REPORT_RETVAL(1);                return 1;            }        }        // If both strings currently point at numerical data, do a conversion and        // a numerical comparison.        if (isdigit(*ptr1) && isdigit(*ptr2)) {            num1 = 0;            num2 = 0;            // Strictly speaking there should be some overflow tests here, but it            // is not worth the trouble.            do {                num1 = (10 * num1) + (*ptr1++ - '0');            } while(isdigit(*ptr1));            do {                num2 = (10 * num2) + (*ptr2++ - '0');            } while(isdigit(*ptr2));            // v2.0 is newer than v1.0            if (num1 < num2) {                CYG_REPORT_RETVAL(1);                return 1;            } else if (num1 > num2) {                CYG_REPORT_RETVAL(-1);                return -1;            } else {                continue;            }        }        // Non-numerical data. If the two characters are the same then        // move on. Note: this has to happen after numerical conversions        // to distinguish v10.0 and v1.0        if (*ptr1 == *ptr2) {            ptr1++; ptr2++;            continue;        }        // If both strings are currently at a separator then move on. All        // separators can be used interchangeably.        if (is_separator(*ptr1) && is_separator(*ptr2)) {            ptr1++; ptr2++;            continue;        }        // If only one string is at a separator, special action        // is needed. v1.1alpha is interpreted as earlier than        // v1.1, but v1.1.3 is a later release.        if (is_separator(*ptr1)) {            return -1;        } else if (is_separator(*ptr2)) {            return 1;        }                // Two different characters, e.g. v1.0alpha vs. v1.0beta        if (*ptr1 < *ptr2) {            CYG_REPORT_RETVAL(1);            return 1;        } else {            CYG_REPORT_RETVAL(-1);            return -1;        }    }    // Not reachable.}//}}}//{{{  Cdl::get_short_form()                                    // ----------------------------------------------------------------------------// It is occasionally useful to take a full CDL name such as CYgpkg_KERNEL// and turn it into a short form such as "kernel". This involves discarding// everything up to and including the first underscore, then lowercasing// all subsequent characters.std::stringCdl::get_short_form(const std::string& original){    CYG_REPORT_FUNCNAME("CdlMisc::get_short_form");    std::string  result = "";    unsigned int size = original.size();    unsigned int i;    for (i = 0; i < size; i++) {        if ('_' == original[i]) {            i++;            break;        }    }    // Either at end of string, or just past the first underscore    for ( ; i < size; i++) {        if (isupper(original[i])) {            result += tolower(original[i]);        } else {            result += original[i];        }    }        CYG_REPORT_RETURN();    return result;}//}}}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -