Improved implementation of parseCompString

Improvements:

- Tolerate formatting irregularities such as spaces befpre or after the colon
  (e.g. 'H2: 1.0')

- Allow names containing commas and semicolons

- Detect errors such as no value being supplied for the last element (e.g. 'H2')

- Single implementation handles both the case where a list of valid names is
  supplied and when any name is allowed
This commit is contained in:
Ray Speth 2014-11-07 02:14:52 +00:00
parent 37f71bd912
commit 07f8d520ee
2 changed files with 23 additions and 68 deletions

View file

@ -88,23 +88,12 @@ std::string lowercase(const std::string& s);
*
* @param ss original string consisting of multiple key:composition
* pairs on multiple lines
* @param names valid names for elements in the composition map
* @param names (optional) valid names for elements in the composition map. If
* empty or unspecified, all values are allowed.
* @return map of names to values
*/
compositionMap parseCompString(const std::string& ss,
const std::vector<std::string>& names);
//! Parse a composition string into a map consisting of individual
//! key:composition pairs.
/*!
* This version of the function returns a map containing only those keys in
* the provided string, and does not require them to be drawn from a specific
* set of names.
*
* @param ss original string consisting of multiple key:composition pairs
* @return map of names to values
*/
compositionMap parseCompString(const std::string& ss);
const std::vector<std::string>& names=std::vector<std::string>());
//! Parse a composition string into individual key:composition pairs
/*!

View file

@ -139,62 +139,28 @@ compositionMap parseCompString(const std::string& ss,
for (size_t k = 0; k < names.size(); k++) {
x[names[k]] = 0.0;
}
std::string s = ss;
std::string num;
do {
size_t ibegin = s.find_first_not_of(", ;\n\t");
if (ibegin != std::string::npos) {
s = s.substr(ibegin,s.size());
size_t icolon = s.find(':');
size_t iend = s.find_first_of(", ;\n\t");
if (icolon != std::string::npos) {
std::string name = stripws(s.substr(0, icolon));
if (iend != std::string::npos) {
num = s.substr(icolon+1, iend-icolon-1);
s = s.substr(iend+1, s.size());
} else {
num = s.substr(icolon+1, s.size());
s = "";
}
if (x.find(name) == x.end()) {
throw CanteraError("parseCompString",
"unknown species " + name);
}
x[name] = fpValueCheck(num);
} else {
s = "";
}
}
} while (s != "");
return x;
}
compositionMap parseCompString(const std::string& ss)
{
compositionMap x;
std::string s = ss;
std::string num;
while (!s.empty()) {
size_t ibegin = s.find_first_not_of(", ;\n\t");
if (ibegin != std::string::npos) {
s = s.substr(ibegin,s.size());
size_t icolon = s.find(':');
size_t iend = s.find_first_of(", ;\n\t");
if (icolon != std::string::npos) {
std::string name = stripws(s.substr(0, icolon));
if (iend != std::string::npos) {
num = s.substr(icolon+1, iend-icolon-1);
s = s.substr(iend+1, s.size());
} else {
num = s.substr(icolon+1, s.size());
s = "";
}
x[name] = fpValueCheck(num);
} else {
s = "";
}
size_t start = 0;
size_t stop = 0;
while (stop < ss.size()) {
size_t colon = ss.find(':', start);
if (colon == npos) {
break;
}
};
size_t valstart = ss.find_first_not_of(" \t\n", colon+1);
stop = ss.find_first_of(", ;\n\t", valstart);
std::string name = stripws(ss.substr(start, colon-start));
if (!names.empty() && x.find(name) == x.end()) {
throw CanteraError("parseCompString",
"unknown species '" + name + "'");
}
x[name] = fpValueCheck(ss.substr(valstart, stop-colon-1));
start = ss.find_first_not_of(", ;\n\t", stop+1);
}
if (stop != npos && !stripws(ss.substr(stop)).empty()) {
throw CanteraError("parseCompString", "Found non-key:value data "
"in composition string: '" + ss.substr(stop) + "'");
}
return x;
}