From d5d37e65af4b85ba6e38b7cb7a2dfa1e9fc9c892 Mon Sep 17 00:00:00 2001 From: Scott R Charlton Date: Thu, 5 Jan 2012 23:07:20 +0000 Subject: [PATCH] windows log functions passed (w/ phreeqcpp -r 5966) except for (PHRQ_io.h -r 5990) git-svn-id: svn://136.177.114.72/svn_GW/IPhreeqc/branches/ErrorHandling@5991 1feff8c3-07ed-0310-ac33-dd36852eb9cd --- doc/Makefile | 5 +- doc/examples/F90GetLogStringLine.f90 | 91 +++++++ doc/examples/GetLogString.c | 52 ++++ doc/examples/Makefile | 10 + include/IPhreeqc.f.inc | 6 +- include/IPhreeqc.f90.inc | 59 +++++ include/IPhreeqc.h | 165 ++++++++++++- include/IPhreeqc.hpp | 68 +++++- src/IPhreeqc.cpp | 89 ++++++- src/IPhreeqcF.f | 58 +++++ src/IPhreeqcLib.cpp | 89 +++++++ src/fwrap.cpp | 72 ++++++ src/fwrap.h | 12 + src/fwrap2.cpp | 25 ++ src/fwrap3.cpp | 25 ++ unit/TestIPhreeqc.cpp | 328 +++++++++++++++++++++++++ unit/TestIPhreeqc.h | 13 +- unit/TestIPhreeqcLib.cpp | 345 +++++++++++++++++++++++++++ unit/TestIPhreeqcLib.h | 13 +- 19 files changed, 1511 insertions(+), 14 deletions(-) create mode 100644 doc/examples/F90GetLogStringLine.f90 create mode 100644 doc/examples/GetLogString.c diff --git a/doc/Makefile b/doc/Makefile index dfb1f0ca..7f4c35cd 100644 --- a/doc/Makefile +++ b/doc/Makefile @@ -12,13 +12,16 @@ EXAMPLES = \ examples/CreateIPhreeqc.c \ examples/GetComponent.c \ examples/GetDumpString.c \ + examples/GetLogString.c \ + examples/GetOutputString.c \ examples/GetSelectedOutputValue.c \ examples/F90ClearAccumulatedLines.f90 \ examples/F90CreateIPhreeqc.f90 \ examples/F90DestroyIPhreeqc.f90 \ examples/F90GetComponent.f90 \ + examples/F90GetLogStringLine.f90 \ + examples/F90GetOutputStringLine.f90 \ examples/F90GetSelectedOutputValue.f90 \ - examples/F90GetDumpLine.f90 \ examples/F90GetDumpStringLine.f90 diff --git a/doc/examples/F90GetLogStringLine.f90 b/doc/examples/F90GetLogStringLine.f90 new file mode 100644 index 00000000..2ce8926b --- /dev/null +++ b/doc/examples/F90GetLogStringLine.f90 @@ -0,0 +1,91 @@ +PROGRAM example + INCLUDE "IPhreeqc.f90.inc" + INTEGER(KIND=4) :: id + INTEGER(KIND=4) :: i + CHARACTER(LEN=80) :: line + + id = CreateIPhreeqc() + IF (id.LT.0) THEN + STOP + END IF + + IF (SetOutputStringOn(id, .TRUE.).NE.IPQ_OK) THEN + CALL OutputErrorString(id) + STOP + END IF + + IF (LoadDatabase(id, "phreeqc.dat").NE.0) THEN + CALL OutputErrorString(id) + STOP + END IF + + IF (AccumulateLine(id, "SOLUTION 1 Pure water").NE.IPQ_OK) THEN + CALL OutputErrorString(id) + STOP + END IF + + IF (AccumulateLine(id, "EQUILIBRIUM_PHASES 1").NE.IPQ_OK) THEN + CALL OutputErrorString(id) + STOP + END IF + + IF (AccumulateLine(id, " Calcite 0 10").NE.IPQ_OK) THEN + CALL OutputErrorString(id) + STOP + END IF + + IF (AccumulateLine(id, "SAVE solution 1").NE.IPQ_OK) THEN + CALL OutputErrorString(id) + STOP + END IF + + IF (AccumulateLine(id, "SAVE equilibrium_phases 1").NE.IPQ_OK) THEN + CALL OutputErrorString(id) + STOP + END IF + + IF (AccumulateLine(id, "DUMP").NE.IPQ_OK) THEN + CALL OutputErrorString(id) + STOP + END IF + + IF (AccumulateLine(id, " -solution 1").NE.IPQ_OK) THEN + CALL OutputErrorString(id) + STOP + END IF + + IF (AccumulateLine(id, " -equilibrium_phases 1").NE.IPQ_OK) THEN + CALL OutputErrorString(id) + STOP + END IF + + IF (AccumulateLine(id, "KNOBS").NE.IPQ_OK) THEN + CALL OutputErrorString(id) + STOP + END IF + + IF (AccumulateLine(id, " -logfile TRUE").NE.IPQ_OK) THEN + CALL OutputErrorString(id) + STOP + END IF + + + WRITE(*,*) "Input:" + CALL OutputAccumulatedLines(id) + + IF (RunAccumulated(id).NE.0) THEN + CALL OutputErrorString(id) + STOP + END IF + + WRITE(*,*) "Log:" + DO i=1,GetLogStringLineCount(id) + CALL GetLogStringLine(id, i, line) + WRITE(*,*) TRIM(line) + END DO + + IF (DestroyIPhreeqc(id).NE.IPQ_OK) THEN + CALL OutputErrorString(id) + STOP + END IF +END PROGRAM example diff --git a/doc/examples/GetLogString.c b/doc/examples/GetLogString.c new file mode 100644 index 00000000..df56104b --- /dev/null +++ b/doc/examples/GetLogString.c @@ -0,0 +1,52 @@ +#include +#include +#include + +#define TRUE 1 + +const char input[] = + "SOLUTION 1 Pure water \n" + "EQUILIBRIUM_PHASES 1 \n" + " Calcite 0 10 \n" + "SAVE solution 1 \n" + "SAVE equilibrium_phases 1 \n" + "DUMP \n" + " -solution 1 \n" + " -equilibrium_phases 1\n" + "KNOBS \n" + " -logfile TRUE \n"; + +int main(void) +{ + int id; + + id = CreateIPhreeqc(); + if (id < 0) { + return EXIT_FAILURE; + } + + if (LoadDatabase(id, "phreeqc.dat") != 0) { + OutputErrorString(id); + return EXIT_FAILURE; + } + + if (SetLogStringOn(id, TRUE) != IPQ_OK) { + OutputErrorString(id); + return EXIT_FAILURE; + } + + if (RunString(id, input) != 0) { + OutputErrorString(id); + return EXIT_FAILURE; + } + + printf("Log:\n"); + printf("%s\n", GetLogString(id)); + + if (DestroyIPhreeqc(id) != IPQ_OK) { + OutputErrorString(id); + return EXIT_FAILURE; + } + + return EXIT_SUCCESS; +} diff --git a/doc/examples/Makefile b/doc/examples/Makefile index 1a0870b7..07ad0c53 100644 --- a/doc/examples/Makefile +++ b/doc/examples/Makefile @@ -16,6 +16,7 @@ TARGETS = \ CreateIPhreeqc \ GetComponent \ GetDumpString \ + GetLogString \ GetOutputString \ GetSelectedOutputValue \ IPhreeqc @@ -25,6 +26,7 @@ F90_TARGETS = \ F90CreateIPhreeqc \ F90GetComponent \ F90GetDumpStringLine \ + F90GetLogStringLine \ F90GetOutputStringLine \ F90ClearAccumulatedLines \ F90GetSelectedOutputValue @@ -44,6 +46,9 @@ GetComponent: GetComponent.lo $(IPHREEQC_LA) GetDumpString: GetDumpString.lo $(IPHREEQC_LA) $(LIBTOOL) --mode=link $(CXX) $(LDFLAGS) -o $@ $< $(IPHREEQC_LA) +GetLogString: GetLogString.lo $(IPHREEQC_LA) + $(LIBTOOL) --mode=link $(CXX) $(LDFLAGS) -o $@ $< $(IPHREEQC_LA) + GetOutputString: GetOutputString.lo $(IPHREEQC_LA) $(LIBTOOL) --mode=link $(CXX) $(LDFLAGS) -o $@ $< $(IPHREEQC_LA) @@ -66,6 +71,9 @@ F90GetComponent: F90GetComponent.lo $(IPHREEQC_LA) F90GetDumpStringLine: F90GetDumpStringLine.lo $(IPHREEQC_LA) $(LIBTOOL) --mode=link $(CXX) $(LDFLAGS) -o $@ $< $(IPHREEQC_LA) $(FCLIBS) +F90GetLogStringLine: F90GetLogStringLine.lo $(IPHREEQC_LA) + $(LIBTOOL) --mode=link $(CXX) $(LDFLAGS) -o $@ $< $(IPHREEQC_LA) $(FCLIBS) + F90GetOutputStringLine: F90GetOutputStringLine.lo $(IPHREEQC_LA) $(LIBTOOL) --mode=link $(CXX) $(LDFLAGS) -o $@ $< $(IPHREEQC_LA) $(FCLIBS) @@ -99,6 +107,7 @@ LO_FILES = \ DestroyIPhreeqc.lo \ GetComponent.lo \ GetDumpString.lo \ + GetLogString.lo \ GetOutputString.lo \ IPhreeqc.lo \ GetSelectedOutputValue.lo @@ -110,6 +119,7 @@ F90_LO_FILES = \ F90DestroyIPhreeqc.lo \ F90GetComponent.lo \ F90GetDumpStringLine.lo \ + F90GetLogStringLine.lo \ F90GetOutputStringLine.lo \ F90ClearAccumulatedLines.lo \ F90GetSelectedOutputValue.lo diff --git a/include/IPhreeqc.f.inc b/include/IPhreeqc.f.inc index 4277cc22..532f58af 100644 --- a/include/IPhreeqc.f.inc +++ b/include/IPhreeqc.f.inc @@ -55,7 +55,9 @@ C LOGICAL(KIND=4) GetErrorFileOn INTEGER(KIND=4) GetErrorStringLine INTEGER(KIND=4) GetErrorStringLineCount - LOGICAL(KIND=4) GetLogFileOn + LOGICAL(KIND=4) GetLogFileOn + LOGICAL(KIND=4) GetLogStringLineCount + LOGICAL(KIND=4) GetLogStringOn LOGICAL(KIND=4) GetOutputFileOn INTEGER(KIND=4) GetOutputStringLineCount LOGICAL(KIND=4) GetOutputStringOn @@ -74,7 +76,9 @@ C INTEGER(KIND=4) SetDumpFileOn INTEGER(KIND=4) SetDumpStringOn INTEGER(KIND=4) SetErrorFileOn + INTEGER(KIND=4) SetLogFileName INTEGER(KIND=4) SetLogFileOn + INTEGER(KIND=4) SetLogStringOn INTEGER(KIND=4) SetOutputFileName INTEGER(KIND=4) SetOutputFileOn INTEGER(KIND=4) SetOutputStringOn diff --git a/include/IPhreeqc.f90.inc b/include/IPhreeqc.f90.inc index 557197b7..566e33bd 100644 --- a/include/IPhreeqc.f90.inc +++ b/include/IPhreeqc.f90.inc @@ -148,6 +148,14 @@ END INTERFACE + INTERFACE + SUBROUTINE GetLogFileName(ID,FNAME) + INTEGER(KIND=4), INTENT(IN) :: ID + CHARACTER(LEN=*), INTENT(OUT) :: FNAME + END SUBROUTINE GetLogFileName + END INTERFACE + + INTERFACE FUNCTION GetLogFileOn(ID) INTEGER(KIND=4), INTENT(IN) :: ID @@ -156,6 +164,31 @@ END INTERFACE + INTERFACE + SUBROUTINE GetLogStringLine(ID,N,LINE) + INTEGER(KIND=4), INTENT(IN) :: ID + INTEGER(KIND=4), INTENT(IN) :: N + CHARACTER(LEN=*), INTENT(OUT) :: LINE + END SUBROUTINE + END INTERFACE + + + INTERFACE + FUNCTION GetLogStringLineCount(ID) + INTEGER(KIND=4), INTENT(IN) :: ID + INTEGER(KIND=4) :: GetLogStringLineCount + END FUNCTION GetLogStringLineCount + END INTERFACE + + + INTERFACE + FUNCTION GetLogStringOn(ID) + INTEGER(KIND=4), INTENT(IN) :: ID + LOGICAL(KIND=4) :: GetLogStringOn + END FUNCTION GetLogStringOn + END INTERFACE + + INTERFACE SUBROUTINE GetOutputFileName(ID,FNAME) INTEGER(KIND=4), INTENT(IN) :: ID @@ -187,6 +220,14 @@ INTEGER(KIND=4) :: GetOutputStringLineCount END FUNCTION GetOutputStringLineCount END INTERFACE + + + INTERFACE + FUNCTION GetOutputStringOn(ID) + INTEGER(KIND=4), INTENT(IN) :: ID + LOGICAL(KIND=4) :: GetOutputStringOn + END FUNCTION GetOutputStringOn + END INTERFACE INTERFACE @@ -344,6 +385,15 @@ END INTERFACE + INTERFACE + FUNCTION SetLogFileName(ID,FNAME) + INTEGER(KIND=4), INTENT(IN) :: ID + CHARACTER(LEN=*), INTENT(IN) :: FNAME + INTEGER(KIND=4) :: SetLogFileName + END FUNCTION SetLogFileName + END INTERFACE + + INTERFACE FUNCTION SetLogFileOn(ID,LOG_ON) INTEGER(KIND=4), INTENT(IN) :: ID @@ -353,6 +403,15 @@ END INTERFACE + INTERFACE + FUNCTION SetLogStringOn(ID,LOG_STRING_ON) + INTEGER(KIND=4), INTENT(IN) :: ID + LOGICAL(KIND=4), INTENT(IN) :: LOG_STRING_ON + INTEGER(KIND=4) :: SetLogStringOn + END FUNCTION SetLogStringOn + END INTERFACE + + INTERFACE FUNCTION SetOutputFileName(ID,FNAME) INTEGER(KIND=4), INTENT(IN) :: ID diff --git a/include/IPhreeqc.h b/include/IPhreeqc.h index a531f889..98bdd1e9 100644 --- a/include/IPhreeqc.h +++ b/include/IPhreeqc.h @@ -446,13 +446,31 @@ extern "C" { */ IPQ_DLL_EXPORT int GetErrorStringLineCount(int id); +/** + * Retrieves the name of the log file. The default name is phreeqc.id.log. + * @param id The instance id returned from \ref CreateIPhreeqc. + * @return filename The name of the log file. + * @see GetLogFileOn, GetLogString, GetLogStringOn, GetLogStringLine, GetLogStringLineCount, SetLogFileName, SetLogFileOn, SetLogStringOn + * @par Fortran90 Interface: + * @htmlonly + * + *
+ *  SUBROUTINE GetLogFileName(ID,FILENAME)
+ *    INTEGER(KIND=4),   INTENT(IN)   :: ID
+ *    CHARACTER(LEN=*),  INTENT(OUT)  :: FILENAME
+ *  END SUBROUTINE GetLogFileName
+ *  
+ *
+ * @endhtmlonly + */ + IPQ_DLL_EXPORT const char* GetLogFileName(int id); + /** * Retrieves the current value of the log file switch. * @param id The instance id returned from \ref CreateIPhreeqc. * @return Non-zero if log messages are written to the phreeqc.id.log file, 0 (zero) otherwise. - * @remarks - * Logging must be enabled through the use of the KNOBS -logfile option in order to receive any log messages. + * @remarks Logging must be enabled through the use of the KNOBS -logfile option in order to receive any log messages. * @see SetLogFileOn * @par Fortran90 Interface: * @htmlonly @@ -468,6 +486,96 @@ extern "C" { */ IPQ_DLL_EXPORT int GetLogFileOn(int id); + +/** + * Retrieves the string buffer containing log output. + * @param id The instance id returned from \ref CreateIPhreeqc. + * @return A null terminated string containing log output. + * @remarks Logging must be enabled through the use of the KNOBS -logfile option in order to receive any log messages. + * @pre \ref SetLogStringOn must have been set to true (non-zero) in order to recieve log output. + * @see GetLogFileOn, GetLogStringLine, GetLogStringLineCount, SetLogFileOn, GetLogStringOn, SetLogStringOn + * @par Fortran90 Interface: + * Not implemented. (see \ref GetLogStringLineCount, \ref GetLogStringLine) + * + * \anchor GetOutputString_c + * @par C Example: + * \include GetOutputString.c + */ + IPQ_DLL_EXPORT const char* GetLogString(int id); + + +/** + * Retrieves the given log line. + * @param id The instance id returned from \ref CreateIPhreeqc. + * @param n The zero-based index of the line to retrieve. + * @return A null terminated string containing the given line. + * Returns an empty string if n is out of range. + * @pre \ref SetLogStringOn must have been set to true (non-zero). + * @see GetLogFileOn, GetLogString, GetLogStringLineCount, GetLogStringOn, SetLogFileOn, SetLogStringOn + * @par Fortran90 Interface: + * @htmlonly + * (Note: N is one-based for the Fortran interface.) + * + *
+ *  SUBROUTINE GetLogStringLine(ID,N,LINE)
+ *    INTEGER(KIND=4),   INTENT(IN)   :: ID
+ *    INTEGER(KIND=4),   INTENT(IN)   :: N
+ *    CHARACTER(LEN=*),  INTENT(OUT)  :: LINE
+ *  END SUBROUTINE GetLogStringLine
+ *  
+ *
+ * @endhtmlonly + * + * \anchor GetLogStringLine_f90 + * @par Fortran90 Example: + * \include F90GetLogStringLine.f90 + */ + IPQ_DLL_EXPORT const char* GetLogStringLine(int id, int n); + +/** + * Retrieves the number of lines in the current log string buffer. + * @param id The instance id returned from \ref CreateIPhreeqc. + * @return The number of lines. + * @pre \ref SetLogStringOn must have been set to true (non-zero). + * @see GetLogFileOn, GetLogString, GetLogStringLine, GetLogStringOn, SetLogFileOn, SetLogStringOn + * @par Fortran90 Interface: + * @htmlonly + * + *
+ *  FUNCTION GetLogStringLineCount(ID)
+ *    INTEGER(KIND=4),  INTENT(IN)  :: ID
+ *    INTEGER(KIND=4)               :: GetLogStringLineCount
+ *  END FUNCTION GetLogStringLineCount
+ *  
+ *
+ * @endhtmlonly + * + * @par Fortran90 Example: + * see \ref GetLogStringLine_f90 "GetLogStringLine" + */ + IPQ_DLL_EXPORT int GetLogStringLineCount(int id); + + +/** + * Retrieves the current value of the log string switch. + * @param id The instance id returned from \ref CreateIPhreeqc. + * @return Non-zero if output is stored, 0 (zero) otherwise. + * @see GetLogFileOn, GetLogString, GetLogStringLine, GetLogStringLineCount, SetLogFileOn, SetLogStringOn + * @par Fortran90 Interface: + * @htmlonly + * + *
+ *  FUNCTION GetLogStringOn(ID)
+ *    INTEGER(KIND=4),  INTENT(IN)  :: ID
+ *    LOGICAL(KIND=4)               :: GetLogStringOn
+ *  END FUNCTION GetLogStringOn
+ *  
+ *
+ * @endhtmlonly + */ + IPQ_DLL_EXPORT int GetLogStringOn(int id); + + /** * Retrieves the name of the output file. The default name is phreeqc.id.out. * @param id The instance id returned from \ref CreateIPhreeqc. @@ -1200,6 +1308,27 @@ Headings */ IPQ_DLL_EXPORT IPQ_RESULT SetErrorFileOn(int id, int error_on); +/** + * Sets the name of the log file. The default value is phreeqc.id.log. + * @param id The instance id returned from \ref CreateIPhreeqc. + * @param filename The name of the log file. + * @retval IPQ_OK Success. + * @retval IPQ_BADINSTANCE The given id is invalid. + * @see GetLogFileName, GetLogFileOn, GetLogString, GetLogStringOn, GetLogStringLine, GetLogStringLineCount, SetLogFileOn, SetLogStringOn + * @par Fortran90 Interface: + * @htmlonly + * + *
+ *  FUNCTION SetLogFileName(ID,FILENAME)
+ *    INTEGER(KIND=4),   INTENT(IN)   :: ID
+ *    CHARACTER(LEN=*),  INTENT(OUT)  :: FILENAME
+ *    INTEGER(KIND=4)                 :: SetLogFileName
+ *  END FUNCTION SetLogFileName
+ *  
+ *
+ * @endhtmlonly + */ + IPQ_DLL_EXPORT IPQ_RESULT SetLogFileName(int id, const char* filename); /** * Sets the log file switch on or off. This switch controls whether or not phreeqc @@ -1227,6 +1356,38 @@ Headings */ IPQ_DLL_EXPORT IPQ_RESULT SetLogFileOn(int id, int log_on); +/** + * Sets the log string switch on or off. This switch controls whether or not the data normally sent + * to the log file are stored in a buffer for retrieval. The initial setting after calling + * \ref CreateIPhreeqc is off. + * @param id The instance id returned from \ref CreateIPhreeqc. + * @param output_string_on If non-zero, captures the log output into a string buffer; + * if zero, log output is not captured to a string buffer. + * @retval IPQ_OK Success. + * @retval IPQ_BADINSTANCE The given id is invalid. + * @see GetLogFileOn, GetLogStringOn, GetLogString, GetLogStringLine, GetLogStringLineCount, SetLogFileOn + * @par Fortran90 Interface: + * @htmlonly + * + *
+ *  FUNCTION SetLogStringOn(ID,LOG_STRING_ON)
+ *    INTEGER(KIND=4),  INTENT(IN)  :: ID
+ *    LOGICAL(KIND=4),  INTENT(IN)  :: LOG_STRING_ON
+ *    INTEGER(KIND=4)               :: SetLogStringOn
+ *  END FUNCTION SetLogStringOn
+ *  
+ *
+ * @endhtmlonly + * + * @par C Example: + * see \ref GetLogString_c "GetLogString" + * + * @par Fortran90 Example: + * see \ref GetLogStringLine_f90 "GetLogStringLine" + */ + IPQ_DLL_EXPORT IPQ_RESULT SetLogStringOn(int id, int log_string_on); + + /** * Sets the name of the output file. This file name is used if not specified within DUMP input. * The default value is phreeqc.id.out. diff --git a/include/IPhreeqc.hpp b/include/IPhreeqc.hpp index d509c00e..4cefa210 100644 --- a/include/IPhreeqc.hpp +++ b/include/IPhreeqc.hpp @@ -205,6 +205,13 @@ public: */ int GetId(void)const; + /** + * Retrieves the name of the log file. The default value is phreeqc.id.log, where id is obtained from \ref GetId. + * @return filename The name of the file to write to. + * @see GetLogFileOn, GetLogString, GetLogStringOn, GetLogStringLine, GetLogStringLineCount, SetLogFileName, SetLogFileOn, SetLogStringOn + */ + const char* GetLogFileName(void)const; + /** * Retrieves the current value of the log file switch. * @retval true Log messages are written to the phreeqc.id.log (where id is obtained from \ref GetId) file. @@ -215,6 +222,41 @@ public: */ bool GetLogFileOn(void)const; + /** + * Retrieves the string buffer containing phreeqc log output. + * @return A null terminated string containing log output. + * @pre + * \ref SetLogStringOn must have been set to true and enabled through the use of the KNOBS -logfile option in order to receive any log messages. + * @see GetLogStringLine, GetLogFileOn, GetLogStringLineCount, GetLogStringOn, SetLogFileOn, SetLogStringOn + */ + const char* GetLogString(void)const; + + /** + * Retrieves the given log line. + * @param n The zero-based index of the line to retrieve. + * @return A null terminated string containing the given line. + * Returns an empty string if n is out of range. + * @pre \ref SetLogStringOn must have been set to true and enabled through the use of the KNOBS -logfile option in order to receive any log messages. + * @see GetLogFileOn, GetLogString, GetLogStringLineCount, GetLogStringOn, SetLogFileOn, SetLogStringOn + */ + const char* GetLogStringLine(int n)const; + + /** + * Retrieves the number of lines in the current log string buffer. + * @return The number of lines. + * @pre \ref SetLogStringOn must have been set to true and enabled through the use of the KNOBS -logfile option in order to receive any log messages. + * @see GetLogFileOn, GetLogString, GetLogStringLine, GetLogStringOn, SetLogFileOn, SetLogStringOn + */ + int GetLogStringLineCount(void)const; + + /** + * Retrieves the current value of the log string switch. + * @retval true Log output is stored. + * @retval false No log output is stored. + * @see GetLogFileOn, GetLogString, GetLogStringLine, GetLogStringLineCount, SetLogFileOn, SetLogStringOn + */ + bool GetLogStringOn(void)const; + /** * Retrieves the name of the output file. The default value is phreeqc.id.out, where id is obtained from \ref GetId. * @return filename The name of the file to write phreeqc output to. @@ -578,6 +620,13 @@ public: */ void SetErrorFileOn(bool bValue); + /** + * Sets the name of the log file. The default value is phreeqc.id.log, where id is obtained from \ref GetId. + * @param filename The name of the file to write log output to. + * @see GetLogFileName, GetLogFileOn, GetLogString, GetLogStringOn, GetLogStringLine, GetLogStringLineCount, SetLogFileOn, SetLogStringOn + */ + void SetLogFileName(const char *filename); + /** * Sets the log file switch on or off. This switch controls whether or not phreeqc * writes log messages to the phreeqc.id.log (where id is obtained from \ref GetId) file. The initial setting is false. @@ -588,6 +637,14 @@ public: */ void SetLogFileOn(bool bValue); + /** + * Sets the log string switch on or off. This switch controls whether or not the data normally sent + * to the log file are stored in a buffer for retrieval. The initial setting is false. + * @param bValue If true, captures log output into a string buffer; if false, log output is not captured to a string buffer. + * @see GetLogFileOn, GetLogString, GetLogStringOn, GetLogStringLine, GetLogStringLineCount, SetLogFileOn + */ + void SetLogStringOn(bool bValue); + /** * Sets the name of the output file. The default value is phreeqc.id.out, where id is obtained from \ref GetId. * @param filename The name of the file to write phreeqc output to. @@ -624,9 +681,10 @@ public: public: // overrides virtual void error_msg(const char *str, bool stop=false); + virtual void log_msg(const char * str); virtual void output_msg(const char *str); - virtual void screen_msg(const char *str); virtual void punch_msg(const char *str); + virtual void screen_msg(const char *str); virtual void warning_msg(const char *str); virtual void fpunchf(const char *name, const char *format, double d); @@ -658,7 +716,8 @@ protected: bool UpdateComponents; bool SelectedOutputOn; bool OutputFileOn; - bool LogOn; + + bool LogFileOn; bool ErrorOn; bool DumpOn; @@ -668,6 +727,11 @@ protected: std::string OutputString; std::vector< std::string > OutputLines; + bool LogStringOn; + std::string LogString; + std::vector< std::string > LogLines; + + #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) diff --git a/src/IPhreeqc.cpp b/src/IPhreeqc.cpp index c8e58fe6..a1fe8ca4 100644 --- a/src/IPhreeqc.cpp +++ b/src/IPhreeqc.cpp @@ -18,17 +18,19 @@ const char DUMP_FILENAME_FORMAT[] = "dump.%d.out"; std::map IPhreeqc::Instances; size_t IPhreeqc::InstancesIndex = 0; + IPhreeqc::IPhreeqc(void) : DatabaseLoaded(false) , ClearAccumulated(false) , UpdateComponents(true) , SelectedOutputOn(false) , OutputFileOn(false) -, LogOn(false) +, LogFileOn(false) , ErrorOn(false) , DumpOn(false) , DumpStringOn(false) , OutputStringOn(false) +, LogStringOn(false) , ErrorReporter(0) , WarningReporter(0) , SelectedOutput(0) @@ -220,9 +222,44 @@ int IPhreeqc::GetId(void)const return (int)this->Index; } +const char* IPhreeqc::GetLogFileName(void)const +{ + return this->LogFileName.c_str(); +} + bool IPhreeqc::GetLogFileOn(void)const { - return this->LogOn; + return this->LogFileOn; +} + +const char* IPhreeqc::GetLogString(void)const +{ + static const char err_msg[] = "GetLogString: LogStringOn not set.\n"; + if (!this->LogStringOn) + { + return err_msg; + } + return this->LogString.c_str(); +} + +const char* IPhreeqc::GetLogStringLine(int n)const +{ + static const char empty[] = ""; + if (n < 0 || n >= this->GetLogStringLineCount()) + { + return empty; + } + return this->LogLines[n].c_str(); +} + +int IPhreeqc::GetLogStringLineCount(void)const +{ + return (int)this->LogLines.size(); +} + +bool IPhreeqc::GetLogStringOn(void)const +{ + return this->LogStringOn; } const char* IPhreeqc::GetOutputFileName(void)const @@ -351,6 +388,8 @@ int IPhreeqc::LoadDatabase(const char* filename) { bool bSaveOutputOn = this->OutputFileOn; this->OutputFileOn = false; + bool bSaveLogFileOn = this->LogFileOn; + this->LogFileOn = false; try { // cleanup @@ -394,6 +433,7 @@ int IPhreeqc::LoadDatabase(const char* filename) this->PhreeqcPtr->phrq_io->clear_istream(); this->DatabaseLoaded = (this->PhreeqcPtr->get_input_errors() == 0); this->OutputFileOn = bSaveOutputOn; + this->LogFileOn = bSaveLogFileOn; return this->PhreeqcPtr->get_input_errors(); } @@ -613,9 +653,22 @@ void IPhreeqc::SetErrorFileOn(bool bValue) this->ErrorOn = bValue; } +void IPhreeqc::SetLogFileName(const char *filename) +{ + if (filename && ::strlen(filename)) + { + this->LogFileName = filename; + } +} + void IPhreeqc::SetLogFileOn(bool bValue) { - this->LogOn = bValue; + this->LogFileOn = bValue; +} + +void IPhreeqc::SetLogStringOn(bool bValue) +{ + this->LogStringOn = bValue; } void IPhreeqc::SetOutputFileName(const char *filename) @@ -720,6 +773,8 @@ void IPhreeqc::do_run(const char* sz_routine, std::istream* pis, PFN_PRERUN_CALL } // release + this->LogString.clear(); + this->LogLines.clear(); this->OutputString.clear(); this->OutputLines.clear(); @@ -752,6 +807,9 @@ void IPhreeqc::do_run(const char* sz_routine, std::istream* pis, PFN_PRERUN_CALL int save_punch_in = this->PhreeqcPtr->punch.in; + //{{ + //}} + this->PhreeqcPtr->dup_print(token, TRUE); if (this->PhreeqcPtr->read_input() == EOF) break; @@ -996,6 +1054,19 @@ void IPhreeqc::do_run(const char* sz_routine, std::istream* pis, PFN_PRERUN_CALL this->update_errors(); // update lines + // + + if (this->LogStringOn) + { + // output lines + std::istringstream iss(this->LogString); + std::string line; + while (std::getline(iss, line)) + { + this->LogLines.push_back(line); + } + } + if (this->OutputStringOn) { // output lines @@ -1035,6 +1106,16 @@ void IPhreeqc::update_errors(void) } } +void IPhreeqc::log_msg(const char * str) +{ + if (this->LogStringOn && this->log_on) + { + this->LogString += str; + } + ASSERT(!(this->LogFileOn ^ (this->log_ostream != 0))); + this->PHRQ_io::log_msg(str); +} + void IPhreeqc::error_msg(const char *str, bool stop) { ASSERT(!(this->ErrorOn ^ (this->error_ostream != 0))); @@ -1112,7 +1193,7 @@ void IPhreeqc::open_output_files(const char* sz_routine) this->warning_msg(oss.str().c_str()); } } - if (this->LogOn) + if (this->LogFileOn) { if (this->log_ostream != NULL) { diff --git a/src/IPhreeqcF.f b/src/IPhreeqcF.f index c3e9b3cf..bf07e187 100644 --- a/src/IPhreeqcF.f +++ b/src/IPhreeqcF.f @@ -149,6 +149,13 @@ INTEGER(KIND=4) :: GetErrorStringLineCountF GetErrorStringLineCount = GetErrorStringLineCountF(ID) END FUNCTION GetErrorStringLineCount +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + SUBROUTINE GetLogFileName(ID,FNAME) + IMPLICIT NONE + INTEGER(KIND=4) :: ID + CHARACTER(LEN=*) :: FNAME + CALL GetLogFileNameF(ID,FNAME) + END SUBROUTINE GetLogFileName !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! FUNCTION GetLogFileOn(ID) IMPLICIT NONE @@ -161,6 +168,38 @@ GetLogFileOn = .TRUE. ENDIF END FUNCTION GetLogFileOn +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +! GetLogString +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + FUNCTION GetLogStringLine(ID,N,LINE) + IMPLICIT NONE + INTEGER(KIND=4) :: ID + INTEGER(KIND=4) :: N + CHARACTER(LEN=*) :: LINE + INTEGER(KIND=4) :: GetLogStringLine + INTEGER(KIND=4) :: GetLogStringLineF + GetLogStringLine = GetLogStringLineF(ID,N,LINE) + END FUNCTION GetLogStringLine +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + FUNCTION GetLogStringLineCount(ID) + IMPLICIT NONE + INTEGER(KIND=4) :: ID + INTEGER(KIND=4) :: GetLogStringLineCount + INTEGER(KIND=4) :: GetLogStringLineCountF + GetLogStringLineCount = GetLogStringLineCountF(ID) + END FUNCTION GetLogStringLineCount +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + FUNCTION GetLogStringOn(ID) + IMPLICIT NONE + INTEGER(KIND=4) :: ID + LOGICAL(KIND=4) :: GetLogStringOn + INTEGER(KIND=4) :: GetLogStringOnF + IF (GetLogStringOnF(ID).EQ.0) THEN + GetLogStringOn = .FALSE. + ELSE + GetLogStringOn = .TRUE. + ENDIF + END FUNCTION GetLogStringOn !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! SUBROUTINE GetOutputFileName(ID,FNAME) IMPLICIT NONE @@ -372,6 +411,15 @@ INTEGER(KIND=4) :: SetErrorFileOnF SetErrorFileOn = SetErrorFileOnF(ID,ERROR_ON) END FUNCTION SetErrorFileOn +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + FUNCTION SetLogFileName(ID,FNAME) + IMPLICIT NONE + INTEGER(KIND=4) :: ID + CHARACTER(LEN=*) :: FNAME + INTEGER(KIND=4) :: SetLogFileName + INTEGER(KIND=4) :: SetLogFileNameF + SetLogFileName = SetLogFileNameF(ID,FNAME) + END FUNCTION SetLogFileName !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! FUNCTION SetLogFileOn(ID,LOG_ON) IMPLICIT NONE @@ -381,6 +429,15 @@ INTEGER(KIND=4) :: SetLogFileOnF SetLogFileOn = SetLogFileOnF(ID,LOG_ON) END FUNCTION SetLogFileOn +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + FUNCTION SetLogStringOn(ID,LOG_STRING_ON) + IMPLICIT NONE + INTEGER(KIND=4) :: ID + LOGICAL(KIND=4) :: LOG_STRING_ON + INTEGER(KIND=4) :: SetLogStringOn + INTEGER(KIND=4) :: SetLogStringOnF + SetLogStringOn = SetLogStringOnF(ID,LOG_STRING_ON) + END FUNCTION SetLogStringOn !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! FUNCTION SetOutputFileName(ID,FNAME) IMPLICIT NONE @@ -417,3 +474,4 @@ INTEGER(KIND=4) :: SetSelOutFileOnF SetSelectedOutputFileOn = SetSelOutFileOnF(ID,SELECTED_ON) END FUNCTION SetSelectedOutputFileOn +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! diff --git a/src/IPhreeqcLib.cpp b/src/IPhreeqcLib.cpp index ecb047f1..9472cbc2 100644 --- a/src/IPhreeqcLib.cpp +++ b/src/IPhreeqcLib.cpp @@ -240,6 +240,18 @@ GetErrorStringLineCount(int id) return IPQ_BADINSTANCE; } +const char* +GetLogFileName(int id) +{ + static const char empty[] = ""; + IPhreeqc* IPhreeqcPtr = IPhreeqcLib::GetInstance(id); + if (IPhreeqcPtr) + { + return IPhreeqcPtr->GetLogFileName(); + } + return empty; +} + int GetLogFileOn(int id) { @@ -258,6 +270,59 @@ GetLogFileOn(int id) return IPQ_BADINSTANCE; } +const char* +GetLogString(int id) +{ + static const char empty[] = ""; + IPhreeqc* IPhreeqcPtr = IPhreeqcLib::GetInstance(id); + if (IPhreeqcPtr) + { + return IPhreeqcPtr->GetLogString(); + } + return empty; +} + +const char* +GetLogStringLine(int id, int n) +{ + static const char err_msg[] = "GetLogStringLine: Invalid instance id.\n"; + IPhreeqc* IPhreeqcPtr = IPhreeqcLib::GetInstance(id); + if (IPhreeqcPtr) + { + return IPhreeqcPtr->GetLogStringLine(n); + } + return err_msg; +} + +int +GetLogStringLineCount(int id) +{ + IPhreeqc* IPhreeqcPtr = IPhreeqcLib::GetInstance(id); + if (IPhreeqcPtr) + { + return IPhreeqcPtr->GetLogStringLineCount(); + } + return 0; +} + +int +GetLogStringOn(int id) +{ + IPhreeqc* IPhreeqcPtr = IPhreeqcLib::GetInstance(id); + if (IPhreeqcPtr) + { + if (IPhreeqcPtr->GetLogStringOn()) + { + return 1; + } + else + { + return 0; + } + } + return IPQ_BADINSTANCE; +} + const char* GetOutputFileName(int id) { @@ -579,6 +644,18 @@ SetErrorFileOn(int id, int value) return IPQ_BADINSTANCE; } +IPQ_RESULT +SetLogFileName(int id, const char* filename) +{ + IPhreeqc* IPhreeqcPtr = IPhreeqcLib::GetInstance(id); + if (IPhreeqcPtr) + { + IPhreeqcPtr->SetLogFileName(filename); + return IPQ_OK; + } + return IPQ_BADINSTANCE; +} + IPQ_RESULT SetLogFileOn(int id, int value) { @@ -591,6 +668,18 @@ SetLogFileOn(int id, int value) return IPQ_BADINSTANCE; } +IPQ_RESULT +SetLogStringOn(int id, int value) +{ + IPhreeqc* IPhreeqcPtr = IPhreeqcLib::GetInstance(id); + if (IPhreeqcPtr) + { + IPhreeqcPtr->SetLogStringOn(value != 0); + return IPQ_OK; + } + return IPQ_BADINSTANCE; +} + IPQ_RESULT SetOutputFileName(int id, const char* filename) { diff --git a/src/fwrap.cpp b/src/fwrap.cpp index fcaa1647..f3d5bf43 100644 --- a/src/fwrap.cpp +++ b/src/fwrap.cpp @@ -176,12 +176,36 @@ GetErrorStringLineF(int *id, int* n, char* line, unsigned int line_length) padfstring(line, ::GetErrorStringLine(*id, (*n) - 1), line_length); } +void +GetLogFileNameF(int *id, char* fname, unsigned int fname_length) +{ + padfstring(fname, ::GetLogFileName(*id), fname_length); +} + int GetLogFileOnF(int *id) { return ::GetLogFileOn(*id); } +int +GetLogStringOnF(int *id) +{ + return ::GetLogStringOn(*id); +} + +int +GetLogStringLineCountF(int *id) +{ + return ::GetLogStringLineCount(*id); +} + +void +GetLogStringLineF(int *id, int* n, char* line, unsigned int line_length) +{ + padfstring(line, ::GetLogStringLine(*id, (*n) - 1), line_length); +} + void GetOutputFileNameF(int *id, char* fname, unsigned int fname_length) { @@ -420,12 +444,35 @@ SetErrorFileOnF(int *id, int* error_on) return ::SetErrorFileOn(*id, *error_on); } +IPQ_RESULT +SetLogFileNameF(int *id, char* fname, unsigned int fname_length) +{ + char* cinput; + + cinput = f2cstring(fname, fname_length); + if (!cinput) + { + ::AddError(*id, "SetLogFileName: Out of memory.\n"); + return IPQ_OUTOFMEMORY; + } + + IPQ_RESULT n = ::SetLogFileName(*id, cinput); + free(cinput); + return n; +} + IPQ_RESULT SetLogFileOnF(int *id, int* log_on) { return ::SetLogFileOn(*id, *log_on); } +IPQ_RESULT +SetLogStringOnF(int *id, int* log_string_on) +{ + return ::SetLogStringOn(*id, *log_string_on); +} + IPQ_RESULT SetOutputFileNameF(int *id, char* fname, unsigned int fname_length) { @@ -536,10 +583,27 @@ IPQ_DLL_EXPORT int __stdcall GETERRORSTRINGLINECOUNT(int *id) { return GetErrorStringLineCountF(id); } +IPQ_DLL_EXPORT void __stdcall GETLOGFILENAME(int *id, char *filename, unsigned int len) +{ + GetLogFileNameF(id, filename, len); +} IPQ_DLL_EXPORT int __stdcall GETLOGFILEON(int *id) { return GetLogFileOnF(id); } +IPQ_DLL_EXPORT int __stdcall GETLOGSTRINGON(int *id) +{ + return GetLogStringOnF(id); +} +// GetLogString +IPQ_DLL_EXPORT void __stdcall GETLOGSTRINGLINE(int *id, int *n, char* line, unsigned int line_length) +{ + GetLogStringLineF(id, n, line, line_length); +} +IPQ_DLL_EXPORT int __stdcall GETLOGSTRINGLINECOUNT(int *id) +{ + return GetLogStringLineCountF(id); +} IPQ_DLL_EXPORT void __stdcall GETOUTPUTFILENAME(int *id, char *filename, unsigned int len) { GetOutputFileNameF(id, filename, len); @@ -634,10 +698,18 @@ IPQ_DLL_EXPORT int __stdcall SETERRORFILEON(int *id, int *error_on) { return SetErrorFileOnF(id, error_on); } +IPQ_DLL_EXPORT int __stdcall SETLOGFILENAME(int *id, char *filename, unsigned int len) +{ + return SetLogFileNameF(id, filename, len); +} IPQ_DLL_EXPORT int __stdcall SETLOGFILEON(int *id, int *log_on) { return SetLogFileOnF(id, log_on); } +IPQ_DLL_EXPORT int __stdcall SETLOGSTRINGON(int *id, int *log_on) +{ + return SetLogStringOnF(id, log_on); +} IPQ_DLL_EXPORT int __stdcall SETOUTPUTFILENAME(int *id, char *filename, unsigned int len) { return SetOutputFileNameF(id, filename, len); diff --git a/src/fwrap.h b/src/fwrap.h index 30a00ad6..fd270829 100644 --- a/src/fwrap.h +++ b/src/fwrap.h @@ -24,7 +24,11 @@ #define GetErrorStringLineCountF FC_FUNC (geterrorstringlinecountf, GETERRORSTRINGLINECOUNTF) #define GetErrorStringLineF FC_FUNC (geterrorstringlinef, GETERRORSTRINGLINEF) #define GetErrorFileOnF FC_FUNC (geterrorfileonf, GETERRORFILEONF) +#define GetLogFileNameF FC_FUNC (getlogfilenamef, GETLOGFILENAMEF) #define GetLogFileOnF FC_FUNC (getlogfileonf, GETLOGFILEONF) +#define GetLogStringLineCountF FC_FUNC (getlogstringlinecountf, GETLOGSTRINGLINECOUNTF) +#define GetLogStringLineF FC_FUNC (getlogstringlinef, GETLOGSTRINGLINEF) +#define GetLogStringOnF FC_FUNC (getlogstringonf, GETLOGSTRINGONF) #define GetOutputFileNameF FC_FUNC (getoutputfilenamef, GETOUTPUTFILENAMEF) #define GetOutputFileOnF FC_FUNC (getoutputfileonf, GETOUTPUTFILEONF) #define GetOutputStringLineF FC_FUNC (getoutputstringlinef, GETOUTPUTSTRINGLINEF) @@ -48,7 +52,9 @@ #define SetDumpFileOnF FC_FUNC (setdumpfileonf, SETDUMPFILEONF) #define SetDumpStringOnF FC_FUNC (setdumpstringonf, SETDUMPSTRINGONF) #define SetErrorFileOnF FC_FUNC (seterrorfileonf, SETERRORFILEONF) +#define SetLogFileNameF FC_FUNC (setlogfilenamef, SETLOGFILENAMEF) #define SetLogFileOnF FC_FUNC (setlogfileonf, SETLOGFILEONF) +#define SetLogStringOnF FC_FUNC (setlogstringonf, SETLOGSTRINGONF) #define SetOutputFileNameF FC_FUNC (setoutputfilenamef, SETOUTPUTFILENAMEF) #define SetOutputFileOnF FC_FUNC (setoutputfileonf, SETOUTPUTFILEONF) #define SetOutputStringOnF FC_FUNC (setoutputstringonf, SETOUTPUTSTRINGONF) @@ -75,7 +81,11 @@ extern "C" { int GetErrorStringLineCountF(int *id); void GetErrorStringLineF(int *id, int* n, char* line, unsigned int line_length); int GetErrorFileOnF(int *id); + void GetLogFileNameF(int *id, char* filename, unsigned int filename_length); int GetLogFileOnF(int *id); + int GetLogStringLineCountF(int *id); + void GetLogStringLineF(int *id, int* n, char* line, unsigned int line_length); + int GetLogStringOnF(int *id); void GetOutputFileNameF(int *id, char* filename, unsigned int filename_length); int GetOutputFileOnF(int *id); int GetOutputStringLineCountF(int *id); @@ -99,7 +109,9 @@ extern "C" { IPQ_RESULT SetDumpFileOnF(int *id, int* dump_on); IPQ_RESULT SetDumpStringOnF(int *id, int* dump_string_on); IPQ_RESULT SetErrorFileOnF(int *id, int* error_on); + IPQ_RESULT SetLogFileNameF(int *id, char* fname, unsigned int fname_length); IPQ_RESULT SetLogFileOnF(int *id, int* log_on); + IPQ_RESULT SetLogStringOnF(int *id, int* log_string_on); IPQ_RESULT SetOutputFileNameF(int *id, char* fname, unsigned int fname_length); IPQ_RESULT SetOutputFileOnF(int *id, int* output_on); IPQ_RESULT SetOutputStringOnF(int *id, int* output_string_on); diff --git a/src/fwrap2.cpp b/src/fwrap2.cpp index 56083441..b6438802 100644 --- a/src/fwrap2.cpp +++ b/src/fwrap2.cpp @@ -76,10 +76,27 @@ IPQ_DLL_EXPORT int GETERRORSTRINGLINECOUNT(int *id) { return GetErrorStringLineCountF(id); } +IPQ_DLL_EXPORT void GETLOGFILENAME(int *id, char *filename, unsigned int len) +{ + GetLogFileNameF(id, filename, len); +} IPQ_DLL_EXPORT int GETLOGFILEON(int *id) { return GetLogFileOnF(id); } +IPQ_DLL_EXPORT int GETLOGSTRINGON(int *id) +{ + return GetLogStringOnF(id); +} +// GetLogString +IPQ_DLL_EXPORT void GETLOGSTRINGLINE(int *id, int *n, char* line, unsigned int line_length) +{ + GetLogStringLineF(id, n, line, line_length); +} +IPQ_DLL_EXPORT int GETLOGSTRINGLINECOUNT(int *id) +{ + return GetLogStringLineCountF(id); +} IPQ_DLL_EXPORT void GETOUTPUTFILENAME(int *id, char *filename, unsigned int len) { GetOutputFileNameF(id, filename, len); @@ -173,10 +190,18 @@ IPQ_DLL_EXPORT int SETERRORFILEON(int *id, int *error_on) { return SetErrorFileOnF(id, error_on); } +IPQ_DLL_EXPORT int SETLOGFILENAME(int *id, char *filename, unsigned int len) +{ + return SetLogFileNameF(id, filename, len); +} IPQ_DLL_EXPORT int SETLOGFILEON(int *id, int *log_on) { return SetLogFileOnF(id, log_on); } +IPQ_DLL_EXPORT int SETLOGSTRINGON(int *id, int *log_on) +{ + return SetLogStringOnF(id, log_on); +} IPQ_DLL_EXPORT int SETOUTPUTFILENAME(int *id, char *filename, unsigned int len) { return SetOutputFileNameF(id, filename, len); diff --git a/src/fwrap3.cpp b/src/fwrap3.cpp index d81b70c4..927fa308 100644 --- a/src/fwrap3.cpp +++ b/src/fwrap3.cpp @@ -76,10 +76,27 @@ IPQ_DLL_EXPORT int geterrorstringlinecount_(int *id) { return GetErrorStringLineCountF(id); } +IPQ_DLL_EXPORT void getlogfilename_(int *id, char *filename, unsigned int len) +{ + GetLogFileNameF(id, filename, len); +} IPQ_DLL_EXPORT int getlogfileon_(int *id) { return GetLogFileOnF(id); } +IPQ_DLL_EXPORT int getlogstringon_(int *id) +{ + return GetLogStringOnF(id); +} +// GetLogString +IPQ_DLL_EXPORT void getlogstringline_(int *id, int *n, char* line, unsigned int line_length) +{ + GetLogStringLineF(id, n, line, line_length); +} +IPQ_DLL_EXPORT int getlogstringlinecount_(int *id) +{ + return GetLogStringLineCountF(id); +} IPQ_DLL_EXPORT void getoutputfilename_(int *id, char *filename, unsigned int len) { GetOutputFileNameF(id, filename, len); @@ -174,10 +191,18 @@ IPQ_DLL_EXPORT int seterrorfileon_(int *id, int *error_on) { return SetErrorFileOnF(id, error_on); } +IPQ_DLL_EXPORT int setlogfilename_(int *id, char *filename, unsigned int len) +{ + return SetLogFileNameF(id, filename, len); +} IPQ_DLL_EXPORT int setlogfileon_(int *id, int *log_on) { return SetLogFileOnF(id, log_on); } +IPQ_DLL_EXPORT int setlogstringon_(int *id, int *log_on) +{ + return SetLogStringOnF(id, log_on); +} IPQ_DLL_EXPORT int setoutputfilename_(int *id, char *filename, unsigned int len) { return SetOutputFileNameF(id, filename, len); diff --git a/unit/TestIPhreeqc.cpp b/unit/TestIPhreeqc.cpp index 085d4e1d..7efff51f 100644 --- a/unit/TestIPhreeqc.cpp +++ b/unit/TestIPhreeqc.cpp @@ -2458,3 +2458,331 @@ void TestIPhreeqc::TestGetOutputStringLine(void) CPPUNIT_ASSERT_EQUAL( std::string(""), std::string(obj.GetOutputStringLine(-3)) ); CPPUNIT_ASSERT_EQUAL( std::string(""), std::string(obj.GetOutputStringLine(-4)) ); } + +void TestIPhreeqc::TestSetLogFileName(void) +{ + char LOG_FILENAME[80]; + sprintf(LOG_FILENAME, "log.%06d.out", ::rand()); + if (::FileExists(LOG_FILENAME)) + { + ::DeleteFile(LOG_FILENAME); + } + + IPhreeqc obj; + + CPPUNIT_ASSERT_EQUAL( 0, obj.LoadDatabase("phreeqc.dat")); + + // add solution block + CPPUNIT_ASSERT_EQUAL( VR_OK, ::SOLUTION(obj, 1.0, 1.0, 1.0) ); + + // add dump block + CPPUNIT_ASSERT_EQUAL( VR_OK, ::DUMP(obj) ); + + // add knobs + CPPUNIT_ASSERT_EQUAL( VR_OK, obj.AccumulateLine("KNOBS") ); + CPPUNIT_ASSERT_EQUAL( VR_OK, obj.AccumulateLine("\t-logfile TRUE") ); + + // run + obj.SetLogFileOn(true); + obj.SetErrorFileOn(false); + obj.SetOutputFileOn(false); + obj.SetSelectedOutputFileOn(false); + obj.SetDumpStringOn(false); + obj.SetDumpFileOn(false); + obj.SetLogFileName(LOG_FILENAME); + + CPPUNIT_ASSERT_EQUAL( 0, obj.RunAccumulated() ); + + CPPUNIT_ASSERT_EQUAL( true, ::FileExists(LOG_FILENAME) ); + + std::string lines[33]; + std::ifstream ifs(LOG_FILENAME); + + size_t i = 0; + while (i < sizeof(lines)/sizeof(lines[0]) && std::getline(ifs, lines[i])) + { + ++i; + } + + CPPUNIT_ASSERT_EQUAL( 25u, i ); + + int line = 0; + CPPUNIT_ASSERT_EQUAL( std::string("-------------------------------------------"), lines[line++] ); + CPPUNIT_ASSERT_EQUAL( std::string("Beginning of initial solution calculations."), lines[line++] ); + CPPUNIT_ASSERT_EQUAL( std::string("-------------------------------------------"), lines[line++] ); + CPPUNIT_ASSERT_EQUAL( std::string(""), lines[line++] ); + CPPUNIT_ASSERT_EQUAL( std::string("Initial solution 1. "), lines[line++] ); + CPPUNIT_ASSERT_EQUAL( std::string(""), lines[line++] ); + CPPUNIT_ASSERT_EQUAL( std::string("Iterations in revise_guesses: 2"), lines[line++] ); + CPPUNIT_ASSERT_EQUAL( std::string(""), lines[line++] ); + CPPUNIT_ASSERT_EQUAL( std::string("Number of infeasible solutions: 0"), lines[line++] ); + CPPUNIT_ASSERT_EQUAL( std::string("Number of basis changes: 0"), lines[line++] ); + CPPUNIT_ASSERT_EQUAL( std::string(""), lines[line++] ); + CPPUNIT_ASSERT_EQUAL( std::string("Number of iterations: 6"), lines[line++] ); + CPPUNIT_ASSERT_EQUAL( std::string(""), lines[line++] ); + CPPUNIT_ASSERT_EQUAL( std::string("------------------"), lines[line++] ); + CPPUNIT_ASSERT_EQUAL( std::string("End of simulation."), lines[line++] ); + CPPUNIT_ASSERT_EQUAL( std::string("------------------"), lines[line++] ); + CPPUNIT_ASSERT_EQUAL( std::string(""), lines[line++] ); + CPPUNIT_ASSERT_EQUAL( std::string("------------------------------------"), lines[line++] ); + CPPUNIT_ASSERT_EQUAL( std::string("Reading input data for simulation 2."), lines[line++] ); + CPPUNIT_ASSERT_EQUAL( std::string("------------------------------------"), lines[line++] ); + CPPUNIT_ASSERT_EQUAL( std::string(""), lines[line++] ); + CPPUNIT_ASSERT_EQUAL( std::string("-----------"), lines[line++] ); + CPPUNIT_ASSERT_EQUAL( std::string("End of run."), lines[line++] ); + CPPUNIT_ASSERT_EQUAL( std::string("-----------"), lines[line++] ); + CPPUNIT_ASSERT_EQUAL( std::string(""), lines[line++] ); + + if (::FileExists(LOG_FILENAME)) + { + ::DeleteFile(LOG_FILENAME); + } +} + +void TestIPhreeqc::TestLogStringOnOff(void) +{ + IPhreeqc obj; + CPPUNIT_ASSERT_EQUAL( false, obj.GetLogStringOn() ); + + obj.SetLogStringOn(true); + CPPUNIT_ASSERT_EQUAL( true, obj.GetLogStringOn() ); + + obj.SetLogStringOn(false); + CPPUNIT_ASSERT_EQUAL( false, obj.GetLogStringOn() ); +} + +void TestIPhreeqc::TestGetLogString(void) +{ + char LOG_FILENAME[80]; + sprintf(LOG_FILENAME, "log.%06d.out", ::rand()); + if (::FileExists(LOG_FILENAME)) + { + ::DeleteFile(LOG_FILENAME); + } + CPPUNIT_ASSERT_EQUAL( false, ::FileExists(LOG_FILENAME) ); + + IPhreeqc obj; + + CPPUNIT_ASSERT_EQUAL( 0, obj.LoadDatabase("phreeqc.dat")); + + // add solution block + CPPUNIT_ASSERT_EQUAL( VR_OK, ::SOLUTION(obj, 1.0, 1.0, 1.0) ); + + // add dump block + CPPUNIT_ASSERT_EQUAL( VR_OK, ::DUMP(obj) ); + + // add knobs + CPPUNIT_ASSERT_EQUAL( VR_OK, obj.AccumulateLine("KNOBS") ); + CPPUNIT_ASSERT_EQUAL( VR_OK, obj.AccumulateLine("\t-logfile TRUE") ); + + // run + obj.SetLogFileOn(true); + obj.SetLogStringOn(true); + + obj.SetDumpFileOn(false); + obj.SetDumpStringOn(false); + obj.SetErrorFileOn(false); + obj.SetOutputFileOn(false); + obj.SetOutputStringOn(false); + obj.SetSelectedOutputFileOn(false); + + obj.SetLogFileName(LOG_FILENAME); + + CPPUNIT_ASSERT_EQUAL( 0, obj.RunAccumulated() ); + + CPPUNIT_ASSERT_EQUAL( true, ::FileExists(LOG_FILENAME) ); + + { + std::ifstream ifs(LOG_FILENAME); + std::string fline((std::istreambuf_iterator(ifs)), std::istreambuf_iterator()); + + std::string sline(obj.GetLogString()); + CPPUNIT_ASSERT( sline.size() > 0 ); + + CPPUNIT_ASSERT_EQUAL( fline, sline ); + } + + if (::FileExists(LOG_FILENAME)) + { + ::DeleteFile(LOG_FILENAME); + } +} + +void TestIPhreeqc::TestGetLogStringLineCount(void) +{ + IPhreeqc obj; + CPPUNIT_ASSERT_EQUAL( 0, obj.GetLogStringLineCount() ); + + CPPUNIT_ASSERT_EQUAL( 0, obj.LoadDatabase("phreeqc.dat")); + + CPPUNIT_ASSERT_EQUAL( 0, obj.GetLogStringLineCount() ); + + // add solution block + CPPUNIT_ASSERT_EQUAL( VR_OK, ::SOLUTION(obj, 1.0, 1.0, 1.0) ); + + // add dump block + CPPUNIT_ASSERT_EQUAL( VR_OK, ::DUMP(obj) ); + + // add knobs + CPPUNIT_ASSERT_EQUAL( VR_OK, obj.AccumulateLine("KNOBS") ); + CPPUNIT_ASSERT_EQUAL( VR_OK, obj.AccumulateLine("\t-logfile TRUE") ); + + // run + obj.SetLogStringOn(false); + obj.SetLogFileOn(false); + obj.SetErrorFileOn(false); + obj.SetOutputFileOn(false); + obj.SetSelectedOutputFileOn(false); + obj.SetDumpStringOn(false); + obj.SetDumpFileOn(false); + + CPPUNIT_ASSERT_EQUAL( 0, obj.RunAccumulated() ); + CPPUNIT_ASSERT_EQUAL( 0, obj.GetLogStringLineCount() ); + + // add solution block + CPPUNIT_ASSERT_EQUAL( VR_OK, ::SOLUTION(obj, 1.0, 1.0, 1.0) ); + + // add dump block + CPPUNIT_ASSERT_EQUAL( VR_OK, ::DUMP(obj) ); + + // add knobs + CPPUNIT_ASSERT_EQUAL( VR_OK, obj.AccumulateLine("KNOBS") ); + CPPUNIT_ASSERT_EQUAL( VR_OK, obj.AccumulateLine("\t-logfile TRUE") ); + + obj.SetLogStringOn(true); + + CPPUNIT_ASSERT_EQUAL( 0, obj.RunAccumulated() ); + CPPUNIT_ASSERT_EQUAL( 29, obj.GetLogStringLineCount() ); + + // add solution block + CPPUNIT_ASSERT_EQUAL( VR_OK, ::SOLUTION(obj, 1.0, 1.0, 1.0) ); + + // add dump block + CPPUNIT_ASSERT_EQUAL( VR_OK, ::DUMP(obj) ); + + // add knobs + CPPUNIT_ASSERT_EQUAL( VR_OK, obj.AccumulateLine("KNOBS") ); + CPPUNIT_ASSERT_EQUAL( VR_OK, obj.AccumulateLine("\t-logfile TRUE") ); + + obj.SetLogStringOn(false); + + CPPUNIT_ASSERT_EQUAL( 0, obj.RunAccumulated() ); + CPPUNIT_ASSERT_EQUAL( 0, obj.GetLogStringLineCount() ); +} + +void TestIPhreeqc::TestGetLogStringLine(void) +{ + IPhreeqc obj; + CPPUNIT_ASSERT_EQUAL( 0, obj.GetLogStringLineCount() ); + + CPPUNIT_ASSERT_EQUAL( 0, obj.LoadDatabase("phreeqc.dat")); + + CPPUNIT_ASSERT_EQUAL( 0, obj.GetLogStringLineCount() ); + + // add solution block + CPPUNIT_ASSERT_EQUAL( VR_OK, ::SOLUTION(obj, 1.0, 1.0, 1.0) ); + + // add dump block + CPPUNIT_ASSERT_EQUAL( VR_OK, ::DUMP(obj) ); + + // add knobs + CPPUNIT_ASSERT_EQUAL( VR_OK, obj.AccumulateLine("KNOBS") ); + CPPUNIT_ASSERT_EQUAL( VR_OK, obj.AccumulateLine("\t-logfile TRUE") ); + + // run + obj.SetOutputStringOn(false); + obj.SetOutputFileOn(false); + obj.SetErrorFileOn(false); + obj.SetLogFileOn(false); + obj.SetSelectedOutputFileOn(false); + obj.SetDumpStringOn(false); + obj.SetDumpFileOn(false); + + CPPUNIT_ASSERT_EQUAL( 0, obj.RunAccumulated() ); + CPPUNIT_ASSERT_EQUAL( 0, obj.GetLogStringLineCount() ); + + int line = 0; + CPPUNIT_ASSERT_EQUAL( std::string(""), std::string(obj.GetLogStringLine(line++)) ); + CPPUNIT_ASSERT_EQUAL( std::string(""), std::string(obj.GetLogStringLine(line++)) ); + CPPUNIT_ASSERT_EQUAL( std::string(""), std::string(obj.GetLogStringLine(line++)) ); + CPPUNIT_ASSERT_EQUAL( std::string(""), std::string(obj.GetLogStringLine(line++)) ); + + // negative lines should be empty + CPPUNIT_ASSERT_EQUAL( std::string(""), std::string(obj.GetLogStringLine(-1)) ); + CPPUNIT_ASSERT_EQUAL( std::string(""), std::string(obj.GetLogStringLine(-2)) ); + CPPUNIT_ASSERT_EQUAL( std::string(""), std::string(obj.GetLogStringLine(-3)) ); + CPPUNIT_ASSERT_EQUAL( std::string(""), std::string(obj.GetLogStringLine(-4)) ); + + // add solution block + CPPUNIT_ASSERT_EQUAL( VR_OK, ::SOLUTION(obj, 1.0, 1.0, 1.0) ); + + // add dump block + CPPUNIT_ASSERT_EQUAL( VR_OK, ::DUMP(obj) ); + + // add knobs + CPPUNIT_ASSERT_EQUAL( VR_OK, obj.AccumulateLine("KNOBS") ); + CPPUNIT_ASSERT_EQUAL( VR_OK, obj.AccumulateLine("\t-logfile TRUE") ); + + obj.SetLogStringOn(true); + + CPPUNIT_ASSERT_EQUAL( 0, obj.RunAccumulated() ); + CPPUNIT_ASSERT_EQUAL( 29, obj.GetLogStringLineCount() ); + + line = 0; + CPPUNIT_ASSERT_EQUAL( std::string("------------------------------------"), std::string(obj.GetLogStringLine(line++)) ); + CPPUNIT_ASSERT_EQUAL( std::string("Reading input data for simulation 1."), std::string(obj.GetLogStringLine(line++)) ); + CPPUNIT_ASSERT_EQUAL( std::string("------------------------------------"), std::string(obj.GetLogStringLine(line++)) ); + CPPUNIT_ASSERT_EQUAL( std::string(""), std::string(obj.GetLogStringLine(line++)) ); + CPPUNIT_ASSERT_EQUAL( std::string("-------------------------------------------"), std::string(obj.GetLogStringLine(line++)) ); + CPPUNIT_ASSERT_EQUAL( std::string("Beginning of initial solution calculations."), std::string(obj.GetLogStringLine(line++)) ); + CPPUNIT_ASSERT_EQUAL( std::string("-------------------------------------------"), std::string(obj.GetLogStringLine(line++)) ); + CPPUNIT_ASSERT_EQUAL( std::string(""), std::string(obj.GetLogStringLine(line++)) ); + CPPUNIT_ASSERT_EQUAL( std::string("Initial solution 1. "), std::string(obj.GetLogStringLine(line++)) ); + CPPUNIT_ASSERT_EQUAL( std::string(""), std::string(obj.GetLogStringLine(line++)) ); + CPPUNIT_ASSERT_EQUAL( std::string("Iterations in revise_guesses: 2"), std::string(obj.GetLogStringLine(line++)) ); + CPPUNIT_ASSERT_EQUAL( std::string(""), std::string(obj.GetLogStringLine(line++)) ); + CPPUNIT_ASSERT_EQUAL( std::string("Number of infeasible solutions: 0"), std::string(obj.GetLogStringLine(line++)) ); + CPPUNIT_ASSERT_EQUAL( std::string("Number of basis changes: 0"), std::string(obj.GetLogStringLine(line++)) ); + CPPUNIT_ASSERT_EQUAL( std::string(""), std::string(obj.GetLogStringLine(line++)) ); + CPPUNIT_ASSERT_EQUAL( std::string("Number of iterations: 6"), std::string(obj.GetLogStringLine(line++)) ); + CPPUNIT_ASSERT_EQUAL( std::string(""), std::string(obj.GetLogStringLine(line++)) ); + CPPUNIT_ASSERT_EQUAL( std::string("------------------"), std::string(obj.GetLogStringLine(line++)) ); + CPPUNIT_ASSERT_EQUAL( std::string("End of simulation."), std::string(obj.GetLogStringLine(line++)) ); + CPPUNIT_ASSERT_EQUAL( std::string("------------------"), std::string(obj.GetLogStringLine(line++)) ); + CPPUNIT_ASSERT_EQUAL( std::string(""), std::string(obj.GetLogStringLine(line++)) ); + CPPUNIT_ASSERT_EQUAL( std::string("------------------------------------"), std::string(obj.GetLogStringLine(line++)) ); + CPPUNIT_ASSERT_EQUAL( std::string("Reading input data for simulation 2."), std::string(obj.GetLogStringLine(line++)) ); + CPPUNIT_ASSERT_EQUAL( std::string("------------------------------------"), std::string(obj.GetLogStringLine(line++)) ); + CPPUNIT_ASSERT_EQUAL( std::string(""), std::string(obj.GetLogStringLine(line++)) ); + CPPUNIT_ASSERT_EQUAL( std::string("-----------"), std::string(obj.GetLogStringLine(line++)) ); + CPPUNIT_ASSERT_EQUAL( std::string("End of run."), std::string(obj.GetLogStringLine(line++)) ); + CPPUNIT_ASSERT_EQUAL( std::string("-----------"), std::string(obj.GetLogStringLine(line++)) ); + CPPUNIT_ASSERT_EQUAL( std::string(""), std::string(obj.GetLogStringLine(line++)) ); + + // add solution block + CPPUNIT_ASSERT_EQUAL( VR_OK, ::SOLUTION(obj, 1.0, 1.0, 1.0) ); + + // add dump block + CPPUNIT_ASSERT_EQUAL( VR_OK, ::DUMP(obj) ); + + // add knobs + CPPUNIT_ASSERT_EQUAL( VR_OK, obj.AccumulateLine("KNOBS") ); + CPPUNIT_ASSERT_EQUAL( VR_OK, obj.AccumulateLine("\t-logfile TRUE") ); + + obj.SetLogStringOn(false); + + CPPUNIT_ASSERT_EQUAL( 0, obj.RunAccumulated() ); + CPPUNIT_ASSERT_EQUAL( 0, obj.GetLogStringLineCount() ); + + line = 0; + CPPUNIT_ASSERT_EQUAL( std::string(""), std::string(obj.GetLogStringLine(line++)) ); + CPPUNIT_ASSERT_EQUAL( std::string(""), std::string(obj.GetLogStringLine(line++)) ); + CPPUNIT_ASSERT_EQUAL( std::string(""), std::string(obj.GetLogStringLine(line++)) ); + CPPUNIT_ASSERT_EQUAL( std::string(""), std::string(obj.GetLogStringLine(line++)) ); + + // negative lines should be empty + CPPUNIT_ASSERT_EQUAL( std::string(""), std::string(obj.GetLogStringLine(-1)) ); + CPPUNIT_ASSERT_EQUAL( std::string(""), std::string(obj.GetLogStringLine(-2)) ); + CPPUNIT_ASSERT_EQUAL( std::string(""), std::string(obj.GetLogStringLine(-3)) ); + CPPUNIT_ASSERT_EQUAL( std::string(""), std::string(obj.GetLogStringLine(-4)) ); +} diff --git a/unit/TestIPhreeqc.h b/unit/TestIPhreeqc.h index c562c45a..44d0e69d 100644 --- a/unit/TestIPhreeqc.h +++ b/unit/TestIPhreeqc.h @@ -45,7 +45,11 @@ class TestIPhreeqc : public CppUnit::TestFixture CPPUNIT_TEST( TestGetOutputString ); CPPUNIT_TEST( TestGetOutputStringLineCount ); CPPUNIT_TEST( TestGetOutputStringLine ); - + CPPUNIT_TEST( TestSetLogFileName ); + CPPUNIT_TEST( TestLogStringOnOff ); + CPPUNIT_TEST( TestGetLogString ); + CPPUNIT_TEST( TestGetLogStringLineCount ); + CPPUNIT_TEST( TestGetLogStringLine ); CPPUNIT_TEST_SUITE_END(); public: @@ -90,7 +94,12 @@ public: void TestOutputStringOnOff(void); void TestGetOutputString(void); void TestGetOutputStringLineCount(void); - void TestGetOutputStringLine(void); + void TestGetOutputStringLine(void); + void TestSetLogFileName(void); + void TestLogStringOnOff(void); + void TestGetLogString(void); + void TestGetLogStringLineCount(void); + void TestGetLogStringLine(void); protected: void TestFileOnOff(const char* FILENAME, bool output_file_on, bool error_file_on, bool log_file_on, bool selected_output_file_on, bool dump_file_on); diff --git a/unit/TestIPhreeqcLib.cpp b/unit/TestIPhreeqcLib.cpp index 5f0e19e3..625ae068 100644 --- a/unit/TestIPhreeqcLib.cpp +++ b/unit/TestIPhreeqcLib.cpp @@ -2919,3 +2919,348 @@ void TestIPhreeqcLib::TestGetOutputStringLine(void) CPPUNIT_ASSERT_EQUAL(IPQ_OK, ::DestroyIPhreeqc(n)); } } + +void TestIPhreeqcLib::TestSetLogFileName(void) +{ + char LOG_FILENAME[80]; + sprintf(LOG_FILENAME, "log.%06d.out", ::rand()); + if (::FileExists(LOG_FILENAME)) + { + ::DeleteFile(LOG_FILENAME); + } + + int n = ::CreateIPhreeqc(); + CPPUNIT_ASSERT(n >= 0); + + CPPUNIT_ASSERT_EQUAL( 0, ::LoadDatabase(n, "phreeqc.dat")); + + // add solution block + CPPUNIT_ASSERT_EQUAL( IPQ_OK, ::SOLUTION(n, 1.0, 1.0, 1.0) ); + + // add dump block + CPPUNIT_ASSERT_EQUAL( IPQ_OK, ::DUMP(n) ); + + // add knobs + CPPUNIT_ASSERT_EQUAL( IPQ_OK, ::AccumulateLine(n, "KNOBS") ); + CPPUNIT_ASSERT_EQUAL( IPQ_OK, ::AccumulateLine(n, "\t-logfile TRUE") ); + + // run + CPPUNIT_ASSERT_EQUAL( IPQ_OK, ::SetLogFileOn(n, 1) ); + CPPUNIT_ASSERT_EQUAL( IPQ_OK, ::SetErrorFileOn(n, 0) ); + CPPUNIT_ASSERT_EQUAL( IPQ_OK, ::SetOutputFileOn(n, 0) ); + CPPUNIT_ASSERT_EQUAL( IPQ_OK, ::SetSelectedOutputFileOn(n, 0) ); + CPPUNIT_ASSERT_EQUAL( IPQ_OK, ::SetDumpStringOn(n, 0) ); + CPPUNIT_ASSERT_EQUAL( IPQ_OK, ::SetDumpFileOn(n, 0) ); + CPPUNIT_ASSERT_EQUAL( IPQ_OK, ::SetLogFileName(n, LOG_FILENAME) ); + + + CPPUNIT_ASSERT_EQUAL( 0, ::RunAccumulated(n) ); + + CPPUNIT_ASSERT_EQUAL( true, ::FileExists(LOG_FILENAME) ); + + std::string lines[33]; + std::ifstream ifs(LOG_FILENAME); + + size_t i = 0; + while (i < sizeof(lines)/sizeof(lines[0]) && std::getline(ifs, lines[i])) + { + ++i; + } + + CPPUNIT_ASSERT_EQUAL( 25u, i ); + + int line = 0; + CPPUNIT_ASSERT_EQUAL( std::string("-------------------------------------------"), lines[line++] ); + CPPUNIT_ASSERT_EQUAL( std::string("Beginning of initial solution calculations."), lines[line++] ); + CPPUNIT_ASSERT_EQUAL( std::string("-------------------------------------------"), lines[line++] ); + CPPUNIT_ASSERT_EQUAL( std::string(""), lines[line++] ); + CPPUNIT_ASSERT_EQUAL( std::string("Initial solution 1. "), lines[line++] ); + CPPUNIT_ASSERT_EQUAL( std::string(""), lines[line++] ); + CPPUNIT_ASSERT_EQUAL( std::string("Iterations in revise_guesses: 2"), lines[line++] ); + CPPUNIT_ASSERT_EQUAL( std::string(""), lines[line++] ); + CPPUNIT_ASSERT_EQUAL( std::string("Number of infeasible solutions: 0"), lines[line++] ); + CPPUNIT_ASSERT_EQUAL( std::string("Number of basis changes: 0"), lines[line++] ); + CPPUNIT_ASSERT_EQUAL( std::string(""), lines[line++] ); + CPPUNIT_ASSERT_EQUAL( std::string("Number of iterations: 6"), lines[line++] ); + CPPUNIT_ASSERT_EQUAL( std::string(""), lines[line++] ); + CPPUNIT_ASSERT_EQUAL( std::string("------------------"), lines[line++] ); + CPPUNIT_ASSERT_EQUAL( std::string("End of simulation."), lines[line++] ); + CPPUNIT_ASSERT_EQUAL( std::string("------------------"), lines[line++] ); + CPPUNIT_ASSERT_EQUAL( std::string(""), lines[line++] ); + CPPUNIT_ASSERT_EQUAL( std::string("------------------------------------"), lines[line++] ); + CPPUNIT_ASSERT_EQUAL( std::string("Reading input data for simulation 2."), lines[line++] ); + CPPUNIT_ASSERT_EQUAL( std::string("------------------------------------"), lines[line++] ); + CPPUNIT_ASSERT_EQUAL( std::string(""), lines[line++] ); + CPPUNIT_ASSERT_EQUAL( std::string("-----------"), lines[line++] ); + CPPUNIT_ASSERT_EQUAL( std::string("End of run."), lines[line++] ); + CPPUNIT_ASSERT_EQUAL( std::string("-----------"), lines[line++] ); + CPPUNIT_ASSERT_EQUAL( std::string(""), lines[line++] ); + + if (::FileExists(LOG_FILENAME)) + { + ::DeleteFile(LOG_FILENAME); + } +} + +void TestIPhreeqcLib::TestLogStringOnOff(void) +{ + int n = ::CreateIPhreeqc(); + CPPUNIT_ASSERT(n >= 0); + + CPPUNIT_ASSERT_EQUAL( false, ::GetLogStringOn(n) != 0 ); + + CPPUNIT_ASSERT_EQUAL( IPQ_OK, ::SetLogStringOn(n, 1) ); + CPPUNIT_ASSERT_EQUAL( true, ::GetLogStringOn(n) != 0 ); + + CPPUNIT_ASSERT_EQUAL( IPQ_OK, ::SetLogStringOn(n, 0) ); + CPPUNIT_ASSERT_EQUAL( false, ::GetLogStringOn(n) != 0 ); + +} + +void TestIPhreeqcLib::TestGetLogString(void) +{ + char LOG_FILENAME[80]; + sprintf(LOG_FILENAME, "log.%06d.out", ::rand()); + if (::FileExists(LOG_FILENAME)) + { + ::DeleteFile(LOG_FILENAME); + } + CPPUNIT_ASSERT_EQUAL( false, ::FileExists(LOG_FILENAME) ); + + int n = ::CreateIPhreeqc(); + CPPUNIT_ASSERT(n >= 0); + + CPPUNIT_ASSERT_EQUAL( 0, ::LoadDatabase(n, "phreeqc.dat")); + + // add solution block + CPPUNIT_ASSERT_EQUAL( IPQ_OK, ::SOLUTION(n, 1.0, 1.0, 1.0) ); + + // add dump block + CPPUNIT_ASSERT_EQUAL( IPQ_OK, ::DUMP(n) ); + + // add knobs + CPPUNIT_ASSERT_EQUAL( IPQ_OK, ::AccumulateLine(n, "KNOBS") ); + CPPUNIT_ASSERT_EQUAL( IPQ_OK, ::AccumulateLine(n, "\t-logfile TRUE") ); + + + // run + CPPUNIT_ASSERT_EQUAL( IPQ_OK, ::SetLogFileOn(n, 1) ); + CPPUNIT_ASSERT_EQUAL( IPQ_OK, ::SetLogStringOn(n, 1) ); + + CPPUNIT_ASSERT_EQUAL( IPQ_OK, ::SetDumpFileOn(n, 0) ); + CPPUNIT_ASSERT_EQUAL( IPQ_OK, ::SetDumpStringOn(n, 0) ); + CPPUNIT_ASSERT_EQUAL( IPQ_OK, ::SetErrorFileOn(n, 0) ); + CPPUNIT_ASSERT_EQUAL( IPQ_OK, ::SetOutputFileOn(n, 0) ); + CPPUNIT_ASSERT_EQUAL( IPQ_OK, ::SetOutputStringOn(n, 0) ); + CPPUNIT_ASSERT_EQUAL( IPQ_OK, ::SetSelectedOutputFileOn(n, 0) ); + + CPPUNIT_ASSERT_EQUAL( IPQ_OK, ::SetLogFileName(n, LOG_FILENAME) ); + CPPUNIT_ASSERT_EQUAL( std::string(LOG_FILENAME), std::string(::GetLogFileName(n)) ); + + CPPUNIT_ASSERT_EQUAL( 0, ::RunAccumulated(n) ); + + CPPUNIT_ASSERT_EQUAL( std::string(LOG_FILENAME), std::string(::GetLogFileName(n)) ); + + CPPUNIT_ASSERT_EQUAL( true, ::FileExists(LOG_FILENAME) ); + + { + std::ifstream ifs(LOG_FILENAME); + std::string fline((std::istreambuf_iterator(ifs)), std::istreambuf_iterator()); + + std::string sline(::GetLogString(n)); + CPPUNIT_ASSERT( sline.size() > 0 ); + + CPPUNIT_ASSERT_EQUAL( fline, sline ); + } + + if (::FileExists(LOG_FILENAME)) + { + ::DeleteFile(LOG_FILENAME); + } +} + +void TestIPhreeqcLib::TestGetLogStringLineCount(void) +{ + int n = ::CreateIPhreeqc(); + CPPUNIT_ASSERT(n >= 0); + + CPPUNIT_ASSERT_EQUAL( 0, ::GetLogStringLineCount(n)); + + CPPUNIT_ASSERT_EQUAL( 0, ::LoadDatabase(n, "phreeqc.dat")); + + CPPUNIT_ASSERT_EQUAL( 0, ::GetLogStringLineCount(n)); + + // add solution block + CPPUNIT_ASSERT_EQUAL( IPQ_OK, ::SOLUTION(n, 1.0, 1.0, 1.0) ); + + // add dump block + CPPUNIT_ASSERT_EQUAL( IPQ_OK, ::DUMP(n) ); + + // add knobs + CPPUNIT_ASSERT_EQUAL( IPQ_OK, ::AccumulateLine(n, "KNOBS") ); + CPPUNIT_ASSERT_EQUAL( IPQ_OK, ::AccumulateLine(n, "\t-logfile TRUE") ); + + // run + CPPUNIT_ASSERT_EQUAL( IPQ_OK, ::SetLogStringOn(n, 0) ); + CPPUNIT_ASSERT_EQUAL( IPQ_OK, ::SetLogFileOn(n, 0) ); + CPPUNIT_ASSERT_EQUAL( IPQ_OK, ::SetErrorFileOn(n, 0) ); + CPPUNIT_ASSERT_EQUAL( IPQ_OK, ::SetOutputFileOn(n, 0) ); + CPPUNIT_ASSERT_EQUAL( IPQ_OK, ::SetOutputStringOn(n, 0) ); + CPPUNIT_ASSERT_EQUAL( IPQ_OK, ::SetSelectedOutputFileOn(n, 0) ); + CPPUNIT_ASSERT_EQUAL( IPQ_OK, ::SetDumpStringOn(n, 0) ); + CPPUNIT_ASSERT_EQUAL( IPQ_OK, ::SetDumpFileOn(n, 0) ); + + CPPUNIT_ASSERT_EQUAL( 0, ::RunAccumulated(n) ); + CPPUNIT_ASSERT_EQUAL( 0, ::GetLogStringLineCount(n) ); + + // add solution block + CPPUNIT_ASSERT_EQUAL( IPQ_OK, ::SOLUTION(n, 1.0, 1.0, 1.0) ); + + // add dump block + CPPUNIT_ASSERT_EQUAL( IPQ_OK, ::DUMP(n) ); + + // add knobs + CPPUNIT_ASSERT_EQUAL( IPQ_OK, ::AccumulateLine(n, "KNOBS") ); + CPPUNIT_ASSERT_EQUAL( IPQ_OK, ::AccumulateLine(n, "\t-logfile TRUE") ); + + CPPUNIT_ASSERT_EQUAL( IPQ_OK, ::SetLogStringOn(n, 1) ); + + CPPUNIT_ASSERT_EQUAL( 0, ::RunAccumulated(n) ); + CPPUNIT_ASSERT_EQUAL( 29, ::GetLogStringLineCount(n) ); + + // add solution block + CPPUNIT_ASSERT_EQUAL( IPQ_OK, ::SOLUTION(n, 1.0, 1.0, 1.0) ); + + // add dump block + CPPUNIT_ASSERT_EQUAL( IPQ_OK, ::DUMP(n) ); + + // add knobs + CPPUNIT_ASSERT_EQUAL( IPQ_OK, ::AccumulateLine(n, "KNOBS") ); + CPPUNIT_ASSERT_EQUAL( IPQ_OK, ::AccumulateLine(n, "\t-logfile TRUE") ); + + CPPUNIT_ASSERT_EQUAL( IPQ_OK, ::SetLogStringOn(n, 0) ); + + CPPUNIT_ASSERT_EQUAL( 0, ::RunAccumulated(n) ); + CPPUNIT_ASSERT_EQUAL( 0, ::GetLogStringLineCount(n) ); +} + +void TestIPhreeqcLib::TestGetLogStringLine(void) +{ + int n = ::CreateIPhreeqc(); + CPPUNIT_ASSERT(n >= 0); + CPPUNIT_ASSERT_EQUAL( 0, ::GetLogStringLineCount(n)); + + CPPUNIT_ASSERT_EQUAL( 0, ::LoadDatabase(n, "phreeqc.dat")); + + CPPUNIT_ASSERT_EQUAL( 0, ::GetLogStringLineCount(n)); + + // add solution block + CPPUNIT_ASSERT_EQUAL( IPQ_OK, ::SOLUTION(n, 1.0, 1.0, 1.0) ); + + // add dump block + CPPUNIT_ASSERT_EQUAL( IPQ_OK, ::DUMP(n) ); + + // add knobs + CPPUNIT_ASSERT_EQUAL( IPQ_OK, ::AccumulateLine(n, "KNOBS") ); + CPPUNIT_ASSERT_EQUAL( IPQ_OK, ::AccumulateLine(n, "\t-logfile TRUE") ); + + // run + CPPUNIT_ASSERT_EQUAL( IPQ_OK, ::SetOutputFileOn(n, 0) ); + CPPUNIT_ASSERT_EQUAL( IPQ_OK, ::SetOutputStringOn(n, 0) ); + CPPUNIT_ASSERT_EQUAL( IPQ_OK, ::SetErrorFileOn(n, 0) ); + CPPUNIT_ASSERT_EQUAL( IPQ_OK, ::SetLogFileOn(n, 0) ); + CPPUNIT_ASSERT_EQUAL( IPQ_OK, ::SetSelectedOutputFileOn(n, 0) ); + CPPUNIT_ASSERT_EQUAL( IPQ_OK, ::SetDumpStringOn(n, 0) ); + CPPUNIT_ASSERT_EQUAL( IPQ_OK, ::SetDumpFileOn(n, 0) ); + + CPPUNIT_ASSERT_EQUAL( 0, ::RunAccumulated(n) ); + CPPUNIT_ASSERT_EQUAL( 0, ::GetLogStringLineCount(n) ); + + int line = 0; + CPPUNIT_ASSERT_EQUAL( std::string(""), std::string(::GetLogStringLine(n, line++)) ); + CPPUNIT_ASSERT_EQUAL( std::string(""), std::string(::GetLogStringLine(n, line++)) ); + CPPUNIT_ASSERT_EQUAL( std::string(""), std::string(::GetLogStringLine(n, line++)) ); + CPPUNIT_ASSERT_EQUAL( std::string(""), std::string(::GetLogStringLine(n, line++)) ); + + // negative lines should be empty + CPPUNIT_ASSERT_EQUAL( std::string(""), std::string(::GetLogStringLine(n, -1)) ); + CPPUNIT_ASSERT_EQUAL( std::string(""), std::string(::GetLogStringLine(n, -2)) ); + CPPUNIT_ASSERT_EQUAL( std::string(""), std::string(::GetLogStringLine(n, -3)) ); + CPPUNIT_ASSERT_EQUAL( std::string(""), std::string(::GetLogStringLine(n, -4)) ); + + // add solution block + CPPUNIT_ASSERT_EQUAL( IPQ_OK, ::SOLUTION(n, 1.0, 1.0, 1.0) ); + + // add dump block + CPPUNIT_ASSERT_EQUAL( IPQ_OK, ::DUMP(n) ); + + // add knobs + CPPUNIT_ASSERT_EQUAL( IPQ_OK, ::AccumulateLine(n, "KNOBS") ); + CPPUNIT_ASSERT_EQUAL( IPQ_OK, ::AccumulateLine(n, "\t-logfile TRUE") ); + + CPPUNIT_ASSERT_EQUAL( IPQ_OK, ::SetLogStringOn(n, 1) ); + + CPPUNIT_ASSERT_EQUAL( 0, ::RunAccumulated(n) ); + CPPUNIT_ASSERT_EQUAL( 29, ::GetLogStringLineCount(n) ); + + line = 0; + CPPUNIT_ASSERT_EQUAL( std::string("------------------------------------"), std::string(::GetLogStringLine(n, line++)) ); + CPPUNIT_ASSERT_EQUAL( std::string("Reading input data for simulation 1."), std::string(::GetLogStringLine(n, line++)) ); + CPPUNIT_ASSERT_EQUAL( std::string("------------------------------------"), std::string(::GetLogStringLine(n, line++)) ); + CPPUNIT_ASSERT_EQUAL( std::string(""), std::string(::GetLogStringLine(n, line++)) ); + CPPUNIT_ASSERT_EQUAL( std::string("-------------------------------------------"), std::string(::GetLogStringLine(n, line++)) ); + CPPUNIT_ASSERT_EQUAL( std::string("Beginning of initial solution calculations."), std::string(::GetLogStringLine(n, line++)) ); + CPPUNIT_ASSERT_EQUAL( std::string("-------------------------------------------"), std::string(::GetLogStringLine(n, line++)) ); + CPPUNIT_ASSERT_EQUAL( std::string(""), std::string(::GetLogStringLine(n, line++)) ); + CPPUNIT_ASSERT_EQUAL( std::string("Initial solution 1. "), std::string(::GetLogStringLine(n, line++)) ); + CPPUNIT_ASSERT_EQUAL( std::string(""), std::string(::GetLogStringLine(n, line++)) ); + CPPUNIT_ASSERT_EQUAL( std::string("Iterations in revise_guesses: 2"), std::string(::GetLogStringLine(n, line++)) ); + CPPUNIT_ASSERT_EQUAL( std::string(""), std::string(::GetLogStringLine(n, line++)) ); + CPPUNIT_ASSERT_EQUAL( std::string("Number of infeasible solutions: 0"), std::string(::GetLogStringLine(n, line++)) ); + CPPUNIT_ASSERT_EQUAL( std::string("Number of basis changes: 0"), std::string(::GetLogStringLine(n, line++)) ); + CPPUNIT_ASSERT_EQUAL( std::string(""), std::string(::GetLogStringLine(n, line++)) ); + CPPUNIT_ASSERT_EQUAL( std::string("Number of iterations: 6"), std::string(::GetLogStringLine(n, line++)) ); + CPPUNIT_ASSERT_EQUAL( std::string(""), std::string(::GetLogStringLine(n, line++)) ); + CPPUNIT_ASSERT_EQUAL( std::string("------------------"), std::string(::GetLogStringLine(n, line++)) ); + CPPUNIT_ASSERT_EQUAL( std::string("End of simulation."), std::string(::GetLogStringLine(n, line++)) ); + CPPUNIT_ASSERT_EQUAL( std::string("------------------"), std::string(::GetLogStringLine(n, line++)) ); + CPPUNIT_ASSERT_EQUAL( std::string(""), std::string(::GetLogStringLine(n, line++)) ); + CPPUNIT_ASSERT_EQUAL( std::string("------------------------------------"), std::string(::GetLogStringLine(n, line++)) ); + CPPUNIT_ASSERT_EQUAL( std::string("Reading input data for simulation 2."), std::string(::GetLogStringLine(n, line++)) ); + CPPUNIT_ASSERT_EQUAL( std::string("------------------------------------"), std::string(::GetLogStringLine(n, line++)) ); + CPPUNIT_ASSERT_EQUAL( std::string(""), std::string(::GetLogStringLine(n, line++)) ); + CPPUNIT_ASSERT_EQUAL( std::string("-----------"), std::string(::GetLogStringLine(n, line++)) ); + CPPUNIT_ASSERT_EQUAL( std::string("End of run."), std::string(::GetLogStringLine(n, line++)) ); + CPPUNIT_ASSERT_EQUAL( std::string("-----------"), std::string(::GetLogStringLine(n, line++)) ); + CPPUNIT_ASSERT_EQUAL( std::string(""), std::string(::GetLogStringLine(n, line++)) ); + + // add solution block + // add solution block + CPPUNIT_ASSERT_EQUAL( IPQ_OK, ::SOLUTION(n, 1.0, 1.0, 1.0) ); + + // add dump block + CPPUNIT_ASSERT_EQUAL( IPQ_OK, ::DUMP(n) ); + + // add knobs + CPPUNIT_ASSERT_EQUAL( IPQ_OK, ::AccumulateLine(n, "KNOBS") ); + CPPUNIT_ASSERT_EQUAL( IPQ_OK, ::AccumulateLine(n, "\t-logfile TRUE") ); + + CPPUNIT_ASSERT_EQUAL( IPQ_OK, ::SetLogStringOn(n, 0) ); + + + CPPUNIT_ASSERT_EQUAL( 0, ::RunAccumulated(n) ); + CPPUNIT_ASSERT_EQUAL( 0, ::GetLogStringLineCount(n) ); + + line = 0; + CPPUNIT_ASSERT_EQUAL( std::string(""), std::string(::GetLogStringLine(n, line++)) ); + CPPUNIT_ASSERT_EQUAL( std::string(""), std::string(::GetLogStringLine(n, line++)) ); + CPPUNIT_ASSERT_EQUAL( std::string(""), std::string(::GetLogStringLine(n, line++)) ); + CPPUNIT_ASSERT_EQUAL( std::string(""), std::string(::GetLogStringLine(n, line++)) ); + + // negative lines should be empty + CPPUNIT_ASSERT_EQUAL( std::string(""), std::string(::GetLogStringLine(n, -1)) ); + CPPUNIT_ASSERT_EQUAL( std::string(""), std::string(::GetLogStringLine(n, -2)) ); + CPPUNIT_ASSERT_EQUAL( std::string(""), std::string(::GetLogStringLine(n, -3)) ); + CPPUNIT_ASSERT_EQUAL( std::string(""), std::string(::GetLogStringLine(n, -4)) ); +} + diff --git a/unit/TestIPhreeqcLib.h b/unit/TestIPhreeqcLib.h index 0af54e33..e187d1a5 100644 --- a/unit/TestIPhreeqcLib.h +++ b/unit/TestIPhreeqcLib.h @@ -52,6 +52,11 @@ class TestIPhreeqcLib : public CppUnit::TestFixture CPPUNIT_TEST( TestGetOutputString ); CPPUNIT_TEST( TestGetOutputStringLineCount ); CPPUNIT_TEST( TestGetOutputStringLine ); + CPPUNIT_TEST( TestSetLogFileName ); + CPPUNIT_TEST( TestLogStringOnOff ); + CPPUNIT_TEST( TestGetLogString ); + CPPUNIT_TEST( TestGetLogStringLineCount ); + CPPUNIT_TEST( TestGetLogStringLine ); CPPUNIT_TEST_SUITE_END(); @@ -104,8 +109,12 @@ public: void TestOutputStringOnOff(void); void TestGetOutputString(void); void TestGetOutputStringLineCount(void); - void TestGetOutputStringLine(void); - + void TestGetOutputStringLine(void); + void TestSetLogFileName(void); + void TestLogStringOnOff(void); + void TestGetLogString(void); + void TestGetLogStringLineCount(void); + void TestGetLogStringLine(void); protected: void TestFileOnOff(const char* FILENAME, int output_file_on, int error_file_on, int log_file_on, int selected_output_file_on, int dump_file_on); };