A few tests need to be updated.

Merged revision(s) 7882-7988 from IPhreeqc/branches/multi_punch:
multi_punch branch

........
Added a Fortran callback.

Will try to revise so that the same callback works for Fortran and C.
........
Revised name to BasicFortran

Added methods for C call SetBasicCallback.

Need to check C side and documentation.
........


git-svn-id: svn://136.177.114.72/svn_GW/IPhreeqc/trunk@7989 1feff8c3-07ed-0310-ac33-dd36852eb9cd
This commit is contained in:
Scott R Charlton 2013-08-28 23:32:19 +00:00
commit 7965206518
5 changed files with 287 additions and 119 deletions

View File

@ -13,7 +13,7 @@
#include <stdio.h> #include <stdio.h>
#include "Debug.h" // ASSERT #include "Debug.h" // ASSERT
#include "SelectedOutput.hxx" // CSelectedOutput #include "CSelectedOutput.hxx" // CSelectedOutput
const size_t RESERVE_ROWS = 80; const size_t RESERVE_ROWS = 80;
const size_t RESERVE_COLS = 80; const size_t RESERVE_COLS = 80;

View File

@ -1,25 +1,29 @@
#include <memory> // auto_ptr #include <memory> // auto_ptr
#include <map>
#include <string.h> #include <string.h>
#include "IPhreeqc.hpp" // IPhreeqc #include "IPhreeqc.hpp" // IPhreeqc
#include "Phreeqc.h" // Phreeqc #include "Phreeqc.h" // Phreeqc
#include "thread.h" #include "thread.h"
#include "Debug.h" // ASSERT #include "Debug.h" // ASSERT
#include "ErrorReporter.hxx" // CErrorReporter #include "ErrorReporter.hxx" // CErrorReporter
#include "SelectedOutput.hxx" // CSelectedOutput #include "CSelectedOutput.hxx" // CSelectedOutput
#include "dumper.h" // dumper #include "phreeqcpp/SelectedOutput.h" // SelectedOutput
#include "dumper.h" // dumper
const char OUTPUT_FILENAME_FORMAT[] = "phreeqc.%d.out"; const char OUTPUT_FILENAME_FORMAT[] = "phreeqc.%d.out";
const char ERROR_FILENAME_FORMAT[] = "phreeqc.%d.err"; const char ERROR_FILENAME_FORMAT[] = "phreeqc.%d.err";
const char LOG_FILENAME_FORMAT[] = "phreeqc.%d.log"; const char LOG_FILENAME_FORMAT[] = "phreeqc.%d.log";
const char PUNCH_FILENAME_FORMAT[] = "selected.%d.out"; const char PUNCH_FILENAME_FORMAT[] = "selected_%d.%d.out";
const char DUMP_FILENAME_FORMAT[] = "dump.%d.out"; const char DUMP_FILENAME_FORMAT[] = "dump.%d.out";
// statics // statics
std::map<size_t, IPhreeqc*> IPhreeqc::Instances; std::map<size_t, IPhreeqc*> IPhreeqc::Instances;
size_t IPhreeqc::InstancesIndex = 0; size_t IPhreeqc::InstancesIndex = 0;
static const char empty[] = "";
IPhreeqc::IPhreeqc(void) IPhreeqc::IPhreeqc(void)
: DatabaseLoaded(false) : DatabaseLoaded(false)
@ -37,7 +41,7 @@ IPhreeqc::IPhreeqc(void)
, ErrorReporter(0) , ErrorReporter(0)
, WarningStringOn(true) , WarningStringOn(true)
, WarningReporter(0) , WarningReporter(0)
, SelectedOutput(0) , CurrentSelectedOutputUserNumber(1)
, SelectedOutputStringOn(false) , SelectedOutputStringOn(false)
, PhreeqcPtr(0) , PhreeqcPtr(0)
, input_file(0) , input_file(0)
@ -47,7 +51,6 @@ IPhreeqc::IPhreeqc(void)
this->ErrorReporter = new CErrorReporter<std::ostringstream>; this->ErrorReporter = new CErrorReporter<std::ostringstream>;
this->WarningReporter = new CErrorReporter<std::ostringstream>; this->WarningReporter = new CErrorReporter<std::ostringstream>;
this->SelectedOutput = new CSelectedOutput();
this->PhreeqcPtr = new Phreeqc(this); this->PhreeqcPtr = new Phreeqc(this);
ASSERT(this->PhreeqcPtr->phast == 0); ASSERT(this->PhreeqcPtr->phast == 0);
@ -59,8 +62,7 @@ IPhreeqc::IPhreeqc(void)
std::pair<std::map<size_t, IPhreeqc*>::iterator, bool> pr = IPhreeqc::Instances.insert(instance); std::pair<std::map<size_t, IPhreeqc*>::iterator, bool> pr = IPhreeqc::Instances.insert(instance);
mutex_unlock(&map_lock); mutex_unlock(&map_lock);
::sprintf(buffer, PUNCH_FILENAME_FORMAT, this->Index); this->SelectedOutputFileNameMap[1] = this->sel_file_name(1);
this->SelectedOutputFileName = buffer;
::sprintf(buffer, OUTPUT_FILENAME_FORMAT, this->Index); ::sprintf(buffer, OUTPUT_FILENAME_FORMAT, this->Index);
this->OutputFileName = buffer; this->OutputFileName = buffer;
@ -82,10 +84,17 @@ IPhreeqc::~IPhreeqc(void)
this->OutputFileOn = false; this->OutputFileOn = false;
#endif #endif
delete this->PhreeqcPtr; delete this->PhreeqcPtr;
delete this->SelectedOutput;
delete this->WarningReporter; delete this->WarningReporter;
delete this->ErrorReporter; delete this->ErrorReporter;
std::map< int, CSelectedOutput* >::iterator sit = this->SelectedOutputMap.begin();
for (; sit != this->SelectedOutputMap.end(); ++sit)
{
delete (*sit).second;
}
this->SelectedOutputMap.clear();
this->CurrentSelectedOutputMap.clear();
mutex_lock(&map_lock); mutex_lock(&map_lock);
std::map<size_t, IPhreeqc*>::iterator it = IPhreeqc::Instances.find(this->Index); std::map<size_t, IPhreeqc*>::iterator it = IPhreeqc::Instances.find(this->Index);
if (it != IPhreeqc::Instances.end()) if (it != IPhreeqc::Instances.end())
@ -328,12 +337,23 @@ bool IPhreeqc::GetOutputStringOn(void)const
int IPhreeqc::GetSelectedOutputColumnCount(void)const int IPhreeqc::GetSelectedOutputColumnCount(void)const
{ {
return (int)this->SelectedOutput->GetColCount(); std::map< int, CSelectedOutput* >::const_iterator ci = this->SelectedOutputMap.find(this->CurrentSelectedOutputUserNumber);
if (ci != this->SelectedOutputMap.end())
{
return (int)(*ci).second->GetColCount();
}
return 0;
} }
const char* IPhreeqc::GetSelectedOutputFileName(void)const const char* IPhreeqc::GetSelectedOutputFileName(void)const
{ {
return this->SelectedOutputFileName.c_str(); static const char empty[] = "";
std::map< int, std::string >::const_iterator ci = this->SelectedOutputFileNameMap.find(this->CurrentSelectedOutputUserNumber);
if (ci != this->SelectedOutputFileNameMap.end())
{
return (*ci).second.c_str();
}
return empty;
} }
bool IPhreeqc::GetSelectedOutputFileOn(void)const bool IPhreeqc::GetSelectedOutputFileOn(void)const
@ -343,7 +363,12 @@ bool IPhreeqc::GetSelectedOutputFileOn(void)const
int IPhreeqc::GetSelectedOutputRowCount(void)const int IPhreeqc::GetSelectedOutputRowCount(void)const
{ {
return (int)this->SelectedOutput->GetRowCount(); std::map< int, CSelectedOutput* >::const_iterator ci = this->SelectedOutputMap.find(this->CurrentSelectedOutputUserNumber);
if (ci != this->SelectedOutputMap.end())
{
return (int)(*ci).second->GetRowCount();
}
return 0;
} }
const char* IPhreeqc::GetSelectedOutputString(void)const const char* IPhreeqc::GetSelectedOutputString(void)const
@ -353,7 +378,12 @@ const char* IPhreeqc::GetSelectedOutputString(void)const
{ {
return err_msg; return err_msg;
} }
return this->SelectedOutputString.c_str(); std::map< int, std::string >::const_iterator cit = this->SelectedOutputStringMap.find(this->CurrentSelectedOutputUserNumber);
if (cit != this->SelectedOutputStringMap.end())
{
return (*cit).second.c_str();
}
return empty;
} }
const char* IPhreeqc::GetSelectedOutputStringLine(int n) const char* IPhreeqc::GetSelectedOutputStringLine(int n)
@ -363,12 +393,17 @@ const char* IPhreeqc::GetSelectedOutputStringLine(int n)
{ {
return empty; return empty;
} }
return this->SelectedOutputLines[n].c_str(); return this->SelectedOutputLinesMap[this->CurrentSelectedOutputUserNumber][n].c_str();
} }
int IPhreeqc::GetSelectedOutputStringLineCount(void)const int IPhreeqc::GetSelectedOutputStringLineCount(void)const
{ {
return (int)this->SelectedOutputLines.size(); std::map< int, std::vector < std::string > >::const_iterator cit = this->SelectedOutputLinesMap.find(this->CurrentSelectedOutputUserNumber);
if (cit != this->SelectedOutputLinesMap.end())
{
return (*cit).second.size();
}
return (int)0;
} }
bool IPhreeqc::GetSelectedOutputStringOn(void)const bool IPhreeqc::GetSelectedOutputStringOn(void)const
@ -386,7 +421,7 @@ VRESULT IPhreeqc::GetSelectedOutputValue(int row, int col, VAR* pVAR)
return VR_INVALIDARG; return VR_INVALIDARG;
} }
VRESULT v = this->SelectedOutput->Get(row, col, pVAR); VRESULT v = this->SelectedOutputMap[this->CurrentSelectedOutputUserNumber]->Get(row, col, pVAR);
switch (v) switch (v)
{ {
case VR_OK: case VR_OK:
@ -494,7 +529,13 @@ int IPhreeqc::LoadDatabase(const char* filename)
// cleanup // cleanup
// //
this->UnLoadDatabase(); this->UnLoadDatabase();
this->SelectedOutput->Clear(); std::map< int, CSelectedOutput* >::iterator it = this->SelectedOutputMap.begin();
for (; it != this->SelectedOutputMap.end(); ++it)
{
delete (*it).second;
}
this->SelectedOutputMap.clear();
this->CurrentSelectedOutputMap.clear();
// open file // open file
// //
@ -543,8 +584,13 @@ int IPhreeqc::LoadDatabaseString(const char* input)
// cleanup // cleanup
// //
this->UnLoadDatabase(); this->UnLoadDatabase();
std::map< int, CSelectedOutput* >::iterator it = this->SelectedOutputMap.begin();
this->SelectedOutput->Clear(); for (; it != this->SelectedOutputMap.end(); ++it)
{
delete (*it).second;
}
this->SelectedOutputMap.clear();
this->CurrentSelectedOutputMap.clear();
std::string s(input); std::string s(input);
std::istringstream iss(s); std::istringstream iss(s);
@ -738,6 +784,11 @@ void IPhreeqc::SetBasicFortranCallback(double (*fcn)(double *x1, double *x2, cha
this->PhreeqcPtr->register_fortran_basic_callback(fcn); this->PhreeqcPtr->register_fortran_basic_callback(fcn);
} }
void IPhreeqc::SetCurrentSelectedOutputUserNumber(int n)
{
this->CurrentSelectedOutputUserNumber = n;
}
void IPhreeqc::SetDumpFileName(const char *filename) void IPhreeqc::SetDumpFileName(const char *filename)
{ {
if (filename && ::strlen(filename)) if (filename && ::strlen(filename))
@ -815,7 +866,9 @@ void IPhreeqc::SetSelectedOutputFileName(const char *filename)
{ {
if (filename && ::strlen(filename)) if (filename && ::strlen(filename))
{ {
this->SelectedOutputFileName = filename; // Can't use this->PhreeqcPtr->SelectedOutput_map since it's necessary
// to override the default filename "selected_output_%d.%d.sel"
this->SelectedOutputFileNameMap[1] = std::string(filename);
} }
} }
@ -851,10 +904,25 @@ void IPhreeqc::UnLoadDatabase(void)
// clear selectedoutput // clear selectedoutput
// //
ASSERT(this->SelectedOutput); std::map< int, CSelectedOutput* >::iterator itt = this->SelectedOutputMap.begin();
this->SelectedOutput->Clear(); for (; itt != this->SelectedOutputMap.end(); ++itt)
this->SelectedOutputString.clear(); {
this->SelectedOutputLines.clear(); delete (*itt).second;
}
this->SelectedOutputMap.clear();
this->CurrentSelectedOutputMap.clear();
std::map< int, std::string >::iterator mit = this->SelectedOutputStringMap.begin();
for (; mit != this->SelectedOutputStringMap.begin(); ++mit)
{
(*mit).second.clear();
}
std::map< int, std::vector< std::string > >::iterator it = this->SelectedOutputLinesMap.begin();
for (; it != this->SelectedOutputLinesMap.begin(); ++it)
{
(*it).second.clear();
}
// clear dump string // clear dump string
// //
@ -872,22 +940,52 @@ void IPhreeqc::UnLoadDatabase(void)
int IPhreeqc::EndRow(void) int IPhreeqc::EndRow(void)
{ {
if (this->SelectedOutput->GetRowCount() <= 1) if (this->CurrentSelectedOutputMap[this->PhreeqcPtr->current_selected_output]->GetRowCount() <= 1)
{ {
// ensure all user_punch headings are included // ensure all user_punch headings are included
ASSERT(this->PhreeqcPtr->n_user_punch_index >= 0); ASSERT(this->PhreeqcPtr->n_user_punch_index >= 0);
for (int i = this->PhreeqcPtr->n_user_punch_index; i < this->PhreeqcPtr->user_punch_count_headings; ++i) if (this->CurrentSelectedOutputMap[this->PhreeqcPtr->current_selected_output] != NULL)
{ {
this->SelectedOutput->PushBackEmpty(this->PhreeqcPtr->user_punch_headings[i]); if (this->PhreeqcPtr->current_user_punch)
{
for (size_t i = this->PhreeqcPtr->n_user_punch_index; i < this->PhreeqcPtr->current_user_punch->Get_headings().size(); ++i)
{
this->CurrentSelectedOutputMap[this->PhreeqcPtr->current_selected_output]->PushBackEmpty(this->PhreeqcPtr->current_user_punch->Get_headings()[i].c_str());
}
}
} }
} }
return this->SelectedOutput->EndRow(); return this->CurrentSelectedOutputMap[this->PhreeqcPtr->current_selected_output]->EndRow();
} }
void IPhreeqc::check_database(const char* sz_routine) void IPhreeqc::check_database(const char* sz_routine)
{ {
this->ErrorReporter->Clear(); this->ErrorReporter->Clear();
this->SelectedOutput->Clear();
std::map< int, CSelectedOutput* >::iterator it = this->SelectedOutputMap.begin();
for (; it != this->SelectedOutputMap.end(); ++it)
{
delete (*it).second;
}
this->SelectedOutputMap.clear();
this->CurrentSelectedOutputMap.clear();
// release
this->LogString.clear();
this->LogLines.clear();
this->OutputString.clear();
this->OutputLines.clear();
std::map< int, std::string >::iterator mit = SelectedOutputStringMap.begin();
for (; mit != SelectedOutputStringMap.begin(); ++mit)
{
(*mit).second.clear();
}
std::map< int, std::vector< std::string > >::iterator lit = this->SelectedOutputLinesMap.begin();
for (; lit != this->SelectedOutputLinesMap.begin(); ++lit)
{
(*lit).second.clear();
}
if (!this->DatabaseLoaded) if (!this->DatabaseLoaded)
{ {
@ -910,14 +1008,6 @@ void IPhreeqc::do_run(const char* sz_routine, std::istream* pis, PFN_PRERUN_CALL
pfn_pre(cookie); pfn_pre(cookie);
} }
// release
this->LogString.clear();
this->LogLines.clear();
this->OutputString.clear();
this->OutputLines.clear();
this->SelectedOutputString.clear();
this->SelectedOutputLines.clear();
/* /*
* set read callback * set read callback
*/ */
@ -945,18 +1035,43 @@ void IPhreeqc::do_run(const char* sz_routine, std::istream* pis, PFN_PRERUN_CALL
#endif #endif
::sprintf(token, "Reading input data for simulation %d.", this->PhreeqcPtr->simulation); ::sprintf(token, "Reading input data for simulation %d.", this->PhreeqcPtr->simulation);
int save_punch_in = this->PhreeqcPtr->punch.in; bool save_punch_in = this->PhreeqcPtr->SelectedOutput_map.size() > 0;
this->PhreeqcPtr->dup_print(token, TRUE); this->PhreeqcPtr->dup_print(token, TRUE);
if (this->PhreeqcPtr->read_input() == EOF) if (this->PhreeqcPtr->read_input() == EOF)
break; break;
if (this->PhreeqcPtr->simulation > 1 && save_punch_in == TRUE && this->PhreeqcPtr->punch.new_def == TRUE) bool bWarning = false;
std::map< int, SelectedOutput >::iterator mit = this->PhreeqcPtr->SelectedOutput_map.begin();
for (; mit != this->PhreeqcPtr->SelectedOutput_map.end(); ++mit)
{ {
std::ostringstream oss; if (this->CurrentSelectedOutputMap.find(&(*mit).second) == this->CurrentSelectedOutputMap.end())
oss << sz_routine << ": Warning SELECTED_OUTPUT has been redefined.\n"; {
this->PhreeqcPtr->warning_msg(oss.str().c_str()); // int -> CSelectedOutput*
std::map< int, CSelectedOutput* >::value_type item((*mit).first, new CSelectedOutput());
this->SelectedOutputMap.insert(item);
// SelectedOutput* -> CSelectedOutput*
this->CurrentSelectedOutputMap.insert(
std::map< SelectedOutput*, CSelectedOutput* >::value_type(
&(*mit).second, item.second));
// SelectedOutput* -> std::string*
this->CurrentToStringMap.insert(
std::map< SelectedOutput*, std::string* >::value_type(
&(*mit).second, &this->SelectedOutputStringMap[(*mit).first]));
}
else
{
ASSERT(this->SelectedOutputMap[(*mit).first] == this->CurrentSelectedOutputMap[&(*mit).second]);
}
if (this->PhreeqcPtr->simulation > 1 && save_punch_in && (*mit).second.Get_new_def() && !bWarning)
{
std::ostringstream oss;
oss << sz_routine << ": Warning SELECTED_OUTPUT has been redefined.\n";
this->PhreeqcPtr->warning_msg(oss.str().c_str());
bWarning = true;
}
} }
if (this->PhreeqcPtr->simulation > 1 && this->PhreeqcPtr->keycount[Keywords::KEY_USER_PUNCH] > 0) if (this->PhreeqcPtr->simulation > 1 && this->PhreeqcPtr->keycount[Keywords::KEY_USER_PUNCH] > 0)
{ {
@ -977,7 +1092,7 @@ void IPhreeqc::do_run(const char* sz_routine, std::istream* pis, PFN_PRERUN_CALL
} }
#ifdef SWIG_SHARED_OBJ #ifdef SWIG_SHARED_OBJ
if (this->PhreeqcPtr->punch.in == TRUE) if (this->PhreeqcPtr->SelectedOutput_map.size() > 0)
{ {
// //
// (punch.in == TRUE) when any "RUN" has contained // (punch.in == TRUE) when any "RUN" has contained
@ -997,7 +1112,15 @@ void IPhreeqc::do_run(const char* sz_routine, std::istream* pis, PFN_PRERUN_CALL
// //
if (!this->SelectedOutputFileOn) if (!this->SelectedOutputFileOn)
{ {
ASSERT(!this->punch_ostream); std::map< int, SelectedOutput >::iterator it = this->PhreeqcPtr->SelectedOutput_map.begin();
for (; it != this->PhreeqcPtr->SelectedOutput_map.end(); ++it)
{
ASSERT((*it).second.Get_punch_ostream() == 0);
}
}
else
{
ASSERT(TRUE);
} }
if (this->PhreeqcPtr->pr.punch == FALSE) if (this->PhreeqcPtr->pr.punch == FALSE)
@ -1007,20 +1130,24 @@ void IPhreeqc::do_run(const char* sz_routine, std::istream* pis, PFN_PRERUN_CALL
// PRINT; -selected_output false // PRINT; -selected_output false
// is given as input // is given as input
// Note: this also disables the CSelectedOutput object // Note: this also disables the CSelectedOutput object
ASSERT(TRUE);
} }
else else
{ {
if (this->PhreeqcPtr->punch.new_def == FALSE) std::map< int, SelectedOutput >::iterator it = this->PhreeqcPtr->SelectedOutput_map.begin();
for (; it != this->PhreeqcPtr->SelectedOutput_map.end(); ++it)
{ {
if (this->SelectedOutputFileOn && !this->punch_ostream) if (this->SelectedOutputFileOn && !(*it).second.Get_punch_ostream())
{ {
// //
// LoadDatabase // LoadDatabase
// do_run -- containing SELECTED_OUTPUT ****TODO**** check -file option // do_run -- containing SELECTED_OUTPUT ****TODO**** check -file option
// another do_run without SELECTED_OUTPUT // another do_run without SELECTED_OUTPUT
// //
std::string filename = this->SelectedOutputFileName; ASSERT(!this->SelectedOutputFileNameMap[(*it).first].empty());
if (!this->punch_open(filename.c_str())) ASSERT(this->SelectedOutputFileNameMap[(*it).first] == this->PhreeqcPtr->SelectedOutput_map[(*it).first].Get_file_name());
std::string filename = this->SelectedOutputFileNameMap[(*it).first];
if (!punch_open(filename.c_str(), std::ios_base::out, (*it).first))
{ {
std::ostringstream oss; std::ostringstream oss;
oss << sz_routine << ": Unable to open:" << "\"" << filename << "\".\n"; oss << sz_routine << ": Unable to open:" << "\"" << filename << "\".\n";
@ -1028,42 +1155,39 @@ void IPhreeqc::do_run(const char* sz_routine, std::istream* pis, PFN_PRERUN_CALL
} }
else else
{ {
ASSERT(this->Get_punch_ostream() != NULL);
ASSERT((*it).second.Get_punch_ostream() == NULL);
int n_user = (*it).first;
this->PhreeqcPtr->SelectedOutput_map[n_user].Set_punch_ostream(this->Get_punch_ostream());
this->Set_punch_ostream(NULL);
// output selected_output headings // output selected_output headings
this->PhreeqcPtr->punch.new_def = TRUE; (*it).second.Set_new_def(TRUE);
this->PhreeqcPtr->tidy_punch();
}
}
}
else
{
if (this->SelectedOutputFileOn && !this->punch_ostream)
{
// This is a special case which could not occur in
// phreeqc
//
// LoadDatabase
// do_run -- containing SELECTED_OUTPUT ****TODO**** check -file option
// another do_run with SELECTED_OUTPUT
//
std::string filename = this->SelectedOutputFileName;
if (!this->punch_open(filename.c_str()))
{
std::ostringstream oss;
oss << sz_routine << ": Unable to open:" << "\"" << filename << "\".\n";
this->PhreeqcPtr->warning_msg(oss.str().c_str());
}
else
{
// output selected_output headings
ASSERT(this->PhreeqcPtr->punch.new_def == TRUE);
this->PhreeqcPtr->tidy_punch(); this->PhreeqcPtr->tidy_punch();
} }
} }
} }
} }
} }
else
{
ASSERT(TRUE);
}
if (!this->SelectedOutputFileOn) ASSERT(!this->punch_ostream); std::map< int, SelectedOutput >::iterator it = this->PhreeqcPtr->SelectedOutput_map.begin();
for (; it != this->PhreeqcPtr->SelectedOutput_map.end(); ++it)
{
if (this->SelectedOutputFileOn)
{
ASSERT((*it).second.Get_punch_ostream());
}
else
{
ASSERT(!(*it).second.Get_punch_ostream());
}
}
// Consider this addition // Consider this addition
{ {
@ -1230,12 +1354,16 @@ void IPhreeqc::do_run(const char* sz_routine, std::istream* pis, PFN_PRERUN_CALL
if (this->SelectedOutputStringOn) if (this->SelectedOutputStringOn)
{ {
// output lines std::map< int, std::string >::iterator mit = this->SelectedOutputStringMap.begin();
std::istringstream iss(this->SelectedOutputString); for (; mit != this->SelectedOutputStringMap.end(); ++mit)
std::string line;
while (std::getline(iss, line))
{ {
this->SelectedOutputLines.push_back(line); // output lines
std::istringstream iss((*mit).second);
std::string line;
while (std::getline(iss, line))
{
this->SelectedOutputLinesMap[(*mit).first].push_back(line);
}
} }
} }
} }
@ -1273,13 +1401,13 @@ void IPhreeqc::log_msg(const char * str)
{ {
this->LogString += str; this->LogString += str;
} }
ASSERT(!(this->LogFileOn ^ (this->log_ostream != 0))); ASSERT(!(this->LogFileOn != (this->log_ostream != 0)));
this->PHRQ_io::log_msg(str); this->PHRQ_io::log_msg(str);
} }
void IPhreeqc::error_msg(const char *str, bool stop) void IPhreeqc::error_msg(const char *str, bool stop)
{ {
ASSERT(!(this->ErrorFileOn ^ (this->error_ostream != 0))); ASSERT(!(this->ErrorFileOn != (this->error_ostream != 0)));
if (this->error_ostream != NULL && this->error_on) if (this->error_ostream != NULL && this->error_on)
{ {
@ -1307,7 +1435,7 @@ void IPhreeqc::error_msg(const char *str, bool stop)
void IPhreeqc::warning_msg(const char *str) void IPhreeqc::warning_msg(const char *str)
{ {
ASSERT(!(this->ErrorFileOn ^ (this->error_ostream != 0))); ASSERT(!(this->ErrorFileOn != (this->error_ostream != 0)));
if (this->error_ostream != NULL && this->error_on) if (this->error_ostream != NULL && this->error_on)
{ {
@ -1332,7 +1460,7 @@ void IPhreeqc::output_msg(const char * str)
{ {
this->OutputString += str; this->OutputString += str;
} }
ASSERT(!(this->OutputFileOn ^ (this->output_ostream != 0))); ASSERT(!(this->OutputFileOn != (this->output_ostream != 0)));
this->PHRQ_io::output_msg(str); this->PHRQ_io::output_msg(str);
} }
@ -1345,9 +1473,9 @@ void IPhreeqc::punch_msg(const char *str)
{ {
if (this->SelectedOutputStringOn && this->punch_on) if (this->SelectedOutputStringOn && this->punch_on)
{ {
this->SelectedOutputString += str; *(this->CurrentToStringMap[this->PhreeqcPtr->current_selected_output]) += str;
} }
ASSERT(!(this->SelectedOutputFileOn ^ (this->punch_ostream != 0))); ASSERT(!(this->SelectedOutputFileOn != (this->PhreeqcPtr->current_selected_output->Get_punch_ostream() != 0)));
this->PHRQ_io::punch_msg(str); this->PHRQ_io::punch_msg(str);
} }
@ -1418,10 +1546,16 @@ int IPhreeqc::close_output_files(void)
delete this->output_ostream; delete this->output_ostream;
delete this->log_ostream; delete this->log_ostream;
delete this->punch_ostream;
delete this->dump_ostream; delete this->dump_ostream;
delete this->error_ostream; delete this->error_ostream;
std::map< int, SelectedOutput >::iterator it = this->PhreeqcPtr->SelectedOutput_map.begin();
for (; it != this->PhreeqcPtr->SelectedOutput_map.end(); ++it)
{
delete (*it).second.Get_punch_ostream();
(*it).second.Set_punch_ostream(NULL);
}
this->error_ostream = 0; this->error_ostream = 0;
this->output_ostream = 0; this->output_ostream = 0;
this->log_ostream = 0; this->log_ostream = 0;
@ -1438,9 +1572,9 @@ void IPhreeqc::fpunchf(const char *name, const char *format, double d)
this->PHRQ_io::fpunchf(name, format, d); this->PHRQ_io::fpunchf(name, format, d);
if (this->SelectedOutputStringOn && this->punch_on) if (this->SelectedOutputStringOn && this->punch_on)
{ {
PHRQ_io::fpunchf_helper(&this->SelectedOutputString, format, d); PHRQ_io::fpunchf_helper(this->CurrentToStringMap[this->PhreeqcPtr->current_selected_output], format, d);
} }
this->SelectedOutput->PushBackDouble(name, d); this->CurrentSelectedOutputMap[this->PhreeqcPtr->current_selected_output]->PushBackDouble(name, d);
} }
catch (std::bad_alloc) catch (std::bad_alloc)
{ {
@ -1455,9 +1589,9 @@ void IPhreeqc::fpunchf(const char *name, const char *format, char *s)
this->PHRQ_io::fpunchf(name, format, s); this->PHRQ_io::fpunchf(name, format, s);
if (this->SelectedOutputStringOn && this->punch_on) if (this->SelectedOutputStringOn && this->punch_on)
{ {
PHRQ_io::fpunchf_helper(&this->SelectedOutputString, format, s); PHRQ_io::fpunchf_helper(this->CurrentToStringMap[this->PhreeqcPtr->current_selected_output], format, s);
} }
this->SelectedOutput->PushBackString(name, s); this->CurrentSelectedOutputMap[this->PhreeqcPtr->current_selected_output]->PushBackString(name, s);
} }
catch (std::bad_alloc) catch (std::bad_alloc)
{ {
@ -1472,9 +1606,9 @@ void IPhreeqc::fpunchf(const char *name, const char *format, int i)
this->PHRQ_io::fpunchf(name, format, i); this->PHRQ_io::fpunchf(name, format, i);
if (this->SelectedOutputStringOn && this->punch_on) if (this->SelectedOutputStringOn && this->punch_on)
{ {
PHRQ_io::fpunchf_helper(&this->SelectedOutputString, format, i); PHRQ_io::fpunchf_helper(this->CurrentToStringMap[this->PhreeqcPtr->current_selected_output], format, i);
} }
this->SelectedOutput->PushBackLong(name, (long)i); this->CurrentSelectedOutputMap[this->PhreeqcPtr->current_selected_output]->PushBackLong(name, (long)i);
} }
catch (std::bad_alloc) catch (std::bad_alloc)
{ {
@ -1487,15 +1621,22 @@ void IPhreeqc::fpunchf_end_row(const char *format)
this->EndRow(); this->EndRow();
} }
bool IPhreeqc::punch_open(const char *file_name, std::ios_base::openmode mode) bool IPhreeqc::punch_open(const char *file_name, std::ios_base::openmode mode, int n_user)
{ {
if (file_name && this->PhreeqcPtr->have_punch_name) if (this->PhreeqcPtr->SelectedOutput_map[n_user].Get_have_punch_name() &&
!this->PhreeqcPtr->SelectedOutput_map[n_user].Get_file_name().empty())
{ {
this->SelectedOutputFileName = file_name; this->SelectedOutputFileNameMap[n_user] = this->PhreeqcPtr->SelectedOutput_map[n_user].Get_file_name();
}
else if (this->SelectedOutputFileNameMap[n_user].empty())
{
this->SelectedOutputFileNameMap[n_user] = this->sel_file_name(n_user);
} }
if (this->SelectedOutputFileOn) if (this->SelectedOutputFileOn)
{ {
return this->PHRQ_io::punch_open(this->SelectedOutputFileName.c_str(), mode); ASSERT(!this->SelectedOutputFileNameMap[n_user].empty());
this->PhreeqcPtr->SelectedOutput_map[n_user].Set_file_name(this->SelectedOutputFileNameMap[n_user]);
return this->ofstream_open(&punch_ostream, this->SelectedOutputFileNameMap[n_user].c_str(), mode);
} }
return true; return true;
} }
@ -1508,3 +1649,10 @@ bool IPhreeqc::output_open(const char *file_name, std::ios_base::openmode mode)
} }
return true; return true;
} }
std::string IPhreeqc::sel_file_name(int n_user)
{
char buffer[80];
::sprintf(buffer, PUNCH_FILENAME_FORMAT, n_user, this->Index);
return std::string(buffer);
}

View File

@ -23,6 +23,7 @@
class Phreeqc; class Phreeqc;
class IErrorReporter; class IErrorReporter;
class CSelectedOutput; class CSelectedOutput;
class SelectedOutput;
/** /**
* @class IPhreeqcStop * @class IPhreeqcStop
@ -325,7 +326,7 @@ public:
/** /**
* Retrieves the number of columns in the selected-output buffer. * Retrieves the number of columns in the selected-output buffer.
* @return The number of columns. * @return The number of columns.
* @see GetSelectedOutputRowCount, GetSelectedOutputValue * @see GetSelectedOutputRowCount, GetSelectedOutputValue, SetCurrentSelectedOutputUserNumber
*/ */
int GetSelectedOutputColumnCount(void)const; int GetSelectedOutputColumnCount(void)const;
@ -334,7 +335,7 @@ public:
* Retrieves the name of the selected output file. This file name is used if not specified within <B>SELECTED_OUTPUT</B> input. * Retrieves the name of the selected output file. This file name is used if not specified within <B>SELECTED_OUTPUT</B> input.
* The default value is <B><I>selected.id.out</I></B>, where id is obtained from \ref GetId. * The default value is <B><I>selected.id.out</I></B>, where id is obtained from \ref GetId.
* @return filename The name of the file to write to. * @return filename The name of the file to write to.
* @see GetSelectedOutputFileOn, GetSelectedOutputString, GetSelectedOutputStringOn, GetSelectedOutputStringLine, GetSelectedOutputStringLineCount, SetSelectedOutputFileName, SetSelectedOutputFileOn, SetSelectedOutputStringOn * @see GetSelectedOutputFileOn, GetSelectedOutputString, GetSelectedOutputStringOn, GetSelectedOutputStringLine, GetSelectedOutputStringLineCount, SetCurrentSelectedOutputUserNumber, SetSelectedOutputFileName, SetSelectedOutputFileOn, SetSelectedOutputStringOn
*/ */
const char* GetSelectedOutputFileName(void)const; const char* GetSelectedOutputFileName(void)const;
@ -349,7 +350,7 @@ public:
/** /**
* Retrieves the number of rows in the selected-output buffer. * Retrieves the number of rows in the selected-output buffer.
* @return The number of rows. * @return The number of rows.
* @see GetSelectedOutputColumnCount, GetSelectedOutputFileOn, GetSelectedOutputValue, SetSelectedOutputFileOn * @see GetSelectedOutputColumnCount, GetSelectedOutputFileOn, GetSelectedOutputValue, SetCurrentSelectedOutputUserNumber, SetSelectedOutputFileOn
*/ */
int GetSelectedOutputRowCount(void)const; int GetSelectedOutputRowCount(void)const;
@ -358,7 +359,7 @@ public:
* @return A null terminated string containing <b>SELECTED_OUTPUT</b>. * @return A null terminated string containing <b>SELECTED_OUTPUT</b>.
* @pre * @pre
* \ref SetSelectedOutputStringOn must have been set to true in order to receive <b>SELECTED_OUTPUT</b>. * \ref SetSelectedOutputStringOn must have been set to true in order to receive <b>SELECTED_OUTPUT</b>.
* @see GetSelectedOutputStringLine, GetSelectedOutputFileOn, GetSelectedOutputStringLineCount, GetSelectedOutputStringOn, SetSelectedOutputFileOn, SetSelectedOutputStringOn * @see GetSelectedOutputStringLine, GetSelectedOutputFileOn, GetSelectedOutputStringLineCount, GetSelectedOutputStringOn, GetSelectedOutputString, SetCurrentSelectedOutputUserNumber, SetSelectedOutputFileOn, SetSelectedOutputStringOn
*/ */
const char* GetSelectedOutputString(void)const; const char* GetSelectedOutputString(void)const;
@ -368,7 +369,7 @@ public:
* @return A null terminated string containing the given line. * @return A null terminated string containing the given line.
* Returns an empty string if n is out of range. * Returns an empty string if n is out of range.
* @pre \ref SetSelectedOutputStringOn must have been set to true. * @pre \ref SetSelectedOutputStringOn must have been set to true.
* @see GetSelectedOutputFileOn, GetSelectedOutputString, GetSelectedOutputStringLineCount, GetSelectedOutputStringOn, SetSelectedOutputFileOn, SetSelectedOutputStringOn * @see GetSelectedOutputFileOn, GetSelectedOutputString, GetSelectedOutputStringLineCount, GetSelectedOutputStringOn, SetCurrentSelectedOutputUserNumber, SetSelectedOutputFileOn, SetSelectedOutputStringOn
*/ */
const char* GetSelectedOutputStringLine(int n); const char* GetSelectedOutputStringLine(int n);
@ -376,7 +377,7 @@ public:
* Retrieves the number of lines in the current selected output string buffer. * Retrieves the number of lines in the current selected output string buffer.
* @return The number of lines. * @return The number of lines.
* @pre \ref SetSelectedOutputStringOn must have been set to true. * @pre \ref SetSelectedOutputStringOn must have been set to true.
* @see GetSelectedOutputFileOn, GetSelectedOutputString, GetSelectedOutputStringLine, GetSelectedOutputStringOn, SetSelectedOutputFileOn, SetSelectedOutputStringOn * @see GetSelectedOutputFileOn, GetSelectedOutputString, GetSelectedOutputStringLine, GetSelectedOutputStringOn, SetCurrentSelectedOutputUserNumber, SetSelectedOutputFileOn, SetSelectedOutputStringOn
*/ */
int GetSelectedOutputStringLineCount(void)const; int GetSelectedOutputStringLineCount(void)const;
@ -398,7 +399,7 @@ public:
* @retval VR_INVALIDCOL The given column is out of range. * @retval VR_INVALIDCOL The given column is out of range.
* @retval VR_OUTOFMEMORY Memory could not be allocated. * @retval VR_OUTOFMEMORY Memory could not be allocated.
* @retval VR_BADINSTANCE The given id is invalid. * @retval VR_BADINSTANCE The given id is invalid.
* @see GetSelectedOutputColumnCount, GetSelectedOutputFileOn, GetSelectedOutputRowCount, GetSelectedOutputValue2, SetSelectedOutputFileOn * @see GetSelectedOutputColumnCount, GetSelectedOutputFileOn, GetSelectedOutputRowCount, GetSelectedOutputValue2, SetCurrentSelectedOutputUserNumber, SetSelectedOutputFileOn
* @remarks * @remarks
* Row 0 contains the column headings to the selected_ouput. * Row 0 contains the column headings to the selected_ouput.
* @par Examples: * @par Examples:
@ -811,6 +812,16 @@ public:
void SetSelectedOutputStringOn(bool bValue); void SetSelectedOutputStringOn(bool bValue);
/**
* Sets the given user number for use in subsequent calls to GetSelectedOutputXXX routines.
* The initial setting is 1.
* @param n The user number as specified in the <B>SELECTED_OUTPUT</B> block.
* @see GetSelectedOutputColumnCount, GetSelectedOutputFileName, GetSelectedOutputRowCount, GetSelectedOutputString, GetSelectedOutputStringLine, GetSelectedOutputStringLineCount, GetSelectedOutputValue
*/
void SetCurrentSelectedOutputUserNumber(int n);
public: public:
// overrides // overrides
virtual void error_msg(const char *str, bool stop=false); virtual void error_msg(const char *str, bool stop=false);
@ -826,7 +837,7 @@ public:
virtual void fpunchf_end_row(const char *format); virtual void fpunchf_end_row(const char *format);
virtual bool output_open(const char *file_name, std::ios_base::openmode mode = std::ios_base::out); virtual bool output_open(const char *file_name, std::ios_base::openmode mode = std::ios_base::out);
virtual bool punch_open(const char *file_name, std::ios_base::openmode mode = std::ios_base::out); virtual bool punch_open(const char *file_name, std::ios_base::openmode mode = std::ios_base::out, int n_user = 1);
protected: protected:
int EndRow(void); int EndRow(void);
@ -842,6 +853,7 @@ protected:
void update_errors(void); void update_errors(void);
std::string sel_file_name(int n_user);
protected: protected:
#if defined(_MSC_VER) #if defined(_MSC_VER)
@ -879,23 +891,27 @@ protected:
std::string WarningString; std::string WarningString;
std::vector< std::string > WarningLines; std::vector< std::string > WarningLines;
CSelectedOutput *SelectedOutput; int CurrentSelectedOutputUserNumber;
std::string StringInput; std::map< int, CSelectedOutput* > SelectedOutputMap;
std::map< SelectedOutput*, CSelectedOutput* > CurrentSelectedOutputMap;
std::map< SelectedOutput*, std::string* > CurrentToStringMap;
std::string StringInput;
std::string DumpString; std::string DumpString;
std::vector< std::string > DumpLines; std::vector< std::string > DumpLines;
std::list< std::string > Components; std::list< std::string > Components;
std::string SelectedOutputFileName; std::map< int, std::string > SelectedOutputFileNameMap;
std::string OutputFileName; std::string OutputFileName;
std::string ErrorFileName; std::string ErrorFileName;
std::string LogFileName; std::string LogFileName;
std::string DumpFileName; std::string DumpFileName;
bool SelectedOutputStringOn; bool SelectedOutputStringOn;
std::string SelectedOutputString; std::map< int, std::string > SelectedOutputStringMap;
std::vector< std::string > SelectedOutputLines; std::map< int, std::vector< std::string > > SelectedOutputLinesMap;
protected: protected:
Phreeqc* PhreeqcPtr; Phreeqc* PhreeqcPtr;

View File

@ -30,8 +30,8 @@ libiphreeqc_la_SOURCES=\
ErrorReporter.hxx\ ErrorReporter.hxx\
IPhreeqc.cpp\ IPhreeqc.cpp\
IPhreeqcLib.cpp\ IPhreeqcLib.cpp\
SelectedOutput.cpp\ CSelectedOutput.cpp\
SelectedOutput.hxx\ CSelectedOutput.hxx\
thread.h\ thread.h\
Var.c\ Var.c\
phreeqcpp/cxxKinetics.cxx\ phreeqcpp/cxxKinetics.cxx\
@ -81,6 +81,8 @@ libiphreeqc_la_SOURCES=\
phreeqcpp/ReadClass.cxx\ phreeqcpp/ReadClass.cxx\
phreeqcpp/runner.cpp\ phreeqcpp/runner.cpp\
phreeqcpp/runner.h\ phreeqcpp/runner.h\
phreeqcpp/SelectedOutput.cpp\
phreeqcpp/SelectedOutput.h\
phreeqcpp/Solution.cxx\ phreeqcpp/Solution.cxx\
phreeqcpp/Solution.h\ phreeqcpp/Solution.h\
phreeqcpp/SolutionIsotope.cxx\ phreeqcpp/SolutionIsotope.cxx\
@ -107,6 +109,8 @@ libiphreeqc_la_SOURCES=\
phreeqcpp/Temperature.h\ phreeqcpp/Temperature.h\
phreeqcpp/Use.cpp\ phreeqcpp/Use.cpp\
phreeqcpp/Use.h\ phreeqcpp/Use.h\
phreeqcpp/UserPunch.cpp\
phreeqcpp/UserPunch.h\
phreeqcpp/Utils.cxx\ phreeqcpp/Utils.cxx\
phreeqcpp/Utils.h\ phreeqcpp/Utils.h\
phreeqcpp/advection.cpp\ phreeqcpp/advection.cpp\