14 #define SNPRINTF _snprintf
16 #define SNPRINTF snprintf
25 #include <boost/algorithm/string.hpp>
29 namespace ba = boost::algorithm;
35 const std::string& sep)
39 for (
size_t i = 0; i < v.size(); i++) {
40 SNPRINTF(buf, 63,
fmt.c_str(), v[i]);
42 if (i != v.size() - 1) {
52 for (
size_t i = 0; i < s.size(); i++) {
61 const std::vector<std::string>& names)
64 for (
size_t k = 0; k < names.size(); k++) {
71 while (stop < ss.size()) {
72 size_t colon = ss.find(
':', left);
76 size_t valstart = ss.find_first_not_of(
" \t\n", colon+1);
77 stop = ss.find_first_of(
", ;\n\t", valstart);
78 std::string name = ba::trim_copy(ss.substr(start, colon-start));
79 if (!names.empty() && x.find(name) == x.end()) {
81 "unknown species '" + name +
"'");
86 value =
fpValueCheck(ss.substr(valstart, stop-valstart));
92 std::string testname = ss.substr(start, stop-start);
93 if (testname.find_first_of(
" \n\t") !=
npos) {
96 }
else if (ss.substr(valstart, stop-valstart).find(
':') !=
npos) {
104 if (
getValue(x, name, 0.0) != 0.0) {
106 "Duplicate key: '" + name +
"'.");
110 start = ss.find_first_not_of(
", ;\n\t", stop+1);
114 throw CanteraError(
"parseCompString",
"Unable to parse key-value pair:"
115 "\n'{}'", ss.substr(start, stop));
117 if (stop !=
npos && !ba::trim_copy(ss.substr(stop)).empty()) {
118 throw CanteraError(
"parseCompString",
"Found non-key:value data "
119 "in composition string: '" + ss.substr(stop) +
"'");
126 return std::atoi(ba::trim_copy(val).c_str());
132 std::stringstream ss(val);
133 ss.imbue(std::locale(
"C"));
140 std::string str = ba::trim_copy(val);
142 throw CanteraError(
"fpValueCheck",
"string has zero length");
149 if (ch ==
'+' || ch ==
'-') {
150 if (str.size() == 1) {
151 throw CanteraError(
"fpValueCheck",
"string ends in '{}'", ch);
155 for (
size_t i = istart; i < str.size(); i++) {
158 }
else if (ch ==
'.') {
162 "string has more than one .");
166 "string has decimal point in exponent");
168 }
else if (ch ==
'e' || ch ==
'E' || ch ==
'd' || ch ==
'D') {
173 "string has more than one exp char");
174 }
else if (i == str.size() - 1) {
176 "string ends in '{}'", ch);
179 if (ch ==
'+' || ch ==
'-') {
180 if (i + 1 == str.size() - 1) {
182 "string ends in '{}'", ch);
188 "Trouble processing string, " + str);
196 std::string s = ba::trim_copy(nameStr);
198 size_t ibegin = s.find_first_not_of(
" ;\n\t");
200 s = s.substr(ibegin,s.size());
201 size_t icolon = s.find(
':');
202 size_t iend = s.find_first_of(
" ;\n\t");
204 phaseName = s.substr(0, icolon);
205 s = s.substr(icolon+1, s.size());
206 icolon = s.find(
':');
209 "two colons in name: '{}'", nameStr);
213 throw CanteraError(
"parseSpeciesName",
"Species name has "
214 "\" ;/\n/\t\" in the middle of it: '{}'", nameStr);
222 std::vector<std::string> v;
226 if (n > 2 || n < 1) {
228 "number of tokens is too high");
238 std::string val = ba::trim_copy(in_val);
245 ba::split(v, val, ba::is_space(), ba::token_compress_on);
248 size_t copyString(
const std::string& source,
char* dest,
size_t length)
250 const char* c_src = source.c_str();
251 size_t N = std::min(length, source.length()+1);
252 size_t ret = (length >= source.length() + 1) ? 0 : source.length() + 1;
253 std::copy(c_src, c_src + N, dest);
255 dest[length-1] =
'\0';
261 return ba::trim_copy(input);
265 return ba::to_lower_copy(input);
269 return ba::iequals(input, test);