From 924f14ff14690ba0ba966fc2ce4c2ac7bb9f27d3 Mon Sep 17 00:00:00 2001 From: Stefan Vigerske Date: Sat, 4 Nov 2023 14:08:45 +0100 Subject: [PATCH] add possibility to append to output file instead of truncating - add option file_append - add default argument for file_append to various API functions - closes #720 --- ChangeLog.md | 4 ++++ src/Common/IpJournalist.cpp | 12 ++++++++---- src/Common/IpJournalist.hpp | 6 ++++-- src/Interfaces/IpIpoptApplication.cpp | 14 +++++++++++--- src/Interfaces/IpIpoptApplication.hpp | 5 +++-- 5 files changed, 30 insertions(+), 11 deletions(-) diff --git a/ChangeLog.md b/ChangeLog.md index e770964da..5e535ef8c 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -15,6 +15,10 @@ More detailed information about incremental changes can be found in the Christoph Hansknecht]. - Print additional messages when reallocation of MA27 working space failed [#671, by Daniel Oliveira]. +- Added option `file_append` to specify whether to append to `output_file` instead of + truncating it. Added default argument `file_append` to `Journalist::AddFileJournal()`, + added default argument `fappend` to `FileJournal::Open()`, and added default argument + `file_append` to `IpoptApplication::OpenOutputFile()`. [#720] ### 3.14.12 (2023-04-05) diff --git a/src/Common/IpJournalist.cpp b/src/Common/IpJournalist.cpp index 093e8e435..eab931a28 100644 --- a/src/Common/IpJournalist.cpp +++ b/src/Common/IpJournalist.cpp @@ -264,14 +264,15 @@ bool Journalist::AddJournal( SmartPtr Journalist::AddFileJournal( const std::string& journal_name, const std::string& fname, - EJournalLevel default_level + EJournalLevel default_level, + bool file_append ) { SmartPtr temp = new FileJournal(journal_name, default_level); // Open the file (Note:, a fname of "stdout" is handled by the // Journal class to mean stdout, etc. - if( temp->Open(fname.c_str()) && AddJournal(GetRawPtr(temp)) ) + if( temp->Open(fname.c_str(), file_append) && AddJournal(GetRawPtr(temp)) ) { return GetRawPtr(temp); } @@ -392,7 +393,10 @@ FileJournal::~FileJournal() file_ = NULL; } -bool FileJournal::Open(const char* fname) +bool FileJournal::Open( + const char* fname, + bool fappend +) { if( file_ && file_ != stdout && file_ != stderr ) { @@ -414,7 +418,7 @@ bool FileJournal::Open(const char* fname) else { // open the file on disk - file_ = fopen(fname, "w+"); + file_ = fopen(fname, fappend ? "a+" : "w+"); if( file_ ) { return true; diff --git a/src/Common/IpJournalist.hpp b/src/Common/IpJournalist.hpp index 8dc86d4ba..97f647ffc 100644 --- a/src/Common/IpJournalist.hpp +++ b/src/Common/IpJournalist.hpp @@ -231,7 +231,8 @@ class IPOPTLIB_EXPORT Journalist: public ReferencedObject virtual SmartPtr AddFileJournal( const std::string& location_name, /**< string identifier, which can be used to obtain the pointer to the new Journal at a later point using the GetJournal method */ const std::string& fname, /**< name of the file to which this Journal corresponds; use "stdout" for stdout and use "stderr" for stderr */ - EJournalLevel default_level = J_WARNING /**< default journal level used to initialize the printing level for all categories */ + EJournalLevel default_level = J_WARNING,/**< default journal level used to initialize the printing level for all categories */ + bool file_append = false /**< whether to append to file or truncate it (since 3.14.13) */ ); /** Get an existing journal. @@ -432,7 +433,8 @@ class IPOPTLIB_EXPORT FileJournal: public Journal * @return false only if the file with the given name could not be opened */ virtual bool Open( - const char* fname + const char* fname, /**< name of file to open */ + bool fappend = false /**< whether to append or truncate file (since 3.14.13) */ ); protected: diff --git a/src/Interfaces/IpIpoptApplication.cpp b/src/Interfaces/IpIpoptApplication.cpp index 8fe88971b..44525aea5 100644 --- a/src/Interfaces/IpIpoptApplication.cpp +++ b/src/Interfaces/IpIpoptApplication.cpp @@ -227,7 +227,9 @@ ApplicationReturnStatus IpoptApplication::Initialize( { file_print_level = print_level; } - bool openend = OpenOutputFile(output_filename, file_print_level); + bool file_append; + options_->GetBoolValue("file_append", file_append, ""); + bool openend = OpenOutputFile(output_filename, file_print_level, file_append); if( !openend ) { jnlst_->Printf(J_ERROR, J_INITIALIZATION, "Error opening output file \"%s\"\n", output_filename.c_str()); @@ -386,6 +388,11 @@ void IpoptApplication::RegisterOptions( "NOTE: This option only works when read from the ipopt.opt options file! " "Determines the verbosity level for the file specified by \"output_file\". " "By default it is the same as \"print_level\"."); + roptions->AddBoolOption( + "file_append", + "Whether to append to output file, if set, instead of truncating.", + false, + "NOTE: This option only works when read from the ipopt.opt options file!"); roptions->AddBoolOption( "print_user_options", "Print all options set by the user.", @@ -943,14 +950,15 @@ ApplicationReturnStatus IpoptApplication::call_optimize() bool IpoptApplication::OpenOutputFile( std::string file_name, - EJournalLevel print_level + EJournalLevel print_level, + bool file_append ) { SmartPtr file_jrnl = jnlst_->GetJournal("OutputFile:" + file_name); if( IsNull(file_jrnl) ) { - file_jrnl = jnlst_->AddFileJournal("OutputFile:" + file_name, file_name.c_str(), print_level); + file_jrnl = jnlst_->AddFileJournal("OutputFile:" + file_name, file_name.c_str(), print_level, file_append); } // Check, if the output file could be created properly diff --git a/src/Interfaces/IpIpoptApplication.hpp b/src/Interfaces/IpIpoptApplication.hpp index afbeea86a..31de64e8c 100644 --- a/src/Interfaces/IpIpoptApplication.hpp +++ b/src/Interfaces/IpIpoptApplication.hpp @@ -180,8 +180,9 @@ class IPOPTLIB_EXPORT IpoptApplication: public ReferencedObject * @return false if there was a problem */ virtual bool OpenOutputFile( - std::string file_name, - EJournalLevel print_level + std::string file_name, /**< name of file to open */ + EJournalLevel print_level, /**< print level to be used */ + bool file_append = false /**< whether to append to file or truncate (since 3.14.13) */ ); /**@name Accessor methods */