void Date::setMonthLengths(std::string monLen) { if( monLen.size() ) monthLengths = monLen; else { if( monthLengths.size() == 0 ) return; } Split x_ml(monthLengths); if( x_ml.size() != 12 ) { std::ostringstream ostr(std::ios::app); ostr << "Date::setMonthLengths()" << "\n12 values reuqired; found: " << monthLengths; exceptionError( ostr.str() ); } for( size_t i=0 ; i < x_ml.size() ; ++i) regularMonthDays[i]=hdhC::string2Double(x_ml[i]); return; }
std::vector<std::string> Base::getVarname( std::string &s) { // There might be a varname specification or not. // no varname found: return true std::vector<std::string> names; std::string list; std::vector<std::string> tokens; tokens.push_back( ":v=" ) ; tokens.push_back( ":varname=" ) ; tokens.push_back( ":vname=" ) ; tokens.push_back( ":variable" ) ; bool isEmpty=true; size_t pos0=0; for( size_t i=0 ; i < tokens.size() ; ++i ) { if( (pos0 = s.find( tokens[i] ) ) < std::string::npos ) // e.g.: s: "...:vname=...:..." and tokens: ":vname=..." isEmpty=false; else if( s.substr(0,tokens[i].size()-1) == tokens[i].substr(1) ) // e.g.: s: "vname=..." and tokens: "vname=..." isEmpty=false; } if( isEmpty ) return names; // the assignment sign size_t pos1=s.find("=",pos0); if( pos1 == std::string::npos ) { std::ostringstream ostr(std::ios::app); ostr << "Base::getVarname(): invalid assignment"; exceptionError( ostr.str() ); std::string note("E8: no rules for finding a variable name."); finally(8, note); } else ++pos1 ; // the end of the assignment size_t pos2=s.find(":",pos1); if( pos2 == std::string::npos ) // the end of the string pos2=s.size(); list=s.substr(pos1, pos2-pos1); // expand the list Split spl(list, ","); for( size_t i=0 ; i < spl.size() ; ++i) names.push_back( spl[i] ) ; return names; }
void Date::addTime(std::string time, std::string unit) { Split splt; // default for units: inherent units if( unit.size() == 0 ) unit = unitStr; // It is save to append units (even if empty) to time // Note: time-unit overrules parameter unit. time += unit; // Split string at positions where digits and characters alternate. splt.setSeparator(":alnum:"); splt = time ; // If there is a mix of digits and non-digits, splt.size() >= 2: // isNonDigit && size == 1 is an error. // size == 0 is an error. // But, for !isNonDigit && size == 1 we got the default bool isNon = ! hdhC::isDigit(time); if( (splt.size() == 1 && isNon) || (splt.size() == 0) ) { std::ostringstream ostr(std::ios::app); ostr << "Date::addTime()" << "\nerror in 2nd parameter (time=" << time << ")" ; exceptionError( ostr.str() ); } // unitStr and int strings are empty. // Pure digits are always converted to days. if( splt.size() == 1 ) { addDays( splt.toDouble(0) ) ; return; } std::string str(splt[1]); if( str[0] == 'y' ) addYears( splt.toDouble(0) ); else if( str.substr(0,2) == "mo" ) addMonths( splt.toDouble(0) ); else if( str[0] == 'd' ) addDays( splt.toDouble(0) ); else if( str[0] == 'h' ) addHours( splt.toDouble(0) ); else if( str.substr(0,2) == "mi" ) addMinutes( splt.toDouble(0) ); else if( str[0] == 's' ) addSeconds( splt.toDouble(0) ); return; }
std::vector<std::string> Base::getVarname( std::string &s, std::vector<std::string> &alias) { // There might be a varname specification or not. // no varname found: return true // The reference 'alias' is special for operations, // e.g. v=x=var1,y=var2,... . If given, then var1 is the // variable returned via the vector and x,y,... are members // stored in alias. std::vector<std::string> list; std::vector<std::string> names; list = getVarname( s ) ; // expand the list for( size_t i=0 ; i < list.size() ; ++i) { Split spl(list[i], "="); if( spl.size() == 2 ) { alias.push_back( spl[0] ) ; names.push_back( spl[1] ) ; } else if( spl.size() == 1 ) { alias.push_back( "" ) ; names.push_back( spl[0] ) ; } else { std::ostringstream ostr(std::ios::app); ostr << "Base::getVarname(): invalid assignment\n"; ostr << " of variable names." ; exceptionError( ostr.str() ); std::string note("E9: invalid assignment of variable names."); finally(9, note); } } return names; }
bool Date::setDate( std::string str, std::string cal, std::string monLen) { // str could contain more information than just the date. // Return true, if no valid date string was found. // Possible input: str="minutes since 1955-01-01 00:00" // str="1955-1-1 00:00" if( str.size() == 0 ) { std::string text("Date::setDate(): empty string"); exceptionError( text.c_str() ); } if( cal.size() ) setCalendar(cal, monLen); // key-words "since" and "before" indicate that a date // serves as a basic date and // key-words: years, months, days, hours, minutes, seconds // indicate the unit of the amount X in getDate(X) relative // to the basic date. The method clears the string from any // key-word. setUnitsAndClear(str) ; if( isFormattedDate || str.find(' ') < std::string::npos ) str = convertFormattedToISO_8601(str) ; if( ! parseISO_8601(str) ) return true; else if( isDateSet && hdhC::isNumber(str) ) { // try the string as float if( setDate(hdhC::string2Double(str)) ) return true; } return false; }
void Base::setVarPropsNoOperation( void ) { // Selection of source variables and renaming takes place. std::vector<std::vector<std::string> > srcVarName; // number of specified source varname(s) size_t totalSVN=0; for( size_t i=0 ; i < pSrcBase.size() ; ++i ) { Base *p=pSrcBase[i]; srcVarName.push_back( *new std::vector<std::string> ); for( size_t j=0 ; j < p->optStr.size() ; ++j ) srcVarName[i] = getVarname(p->optStr[j]) ; // try for matching '.*' if( srcVarName[i].size() == 1 && srcVarName[i][0] == ".*" ) { srcVarName[i].clear() ; std::string t0; for( size_t j=0 ; j < p->variable.size() ; ++j ) srcVarName[i].push_back( p->variable[j].name ); } totalSVN += srcVarName[i].size() ; } // Clear varName, if matching for ".*" // Users would likely use the default, i.e. nothing if( varName.size() == 1 && varName[0] == ".*" ) varName.clear() ; if( varName.size() == 0 && totalSVN == 0 ) { // Nothing was specified, so set all you can get. // Getting multiple varnames from multiple sources is ok. for( size_t i=0 ; i < pSrcBase.size() ; ++i ) { Base *p=pSrcBase[i]; for( size_t j=0 ; j < p->variable.size() ; ++j ) { srcVariable.push_back( *new Variable) ; srcVariable.back().name = p->variable[j].name ; varName.push_back( p->variable[j].name ); setSrcVariable(srcVariable.back(), p); } } return; } // ------------------------------------ // vN == 0 && sN > 0 --> vN[i] = sN[i] // This is also for swapping variables in the OutFile if( varName.size() == 0 && totalSVN > 0 ) { // assign srcVarName(s) to varName(s) for( size_t i=0 ; i < srcVarName.size() ; ++i ) { Base *p=pSrcBase[i]; for( size_t j=0 ; j < srcVarName[i].size() ; ++j ) { // find the one you want to for( size_t k=0 ; k < p->variable.size() ; ++k ) { if( p->variable[k].name == srcVarName[i][j] ) { srcVariable.push_back( *new Variable) ; srcVariable.back().name = p->variable[k].name ; varName.push_back( p->variable[k].name ); setSrcVariable(srcVariable.back(), p); } } } } return; } // ------------------------------------ // select varname and rename implicitly, respectively. if( varName.size() > 0 && totalSVN == 0 ) { if( varName.size() == pSrcBase.size() ) { // vN > 0 && sN == 0 && vN == numOfObj --> first of each object for( size_t i=0 ; i < pSrcBase.size() ; ++i ) { Base *p=pSrcBase[i]; // find the one you want to if( p->variable.size() > 0 ) { srcVariable.push_back( *new Variable) ; srcVariable.back().name = p->variable[0].name ; setSrcVariable(srcVariable.back(), p); } } return; } else { // vN > 0 && sN == 0 && vN != numOfObj // --> as many as available from the first, and then // from the second until the number of varNames is reached. size_t count=0; for( size_t i=0 ; i < pSrcBase.size() ; ++i ) { Base *p=pSrcBase[i]; // find the one you want to for( size_t j=0 ; j < p->variable.size() ; ++j ) { srcVariable.push_back( *new Variable) ; srcVariable.back().name = p->variable[i].name ; setSrcVariable(srcVariable.back(), p); ++count; if( count == varName.size() ) return; } } } return; } // ------------------------------------ // vN > 0 && sN > 0 // --> rename explicitly (partially) if( varName.size() > 0 && totalSVN > 0 ) { // Rename variables. // varName[i] corresponds to srcVarName[i] // sequentially from left to right in the sequence of objects, // e.g.: v1,v2,v3,v4 <--> b0:v1, b1:v1,v2, b3:v1 // Note: The for-loop is for the case: varname.size==totalSVN. // Reasonable args are in the responsibility of the user size_t id=0; size_t num=0; for( size_t i=0 ; i < varName.size() ; ++i) { /* if( srcVarName[thisID].size() == num ) { num=0; ++id; } */ if( srcVarName.size() == id ) { std::ostringstream ostr(std::ios::app); ostr << "Base::setVarPropsNoOperation(): "; ostr << "no rules for this setting." << std::endl; exceptionError( ostr.str() ); std::string note("E7: No rules for finding a variable name."); finally(7, note); } srcVariable.push_back( *new Variable ); srcVariable.back().name=srcVarName[id][num]; setSrcVariable(srcVariable.back(), pSrcBase[id]); ++num; } // continue, if varName.size < totalSVN. /* if( srcVarName[thisID].size() == num ) { ++id; num=0; } */ for( ; id < srcVarName.size() ; ++id) { for( ; num < srcVarName[id].size() ; ++num) { srcVariable.push_back( *new Variable ); srcVariable.back().name=srcVarName[id][num]; varName.push_back( srcVarName[id][num] ); setSrcVariable(srcVariable.back(), pSrcBase[id]); } num=0; } return; } // Here we arrived in case of error. std::ostringstream ostr(std::ios::app); ostr << "Base::setVarPropsNoOperation(): "; ostr << "no rules for this setting."; exceptionError( ostr.str() ); std::string note("E8: no rules for finding a variable name."); finally(8, note); return; }
void Base::setVarPropsForOperation( void ) { // Notation: // vN: number of current variables // sN: number of names of sources summing sN[i0], sN[i1], ... // Notation: args in <operation>: a_ij is linked to obj[i]v[j]. // sN == 0 --> a_ij = obj[i][0] with x=0,1,... // sN == num of ops --> a_ij = obj[i]v[j] // sN > num of ops --> error // connect each alias to the corresponding variable // number of specified source varname(s) std::vector<std::string> sVN; std::vector<std::string> alias; std::vector<std::string> srcVarName; // Find matches for aliased srcVarNames and variables. // Loop through source objects. for( size_t j=0 ; j < pSrcBase.size() ; ++j ) { Base *p=pSrcBase[j]; // get source varname(s) and aliases srcVarName.clear(); alias.clear(); for( size_t k=0 ; k < p->optStr.size() ; ++k ) { std::vector<std::string> s0; std::vector<std::string> a0; s0 = getVarname( p->optStr[k], a0); for( size_t k1=0 ; k1 < s0.size() ; ++k1 ) { if( s0[k1].size() > 0 ) { srcVarName.push_back( s0[k1] ) ; if( a0[k1].size() > 0 ) alias.push_back( a0[k1] ); } } } // look for matches of operandStr and aliases for( size_t i=0 ; i < operandStr.size() ; ++i ) { for( size_t j=0 ; j < alias.size() ; ++j ) { if( alias[j] != operandStr[i] ) continue; for( size_t k=0 ; k < p->variable.size() ; ++k ) { if( p->variable[k].name == srcVarName[j] ) { srcVariable.push_back( *new Variable) ; srcVariable.back().name = p->variable[k].name ; // varName.push_back( p->variable[k].name ); setSrcVariable(srcVariable.back(), p); opMap[operandStr[i]] = &srcVariable.back(); } } } } } if( opMap.size() > 0 ) return; // No source varname specified. Then try whether there is // the same number of operandStr in the declaration // for the operation as of number of source objects. if( operandStr.size() == pSrcBase.size() ) { for( size_t i=0 ; i < pSrcBase.size() ; ++i ) { Base *p=pSrcBase[i]; srcVariable.push_back( *new Variable) ; srcVariable.back().name = p->variable[0].name ; setSrcVariable(srcVariable.back(), p); opMap[operandStr[i]] =&srcVariable.back(); } return; } // cannot connect alias to the corresponding variable std::ostringstream ostr(std::ios::app); ostr << "Base::setVarPropsForOperation(): " ; ostr << "no rules to link alias to variables in operation.\n"; ostr << "Operation:"; for(size_t j=0 ; j < optStr.size() ;++j) ostr << optStr[j] << " " ; ostr << "\nSource objects:\n"; for(size_t j=0 ; j < pSrcBase.size() ;++j) { Base *p=pSrcBase[j]; for(size_t i=0 ; i < optStr.size() ;++i) ostr << p->optStr[i] << " " ; } exceptionError( ostr.str() ); std::string note("E6: no rules to link alias to any variable in operation."); finally(6, note); return; }