Warn for type mismatch for gmx printf like functions 2/3
[gromacs.git] / src / gromacs / utility / loggerbuilder.cpp
blob5d286a6d9591918457efd40140a5da307c0aa24e
1 /*
2 * This file is part of the GROMACS molecular simulation package.
4 * Copyright (c) 2016,2018, by the GROMACS development team, led by
5 * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
6 * and including many others, as listed in the AUTHORS file in the
7 * top-level source directory and at http://www.gromacs.org.
9 * GROMACS is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public License
11 * as published by the Free Software Foundation; either version 2.1
12 * of the License, or (at your option) any later version.
14 * GROMACS is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with GROMACS; if not, see
21 * http://www.gnu.org/licenses, or write to the Free Software Foundation,
22 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
24 * If you want to redistribute modifications to GROMACS, please
25 * consider that scientific software is very special. Version
26 * control is crucial - bugs must be traceable. We will be happy to
27 * consider code for inclusion in the official distribution, but
28 * derived work must not be called official GROMACS. Details are found
29 * in the README & COPYING files - if they are missing, get the
30 * official version at http://www.gromacs.org.
32 * To help us fund GROMACS development, we humbly ask that you cite
33 * the research papers on the package. Check out http://www.gromacs.org.
35 #include "gmxpre.h"
37 #include "loggerbuilder.h"
39 #include <memory>
40 #include <vector>
42 #include "gromacs/utility/filestream.h"
43 #include "gromacs/utility/logger.h"
44 #include "gromacs/utility/stringutil.h"
45 #include "gromacs/utility/textwriter.h"
47 namespace gmx
50 class LogTargetCollection : public ILogTarget
52 public:
53 void addTarget(ILogTarget *target)
55 targets_.push_back(target);
58 void writeEntry(const LogEntry &entry) override
60 for (ILogTarget *target : targets_)
62 target->writeEntry(entry);
66 private:
67 std::vector<ILogTarget *> targets_;
70 class LogTargetFormatter : public ILogTarget
72 public:
73 explicit LogTargetFormatter(TextOutputStream *stream) : writer_(stream) {}
75 void writeEntry(const LogEntry &entry) override;
77 private:
78 TextWriter writer_;
82 void LogTargetFormatter::writeEntry(const LogEntry &entry)
84 if (entry.asParagraph)
86 writer_.ensureEmptyLine();
88 writer_.writeLine(entry.text);
89 if (entry.asParagraph)
91 writer_.ensureEmptyLine();
95 /********************************************************************
96 * LoggerOwner::Impl
99 class LoggerOwner::Impl
101 public:
102 explicit Impl(ILogTarget *loggerTargets[MDLogger::LogLevelCount])
103 : logger_(loggerTargets)
107 MDLogger logger_;
108 std::vector<std::unique_ptr<TextOutputStream> > streams_;
109 std::vector<std::unique_ptr<ILogTarget> > targets_;
112 /********************************************************************
113 * LoggerOwner
116 LoggerOwner::LoggerOwner(std::unique_ptr<Impl> impl)
117 : impl_(impl.release()), logger_(&impl_->logger_)
121 LoggerOwner::LoggerOwner(LoggerOwner &&other) noexcept
122 : impl_(std::move(other.impl_)), logger_(&impl_->logger_)
126 LoggerOwner &LoggerOwner::operator=(LoggerOwner &&other) noexcept
128 impl_ = std::move(other.impl_);
129 logger_ = &impl_->logger_;
130 return *this;
133 LoggerOwner::~LoggerOwner()
137 /********************************************************************
138 * LoggerBuilder::Impl
141 class LoggerBuilder::Impl
143 public:
144 std::vector<std::unique_ptr<TextOutputStream> > streams_;
145 std::vector<std::unique_ptr<ILogTarget> > targets_;
146 std::vector<ILogTarget *> loggerTargets_[MDLogger::LogLevelCount];
149 /********************************************************************
150 * LoggerBuilder
153 LoggerBuilder::LoggerBuilder()
154 : impl_(new Impl)
158 LoggerBuilder::~LoggerBuilder()
162 void LoggerBuilder::addTargetStream(MDLogger::LogLevel level, TextOutputStream *stream)
164 impl_->targets_.push_back(std::unique_ptr<ILogTarget>(new LogTargetFormatter(stream)));
165 ILogTarget *target = impl_->targets_.back().get();
166 for (int i = 0; i <= static_cast<int>(level); ++i)
168 impl_->loggerTargets_[i].push_back(target);
172 void LoggerBuilder::addTargetFile(MDLogger::LogLevel level, FILE *fp)
174 std::unique_ptr<TextOutputStream> stream(new TextOutputFile(fp));
175 addTargetStream(level, stream.get());
176 impl_->streams_.push_back(std::move(stream));
179 LoggerOwner LoggerBuilder::build()
181 ILogTarget *loggerTargets[MDLogger::LogLevelCount];
182 for (int i = 0; i < MDLogger::LogLevelCount; ++i)
184 auto &levelTargets = impl_->loggerTargets_[i];
185 loggerTargets[i] = nullptr;
186 if (!levelTargets.empty())
188 if (levelTargets.size() == 1)
190 loggerTargets[i] = levelTargets[0];
192 else
194 std::unique_ptr<LogTargetCollection> collection(new LogTargetCollection);
195 for (auto &target : levelTargets)
197 collection->addTarget(target);
199 loggerTargets[i] = collection.get();
200 impl_->targets_.push_back(std::move(collection));
203 levelTargets.clear();
205 std::unique_ptr<LoggerOwner::Impl> data(new LoggerOwner::Impl(loggerTargets));
206 data->targets_ = std::move(impl_->targets_);
207 data->streams_ = std::move(impl_->streams_);
208 return LoggerOwner(std::move(data));
211 } // namespace gmx