Merge release-4-6 into master
[alexxy/gromacs.git] / src / gromacs / utility / messagestringcollector.cpp
1 /*
2  *
3  *                This source code is part of
4  *
5  *                 G   R   O   M   A   C   S
6  *
7  *          GROningen MAchine for Chemical Simulations
8  *
9  * Written by David van der Spoel, Erik Lindahl, Berk Hess, and others.
10  * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
11  * Copyright (c) 2001-2009, The GROMACS development team,
12  * check out http://www.gromacs.org for more information.
13  *
14  * This program is free software; you can redistribute it and/or
15  * modify it under the terms of the GNU General Public License
16  * as published by the Free Software Foundation; either version 2
17  * of the License, or (at your option) any later version.
18  *
19  * If you want to redistribute modifications, please consider that
20  * scientific software is very special. Version control is crucial -
21  * bugs must be traceable. We will be happy to consider code for
22  * inclusion in the official distribution, but derived work must not
23  * be called official GROMACS. Details are found in the README & COPYING
24  * files - if they are missing, get the official version at www.gromacs.org.
25  *
26  * To help us fund GROMACS development, we humbly ask that you cite
27  * the papers on the package - you can find them in the top README file.
28  *
29  * For more info, check our website at http://www.gromacs.org
30  */
31 /*! \internal \file
32  * \brief
33  * Implements gmx::MessageStringCollector.
34  *
35  * \author Teemu Murtola <teemu.murtola@cbr.su.se>
36  * \ingroup module_utility
37  */
38 #include "gromacs/utility/messagestringcollector.h"
39
40 #include <vector>
41
42 #include "gromacs/utility/gmxassert.h"
43
44 namespace gmx
45 {
46
47 class MessageStringCollector::Impl
48 {
49     public:
50         Impl() : prevContext_(0) {}
51
52         std::vector<std::string> contexts_;
53         std::string              text_;
54         size_t                   prevContext_;
55 };
56
57 MessageStringCollector::MessageStringCollector()
58     : impl_(new Impl)
59 {
60 }
61
62 MessageStringCollector::~MessageStringCollector()
63 {
64 }
65
66 void MessageStringCollector::startContext(const char *name)
67 {
68     impl_->contexts_.push_back(name);
69 }
70
71 void MessageStringCollector::append(const std::string &message)
72 {
73     int indent = static_cast<int>(impl_->prevContext_ * 2);
74     if (!impl_->contexts_.empty())
75     {
76         std::vector<std::string>::const_iterator ci;
77         for (ci = impl_->contexts_.begin() + impl_->prevContext_;
78              ci != impl_->contexts_.end(); ++ci)
79         {
80             impl_->text_.append(indent, ' ');
81             impl_->text_.append(*ci);
82             impl_->text_.append("\n");
83             indent += 2;
84         }
85     }
86     impl_->prevContext_ = impl_->contexts_.size();
87
88     // TODO: Put this into a more generic helper, could be useful elsewhere
89     size_t pos = 0;
90     while (pos < message.size())
91     {
92         size_t nextpos = message.find_first_of('\n', pos);
93         impl_->text_.append(indent, ' ');
94         impl_->text_.append(message.substr(pos, nextpos - pos));
95         impl_->text_.append("\n");
96         if (nextpos == std::string::npos)
97         {
98             break;
99         }
100         pos = nextpos + 1;
101     }
102 }
103
104 void MessageStringCollector::finishContext()
105 {
106     GMX_RELEASE_ASSERT(!impl_->contexts_.empty(),
107                        "finishContext() called without context");
108     impl_->contexts_.pop_back();
109     if (impl_->prevContext_ > impl_->contexts_.size())
110     {
111         impl_->prevContext_ = impl_->contexts_.size();
112     }
113 }
114
115 void MessageStringCollector::clear()
116 {
117     impl_->contexts_.clear();
118     impl_->text_.clear();
119     impl_->prevContext_ = 0;
120 }
121
122 bool MessageStringCollector::isEmpty() const
123 {
124     return impl_->text_.empty();
125 }
126
127 std::string MessageStringCollector::toString() const
128 {
129     return impl_->text_;
130 }
131
132 } // namespace gmx