示例#1
0
ERRCODE Config::load( string filename )
{
    string tmp;
    char *line = NULL;
    FILE *fp = NULL;
    size_t len = 0, linenum = 0;
    ssize_t read;

    vector<string> tokens;
    C_NODE node;
    nodes.clear();

    enforce(( fp = fopen( filename.c_str(), "r" )) != NULL,
            "Failed to read from file " << filename << ": " 
            << strerror( errno ));

    // replace with fgets
    while(( read = readline( &line, &len, fp )) != -1 ) {
        linenum++;
        tmp = line;
        trim( tmp );
        if( tmp.empty() || tmp[0] == '#' ) continue;

        node.type = NONE;
        node.list.clear();
        node.length = false;
        tokens.clear();
        stringTok( tmp, tokens );

        // test min number of tokens
        enforce( tokens.size() >= 4, 
                "Failed to parse " << filename << " ( " <<
                tokens.size() << " < 4 )\n" << linenum << ": " << line );

        // test for type
        if( tokens[0][0] == '$' ) {
            node.length = true;
            tokens[0] = tokens[0].substr( 1 );
        }

        for( size_t j = 0; j < VTYPEL; ++j ) {
            if( iequals( tokens[0], VTYPES[j] )) {
                node.type = (VTYPE)j;
                break;
            }
        }
        enforce( node.type != NONE,
                "Failed to parse " << filename << " ( \"" <<
                tokens[0] << "\" != TYPE  )\n" << linenum << ": " << line );
                
        // test for open bracket
        enforce( iequals( tokens[1], "{" ),
                "Failed to parse " << filename << " ( \"" <<
                tokens[1] << "\" != \"{\"  )\n" << linenum << ": " << line );

        for( size_t j = 2; j < tokens.size(); j++ ) {
            enforce( tokens[j][0] != '#', 
                "Failed to parse " << filename << " ( \'" <<
                tokens[j][0] << "\' == \'#\'  )\n" << linenum << ": " << line );
            if( iequals( tokens[j], "}" )) {
                if( j + 1 < tokens.size()) {
                    enforce( tokens[j+1][0] == '#',
                        "Failed to parse " << filename << " ( \'" <<
                        tokens[j][0] << "\' != \'#\'  )\n" << linenum << ": " << line );
                }
                break;
            }
            node.list.push_back( tokens[j] );
        }
        nodes.push_back(node);
    }
    fclose( fp );
    free( line );
    return PK_OK;
}
示例#2
0
int Unit::set(const std::string &value)
{
    this->clear();
    
    std::string unitString = value;
    stringTrim(unitString);
    
    if(unitString.empty()) return 0;
    
    stringReplace(unitString, "**", "");                   // remove exponentiation symbols
    stringReplace(unitString, "^",  "");
    stringReplace(unitString, "*",  " ");                  // replace multiplication symbols with space for tokenising
    stringReplace(unitString, "/",  " /");                 // pad division symbols with space for tokenising
    while(stringReplace(unitString, "/ ", "/") == 0);      // remove all spaces after division symbols
    
    std::vector<std::string> tokens;
    
    // Tokenise string using spaces:
    if(stringTok(unitString, tokens, " ") != 0)
    {
        std::cerr << "Error (Unit): Failed to tokenise unit string." << std::endl;
        this->clear();
        return 1;
    }
    
    if(tokens.size() < 1)
    {
        std::cerr << "Error (Unit): Failed to tokenise unit string." << std::endl;
        this->clear();
        return 1;
    }
    
    // Loop through all tokens:
    for(size_t i = 0; i < tokens.size(); i++)
    {
        int factorDiv = 1;     // Will become -1 if division sign '/' found.
        int exponent  = 1;     // Exponent of the unit; defaults to 1 if unspecified.
        
        
        // Check for division symbol:
        
        if(tokens[i].substr(0, 1) == "/")
        {
            tokens[i] = tokens[i].substr(1, tokens[i].size() - 1);
            factorDiv = -1;
        }
        
        // Extract exponent:
        
        size_t posExp = tokens[i].find_first_of("+-0123456789");
        
        if(posExp != std::string::npos)
        {
            exponent = stringToNumber<int>(tokens[i].substr(posExp));
        }
        
        exponent *= factorDiv;
        
        // Only proceed if unit is not unity:
        if(exponent != 0 and tokens[i] != "1")
        {
            // Extract base unit and prefix:
            bool success = false;
            
            std::map<std::string, std::vector<int> >::const_iterator iterUnit = unitMap.begin();
            do
            {
                std::map<std::string, int>::const_iterator iterPrefix = prefixMap.begin();
                do
                {
                    std::string searchKey = iterPrefix->first + iterUnit->first;
                    
                    if(searchKey == tokens[i].substr(0, posExp))
                    {
                        success = true;
                        
                        int prefix = iterPrefix->second;
                        std::vector<int> unit(iterUnit->second);
                        
                        // Take care of special case 'kg':
                        if(iterUnit->first == "g") prefix -= 3;
                        
                        for(size_t ii = 0; ii < UNIT_NUMBER_BASE_UNITS; ii++)
                        {
                            units[ii] += unit[ii] * exponent;
                        }
                        
                        prefixes += prefix * exponent;
                    }
                    
                    iterPrefix++;
                }
                while(success == false and iterPrefix != prefixMap.end());
                
                iterUnit++;
            }
            while(success == false and iterUnit != unitMap.end());
            
            if(success == false)
            {
                std::cerr << "Error (Unit): Unknown unit: \'" << value << "\'."   << std::endl;
                std::cerr << "              Creating dimensionless unit instead." << std::endl;
                clear();
                return 1;
            }
        }
    }
    
    return 0;
}