iphreeqc/Parser.cxx
David L Parkhurst ff19c86d65 The tellg and seekg did not work for gz files because the
methods are not implemented.

Modified the parser to accumulate lines so that they
could be turned into a stream and reread. Modified
kinetics, exchange, ppassemblage, ssassemblage, and surface to use the new way to reread lines for component values. 

git-svn-id: svn://136.177.114.72/svn_GW/phreeqcpp/trunk@3742 1feff8c3-07ed-0310-ac33-dd36852eb9cd
2009-11-03 17:55:36 +00:00

1326 lines
28 KiB
C++

// Parser.cpp: implementation of the CParser class.
//
//////////////////////////////////////////////////////////////////////
#ifdef _DEBUG
#pragma warning(disable : 4786) // disable truncation warning (Only used by debugger)
#endif
#include "Parser.h"
#include "Utils.h"
#include "output.h"
#include <algorithm> // std::transform
#include <map> // std::map
#include <cassert> // assert
#include <iostream> // std::cout std::cerr
#include "char_star.h"
extern char *string_hsave(const char *str);
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CParser::CParser(std::istream & input):m_input_stream(input), m_output_stream(std::cout), m_error_stream(std::cerr),
m_input_error(0),
m_next_keyword(KT_NONE)
{
m_line_save.reserve(80);
m_line.reserve(80);
echo_file = EO_ALL;
echo_stream = EO_NONE;
accumulate = false;
}
CParser::CParser(std::istream & input, std::ostream & output):m_input_stream(input), m_output_stream(output), m_error_stream(std::cerr),
m_input_error(0),
m_next_keyword(KT_NONE)
{
m_line_save.reserve(80);
m_line.reserve(80);
echo_file = EO_ALL;
echo_stream = EO_NONE;
accumulate = false;
}
CParser::CParser(std::istream & input, std::ostream & output, std::ostream & error):m_input_stream(input), m_output_stream(output), m_error_stream(error),
m_input_error(0),
m_next_keyword(KT_NONE)
{
m_line_save.reserve(80);
m_line.reserve(80);
echo_file = EO_ALL;
echo_stream = EO_NONE;
accumulate = false;
}
CParser::~CParser()
{
}
CParser::LINE_TYPE CParser::check_line(const std::string & str,
bool allow_empty, bool allow_eof,
bool allow_keyword, bool print)
{
LINE_TYPE
i;
// Get line
do
{
i = get_line();
// reset iss
m_line_iss.str(m_line);
m_line_iss.seekg(0, std::ios_base::beg);
m_line_iss.clear();
// output for stream
switch (this->echo_stream)
{
case EO_NONE:
break;
case EO_ALL:
if (i != LT_EOF)
{
std::ostringstream msg;
msg << "\t" << m_line_save << "\n";
get_output() << msg;
}
break;
case EO_KEYWORDS:
if (i == LT_KEYWORD)
{
std::ostringstream msg;
msg << "\t" << m_line_save << "\n";
get_output() << msg;
}
break;
case EO_NOKEYWORDS:
if (i != LT_KEYWORD && i != LT_EOF)
{
std::ostringstream msg;
msg << "\t" << m_line_save << "\n";
get_output() << msg;
}
break;
}
// output for file
switch (this->echo_file)
{
case EO_NONE:
break;
case EO_ALL:
if (i != LT_EOF)
{
std::ostringstream msg;
msg << "\t" << m_line_save << "\n";
output_msg(OUTPUT_MESSAGE, "%s", msg.str().c_str());
}
break;
case EO_KEYWORDS:
if (i == LT_KEYWORD)
{
std::ostringstream msg;
msg << "\t" << m_line_save << "\n";
output_msg(OUTPUT_MESSAGE, "%s", msg.str().c_str());
}
break;
case EO_NOKEYWORDS:
if (i != LT_KEYWORD && i != LT_EOF)
{
std::ostringstream msg;
msg << "\t" << m_line_save << "\n";
output_msg(OUTPUT_MESSAGE, "%s", msg.str().c_str());
}
break;
}
}
while (i == LT_EMPTY && allow_empty == false);
// Check eof
if (i == LT_EOF && allow_eof == false)
{
std::ostringstream msg;
msg << "Unexpected eof while reading " << str <<
"\nExecution terminated.\n";
error_msg(msg, OT_STOP);
}
// Check keyword
if (i == LT_KEYWORD && allow_keyword == false)
{
std::ostringstream msg;
msg << "Expected data for " << str <<
", but got a keyword ending data block.";
error_msg(msg, OT_CONTINUE);
incr_input_error();
}
m_line_type = i;
return i;
}
CParser::LINE_TYPE CParser::get_line()
{
CParser::LINE_TYPE return_value = LT_EMPTY;
while (return_value == LT_EMPTY)
{
//
// Eliminate all characters after # sign as a comment
//
//
// Get line, check for eof
//
if (get_logical_line() == LT_EOF)
{
if (!m_input_stream.eof())
{
error_msg("Reading input file.", OT_CONTINUE);
error_msg("istream::get() returned an error.", OT_STOP);
}
else
{
//{{MOD
m_line.erase(m_line.begin(), m_line.end()); // m_line.clear();
//}}MOD
m_next_keyword = KT_EOF;
return LT_EOF;
}
}
//
// Get long lines
//
bool
empty = true;
m_line = m_line_save.substr(0, m_line_save.find_first_of('#'));
for (unsigned int i = 0; i < m_line.size(); ++i)
{
if (!::isspace(m_line[i]))
{
empty = false;
break;
}
}
if (this->accumulate)
{
this->accumulated.append(m_line_save);
this->accumulated.append("\n");
}
//
// New line character encountered
//
return_value = (empty ? LT_EMPTY : LT_OK);
}
//
// Determine return_value
//
if (return_value == LT_OK)
{
if (check_key(m_line.begin(), m_line.end()))
{
return_value = LT_KEYWORD;
}
else
{
std::string::iterator beg = m_line.begin();
std::string::iterator end = m_line.end();
std::string token;
copy_token(token, beg, end);
if (token.size() > 1 && token[0] == '-' &&::isalpha(token[1]))
{
return_value = LT_OPTION;
}
}
}
return return_value;
}
/**
Reads input stream until end of line, ";", or eof
stores characters in line_save
returns:
EOF on empty line on end of file or
OK otherwise
*/
CParser::LINE_TYPE CParser::get_logical_line()
{
int
j;
unsigned int
pos;
char
c;
m_line_save.erase(m_line_save.begin(), m_line_save.end()); // m_line_save.clear();
while ((j = m_input_stream.get()) != std::char_traits < char >::eof())
{
c = (char) j;
if (c == '#')
{
// ignore all chars after # until newline
do
{
c = (char) j;
if (c == '\n')
{
break;
}
m_line_save += c;
}
while ((j =
m_input_stream.get()) != std::char_traits <
char >::eof());
}
if (c == ';')
break;
if (c == '\n')
{
break;
}
if (c == '\\')
{
pos = (int) m_line_save.size();
m_line_save += c;
while ((j =
m_input_stream.get()) != std::char_traits < char >::eof())
{
c = (char) j;
if (c == '\\')
{
pos = (int) m_line_save.size();
m_line_save += c;
continue;
}
if (c == '\n')
{
// remove '\\'
for (; pos < m_line_save.size(); pos++)
{
m_line_save[pos] = m_line_save[pos + 1];
}
m_line_save.erase(m_line_save.size() - 1, 1);
break;
}
m_line_save += c;
if (!::isspace(j))
break;
}
}
else
{
m_line_save += c;
}
}
if (j == std::char_traits < char >::eof() && m_line_save.size() == 0)
{
return (LT_EOF);
}
return (LT_OK);
}
//bool CParser::check_key(const std::string::iterator ptr)
bool
CParser::check_key(std::string::iterator begin, std::string::iterator end)
{
static std::map < std::string, KEY_TYPE > s_keyword_map;
if (s_keyword_map.size() == 0)
{
s_keyword_map.insert(std::map < std::string,
KEY_TYPE >::value_type("solution_raw",
KT_SOLUTION_RAW));
s_keyword_map.insert(std::map < std::string,
KEY_TYPE >::value_type("exchange_raw",
KT_EXCHANGE_RAW));
s_keyword_map.insert(std::map < std::string,
KEY_TYPE >::value_type("gas_phase_raw",
KT_GASPHASE_RAW));
s_keyword_map.insert(std::map < std::string,
KEY_TYPE >::value_type("kinetics_raw",
KT_KINETICS_RAW));
s_keyword_map.insert(std::map < std::string,
KEY_TYPE >::value_type("equilibrium_phases_raw",
KT_PPASSEMBLAGE_RAW));
s_keyword_map.insert(std::map < std::string,
KEY_TYPE >::value_type("solid_solutions_raw",
KT_SSASSEMBLAGE_RAW));
s_keyword_map.insert(std::map < std::string,
KEY_TYPE >::value_type("surface_raw",
KT_SURFACE_RAW));
}
std::string lowercase;
copy_token(lowercase, begin, end);
std::transform(lowercase.begin(), lowercase.end(), lowercase.begin(),
tolower);
m_next_keyword = KT_NONE;
std::map < std::string, KEY_TYPE >::iterator map_iter =
s_keyword_map.find(lowercase);
if (map_iter == s_keyword_map.end())
return false;
m_next_keyword = (*map_iter).second;
return true;
}
CParser::STATUS_TYPE CParser::check_units(std::string & tot_units,
bool alkalinity,
bool check_compatibility,
const std::string & default_units,
bool print)
{
/*
* Check if legitimate units
* Input:
* tot_units character string to check,
* alkalinity true if alkalinity, false if any other total,
* check_compatibility true check alk and default units, false otherwise
* default_units character string of default units (check /L, /kg, etc)
* print true print warning messages
* Output:
* tot_units standard form for unit
*/
using
Utilities::str_tolower;
using
Utilities::replace;
using
Utilities::squeeze_white;
static const char *
units[] = {
"Mol/l", /* 0 */
"mMol/l", /* 1 */
"uMol/l", /* 2 */
"g/l", /* 3 */
"mg/l", /* 4 */
"ug/l", /* 5 */
"Mol/kgs", /* 6 */
"mMol/kgs", /* 7 */
"uMol/kgs", /* 8 */
"g/kgs", /* 9 = ppt */
"mg/kgs", /* 10 = ppm */
"ug/kgs", /* 11 = ppb */
"Mol/kgw", /* 12 = mol/kg H2O */
"mMol/kgw", /* 13 = mmol/kg H2O */
"uMol/kgw", /* 14 = umol/kg H2O */
"g/kgw", /* 15 = mol/kg H2O */
"mg/kgw", /* 16 = mmol/kg H2O */
"ug/kgw", /* 17 = umol/kg H2O */
"eq/l", /* 18 */
"meq/l", /* 19 */
"ueq/l", /* 20 */
"eq/kgs", /* 21 */
"meq/kgs", /* 22 */
"ueq/kgs", /* 23 */
"eq/kgw", /* 24 */
"meq/kgw", /* 25 */
"ueq/kgw", /* 26 */
};
squeeze_white(tot_units);
str_tolower(tot_units);
replace("milli", "m", tot_units);
replace("micro", "u", tot_units);
replace("grams", "g", tot_units);
replace("gram", "g", tot_units);
replace("moles", "Mol", tot_units);
replace("mole", "Mol", tot_units);
replace("mol", "Mol", tot_units);
replace("liter", "l", tot_units);
replace("kgh", "kgw", tot_units);
replace("ppt", "g/kgs", tot_units);
replace("ppm", "mg/kgs", tot_units);
replace("ppb", "ug/kgs", tot_units);
replace("equivalents", "eq", tot_units);
replace("equivalent", "eq", tot_units);
replace("equiv", "eq", tot_units);
std::string::size_type end;
if ((end = tot_units.find("/l")) != std::string::npos)
{
tot_units.resize(end + 2);
}
if ((end = tot_units.find("/kgs")) != std::string::npos)
{
tot_units.resize(end + 4);
}
if ((end = tot_units.find("/kgw")) != std::string::npos)
{
tot_units.resize(end + 4);
}
//
// Check if unit in list
//
bool
found = false;
for (unsigned int i = 0; i < sizeof(units) / sizeof(char *); ++i)
{
if (tot_units.compare(units[i]) == 0)
{
found = true;
break;
}
}
if (!found)
{
if (print)
{
std::ostringstream err;
err << "Unknown unit, " << tot_units;
error_msg(err, OT_CONTINUE);
}
return PARSER_ERROR;
}
//
// Check if units are compatible with default_units
//
if (check_compatibility == false)
return PARSER_OK;
//
// Special cases for alkalinity
//
if (alkalinity == true && tot_units.find("Mol") != std::string::npos)
{
if (print)
{
warning_msg
("Alkalinity given in moles, assumed to be equivalents.");
}
replace("Mol", "eq", tot_units);
}
if (alkalinity == false && tot_units.find("eq") != std::string::npos)
{
if (print)
{
error_msg("Only alkalinity can be entered in equivalents.",
OT_CONTINUE);
}
return PARSER_ERROR;
}
//
// See if default_units are compatible with tot_units
//
if (default_units.find("/l") != std::string::npos
&& tot_units.find("/l") != std::string::npos)
return PARSER_OK;
if (default_units.find("/kgs") != std::string::npos
&& tot_units.find("/kgs") != std::string::npos)
return PARSER_OK;
if (default_units.find("/kgw") != std::string::npos
&& tot_units.find("/kgw") != std::string::npos)
return PARSER_OK;
std::string str = default_units;
replace("kgs", "kg solution", str);
replace("kgs", "kg solution", tot_units);
replace("kgw", "kg water", str);
replace("kgw", "kg water", tot_units);
replace("/l", "/L", str);
replace("Mol", "mol", str);
replace("/l", "/L", tot_units);
replace("Mol", "mol", tot_units);
if (print)
{
std::ostringstream err;
err << "Units for master species, " << tot_units <<
", are not compatible with default units, " << str << ".";
error_msg(err, OT_CONTINUE);
}
return PARSER_ERROR;
}
CParser::TOKEN_TYPE CParser::token_type(const std::string & token)
{
if (!token.empty())
{
if (::isupper(token[0]))
{
return CParser::TT_UPPER;
}
else if (::islower(token[0]))
{
return CParser::TT_LOWER;
}
else if (::isdigit(token[0]) || token[0] == '.' || token[0] == '-')
{
return CParser::TT_DIGIT;
}
else
{
assert(!::isspace(token[0]));
return CParser::TT_UNKNOWN;
}
}
else
{
return CParser::TT_EMPTY;
}
}
CParser::TOKEN_TYPE CParser::peek_token()
{
std::istringstream::pos_type pos = m_line_iss.tellg();
std::string token;
m_line_iss >> token;
m_line_iss.seekg(pos);
return token_type(token);
}
CParser::TOKEN_TYPE CParser::copy_token(std::string & token,
std::string::iterator & begin,
std::string::iterator & end)
{
if (begin != end)
{
std::string::iterator b = begin;
for (; b < end &&::isspace(*b); ++b);
begin = b;
for (; begin < end && !::isspace(*begin); ++begin);
token.assign(b, begin);
}
else
{
token.resize(0);
}
return token_type(token);
}
CParser::TOKEN_TYPE CParser::copy_token(std::string & token,
std::istream & is)
{
is >> token;
return token_type(token);
}
CParser::TOKEN_TYPE CParser::copy_token(std::string & token,
std::istream::pos_type & pos)
{
m_line_iss.seekg(pos);
// m_line_iss >> token;
if (!(m_line_iss >> token))
{
token.erase(token.begin(), token.end()); // token.clear();
}
pos = m_line_iss.tellg();
return token_type(token);
}
CParser::FIND_TYPE CParser::find_option(const std::string & item, int *n,
const std::vector < std::string >
&list, bool exact)
{
std::string token(item);
std::transform(token.begin(), token.end(), token.begin(), tolower);
for (unsigned int i = 0; i < list.size(); i++)
{
if (exact == true)
{
if (list[i].compare(token) == 0)
{
*n = i;
return FT_OK;
}
}
else
{
if (list[i].find(token) == 0)
{
*n = i;
return FT_OK;
}
}
}
*n = -1;
return FT_ERROR;
}
// OPTION_TYPE get_option(const char **opt_list, int count_opt_list, char **next_char)
// OPTION_TYPE CParser::get_option(const std::vector<std::string>& opt_list, std::string::iterator& next_char)
int
CParser::get_option(const std::vector < std::string > &opt_list,
std::string::iterator & next_char)
{
//
// Read a line and check for options
//
int j;
int /* opt_l, */ opt;
//char *opt_ptr;
std::string::iterator opt_ptr;
// char option[MAX_LENGTH];
std::string option;
fprintf(stderr, "Did not think this get_option was called\n");
//
// Read line
//
LINE_TYPE lt = check_line("get_option", false, true, true, true);
if (lt == LT_EOF)
{
j = OPT_EOF;
}
else if (lt == LT_KEYWORD)
{
j = OPT_KEYWORD;
}
else if (lt == LT_OPTION)
{
opt_ptr = m_line.begin();
std::string::iterator end = m_line.end();
copy_token(option, opt_ptr, end);
if (find_option(option, &opt, opt_list, false) == CParser::FT_OK)
{
j = opt;
m_line_save.replace(m_line_save.find(option), option.size(),
opt_list[opt]);
m_line.replace(m_line.find(option), option.size(), opt_list[opt]);
opt_ptr = m_line.begin();
std::string::iterator end = m_line.end();
copy_token(option, opt_ptr, end);
next_char = opt_ptr;
if (true) // pr.echo_input == TRUE
{
if (true) // database_file == NULL
{
get_output() << "\t" << m_line_save << "\n";
}
}
}
else
{
if (true) // (database_file == NULL)
{
get_output() << "\t" << m_line_save << "\n";
}
//////std::istringstream err_msg;
//////err_msg << "Unknown option.";
//////err_msg << line_save;
//////error_msg(const std::string& msg, ONERROR_TYPE);
// error_msg("Unknown option.", CONTINUE);
// error_msg(line_save, CONTINUE);
// input_error++;
std::cerr << "Unknown option." << "\n";
std::cerr << m_line_save << "\n";
j = OPT_ERROR;
next_char = m_line.begin();
}
}
else
{
opt_ptr = m_line.begin();
std::string::iterator end = m_line.end();
copy_token(option, opt_ptr, end);
if (find_option(option, &opt, opt_list, true) == FT_OK)
{
j = opt;
next_char = opt_ptr;
}
else
{
j = OPT_DEFAULT;
next_char = m_line.begin();
}
if (true) // pr.echo_input == TRUE
{
if (true) // database_file == NULL
{
std::cout << "\t" << m_line_save << "\n";
}
}
}
return (j);
}
int
CParser::get_option(const std::vector < std::string > &opt_list,
std::istream::pos_type & next_pos)
{
//
// Read a line and check for options
//
int j;
int opt;
std::istream::pos_type pos_ptr;
std::string option;
//
// Read line
//
LINE_TYPE lt = check_line("get_option", false, true, true, true);
if (lt == LT_EOF)
{
j = OPT_EOF;
}
else if (lt == LT_KEYWORD)
{
j = OPT_KEYWORD;
}
else if (lt == LT_OPTION)
{
std::string::iterator opt_ptr = m_line.begin();
std::string::iterator end = m_line.end();
copy_token(option, opt_ptr, end);
if (find_option(option.substr(1), &opt, opt_list, false) == FT_OK)
{
// replace -option with option
j = opt;
m_line_save.replace(m_line_save.find(option), option.size(),
opt_list[opt]);
m_line.replace(m_line.find(option), option.size(), opt_list[opt]);
// reset iss
m_line_iss.str(m_line);
m_line_iss.seekg(0, std::ios_base::beg);
m_line_iss.clear();
pos_ptr = 0;
copy_token(option, pos_ptr);
next_pos = pos_ptr;
//{{
//// m_line_iss.clear();
//}}
/*
if (true) // pr.echo_input == TRUE
{
if (true) // database_file == NULL
{
get_output() << "\t" << m_line_save << "\n";
}
}
*/
}
else
{
/*
if (true) // (database_file == NULL)
{
get_output() << "\t" << m_line_save << "\n";
}
*/
//error_msg("Unknown option.", OT_CONTINUE);
//error_msg(m_line_save.c_str(), OT_CONTINUE);
//incr_input_error();
j = OPT_ERROR;
next_pos = pos_ptr;
}
}
else
{
//pos_ptr = 0;
//copy_token(option, pos_ptr);
//if (find_option(option, &opt, opt_list, true) == FT_OK)
//{
// j = opt;
// next_pos = pos_ptr;
//}
//else
//{
// j = OPT_DEFAULT;
// next_pos = 0;
//}
//std::istringstream m_line_iss_copy = m_line_iss;
pos_ptr = m_line_iss.tellg();
m_line_iss >> option;
if (find_option(option, &opt, opt_list, true) == FT_OK)
{
j = opt;
next_pos = m_line_iss.tellg();
}
else
{
j = OPT_DEFAULT;
m_line_iss.seekg(pos_ptr);
m_line_iss.clear();
next_pos = pos_ptr;
//m_line_iss >> option;
}
/*
if (true) // pr.echo_input == TRUE
{
if (true) // database_file == NULL
{
fprintf(stderr, "Yikes 3\n");
get_output() << "\t" << m_line_save << "\n";
}
}
*/
}
return (j);
}
int
CParser::error_msg(const char *err_str, ONERROR_TYPE ot)
{
::error_msg(err_str, (int) ot);
m_error_stream << "ERROR: " << err_str << "\n";
m_error_stream.flush();
m_output_stream << "ERROR: " << err_str << "\n";
m_output_stream.flush();
if (ot == OT_STOP)
{
exit(1);
}
return 0;
}
int
CParser::warning_msg(const char *err_str)
{
m_error_stream << "WARNING: " << err_str << "\n";
m_error_stream.flush();
m_output_stream << "WARNING: " << err_str << "\n";
m_output_stream.flush();
return 0;
}
CParser::STATUS_TYPE CParser::get_elt(std::string::iterator & begin,
const std::string::iterator end,
std::string & element)
{
element.erase(element.begin(), element.end()); // element.clear();
if (begin == end)
{
error_msg("Empty string in get_elt. Expected an element name.",
OT_CONTINUE);
return PARSER_ERROR;
}
//
// Load name into char array element
//
char
c = *begin;
++begin;
element.insert(element.end(), c); // element.push_back(c);
if (c == '[')
{
while ((c = *begin) != ']')
{
element.insert(element.end(), c); // element.push_back(c);
++begin;
if ((c = *begin) == ']')
{
element.insert(element.end(), c); // element.push_back(c);
++begin;
break;
}
else if (begin == end)
{
error_msg("No ending bracket (]) for element name",
OT_CONTINUE);
incr_input_error();
return PARSER_ERROR;
}
}
while (::islower(c = *begin) || c == '_')
{
element.insert(element.end(), c); // element.push_back(c);
++begin;
if (begin == end)
break;
}
}
else
{
while (::islower(c = *begin) || c == '_')
{
element.insert(element.end(), c); // element.push_back(c);
++begin;
if (begin == end)
break;
}
}
return PARSER_OK;
}
CParser::STATUS_TYPE CParser::parse_couple(std::string & token)
{
// Parse couple puts redox couples in standard form
// "+" is removed and couples are rewritten in sort
// order.
if (Utilities::strcmp_nocase_arg1(token.c_str(), "pe") == 0)
{
Utilities::str_tolower(token);
return PARSER_OK;
}
while (Utilities::replace("+", "", token));
std::string::iterator ptr = token.begin();
std::string elt1;
get_elt(ptr, token.end(), elt1);
if (*ptr != '(')
{
std::ostringstream err_msg;
err_msg << "Element name must be followed by " <<
"parentheses in redox couple, " << token << ".";
error_msg(err_msg, OT_CONTINUE);
incr_input_error();
return PARSER_ERROR;
}
int
paren_count = 1;
std::string paren1 = "(";
while (ptr != token.end())
{
++ptr;
if (*ptr == '/' || ptr == token.end())
{
std::ostringstream err_msg;
err_msg << "End of line or " "/"
" encountered before end of parentheses, " << token << ".";
error_msg(err_msg, OT_CONTINUE);
return PARSER_ERROR;
}
paren1.insert(paren1.end(), *ptr); // element.push_back(c);
if (*ptr == '(')
++paren_count;
if (*ptr == ')')
--paren_count;
if (paren_count == 0)
break;
}
++ptr;
if (ptr == token.end() || *ptr != '/')
{
std::ostringstream err_msg;
err_msg << " " "/" " must follow parentheses " <<
"ending first half of redox couple, " << token << ".";
error_msg(err_msg, OT_CONTINUE);
return PARSER_ERROR;
}
++ptr;
std::string elt2;
get_elt(ptr, token.end(), elt2);
if (elt1.compare(elt2) != 0)
{
std::ostringstream err_msg;
err_msg << "Redox couple must be two redox states " <<
"of the same element, " << token << ".";
error_msg(err_msg, OT_CONTINUE);
return PARSER_ERROR;
}
if (*ptr != '(')
{
std::ostringstream err_msg;
err_msg << "Element name must be followed by "
"parentheses in redox couple, " << token << ".";
error_msg(err_msg, OT_CONTINUE);
incr_input_error();
return PARSER_ERROR;
}
std::string paren2 = "(";
paren_count = 1;
while (ptr != token.end())
{
++ptr;
if (*ptr == '/' || ptr == token.end())
{
std::ostringstream err_msg;
err_msg << "End of line or " "/"
" encountered before end of parentheses, " << token << ".";
error_msg(err_msg, OT_CONTINUE);
return PARSER_ERROR;
}
paren2.insert(paren2.end(), *ptr); // element.push_back(c);
if (*ptr == '(')
++paren_count;
if (*ptr == ')')
--paren_count;
if (paren_count == 0)
break;
}
if (paren1.compare(paren2) < 0)
{
token = elt1 + paren1 + std::string("/") + elt2 + paren2;
}
else if (paren1.compare(paren2) > 0)
{
token = elt2 + paren2 + std::string("/") + elt1 + paren1;
}
else
{
std::ostringstream err_msg;
err_msg << "Both parts of redox couple are the same, " <<
token << ".";
error_msg(err_msg, OT_CONTINUE);
return PARSER_ERROR;
}
return PARSER_OK;
}
CParser::STATUS_TYPE CParser::addPair(std::map < char *, double,
CHARSTAR_LESS > &totals,
std::istream::pos_type & pos)
{
std::string token;
char *
ctoken;
double
d;
CParser::TOKEN_TYPE j;
m_line_iss.seekg(pos);
j = copy_token(token, pos);
if (j == TT_EMPTY)
return PARSER_OK;
if (!(m_line_iss >> d))
{
return PARSER_ERROR;
}
ctoken = string_hsave(token.c_str());
totals[ctoken] = d;
return PARSER_OK;
}
CParser::STATUS_TYPE CParser::addPair(std::map < char *, double >&totals,
std::istream::pos_type & pos)
{
std::string token;
char *
ctoken;
double
d;
CParser::TOKEN_TYPE j;
m_line_iss.seekg(pos);
j = copy_token(token, pos);
if (j == TT_EMPTY)
return PARSER_OK;
if (!(m_line_iss >> d))
{
return PARSER_ERROR;
}
ctoken = string_hsave(token.c_str());
totals[ctoken] = d;
return PARSER_OK;
}
int
CParser::getOptionFromLastLine(const std::vector < std::string > &opt_list,
std::string::iterator & next_char)
{
//
// Read a line and check for options
//
int j;
int /* opt_l, */ opt;
//char *opt_ptr;
std::string::iterator opt_ptr;
// char option[MAX_LENGTH];
std::string option;
//
// Read line
//
LINE_TYPE lt = m_line_type;
if (lt == LT_EOF)
{
j = OPT_EOF;
}
else if (lt == LT_KEYWORD)
{
j = OPT_KEYWORD;
}
else if (lt == LT_OPTION)
{
opt_ptr = m_line.begin();
std::string::iterator end = m_line.end();
copy_token(option, opt_ptr, end);
if (find_option(option, &opt, opt_list, false) == CParser::FT_OK)
{
j = opt;
m_line_save.replace(m_line_save.find(option), option.size(),
opt_list[opt]);
m_line.replace(m_line.find(option), option.size(), opt_list[opt]);
opt_ptr = m_line.begin();
std::string::iterator end = m_line.end();
copy_token(option, opt_ptr, end);
next_char = opt_ptr;
if (true) // pr.echo_input == TRUE
{
if (true) // database_file == NULL
{
get_output() << "\t" << m_line_save << "\n";
}
}
}
else
{
if (true) // (database_file == NULL)
{
get_output() << "\t" << m_line_save << "\n";
}
//////std::istringstream err_msg;
//////err_msg << "Unknown option.";
//////err_msg << line_save;
//////error_msg(const std::string& msg, ONERROR_TYPE);
// error_msg("Unknown option.", CONTINUE);
// error_msg(line_save, CONTINUE);
// input_error++;
std::cerr << "Unknown option." << "\n";
std::cerr << m_line_save << "\n";
j = OPT_ERROR;
next_char = m_line.begin();
}
}
else
{
opt_ptr = m_line.begin();
std::string::iterator end = m_line.end();
copy_token(option, opt_ptr, end);
if (find_option(option, &opt, opt_list, true) == FT_OK)
{
j = opt;
next_char = opt_ptr;
}
else
{
j = OPT_DEFAULT;
next_char = m_line.begin();
}
if (true) // pr.echo_input == TRUE
{
if (true) // database_file == NULL
{
std::cout << "\t" << m_line_save << "\n";
}
}
}
return (j);
}
int
CParser::getOptionFromLastLine(const std::vector < std::string > &opt_list,
std::istream::pos_type & next_pos)
{
//
// Read a line and check for options
//
int j;
int opt;
std::istream::pos_type pos_ptr;
std::string option;
//
// Read line
//
//LINE_TYPE lt = check_line("get_option", false, true, true, false);
LINE_TYPE lt = m_line_type;
if (lt == LT_EOF)
{
j = OPT_EOF;
}
else if (lt == LT_KEYWORD)
{
j = OPT_KEYWORD;
}
else if (lt == LT_OPTION)
{
std::string::iterator opt_ptr = m_line.begin();
std::string::iterator end = m_line.end();
copy_token(option, opt_ptr, end);
if (find_option(option.substr(1), &opt, opt_list, false) == FT_OK)
{
// replace -option with option
j = opt;
m_line_save.replace(m_line_save.find(option), option.size(),
opt_list[opt]);
m_line.replace(m_line.find(option), option.size(), opt_list[opt]);
// reset iss
m_line_iss.str(m_line);
m_line_iss.seekg(0, std::ios_base::beg);
m_line_iss.clear();
pos_ptr = 0;
copy_token(option, pos_ptr);
next_pos = pos_ptr;
//{{
//// m_line_iss.clear();
//}}
if (true) // pr.echo_input == TRUE
{
if (true) // database_file == NULL
{
get_output() << "\t" << m_line_save << "\n";
}
}
}
else
{
if (true) // (database_file == NULL)
{
get_output() << "\t" << m_line_save << "\n";
}
error_msg("Unknown option.", OT_CONTINUE);
error_msg(m_line_save.c_str(), OT_CONTINUE);
incr_input_error();
j = OPT_ERROR;
next_pos = pos_ptr;
}
}
else
{
pos_ptr = 0;
copy_token(option, pos_ptr);
if (find_option(option, &opt, opt_list, true) == FT_OK)
{
j = opt;
next_pos = pos_ptr;
}
else
{
j = OPT_DEFAULT;
next_pos = 0;
}
if (true) // pr.echo_input == TRUE
{
if (true) // database_file == NULL
{
get_output() << "\t" << m_line_save << "\n";
}
}
}
return (j);
}