added common directory for Parser/PHRQ_base/PHRQ_io/phrqtype/Utils

git-svn-id: svn://136.177.114.72/svn_GW/phreeqc3/trunk@10053 1feff8c3-07ed-0310-ac33-dd36852eb9cd
This commit is contained in:
Scott R Charlton 2015-08-08 00:32:59 +00:00
commit caecf8b8d6
9 changed files with 3111 additions and 0 deletions

108
PHRQ_base.cxx Normal file
View File

@ -0,0 +1,108 @@
#include "PHRQ_base.h"
#include <iostream>
#include "PHRQ_io.h"
PHRQ_base::
PHRQ_base(void)
{
this->io = NULL;
base_error_count = 0;
}
PHRQ_base::
PHRQ_base(PHRQ_io * p_io)
{
this->io = p_io;
base_error_count = 0;
}
PHRQ_base::
~PHRQ_base()
{
}
void PHRQ_base::
error_msg(const std::string & stdstr, int stop)
{
this->base_error_count++;
std::ostringstream msg;
msg << "ERROR: " << stdstr << "\n";
if (this->io)
{
this->io->output_msg(msg.str().c_str());
this->io->log_msg(msg.str().c_str());
this->io->error_msg("\n");
this->io->error_msg(msg.str().c_str(), stop!=0);
}
else
{
#if !defined(R_SO)
std::cerr << msg.str().c_str();
std::cout << msg.str().c_str();
#endif
}
if (stop != 0)
{
throw PhreeqcStop();
}
}
void PHRQ_base::
warning_msg(const std::string & stdstr)
{
if (this->io)
{
this->io->warning_msg(stdstr.c_str());
}
else
{
#if !defined(R_SO)
std::cerr << stdstr << "\n";
std::cout << stdstr << "\n";
#endif
}
}
void PHRQ_base::
output_msg(const std::string & stdstr)
{
if (this->io)
{
this->io->output_msg(stdstr.c_str());
}
else
{
#if !defined(R_SO)
std::cout << stdstr << "\n";
#endif
}
}
void PHRQ_base::
screen_msg(const std::string & stdstr)
{
if (this->io)
{
this->io->screen_msg(stdstr.c_str());
}
else
{
#if !defined(R_SO)
std::cerr << stdstr << "\n";
#endif
}
}
void PHRQ_base::
echo_msg(const std::string & stdstr)
{
if (this->io)
{
this->io->echo_msg(stdstr.c_str());
}
else
{
#if !defined(R_SO)
std::cout << stdstr << "\n";
#endif
}
}

46
PHRQ_base.h Normal file
View File

@ -0,0 +1,46 @@
#ifndef _PHRQBASE_H
#define _PHRQBASE_H
#include <sstream>
class PHRQ_io;
class PHRQ_base
{
public:
// constructors
PHRQ_base(void);
PHRQ_base(PHRQ_io *);
virtual ~ PHRQ_base();
// methods
void output_msg(const std::string &);
void error_msg(const std::string &, int stop=0);
void warning_msg(const std::string &);
void screen_msg(const std::string &);
void echo_msg(const std::string &);
void Set_io(PHRQ_io * p_io)
{
this->io = p_io;
}
PHRQ_io * Get_io(void)
{
return this->io;
}
void Set_base_error_count(int i)
{
this->base_error_count = i;
}
int Get_base_error_count(void)
{
return this->base_error_count;
}
// data
protected:
PHRQ_io * io;
int base_error_count;
};
#endif /* _PHRQBASE_H */

901
PHRQ_io.cpp Normal file
View File

