Changeset 399 for trunk/src/core


Ignore:
Timestamp:
Apr 6, 2006 7:31:53 PM (18 years ago)
Author:
dkearney
Message:

improved the tcl bindings,
added units code to core so tcl can show compatible conversions,
added installdir to tcl pkg index file,
added rappture exec for tcl

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/core/RpUnits.cc

    r388 r399  
    183183 */
    184184std::list<std::string>
    185 RpUnits::getCompatible() const {
     185RpUnits::getCompatible(double expMultiplier) const {
    186186
    187187    std::list<std::string> compatList;
    188188    std::list<std::string> basisCompatList;
    189     std::string myName         = getUnitsName();
    190     std::string otherName      = getUnitsName();
    191     convEntry* myConversions   = this->convList;
     189    std::string myName          = getUnitsName();
     190    // std::stringstream otherName;
     191    std::string otherName       = "";
     192    std::string otherBasisName  = "";
     193    std::string blank           = "";
     194    // double otherExp             = 1.0;
     195    convEntry* myConversions    = this->convList;
     196    const RpUnits * basis       = NULL;
    192197
    193198    if (this->basis) {
     
    195200        compatList.merge(basisCompatList);
    196201    }
    197 
    198     // run through the conversion list
    199     // for each entry, look at the name
    200     // if the name is not equal to the name of this RpUnits object,
    201     // store the fromPtr->getUnitsName() into compatList
    202     // else store the toPtr->getUnitsName() into compatList
    203     //
    204     while (myConversions != NULL) {
    205         otherName = myConversions->conv->toPtr->getUnitsName();
    206         if (otherName == myName) {
    207             otherName = myConversions->conv->fromPtr->getUnitsName();
    208         }
    209         compatList.push_back(otherName);
    210         myConversions = myConversions->next;
     202    else {
     203        // only basis units should be in here
     204        //
     205        // run through the conversion list
     206        // for each entry, look at the name
     207        // if the name is not equal to the name of this RpUnits object,
     208        // store the fromPtr->getUnitsName() into compatList
     209        // else store the toPtr->getUnitsName() into compatList
     210        //
     211        while (myConversions != NULL) {
     212
     213            otherName = myConversions->conv->toPtr->getUnitsName();
     214            /*
     215            otherName.str("");
     216            otherName << myConversions->conv->toPtr->getUnitsName();
     217            otherExp = myConversions->conv->fromPtr->getExponent();
     218            if ( (otherExp != 1) && (expMultiplier != 1) ) {
     219                otherName << otherExp * expMultiplier;
     220            }
     221            */
     222            basis = myConversions->conv->toPtr->basis;
     223
     224            // if (myName == otherName.str()) {
     225            if (myName == otherName) {
     226                otherName = myConversions->conv->fromPtr->getUnitsName();
     227                /*
     228                otherName.str("");
     229                otherName << myConversions->conv->fromPtr->getUnitsName();
     230                if ( (otherExp != 1) && (expMultiplier != 1) ) {
     231                    otherExp = myConversions->conv->fromPtr->getExponent();
     232                    otherName << otherExp * expMultiplier;
     233                }
     234                */
     235                basis = myConversions->conv->fromPtr->basis;
     236            }
     237
     238            // check to see if they are the same basis,
     239            // no need to list all of the metric conversions.
     240            if (basis) {
     241                if (basis->getUnitsName() == myName) {
     242                    // do not add this unit to the conversion
     243                    // because its a derived unit.
     244                    myConversions = myConversions->next;
     245                    continue;
     246                }
     247            }
     248
     249            // add the other unit's name to the list of compatible units
     250            // compatList.push_back(otherName.str());
     251            std::cout << " pushing " << otherName << std::endl;
     252            compatList.push_back(otherName);
     253
     254            // advance to the next conversion
     255            myConversions = myConversions->next;
     256        }
    211257    }
    212258
     
    556602    return unitEntry;
    557603}
     604
     605/**********************************************************************/
     606// METHOD: validate()
     607/// Split a string of units and check that each unit is available as an object
     608/**
     609 * Splits a string of units like cm2/kVns into a list of units like
     610 * cm2, kV1, ns1 where an exponent is provided for each list entry.
     611 * It checks to see that each unit actually exists as a valid defined unit.
     612 * If the unit exists or can be interpreted, the function keeps parsing the
     613 * string until it reaches the end of the string. If the function comes
     614 * across a unit that is unrecognized or can not be interpreted, then it
     615 * returns error (a non-zero value).
     616 *
     617 * this code is very similar to units2list()
     618 *
     619 * if &compatList == NULL, no compatible list of units will be generated.
     620 * this function does not do a good job of placing the available units
     621 * back into the original formula. i still need to work on this.
     622 */
     623
     624int
     625RpUnits::validate ( const std::string& inUnits,
     626                    std::string& type,
     627                    std::list<std::string>* compatList ) {
     628
     629    std::string myInUnits   = inUnits;
     630    std::string sendUnitStr = "";
     631    double exponent         = 1;
     632    int offset              = 0;
     633    int idx                 = 0;
     634    int last                = 0;
     635    int err                 = 0; // did we come across an unrecognized unit
     636    const RpUnits* unit     = NULL;
     637    std::list<std::string> basisCompatList;
     638    std::list<std::string>::iterator compatListIter;
     639    std::stringstream unitWExp;
     640
     641
     642    while ( !myInUnits.empty() ) {
     643
     644        // check to see if we came across a '/' character
     645        last = myInUnits.length()-1;
     646        if (myInUnits[last] == '/') {
     647            type = myInUnits[last] + type;
     648            myInUnits.erase(last);
     649            continue;
     650        }
     651
     652        // get the exponent
     653        offset = RpUnits::grabExponent(myInUnits,&exponent);
     654        myInUnits.erase(offset);
     655        idx = offset - 1;
     656
     657        // grab the largest string we can find
     658        offset = RpUnits::grabUnitString(myInUnits);
     659        idx = offset;
     660
     661        // figure out if we have some defined units in that string
     662        sendUnitStr = myInUnits.substr(offset,std::string::npos);
     663        if ((unit = grabUnits(sendUnitStr,&offset))) {
     664            // a unit was found
     665            // erase the found unit's name from our search string
     666            myInUnits.erase(idx+offset);
     667
     668            // add the type to the type string
     669            type = unit->getType() + type;
     670
     671            // merge the compatible units
     672            if (compatList) {
     673                basisCompatList = unit->getCompatible(exponent);
     674
     675                // adjust exponents as necessary
     676                if ( (exponent != 0) && (exponent != 1) ) {
     677                    compatListIter = compatList->begin();
     678                    while (compatListIter != compatList->end()) {
     679                        unitWExp << *compatListIter << exponent;
     680                        *compatListIter = unitWExp.str();
     681                    }
     682                }
     683
     684                compatList->merge(basisCompatList);
     685            }
     686        }
     687        else {
     688            // we came across a unit we did not recognize
     689            // raise error and exit
     690            err++;
     691            break;
     692        }
     693
     694        // reset our vars
     695        idx = 0;
     696        offset = 0;
     697        exponent = 1;
     698    }
     699
     700    // clean out any duplicate entries.
     701    if (compatList) {
     702        compatList->unique();
     703    }
     704
     705    return err;
     706}
     707
    558708
    559709/**********************************************************************/
Note: See TracChangeset for help on using the changeset viewer.