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 "Debug.h" // ASSERT
#include "SelectedOutput.hxx" // CSelectedOutput
#include "CSelectedOutput.hxx" // CSelectedOutput
const size_t RESERVE_ROWS = 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 "IPhreeqc.hpp" // IPhreeqc
#include "Phreeqc.h" // Phreeqc
#include "IPhreeqc.hpp" // IPhreeqc
#include "Phreeqc.h" // Phreeqc
#include "thread.h"
#include "Debug.h" // ASSERT
#include "ErrorReporter.hxx" // CErrorReporter
#include "SelectedOutput.hxx" // CSelectedOutput
#include "dumper.h" // dumper
#include "Debug.h" // ASSERT
#include "ErrorReporter.hxx" // CErrorReporter
#include "CSelectedOutput.hxx" // CSelectedOutput
#include "phreeqcpp/SelectedOutput.h" // SelectedOutput
#include "dumper.h" // dumper
const char OUTPUT_FILENAME_FORMAT[] = "phreeqc.%d.out";
const char ERROR_FILENAME_FORMAT[] = "phreeqc.%d.err";
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";
// statics
std::map<size_t, IPhreeqc*> IPhreeqc::Instances;
size_t IPhreeqc::InstancesIndex = 0;
static const char empty[] = "";
IPhreeqc::IPhreeqc(void)
: DatabaseLoaded(false)
@ -37,7 +41,7 @@ IPhreeqc::IPhreeqc(void)
, ErrorReporter(0)
, WarningStringOn(true)
, WarningReporter(0)
, SelectedOutput(0)
, CurrentSelectedOutputUserNumber(1)
, SelectedOutputStringOn(false)
, PhreeqcPtr(0)
, input_file(0)
@ -47,7 +51,6 @@ IPhreeqc::IPhreeqc(void)
this->ErrorReporter = new CErrorReporter<std::ostringstream>;
this->WarningReporter = new CErrorReporter<std::ostringstream>;
this->SelectedOutput = new CSelectedOutput();
this->PhreeqcPtr = new Phreeqc(this);
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);
mutex_unlock(&map_lock);
::sprintf(buffer, PUNCH_FILENAME_FORMAT, this->Index);
this->SelectedOutputFileName = buffer;
this->SelectedOutputFileNameMap[1] = this->sel_file_name(1);
::sprintf(buffer, OUTPUT_FILENAME_FORMAT, this->Index);
this->OutputFileName = buffer;
@ -82,10 +84,17 @@ IPhreeqc::~IPhreeqc(void)
this->OutputFileOn = false;
#endif
delete this->PhreeqcPtr;
delete this->SelectedOutput;
delete this->WarningReporter;
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);
std::map<size_t, IPhreeqc*>::iterator it = IPhreeqc::Instances.find(this->Index);
if (it != IPhreeqc::Instances.end())
@ -328,12 +337,23 @@ bool IPhreeqc::GetOutputStringOn(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
{
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
@ -343,7 +363,12 @@ bool IPhreeqc::GetSelectedOutputFileOn(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
@ -353,7 +378,12 @@ const char* IPhreeqc::GetSelectedOutputString(void)const
{
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)
@ -363,12 +393,17 @@ const char* IPhreeqc::GetSelectedOutputStringLine(int n)
{
return empty;
}
return this->SelectedOutputLines[n].c_str();
return this->SelectedOutputLinesMap[this->CurrentSelectedOutputUserNumber][n].c_str();
}
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
@ -386,7 +421,7 @@ VRESULT IPhreeqc::GetSelectedOutputValue(int row, int col, VAR* pVAR)
return VR_INVALIDARG;
}
VRESULT v = this->SelectedOutput->Get(row, col, pVAR);
VRESULT v = this->SelectedOutputMap[this->CurrentSelectedOutputUserNumber]->Get(row, col, pVAR);
switch (v)
{
case VR_OK:
@ -494,7 +529,13 @@ int IPhreeqc::LoadDatabase(const char* filename)
// cleanup
//
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
//
@ -543,8 +584,13 @@ int IPhreeqc::LoadDatabaseString(const char* input)
// cleanup
//
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();
std::string s(input);
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);
}
void IPhreeqc::SetCurrentSelectedOutputUserNumber(int n)
{
this->CurrentSelectedOutputUserNumber = n;
}
void IPhreeqc::SetDumpFileName(const char *filename)
{
if (filename && ::strlen(filename))
@ -815,7 +866,9 @@ void IPhreeqc::SetSelectedOutputFileName(const char *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
//
ASSERT(this->SelectedOutput);
this->SelectedOutput->Clear();
this->SelectedOutputString.clear();
this->SelectedOutputLines.clear();
std::map< int, CSelectedOutput* >::iterator itt = this->SelectedOutputMap.begin();
for (; itt != this->SelectedOutputMap.end(); ++itt)
{
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
//
@ -872,22 +940,52 @@ void IPhreeqc::UnLoadDatabase(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
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)
{
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)
{
@ -910,14 +1008,6 @@ void IPhreeqc::do_run(const char* sz_routine, std::istream* pis, PFN_PRERUN_CALL
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
*/
@ -945,18 +1035,43 @@ void IPhreeqc::do_run(const char* sz_routine, std::istream* pis, PFN_PRERUN_CALL
#endif
::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);
if (this->PhreeqcPtr->read_input() == EOF)
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;
oss << sz_routine << ": Warning SELECTED_OUTPUT has been redefined.\n";
this->PhreeqcPtr->warning_msg(oss.str().c_str());
if (this->CurrentSelectedOutputMap.find(&(*mit).second) == this->CurrentSelectedOutputMap.end())
{
// 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)
{
@ -977,7 +1092,7 @@ void IPhreeqc::do_run(const char* sz_routine, std::istream* pis, PFN_PRERUN_CALL
}
#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
@ -997,7 +1112,15 @@ void IPhreeqc::do_run(const char* sz_routine, std::istream* pis, PFN_PRERUN_CALL
//
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)
@ -1007,20 +1130,24 @@ void IPhreeqc::do_run(const char* sz_routine, std::istream* pis, PFN_PRERUN_CALL
// PRINT; -selected_output false
// is given as input
// Note: this also disables the CSelectedOutput object
ASSERT(TRUE);
}
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
// do_run -- containing SELECTED_OUTPUT ****TODO**** check -file option
// another do_run without SELECTED_OUTPUT
//
std::string filename = this->SelectedOutputFileName;
if (!this->punch_open(filename.c_str()))
ASSERT(!this->SelectedOutputFileNameMap[(*it).first].empty());
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;
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
{
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
this->PhreeqcPtr->punch.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);
(*it).second.Set_new_def(TRUE);
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
{
@ -1230,12 +1354,16 @@ void IPhreeqc::do_run(const char* sz_routine, std::istream* pis, PFN_PRERUN_CALL
if (this->SelectedOutputStringOn)
{
// output lines
std::istringstream iss(this->SelectedOutputString);
std::string line;
while (std::getline(iss, line))
std::map< int, std::string >::iterator mit = this->SelectedOutputStringMap.begin();
for (; mit != this->SelectedOutputStringMap.end(); ++mit)
{
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;
}
ASSERT(!(this->LogFileOn ^ (this->log_ostream != 0)));
ASSERT(!(this->LogFileOn != (this->log_ostream != 0)));
this->PHRQ_io::log_msg(str);
}
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)
{
@ -1307,7 +1435,7 @@ void IPhreeqc::error_msg(const char *str, bool stop)
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)
{
@ -1332,7 +1460,7 @@ void IPhreeqc::output_msg(const char * str)
{
this->OutputString += str;
}
ASSERT(!(this->OutputFileOn ^ (this->output_ostream != 0)));
ASSERT(!(this->OutputFileOn != (this->output_ostream != 0)));
this->PHRQ_io::output_msg(str);
}
@ -1345,9 +1473,9 @@ void IPhreeqc::punch_msg(const char *str)
{
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);
}
@ -1418,10 +1546,16 @@ int IPhreeqc::close_output_files(void)
delete this->output_ostream;
delete this->log_ostream;
delete this->punch_ostream;
delete this->dump_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->output_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);
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)
{
@ -1455,9 +1589,9 @@ void IPhreeqc::fpunchf(const char *name, const char *format, char *s)
this->PHRQ_io::fpunchf(name, format, s);
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)
{
@ -1472,9 +1606,9 @@ void IPhreeqc::fpunchf(const char *name, const char *format, int i)
this->PHRQ_io::fpunchf(name, format, i);
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)
{
@ -1487,15 +1621,22 @@ void IPhreeqc::fpunchf_end_row(const char *format)
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)
{
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;
}
@ -1508,3 +1649,10 @@ bool IPhreeqc::output_open(const char *file_name, std::ios_base::openmode mode)
}
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 IErrorReporter;
class CSelectedOutput;
class SelectedOutput;
/**
* @class IPhreeqcStop
@ -325,7 +326,7 @@ public:
/**
* Retrieves the number of columns in the selected-output buffer.
* @return The number of columns.
* @see GetSelectedOutputRowCount, GetSelectedOutputValue
* @see GetSelectedOutputRowCount, GetSelectedOutputValue, SetCurrentSelectedOutputUserNumber
*/
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.
* 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.
* @see GetSelectedOutputFileOn, GetSelectedOutputString, GetSelectedOutputStringOn, GetSelectedOutputStringLine, GetSelectedOutputStringLineCount, SetSelectedOutputFileName, SetSelectedOutputFileOn, SetSelectedOutputStringOn
* @see GetSelectedOutputFileOn, GetSelectedOutputString, GetSelectedOutputStringOn, GetSelectedOutputStringLine, GetSelectedOutputStringLineCount, SetCurrentSelectedOutputUserNumber, SetSelectedOutputFileName, SetSelectedOutputFileOn, SetSelectedOutputStringOn
*/
const char* GetSelectedOutputFileName(void)const;
@ -349,7 +350,7 @@ public:
/**
* Retrieves the number of rows in the selected-output buffer.
* @return The number of rows.
* @see GetSelectedOutputColumnCount, GetSelectedOutputFileOn, GetSelectedOutputValue, SetSelectedOutputFileOn
* @see GetSelectedOutputColumnCount, GetSelectedOutputFileOn, GetSelectedOutputValue, SetCurrentSelectedOutputUserNumber, SetSelectedOutputFileOn
*/
int GetSelectedOutputRowCount(void)const;
@ -358,7 +359,7 @@ public:
* @return A null terminated string containing <b>SELECTED_OUTPUT</b>.
* @pre
* \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;
@ -368,7 +369,7 @@ public:
* @return A null terminated string containing the given line.
* Returns an empty string if n is out of range.
* @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);
@ -376,7 +377,7 @@ public:
* Retrieves the number of lines in the current selected output string buffer.
* @return The number of lines.
* @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;
@ -398,7 +399,7 @@ public:
* @retval VR_INVALIDCOL The given column is out of range.
* @retval VR_OUTOFMEMORY Memory could not be allocated.
* @retval VR_BADINSTANCE The given id is invalid.
* @see GetSelectedOutputColumnCount, GetSelectedOutputFileOn, GetSelectedOutputRowCount, GetSelectedOutputValue2, SetSelectedOutputFileOn
* @see GetSelectedOutputColumnCount, GetSelectedOutputFileOn, GetSelectedOutputRowCount, GetSelectedOutputValue2, SetCurrentSelectedOutputUserNumber, SetSelectedOutputFileOn
* @remarks
* Row 0 contains the column headings to the selected_ouput.
* @par Examples:
@ -811,6 +812,16 @@ public:
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:
// overrides
virtual void error_msg(const char *str, bool stop=false);
@ -826,7 +837,7 @@ public:
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 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:
int EndRow(void);
@ -842,6 +853,7 @@ protected:
void update_errors(void);
std::string sel_file_name(int n_user);
protected:
#if defined(_MSC_VER)
@ -879,23 +891,27 @@ protected:
std::string WarningString;
std::vector< std::string > WarningLines;
CSelectedOutput *SelectedOutput;
std::string StringInput;
int CurrentSelectedOutputUserNumber;
std::map< int, CSelectedOutput* > SelectedOutputMap;
std::map< SelectedOutput*, CSelectedOutput* > CurrentSelectedOutputMap;
std::map< SelectedOutput*, std::string* > CurrentToStringMap;
std::string StringInput;
std::string DumpString;
std::vector< std::string > DumpLines;
std::list< std::string > Components;
std::string SelectedOutputFileName;
std::map< int, std::string > SelectedOutputFileNameMap;
std::string OutputFileName;
std::string ErrorFileName;
std::string LogFileName;
std::string DumpFileName;
bool SelectedOutputStringOn;
std::string SelectedOutputString;
std::vector< std::string > SelectedOutputLines;
bool SelectedOutputStringOn;
std::map< int, std::string > SelectedOutputStringMap;
std::map< int, std::vector< std::string > > SelectedOutputLinesMap;
protected:
Phreeqc* PhreeqcPtr;

View File

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