bool ConfigReader::parse_obj(const std::string &key, std::string &obj, std::string &err) { std::vector<std::string> items; std::string okey, oval; std::unordered_map<std::string, std::string> map; size_t ind; /* remove surrounding braces and whitespace */ obj = obj.substr(1); remove_leading(obj); while (obj.back() != '}') obj.pop_back(); obj.pop_back(); while (isspace(obj.back())) obj.pop_back(); utils::split(obj, '\n', items); for (std::string s : items) { if ((ind = s.find('=')) == std::string::npos) { err = "unrecognized token in list -- "; for (ind = 0; !isspace(s[ind]); ++ind) err += s[ind]; return false; } okey = s.substr(0, ind); while (isspace(okey.back())) okey.pop_back(); oval = parse_string(s); map[okey] = oval; } olistmap[key].emplace_back(map); return true; }
std::string ConfigReader::parse_list(const std::string &buf, std::string &err) { std::string out, s, val; size_t ind, nl; /* remove surrounding braces */ s = buf.substr(1); while (isspace(s.back()) || s.back() == '}') s.pop_back(); ind = 0; while (ind != std::string::npos) { remove_leading(s); if ((ind = s.find(',')) == std::string::npos) { val = s; } else { val = s.substr(0, ind); if (ind == s.length() - 1) { err = "expected item after comma"; return ""; } } if ((nl = val.find('\n')) != std::string::npos) { err = "unexpected list continuation after "; err += val.substr(0, nl); return ""; } out += val; if (ind != std::string::npos) out += '\n'; s = s.substr(ind + 1); } return out; }
std::string ConfigReader::parse_olist(const std::string &key, const std::string &buf, std::string &err) { std::string s, item; size_t end; s = buf.substr(1); while (s.back() != '}') s.pop_back(); s.pop_back(); while (isspace(s.back())) s.pop_back(); end = 0; while (end != std::string::npos) { remove_leading(s); if ((end = s.find('}')) != std::string::npos) { item = s.substr(0, end + 1); if (!parse_obj(key, item, err)) return ""; s = s.substr(end + 1); remove_leading(s); if (s[0] == ',') { s = s.substr(1); if (s.find('{') == std::string::npos) { err = "expected item after comma"; return ""; } } else if (s.find('{') != std::string::npos) { err = "unexpected list continuation"; return ""; } } } return "olist"; }
bool ConfigReader::read() { std::string buf, line, key, val, err; std::ifstream reader(config_path); uint16_t nline, nsettings; size_t ind, set; int8_t open; nsettings = sizeof(settings) / sizeof(settings[0]); nline = set = open = 0; while (std::getline(reader, line)) { ++nline; /* remove commented sections of lines */ if ((ind = line.find('#')) != std::string::npos && line[ind - 1] != '\\') line = line.substr(0, ind); if (blank(line)) continue; if (!open) { remove_leading(line); if ((ind = line.find('=')) == std::string::npos) { err = "unrecognized token -- "; for (ind = 0; !isspace(line[ind]); ++ind) err += line[ind]; std::cerr << config_path << ": line " << nline << ": " << err << std::endl; return false; } key = line.substr(0, ind); while (isspace(key.back())) key.pop_back(); for (set = 0; set < nsettings; ++set) { if (key == settings[set].key) break; } if (set == nsettings) { std::cerr << config_path << ": line " << nline << ": unrecognized key -- " << key << std::endl; return false; } } if (settings[set].val_type == STRING) { if ((val = parse_string(line)).empty()) { std::cerr << config_path << ": line " << nline << ": no setting provided for " << key << std::endl; return false; } setmap[key] = val; } else { /* reading a list within a brace block */ ind = -1; while ((ind = line.find('{', ind + 1)) != std::string::npos) ++open; if (open) { remove_leading(line); buf += line + '\n'; ind = -1; while ((ind = line.find('}', ind + 1)) != std::string::npos) --open; } if (!open) { if ((val = parse_string(buf)).empty()) { std::cerr << config_path << ": line " << nline << ": no setting " "provided for " << key << std::endl; return false; } if (settings[set].val_type == LIST) val = parse_list(val, err); else val = parse_olist(key, val, err); if (val.empty()) { std::cerr << config_path << ": line " << nline << ": " << err << std::endl; return false; } setmap[key] = val; buf = ""; } } } if (open) { std::cerr << config_path << ": unexpected end of file" << std::endl; return false; } for (set = 0; set < nsettings; ++set) { if (setmap.find(settings[set].key) == setmap.end()) { std::cerr << config_path << ": missing required setting: " << settings[set].key << std::endl; return false; } } return true; }
std::string ConfigReader::parse_string(const std::string &buf) { std::string val = buf.substr(buf.find('=') + 1); remove_leading(val); return val; }
void eoRealVectorBounds::readFrom(std::string _value) { // keep track of old size - to adjust in the end unsigned oldSize = size(); // clean-up before filling in if (ownedBounds.size()>0) for (unsigned i = 0; i < ownedBounds.size(); ++i) { delete ownedBounds[i]; } ownedBounds.resize(0); factor.resize(0); resize(0); // now read std::string delim(",; "); while (_value.size()>0) { if (!remove_leading(_value, delim)) // only delimiters were left break; // look for opening char size_t posDeb = _value.find_first_of("[("); if (posDeb >= _value.size()) // nothing left to read (though probably a syntax error there) { break; } // ending char std::string closeChar = (_value[posDeb] == '(' ? std::string(")") : std::string("]") ); size_t posFin = _value.find_first_of(std::string(closeChar)); if (posFin >= _value.size()) throw std::runtime_error("Syntax error when reading bounds"); // y a-t-il un nbre devant unsigned count = 1; if (posDeb > 0) // something before opening { std::string sCount = _value.substr(0, posDeb); count = read_int(sCount); if (count <= 0) throw std::runtime_error("Syntax error when reading bounds"); } // the bounds std::string sBounds = _value.substr(posDeb+1, posFin-posDeb-1); // and remove from original string _value = _value.substr(posFin+1); remove_leading(sBounds, delim); size_t posDelim = sBounds.find_first_of(delim); if (posDelim >= sBounds.size()) throw std::runtime_error("Syntax error when reading bounds"); bool minBounded=false, maxBounded=false; double minBound=0, maxBound=0; // min bound std::string sMinBounds = sBounds.substr(0,posDelim); if (sMinBounds != std::string("-inf")) { minBounded = true; minBound = read_double(sMinBounds); } // max bound size_t posEndDelim = sBounds.find_first_not_of(delim,posDelim); std::string sMaxBounds = sBounds.substr(posEndDelim); if (sMaxBounds != std::string("+inf")) { maxBounded = true; maxBound = read_double(sMaxBounds); } // now create the eoRealBounds objects eoRealBounds *ptBounds; if (minBounded && maxBounded) ptBounds = new eoRealInterval(minBound, maxBound); else if (!minBounded && !maxBounded) // no bound at all ptBounds = new eoRealNoBounds; else if (!minBounded && maxBounded) ptBounds = new eoRealAboveBound(maxBound); else if (minBounded && !maxBounded) ptBounds = new eoRealBelowBound(minBound); // store it for memory management ownedBounds.push_back(ptBounds); // push the count factor.push_back(count); // and add count of it to the actual bounds for (unsigned i=0; i<count; i++) push_back(ptBounds); } // now adjust the size to the initial value adjust_size(oldSize); }
/** the constructor for eoGeneralRealBound - from a string * very similar to the eoRealVectorBounds::readFrom above * but was written much later so the readFrom does not call this one * as it should do */ eoRealBounds* eoGeneralRealBounds::getBoundsFromString(std::string _value) { // now read std::string delim(",; "); std::string beginOrClose("[(])"); if (!remove_leading(_value, delim)) // only delimiters were left throw std::runtime_error("Syntax error in eoGeneralRealBounds Ctor"); // look for opening char size_t posDeb = _value.find_first_of(beginOrClose); // allow ]a,b] if (posDeb >= _value.size()) // nothing left to read throw std::runtime_error("Syntax error in eoGeneralRealBounds Ctor"); // ending char: next {}() after posDeb size_t posFin = _value.find_first_of(beginOrClose,posDeb+1); if (posFin >= _value.size()) // not found throw std::runtime_error("Syntax error in eoGeneralRealBounds Ctor"); // the bounds std::string sBounds = _value.substr(posDeb+1, posFin-posDeb-1); // and remove from original string _value = _value.substr(posFin+1); remove_leading(sBounds, delim); size_t posDelim = sBounds.find_first_of(delim); if (posDelim >= sBounds.size()) throw std::runtime_error("Syntax error in eoGeneralRealBounds Ctor"); bool minBounded=false, maxBounded=false; double minBound=0, maxBound=0; // min bound std::string sMinBounds = sBounds.substr(0,posDelim); if ( (sMinBounds != std::string("-inf")) && (sMinBounds != std::string("-infinity")) ) { minBounded = true; minBound = read_double(sMinBounds); } // max bound size_t posEndDelim = sBounds.find_first_not_of(delim,posDelim); std::string sMaxBounds = sBounds.substr(posEndDelim); if ( (sMaxBounds != std::string("+inf")) && (sMaxBounds != std::string("+infinity")) ) { maxBounded = true; maxBound = read_double(sMaxBounds); } // now create the embedded eoRealBounds object eoRealBounds * locBound; if (minBounded && maxBounded) { if (maxBound <= minBound) throw std::runtime_error("Syntax error in eoGeneralRealBounds Ctor"); locBound = new eoRealInterval(minBound, maxBound); } else if (!minBounded && !maxBounded) // no bound at all locBound = new eoRealNoBounds; else if (!minBounded && maxBounded) locBound = new eoRealAboveBound(maxBound); else if (minBounded && !maxBounded) locBound = new eoRealBelowBound(minBound); return locBound; }