@ -0,0 +1,901 @@
#include <assert.h>
#include "PHRQ_io.h"
#include "Parser.h"
#include <algorithm>
#include <cctype>
#include <fstream>
#include <iostream>
#include <sstream>
#include <set>
#include <string.h>
#include <stdio.h>
#include <stdarg.h>
PHRQ_io::
PHRQ_io(void)
{
output_ostream = NULL;
log_ostream = NULL;
punch_ostream = NULL;
#ifdef ERROR_OSTREAM
error_ostream = NULL;
#else
error_file = NULL;
#endif
dump_ostream = NULL;
io_error_count = 0;
output_on = true;
log_on = false;
punch_on = true;
error_on = true;
dump_on = true;
echo_on = true;
screen_on = true;
echo_destination = ECHO_OUTPUT;
m_next_keyword = Keywords::KEY_NONE;
accumulate = false;
m_line_type = PHRQ_io::LT_EMPTY;
}
PHRQ_io::
~PHRQ_io()
{
}
// ---------------------------------------------------------------------- */
// output ostream methods
// ---------------------------------------------------------------------- */
bool PHRQ_io::
ofstream_open(std::ostream **os, const char *file_name, std::ios_base::openmode mode)
{
std::ofstream *ofs = new std::ofstream(file_name, mode);
if (ofs && ofs->is_open())
{
*os = ofs;
return true;
}
delete ofs;
return false;
}
/* ---------------------------------------------------------------------- */
bool PHRQ_io::
output_open(const char *file_name, std::ios_base::openmode mode)
/* ---------------------------------------------------------------------- */
{
return ofstream_open(&output_ostream, file_name, mode);
}
/* ---------------------------------------------------------------------- */
void PHRQ_io::
output_flush(void)
/* ---------------------------------------------------------------------- */
{
if (output_ostream)
{
output_ostream->flush();
}
}
/* ---------------------------------------------------------------------- */
void PHRQ_io::
output_close(void)
/* ---------------------------------------------------------------------- */
{
safe_close(&output_ostream);
}
/* ---------------------------------------------------------------------- */
void PHRQ_io::
output_msg(const char * str)
/* ---------------------------------------------------------------------- */
{
if (output_ostream != NULL && output_on)
{
(*output_ostream) << str;
}
//output_flush();
}
// ---------------------------------------------------------------------- */
// log ostream methods
// ---------------------------------------------------------------------- */
bool PHRQ_io::
log_open(const char *file_name, std::ios_base::openmode mode)
/* ---------------------------------------------------------------------- */
{
return ofstream_open(&log_ostream, file_name, mode);
}
/* ---------------------------------------------------------------------- */
void PHRQ_io::
log_flush(void)
/* ---------------------------------------------------------------------- */
{
if (log_ostream)
{
log_ostream->flush();
}
}
/* ---------------------------------------------------------------------- */
void PHRQ_io::
log_close(void)
/* ---------------------------------------------------------------------- */
{
safe_close(&log_ostream);
}
/* ---------------------------------------------------------------------- */
void PHRQ_io::
log_msg(const char * str)
/* ---------------------------------------------------------------------- */
{
if (log_ostream != NULL && log_on)
{
(*log_ostream) << str;
}
}
// ---------------------------------------------------------------------- */
// punch ostream methods
// ---------------------------------------------------------------------- */
bool PHRQ_io::
punch_open(const char *file_name, std::ios_base::openmode mode, int n_user)
/* ---------------------------------------------------------------------- */
{
return ofstream_open(&punch_ostream, file_name, mode);
}
/* ---------------------------------------------------------------------- */
void PHRQ_io::
punch_flush(void)
/* ---------------------------------------------------------------------- */
{
if (punch_ostream)
{
punch_ostream->flush();
}
}
/* ---------------------------------------------------------------------- */
void PHRQ_io::
punch_close(void)
/* ---------------------------------------------------------------------- */
{
safe_close(&punch_ostream);
}
/* ---------------------------------------------------------------------- */
void PHRQ_io::
punch_msg(const char * str)
/* ---------------------------------------------------------------------- */
{
if (punch_ostream != NULL && punch_on)
{
(*punch_ostream) << str;
}
}
// ---------------------------------------------------------------------- */
// error file methods
// ---------------------------------------------------------------------- */
#ifdef ERROR_OSTREAM
/* ---------------------------------------------------------------------- */
bool PHRQ_io::
error_open(const char *file_name, std::ios_base::openmode mode)
/* ---------------------------------------------------------------------- */
{
if (file_name != NULL)
{
if (!ofstream_open(&error_ostream, file_name, mode))
{
#if !defined(R_SO)
error_ostream = &std::cerr;
#endif
return false;
}
}
else
{
#if !defined(R_SO)
error_ostream = &std::cerr;
#endif
}
return true;
}
/* ---------------------------------------------------------------------- */
void PHRQ_io::
error_flush(void)
/* ---------------------------------------------------------------------- */
{
if (error_ostream)
{
error_ostream->flush();
}
}
/* ---------------------------------------------------------------------- */
void PHRQ_io::
error_close(void)
/* ---------------------------------------------------------------------- */
{
safe_close(&error_ostream);
}
/* ---------------------------------------------------------------------- */
void PHRQ_io::
error_msg(const char *err_str, bool stop)
/* ---------------------------------------------------------------------- */
{
io_error_count++;
if (error_ostream != NULL && error_on)
{
//(*error_ostream) << err_str;
screen_msg(err_str);
error_flush();
}
if (stop)
{
if (error_ostream != NULL && error_on)
{
//(*error_ostream) << "Stopping.\n";
screen_msg("Stopping.\n");
error_ostream->flush();
}
output_msg("Stopping.\n");
log_msg("Stopping.\n");
throw PhreeqcStop();
}
}
/* ---------------------------------------------------------------------- */
void PHRQ_io::
warning_msg(const char *err_str)
/* ---------------------------------------------------------------------- */
{
if (error_ostream != NULL && error_on)
{
//(*error_ostream) << err_str << "\n";
std::string err_stdstr(err_str);
err_stdstr.append("\n");
screen_msg(err_stdstr.c_str());
error_ostream->flush();
}
std::ostringstream warn_str;
warn_str << err_str << "\n";
log_msg(warn_str.str().c_str());
log_flush();
output_msg(warn_str.str().c_str());
output_flush();
}
/* ---------------------------------------------------------------------- */
void PHRQ_io::
screen_msg(const char * str)
/* ---------------------------------------------------------------------- */
{
if (error_ostream != NULL && screen_on)
{
(*error_ostream) << str;
}
}
#else
/* ---------------------------------------------------------------------- */
bool PHRQ_io::
error_open(const char *file_name, const char * mode)
/* ---------------------------------------------------------------------- */
{
if (file_name != NULL)
{
if ((error_file = fopen(file_name, mode)) == NULL)
{
error_file = stderr;
return false;
}
}
else
{
error_file = stderr;
}
return true;
}
/* ---------------------------------------------------------------------- */
void PHRQ_io::
error_flush(void)
/* ---------------------------------------------------------------------- */
{
if (error_file)
{
fflush(error_file);
}
}
/* ---------------------------------------------------------------------- */
void PHRQ_io::
error_close(void)
/* ---------------------------------------------------------------------- */
{
safe_close(&error_file);
}
/* ---------------------------------------------------------------------- */
void PHRQ_io::
error_msg(const char *err_str, bool stop)
/* ---------------------------------------------------------------------- */
{
io_error_count++;
if (error_file != NULL && error_on)
{
//(*error_file) << err_str;
screen_msg(err_str);
error_flush();
}
if (stop)
{
if (error_file != NULL && error_on)
{
//(*error_file) << "Stopping.\n";
screen_msg("Stopping.\n");
fflush(error_file);
}
output_msg("Stopping.\n");
log_msg("Stopping.\n");
}
}
/* ---------------------------------------------------------------------- */
void PHRQ_io::
warning_msg(const char *err_str)
/* ---------------------------------------------------------------------- */
{
if (error_file != NULL && error_on)
{
//(*error_file) << err_str << "\n";
std::string err_stdstr(err_str);
err_stdstr.append("\n");
screen_msg(err_stdstr.c_str());
error_flush();
}
std::ostringstream warn_str;
warn_str << err_str << "\n";
log_msg(warn_str.str().c_str());
log_flush();
output_msg(warn_str.str().c_str());
output_flush();
}
/* ---------------------------------------------------------------------- */
void PHRQ_io::
screen_msg(const char * str)
/* ---------------------------------------------------------------------- */
{
std::string stdstr(str);
if (error_file != NULL && screen_on)
{
fprintf(error_file, "%s", str);
}
}
#endif
// ---------------------------------------------------------------------- */
// dump ostream methods
// ---------------------------------------------------------------------- */
/* ---------------------------------------------------------------------- */
bool PHRQ_io::
dump_open(const char *file_name, std::ios_base::openmode mode)
/* ---------------------------------------------------------------------- */
{
return ofstream_open(&dump_ostream, file_name, mode);
}
/* ---------------------------------------------------------------------- */
void PHRQ_io::
dump_flush(void)
/* ---------------------------------------------------------------------- */
{
if (dump_ostream)
{
dump_ostream->flush();
}
}
/* ---------------------------------------------------------------------- */
void PHRQ_io::
dump_close(void)
/* ---------------------------------------------------------------------- */
{
safe_close(&dump_ostream);
}
/* ---------------------------------------------------------------------- */
void PHRQ_io::
dump_msg(const char * str)
/* ---------------------------------------------------------------------- */
{
if (dump_ostream != NULL && dump_on)
{
(*dump_ostream) << str;
}
}
int PHRQ_io::
getc(void)
{
if (std::istream* is = get_istream())
{
int n = is->get();
if (n == 13 && is->peek() == 10)
{
n = is->get();
}
return n;
}
return EOF;
}
/* ---------------------------------------------------------------------- */
void PHRQ_io::
fpunchf(const char *name, const char *format, double d)
/* ---------------------------------------------------------------------- */
{
if (punch_ostream != NULL && punch_on)
{
fpunchf_helper(punch_ostream, format, d);
}
}
/* ---------------------------------------------------------------------- */
void PHRQ_io::
fpunchf(const char *name, const char *format, char * s)
/* ---------------------------------------------------------------------- */
{
if (punch_ostream != NULL && punch_on)
{
fpunchf_helper(punch_ostream, format, s);
}
}
/* ---------------------------------------------------------------------- */
void PHRQ_io::
fpunchf(const char *name, const char *format, int d)
/* ---------------------------------------------------------------------- */
{
if (punch_ostream != NULL && punch_on)
{
fpunchf_helper(punch_ostream, format, d);
}
}
/* ---------------------------------------------------------------------- */
void PHRQ_io::
fpunchf_helper(std::ostream *os, const char *format, ...)
/* ---------------------------------------------------------------------- */
{
if (os)
{
const size_t STACK_MAX = 2048;
char stack_buffer[STACK_MAX];
va_list args;
va_start(args, format);
int j = ::vsnprintf(stack_buffer, STACK_MAX, format, args);
bool success = (j >= 0 && j < (int) STACK_MAX);
va_end(args);
if (success)
{
(*os) << stack_buffer;
}
else
{
size_t alloc_buffer_size = STACK_MAX * 2;
char *alloc_buffer = new char[alloc_buffer_size];
do
{
va_list args;
va_start(args, format);
j = ::vsnprintf(alloc_buffer, alloc_buffer_size, format, args);
success = (j >= 0 && j < (int) alloc_buffer_size);
va_end(args);
if (!success)
{
delete[] alloc_buffer;
alloc_buffer_size *= 2;
alloc_buffer = new char[alloc_buffer_size];
}
}
while (!success);
(*os) << alloc_buffer;
delete[] alloc_buffer;
}
}
}
/* ---------------------------------------------------------------------- */
void PHRQ_io::
fpunchf_helper(std::string *str, const char *format, ...)
/* ---------------------------------------------------------------------- */
{
if (str)
{
const size_t STACK_MAX = 2048;
char stack_buffer[STACK_MAX];
va_list args;
va_start(args, format);
int j = ::vsnprintf(stack_buffer, STACK_MAX, format, args);
bool success = (j >= 0 && j < (int) STACK_MAX);
va_end(args);
if (success)
{
(*str) += stack_buffer;
}
else
{
size_t alloc_buffer_size = STACK_MAX * 2;
char *alloc_buffer = new char[alloc_buffer_size];
do
{
va_list args;
va_start(args, format);
j = ::vsnprintf(alloc_buffer, alloc_buffer_size, format, args);
success = (j >= 0 && j < (int) alloc_buffer_size);
va_end(args);
if (!success)
{
delete[] alloc_buffer;
alloc_buffer_size *= 2;
alloc_buffer = new char[alloc_buffer_size];
}
}
while (!success);
(*str) += alloc_buffer;
delete[] alloc_buffer;
}
}
}
/* ---------------------------------------------------------------------- */
void PHRQ_io::fpunchf_end_row(const char *format)
/* ---------------------------------------------------------------------- */
{
//NOOP for Phreeqc
}
/* ---------------------------------------------------------------------- */
void PHRQ_io::
close_ostreams(void)
/* ---------------------------------------------------------------------- */
{
std::set<std::ostream *> streams;
streams.insert(output_ostream);
streams.insert(log_ostream);
// streams.insert(punch_ostream); // Should be deleted in ~SelectedOutput
#ifdef ERROR_OSTREAM
streams.insert(error_ostream);
#else
safe_close(&error_file);
#endif
streams.insert(dump_ostream);
std::set<std::ostream *>::iterator it = streams.begin();
for (; it != streams.end(); it++)
{
std::ostream * x = *it;
safe_close(&x);
}
output_ostream = NULL;
log_ostream = NULL;
punch_ostream = NULL;
#ifdef ERROR_OSTREAM
error_ostream = NULL;
#else
error_file = NULL;
#endif
dump_ostream = NULL;
}
//safe_close is static method
/* ---------------------------------------------------------------------- */
void PHRQ_io::
safe_close(std::ostream **stream_ptr)
/* ---------------------------------------------------------------------- */
{
if (
#if !defined(R_SO)
*stream_ptr != &std::cerr &&
*stream_ptr != &std::cout &&
*stream_ptr != &std::clog &&
#endif
*stream_ptr != NULL)
{
delete *stream_ptr;
*stream_ptr = NULL;
}
}
void PHRQ_io::
safe_close(FILE **file_ptr)
/* ---------------------------------------------------------------------- */
{
if (
#if !defined(R_SO)
*file_ptr != stderr &&
*file_ptr != stdout &&
*file_ptr != stdin &&
#endif
*file_ptr != NULL)
{
fclose(*file_ptr);
*file_ptr = NULL;
}
}
/* ---------------------------------------------------------------------- */
void PHRQ_io::
echo_msg(const char * str)
/* ---------------------------------------------------------------------- */
{
if (echo_on)
{
switch (this->echo_destination)
{
case ECHO_LOG:
log_msg(str);
break;
case ECHO_OUTPUT:
output_msg(str);
break;
}
}
}
std::istream * PHRQ_io::
get_istream()
{
if (istream_list.size() > 0)
{
return istream_list.front();
}
else
{
return NULL;
}
}
void PHRQ_io::
push_istream(std::istream * cookie, bool auto_delete)
{
istream_list.push_front(cookie);
delete_istream_list.push_front(auto_delete);
}
void PHRQ_io::
clear_istream(void)
{
while (istream_list.size() > 0)
{
pop_istream();
}
}
void PHRQ_io::
pop_istream()
{
if (istream_list.size() > 0)
{
if (delete_istream_list.front())
{
delete istream_list.front();
}
istream_list.pop_front();
delete_istream_list.pop_front();
}
}
/* ---------------------------------------------------------------------- */
PHRQ_io::LINE_TYPE PHRQ_io::
get_line(void)
/* ---------------------------------------------------------------------- */
{
/*
* Read a line from input file put in "line".
* Copy of input line is stored in "line_save".
* Characters after # are discarded in line but retained in "line_save"
*
* Arguments:
* fp is file name
* Returns:
* EMPTY,
* EOF,
* KEYWORD,
* OK,
* OPTION
*/
std::string stdtoken;
bool continue_loop = true;;
PHRQ_io::LINE_TYPE return_value;
// loop for include files
for (;;)
{
if (this->get_istream() == NULL)
{
break;
}
return_value = LT_EMPTY;
while (return_value == LT_EMPTY)
{
/*
* Eliminate all characters after # sign as a comment
*/
/*
* Get line, check for eof
*/
continue_loop = false;
if (get_logical_line() == LT_EOF)
{
//pop next file
this->pop_istream();
continue_loop = true;
break;
}
/*
* 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);
}
if (continue_loop) continue;
//
// 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;
CParser::copy_token(token, beg, end);
if (token.size() > 1 && token[0] == '-' &&::isalpha(token[1]))
{
return_value = LT_OPTION;
}
}
}
// add new include file to stack
std::string::iterator beg = m_line.begin();
std::string::iterator end = m_line.end();
CParser::copy_token(stdtoken, beg, end);
std::transform(stdtoken.begin(), stdtoken.end(), stdtoken.begin(), ::tolower);
if ((strstr(stdtoken.c_str(),"include$") == stdtoken.c_str()) ||
(strstr(stdtoken.c_str(),"include_file") == stdtoken.c_str()))
{
std::string file_name;
file_name.assign(beg, end);
file_name = trim(file_name);
if (file_name.size() > 0)
{
std::ifstream *next_stream = new std::ifstream(file_name.c_str(), std::ios_base::in);
if (!next_stream->is_open())
{
std::ostringstream errstr;
errstr << "\n*********** Could not open include file " << file_name
<<".\n Please, write the full path to this file. ***********\n\n";
delete next_stream;
#if defined(PHREEQCI_GUI)
warning_msg(errstr.str().c_str());
continue;
#else
output_msg(errstr.str().c_str());
error_msg(errstr.str().c_str(), OT_STOP);
#endif
}
else
{
this->push_istream(next_stream);
}
continue;
}
}
return return_value;
}
m_next_keyword = Keywords::KEY_END;
return LT_EOF;
}
/**
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
*/
PHRQ_io::LINE_TYPE PHRQ_io::
get_logical_line(void)
{
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 = getc()) != 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 = getc()) != EOF);
}
if (c == ';')
break;
if (c == '\n')
{
break;
}
if (c == '\\')
{
pos = (int) m_line_save.size();
m_line_save += c;
while ((j = getc()) != EOF)
{
c = (char) j;
if (c == '\\')
{
pos = (int) m_line_save.size();
m_line_save += c;
continue;
}
if (c == '\n')
{
// remove '\\'
m_line_save = m_line_save.substr(0,pos);
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 PHRQ_io::
check_key(std::string::iterator begin, std::string::iterator end)
{
std::string lowercase;
CParser::copy_token(lowercase, begin, end);
std::transform(lowercase.begin(), lowercase.end(), lowercase.begin(),
tolower);
m_next_keyword = Keywords::Keyword_search(lowercase);
if (m_next_keyword == Keywords::KEY_NONE)
{
return false;
}
return true;
}

211
PHRQ_io.h Normal file
View File

@ -0,0 +1,211 @@
#ifndef _PHRQIO_H
#define _PHRQIO_H
#if defined(_WINDLL)
#define IPQ_DLL_EXPORT __declspec(dllexport)
#else
#define IPQ_DLL_EXPORT
#endif
#include <iostream>
#include <exception>
#include <list>
#include "Keywords.h"
#include <time.h>
#define ERROR_OSTREAM
class PhreeqcStop : public std::exception
{
};
class IPQ_DLL_EXPORT PHRQ_io
{
public:
enum LINE_TYPE
{
LT_EOF = -1,
LT_OK = 1,
LT_EMPTY = 2,
LT_KEYWORD = 3,
LT_OPTION = 8
};
enum ONERROR_TYPE
{
OT_CONTINUE = 0,
OT_STOP = 1
};
// constructor/destructor
PHRQ_io(void);
virtual ~ PHRQ_io();
// methods
static void safe_close(std::ostream **stream_ptr);
static void safe_close(FILE **file_ptr);
void close_ostreams(void);
void Set_io_error_count(int i) {this->io_error_count = i;};
int Get_io_error_count(void) {return this->io_error_count;};
// istreams
std::istream *get_istream();
void pop_istream();
void push_istream(std::istream * cookie, bool auto_delete = true);
void clear_istream(void);
// helper
bool ofstream_open(std::ostream **os, const char *file_name, std::ios_base::openmode mode = std::ios_base::out);
// output_ostream
virtual bool output_open(const char *file_name, std::ios_base::openmode mode = std::ios_base::out);
void output_flush(void);
void output_close(void);
virtual void output_msg(const char * str);
void Set_output_ostream(std::ostream * out) {this->output_ostream = out;};
std::ostream *Get_output_ostream(void) {return this->output_ostream;};
void Set_output_on(bool tf) {this->output_on = tf;};
bool Get_output_on(void) {return this->output_on;};
// log_ostream
virtual bool log_open(const char *file_name, std::ios_base::openmode mode = std::ios_base::out);
void log_flush(void);
void log_close(void);
virtual void log_msg(const char * str);
void Set_log_ostream(std::ostream * out) {this->log_ostream = out;}
std::ostream *Get_log_ostream(void) {return this->log_ostream;}
void Set_log_on(bool tf) {this->log_on = tf;}
bool Get_log_on(void) {return this->log_on;}
// punch_ostream
virtual bool punch_open(const char *file_name, std::ios_base::openmode mode = std::ios_base::out, int n_user = 1);
void punch_flush(void);
void punch_close(void);
virtual void punch_msg(const char * str);
void Set_punch_ostream(std::ostream * out) {this->punch_ostream = out;}
std::ostream *Get_punch_ostream(void) {return this->punch_ostream;}
void Set_punch_on(bool tf) {this->punch_on = tf;}
bool Get_punch_on(void) {return this->punch_on;}
// error_ostream
#ifdef ERROR_OSTREAM
virtual bool error_open(const char *file_name, std::ios_base::openmode mode = std::ios_base::out);
void error_flush(void);
void error_close(void);
virtual void error_msg(const char * str, bool stop=false);
void Set_error_ostream(std::ostream * out) {this->error_ostream = out;}
std::ostream *Get_error_ostream(void) {return this->error_ostream;}
void Set_error_on(bool tf) {this->error_on = tf;}
bool Get_error_on(void) {return this->error_on;}
virtual void warning_msg(const char *err_str);
#else
virtual bool error_open(const char *file_name, const char * mode = "w");
void error_flush(void);
void error_close(void);
virtual void error_msg(const char * str, bool stop=false);
void Set_error_file(FILE * out) {this->error_file = out;}
FILE *Get_error_file(void) {return this->error_file;}
void Set_error_on(bool tf) {this->error_on = tf;}
bool Get_error_on(void) {return this->error_on;}
virtual void warning_msg(const char *err_str);
#endif
// dump_ostream
virtual bool dump_open(const char *file_name, std::ios_base::openmode mode = std::ios_base::out);
void dump_flush(void);
void dump_close(void);
virtual void dump_msg(const char * str);
void Set_dump_ostream(std::ostream * out) {this->dump_ostream = out;};
std::ostream *Get_dump_ostream(void) {return this->dump_ostream;};
void Set_dump_on(bool tf) {this->dump_on = tf;};
bool Get_dump_on(void) {return this->dump_on;};
// fpunchf
virtual void fpunchf(const char *name, const char *format, double d);
virtual void fpunchf(const char *name, const char *format, char * d);
virtual void fpunchf(const char *name, const char *format, int d);
virtual void fpunchf_end_row(const char *format);
static void fpunchf_helper(std::ostream *os, const char *format, ...);
static void fpunchf_helper(std::string *str, const char *format, ...);
virtual void screen_msg(const char * str);
void Set_screen_on(bool tf) {this->screen_on = tf;};
bool Get_screen_on(void) {return this->screen_on;};
// input methods
virtual int getc(void);
virtual LINE_TYPE get_line(void);
virtual LINE_TYPE get_logical_line(void);
bool check_key(std::string::iterator begin, std::string::iterator end);
std::string & Get_m_line() {return m_line;}
std::string & Get_m_line_save() {return m_line_save;}
std::string & Get_accumulated() {return accumulated;}
LINE_TYPE Get_m_line_type() {return m_line_type;};
void Set_accumulate(bool tf)
{
if (tf)
{
accumulated.clear();
}
this->accumulate = tf;
}
Keywords::KEYWORDS Get_m_next_keyword() const {return m_next_keyword;}
// echo
enum ECHO_OPTION
{
ECHO_LOG,
ECHO_OUTPUT
};
virtual void echo_msg(const char * str);
void Set_echo_on(bool tf) {this->echo_on = tf;};
bool Get_echo_on(void) {return this->echo_on;};
void Set_echo_destination(ECHO_OPTION eo) {this->echo_destination = eo;};
ECHO_OPTION Get_echo_destination(void) {return this->echo_destination;};
// data
protected:
std::ostream *output_ostream;
std::ostream *log_ostream;
std::ostream *punch_ostream;
#ifdef ERROR_OSTREAM
std::ostream *error_ostream;
#else
FILE * error_file;
#endif
std::ostream *dump_ostream;
int io_error_count;
bool output_on;
bool log_on;
bool punch_on;
bool error_on;
bool dump_on;
bool echo_on;
bool screen_on;
ECHO_OPTION echo_destination;
#if defined(_MSC_VER)
/* disable warning C4251: 'identifier' : class 'type' needs to have dll-interface to be used by clients of class 'type2' */
#pragma warning(disable:4251)
#endif
std::list <std::istream *> istream_list;
std::list <bool> delete_istream_list;
std::string m_line;
std::string m_line_save;
std::string accumulated;
#if defined(_MSC_VER)
/* reset warning C4251 */
#pragma warning(default:4251)
#endif
// input data members
Keywords::KEYWORDS m_next_keyword;
bool accumulate;
LINE_TYPE m_line_type;
};
#endif /* _PHRQIO_H */

1317
Parser.cxx Normal file

File diff suppressed because it is too large Load Diff

296
Parser.h Normal file
View File

@ -0,0 +1,296 @@
#if !defined(PARSER_H_INCLUDED)
#define PARSER_H_INCLUDED
#if defined(WIN32)
#include <windows.h>
#endif
#include <string> // std::string
#include <map> // std::map
#include <vector> // std::vector
#include <sstream> // std::istringstream std::ostringstream
#include <ostream> // std::ostream
#include <istream> // std::istream
#include <cctype> // std::isspace
#include <algorithm> // std::find_if
#include <functional> // std::ptr_fun std::not1
#include "PHRQ_base.h"
#include "Keywords.h"
#include "PHRQ_io.h"
#ifdef _DEBUG
#define isspace(a) isspace((a) < -1 ? (a) + 256 : (a))
#define isupper(a) isupper((a) < -1 ? (a) + 256 : (a))
#define islower(a) islower((a) < -1 ? (a) + 256 : (a))
#define isdigit(a) isdigit((a) < -1 ? (a) + 256 : (a))
#define isalpha(a) isalpha((a) < -1 ? (a) + 256 : (a))
#endif
class CParser: public PHRQ_base
{
public:
CParser(PHRQ_io *io=NULL);
CParser(std::istream & input, PHRQ_io *io=NULL);
//CParser(std::istream & input, std::ostream & output, PHRQ_io *io=NULL);
//CParser(std::istream & input, std::ostream & output,
// std::ostream & error, PHRQ_io *io=NULL);
virtual ~ CParser();
enum TOKEN_TYPE
{
TT_EMPTY = 2,
TT_UPPER = 4,
TT_LOWER = 5,
TT_DIGIT = 6,
TT_UNKNOWN = 7
};
enum FIND_TYPE
{
FT_OK = 0,
FT_ERROR = 1
};
enum OPT_TYPE
{
OPT_DEFAULT = -4,
OPT_ERROR = -3,
OPT_KEYWORD = -2,
OPT_EOF = -1
};
enum ECHO_OPTION
{
EO_NONE = 0,
EO_ALL = 1,
EO_KEYWORDS = 2,
EO_NOKEYWORDS = 3
};
enum STATUS_TYPE
{
PARSER_ERROR = 0,
PARSER_OK = 1
};
/**
Function gets a new line and checks for empty, eof, and keywords.
Arguments:
string Input, character string used in printing error message
allow_empty Input, True or false, if a blank line is accepable
if false, another line is read
allow_eof Input, True or false, if EOF is acceptable
allow_keyword Input, True or false, if a keyword is acceptable
Returns:
LT_EMPTY if empty line read and allow_empty == true
LT_KEYWORD if line begins with keyword
LT_EOF if eof and allow_eof == true
LT_OK otherwise
LT_OPTION if line begins with -[alpha]
Terminates if EOF and allow_eof == false.
*/
PHRQ_io::LINE_TYPE check_line(const std::string & str, bool allow_empty,
bool allow_eof, bool allow_keyword, bool print);
/**
Read a line from input file put in "line".
Copy of input line is stored in "line_save".
Characters after # are discarded in line but retained in "line_save"
Arguments:
None
Returns:
LT_EMPTY,
LT_EOF,
LT_KEYWORD,
LT_OK,
LT_OPTION
*/
PHRQ_io::LINE_TYPE get_line();
PHRQ_io::LINE_TYPE get_line_phrq_io();
// bool check_key(const std::string::iterator ptr);
bool check_key(std::string::iterator begin, std::string::iterator end);
STATUS_TYPE check_units(std::string & tot_units, bool alkalinity,
bool check_compatibility,
const std::string & default_units, bool print);
//KEY_TYPE next_keyword() const
Keywords::KEYWORDS next_keyword() const
{
return m_next_keyword;
}
int get_option(const std::vector < std::string > &opt_list,
std::string::iterator & next_char);
int get_option(const std::vector < std::string > &opt_list,
std::istream::pos_type & next_pos);
int getOptionFromLastLine(const std::vector < std::string > &opt_list,
std::string::iterator & next_char, bool flag_error);
int getOptionFromLastLine(const std::vector < std::string > &opt_list,
std::istream::pos_type & next_pos, bool flag_error);
std::string & line()
{
return m_line;
}
std::string & line_save()
{
return m_line_save;
}
std::string & get_accumulated()
{
return accumulated;
}
void set_accumulate(bool tf)
{
if (tf)
{
accumulated.clear();
}
this->accumulate = tf;
}
std::istringstream & get_iss()
{
return m_line_iss;
}
int incr_input_error();
int get_input_error()
{
return m_input_error;
}
/**
Copies from begin to token until first space is encountered.
Arguments:
token output, the token
begin input, begin iterator
end input, end iterator
Returns:
TT_EMPTY
TT_UPPER
TT_LOWER
TT_DIGIT
TT_UNKNOWN
*/
static CParser::TOKEN_TYPE copy_token(std::string & token,
std::string::iterator & begin,
std::string::iterator & end);
static CParser::TOKEN_TYPE copy_title(std::string & token,
std::string::iterator & begin,
std::string::iterator & end);
static CParser::TOKEN_TYPE token_type(const std::string & token);
static CParser::TOKEN_TYPE copy_token(std::string & token, std::istream & is);
CParser::TOKEN_TYPE copy_token(std::string & token, std::istream::pos_type & pos);
bool get_true_false(std::istream::pos_type & pos, bool def);
CParser::TOKEN_TYPE get_rest_of_line(std::string &token);
static CParser::TOKEN_TYPE parse_delimited(std::string & source, std::string & result, const std::string& t);
CParser::TOKEN_TYPE peek_token();
PHRQ_io::LINE_TYPE get_m_line_type(void) const {return this->m_line_type;}
/**
Function reads an element name out of the equation string.
An element name is composed of a capital letter followed by any number
of lower case characters.
Arguments:
begin input, points to position in the equation to begin
output, points to next character of equation after
element name.
end input, points to last position in the equation
element input pointer to place to return element character string
*/
STATUS_TYPE get_elt(std::string::iterator & begin,
const std::string::iterator end,
std::string & element);
/**
Compares a string value to match beginning letters of a list of options
Arguments:
item entry: pointer to string to compare
n exit: item in list that was matched
list entry: pointer to list of character values, assumed to
be lower case
count_list entry: number of character values in list
Returns:
OK item matched
ERROR item not matched
n -1 item not matched
i position of match in list
*/
static FIND_TYPE find_option(const std::string & item, int *n,
const std::vector < std::string > &list,
bool exact);
void set_echo_file(ECHO_OPTION opt)
{
echo_file = opt;
}
ECHO_OPTION get_echo_file()
{
return this->echo_file;
};
void set_echo_stream(ECHO_OPTION opt)
{
echo_stream = opt;
}
ECHO_OPTION get_echo_stream()
{
return this->echo_stream;
};
STATUS_TYPE parse_couple(std::string & token);
template <class T>
STATUS_TYPE addPair(std::map < std::string, T >&totals,
std::istream::pos_type & pos);
protected:
PHRQ_io::LINE_TYPE get_logical_line();
protected:
std::istream & m_input_stream;
//std::ostream & m_output_stream;
//std::ostream & m_error_stream;
int m_input_error;
//KEY_TYPE m_next_keyword;
Keywords::KEYWORDS m_next_keyword;
std::string m_line;
std::string m_line_save;
std::istringstream m_line_iss;
PHRQ_io::LINE_TYPE m_line_type;
ECHO_OPTION echo_stream;
ECHO_OPTION echo_file;
std::string accumulated;
bool accumulate;
bool phrq_io_only;
};
// Global functions
static inline std::string &trim_left(std::string &s)
{
s.erase(s.begin(), std::find_if(s.begin(), s.end(), std::not1(std::ptr_fun<int, int>(std::isspace))));
return s;
}
static inline std::string &trim_right(std::string &s)
{
s.erase(std::find_if(s.rbegin(), s.rend(), std::not1(std::ptr_fun<int, int>(std::isspace))).base(), s.end());
return s;
}
static inline std::string &trim(std::string &s)
{
return trim_left(trim_right(s));
}
#endif // PARSER_H_INCLUDED

186
Utils.cxx Normal file
View File

@ -0,0 +1,186 @@
#ifdef _DEBUG
#pragma warning(disable : 4786) // disable truncation warning (Only used by debugger)
#endif
#include <stdlib.h> // ::tolower
#include <ctype.h> // ::tolower
#include <algorithm> // std::transform
#include <iostream> // std::cout std::cerr
#include <string.h>
#include "Utils.h"
#include "Parser.h"
#include "float.h"
#include "math.h"
////////////////////////////////////////////////////////////////////////////
int
Utilities::strcmp_nocase_arg1(const char *str1, const char *str2)
////////////////////////////////////////////////////////////////////////////
{
//
// Compare two strings disregarding case
//
int c1, c2;
while ((c1 =::tolower(*str1++)) == (c2 = *str2++))
{
if (c1 == '\0')
return (0);
}
if (c1 < c2)
return (-1);
return (1);
}
////////////////////////////////////////////////////////////////////////////
int
Utilities::strcmp_nocase(const char *str1, const char *str2)
////////////////////////////////////////////////////////////////////////////
{
//
// Compare two strings disregarding case
//
int c1, c2;
while ((c1 =::tolower(*str1++)) == (c2 =::tolower(*str2++)))
{
if (c1 == '\0')
return (0);
}
if (c1 < c2)
return (-1);
return (1);
}
////////////////////////////////////////////////////////////////////////////
void
Utilities::str_tolower(std::string & str)
////////////////////////////////////////////////////////////////////////////
{
std::transform(str.begin(), str.end(), str.begin(), tolower);
}
////////////////////////////////////////////////////////////////////////////
void
Utilities::str_toupper(std::string & str)
////////////////////////////////////////////////////////////////////////////
{
std::transform(str.begin(), str.end(), str.begin(), toupper);
}
////////////////////////////////////////////////////////////////////////////
std::string
Utilities::pad_right(const std::string & str, size_t l)
////////////////////////////////////////////////////////////////////////////
{
std::string new_str(str);
size_t length = new_str.size();
if (length < l)
{
new_str = new_str.insert(length, l - length, ' ');
}
return new_str;
}
////////////////////////////////////////////////////////////////////////////
bool
Utilities::replace(const char *str1, const char *str2, std::string & str)
////////////////////////////////////////////////////////////////////////////
{
std::string::size_type n = str.find(str1, 0);
if (n == std::string::npos)
return false;
str.replace(n, ::strlen(str1), str2);
return true;
}
////////////////////////////////////////////////////////////////////////////
void
Utilities::squeeze_white(std::string & s_l)
////////////////////////////////////////////////////////////////////////////
{
std::string str;
std::string::iterator beg = s_l.begin();
std::string::iterator end = s_l.end();
//CParser::copy_token(str, beg, end);
std::string::iterator pos;
for (pos = beg; pos != end; pos++)
{
int c = *pos;
if (!::isspace(c))
{
str += c;
}
}
s_l = str;
}
////////////////////////////////////////////////////////////////////////////
double
Utilities::convert_time(double t, std::string in, std::string out)
////////////////////////////////////////////////////////////////////////////
{
Utilities::str_tolower(in);
// convert t to seconds
if (in.substr(0,1) == "m")
{
t = t * 60.;
}
if (in.substr(0,1) == "h")
{
t = t * 3600.;
}
if (in.substr(0,1) == "d")
{
t = t * 3600. * 24.;
}
if (in.substr(0,1) == "y")
{
t = t * 3600. * 24. * 365.25;
}
// convert to ouput units
if (out.substr(0,1) == "m")
{
t = t / 60.;
}
if (out.substr(0,1) == "h")
{
t = t / 3600.;
}
if (out.substr(0,1) == "d")
{
t = t / ( 3600. * 24.);
}
if (out.substr(0,1) == "y")
{
t = t / (3600. * 24. * 365.25);
}
return t;
}
LDBLE
Utilities::safe_exp(LDBLE t)
////////////////////////////////////////////////////////////////////////////
{
LDBLE f = 1.442695*t; // convert to exp for 2.0
if (f > DBL_MAX_EXP - 50.0)
{
return pow(2, DBL_MAX_EXP - 50.0);
}
else if (f < DBL_MIN_EXP + 50.0)
{
return pow(2, DBL_MIN_EXP + 50.0);
}
return exp(t);
}
//+NAN LDBLE: 7ff8000000000000
//-NAN LDBLE: fff8000000000000
/*
LDBLE Utilities::get_nan(void)
{
unsigned long long raw = 0x7ff0000000000000;
LDBLE d = *( LDBLE* )&raw;
return(d);
}
*/

28
Utils.h Normal file
View File

@ -0,0 +1,28 @@
#if !defined(UTILITIES_H_INCLUDED)
#define UTILITIES_H_INCLUDED
#include <string>
#include <sstream> // std::istringstream std::ostringstream
#include <ostream> // std::ostream
#include <istream> // std::istream
#include <map> // std::map
#include "phrqtype.h"
namespace Utilities
{
const char INDENT[] = " ";
int strcmp_nocase(const char *str1, const char *str2);
int strcmp_nocase_arg1(const char *str1, const char *str2);
void str_tolower(std::string & str);
void str_toupper(std::string & str);
std::string pad_right(const std::string & str, size_t l);
bool replace(const char *str1, const char *str2, std::string & str);
void squeeze_white(std::string & s_l);
double convert_time(double t, std::string in, std::string out);
LDBLE safe_exp(LDBLE t);
}
#endif // UTILITIES_H_INCLUDED

18
phrqtype.h Normal file
View File

@ -0,0 +1,18 @@
#ifndef _INC_PHRQTYPE_H
#define _INC_PHRQTYPE_H
/*
* The following implements long double
* Many machines long double = double so there is no advantage
* Check float.h include file for number of digits (LDBL_DIG)
* Need to define here and in cl1.c
*/
/*#define USE_LONG_DOUBLE*/
#ifdef USE_LONG_DOUBLE
#define LDBLE long double
#define SCANFORMAT "%Lf"
#else
#define LDBLE double
#define SCANFORMAT "%lf"
#endif
#endif /* _INC_PHRQTYPE_H */