Branch data Line data Source code
1 : : // -*- C++ -*-
2 : : /***************************************************************************
3 : : *
4 : : * The IPPL Framework
5 : : *
6 : : * This program was prepared by PSI.
7 : : * All rights in the program are reserved by PSI.
8 : : * Neither PSI nor the author(s)
9 : : * makes any warranty, express or implied, or assumes any liability or
10 : : * responsibility for the use of this software
11 : : *
12 : : * Visit www.amas.web.psi for more details
13 : : *
14 : : ***************************************************************************/
15 : :
16 : : // -*- C++ -*-
17 : : /***************************************************************************
18 : : *
19 : : * The IPPL Framework
20 : : *
21 : : *
22 : : * Visit http://people.web.psi.ch/adelmann/ for more details
23 : : *
24 : : ***************************************************************************/
25 : :
26 : : // include files
27 : : #include "Ippl.h"
28 : :
29 : : #include "Utility/Inform.h"
30 : :
31 : : #include <cstring>
32 : : #include <fstream>
33 : :
34 : : // range of Inform message levels
35 : : constexpr int MIN_INFORM_LEVEL = 1;
36 : : constexpr int MAX_INFORM_LEVEL = 5;
37 : :
38 : : /////////////////////////////////////////////////////////////////////
39 : : // manipulator functions
40 : :
41 : : // signal we wish to send the message
42 : 0 : Inform& endl(Inform& inf) {
43 [ # # ]: 0 : inf << '\n';
44 : 0 : return inf.outputMessage();
45 : : }
46 : :
47 : : // set the current msg level
48 : 0 : Inform& level1(Inform& inf) {
49 : 0 : return inf.setMessageLevel(1);
50 : : }
51 : 0 : Inform& level2(Inform& inf) {
52 : 0 : return inf.setMessageLevel(2);
53 : : }
54 : 0 : Inform& level3(Inform& inf) {
55 : 0 : return inf.setMessageLevel(3);
56 : : }
57 : 0 : Inform& level4(Inform& inf) {
58 : 0 : return inf.setMessageLevel(4);
59 : : }
60 : 0 : Inform& level5(Inform& inf) {
61 : 0 : return inf.setMessageLevel(5);
62 : : }
63 : :
64 : : /////////////////////////////////////////////////////////////////////
65 : : // perform initialization for this object; called by the constructors.
66 : : // arguments = prefix string, print node
67 : 2520 : void Inform::setup(const char* myname, int pnode) {
68 : 2520 : On = true;
69 : :
70 [ + + ]: 2520 : if (ippl::Info != NULL) {
71 : 1684 : OutputLevel = ippl::Info->getOutputLevel();
72 : : } else {
73 : 836 : OutputLevel = MIN_INFORM_LEVEL;
74 : : }
75 : 2520 : MsgLevel = MIN_INFORM_LEVEL;
76 : 2520 : PrintNode = pnode;
77 : :
78 [ + - ]: 2520 : if (myname != 0) {
79 : 2520 : Name = strcpy(new char[strlen(myname) + 1], myname);
80 : : } else {
81 : 0 : Name = 0;
82 : : }
83 : 2520 : }
84 : :
85 : : /////////////////////////////////////////////////////////////////////
86 : : // class constructor
87 : 848 : Inform::Inform(const char* myname, int pnode)
88 [ + - ]: 848 : : FormatBuf(std::ios::out)
89 : 848 : , OpenedSuccessfully(true) {
90 : : // in this case, the default destination stream is cout
91 : 848 : NeedClose = false;
92 : 848 : MsgDest = &std::cout;
93 : :
94 : : // perform all other needed initialization
95 [ + - ]: 848 : setup(myname, pnode);
96 : 848 : }
97 : :
98 : : /////////////////////////////////////////////////////////////////////
99 : : // class constructor specifying a file to open
100 : 0 : Inform::Inform(const char* myname, const char* fname, const WriteMode opnmode, int pnode)
101 [ # # ]: 0 : : FormatBuf(std::ios::out)
102 : 0 : , OpenedSuccessfully(true) {
103 : : // only open a file if we're on the proper node
104 : 0 : MsgDest = 0;
105 [ # # # # : 0 : if (pnode >= 0 && pnode == ippl::Comm->rank()) {
# # ]
106 [ # # ]: 0 : if (opnmode == OVERWRITE)
107 [ # # # # : 0 : MsgDest = new std::ofstream(fname, std::ios::out);
# # # # ]
108 : : else
109 [ # # # # : 0 : MsgDest = new std::ofstream(fname, std::ios::app);
# # # # ]
110 : : }
111 : :
112 : : // make sure it was opened properly
113 [ # # # # : 0 : if (MsgDest == 0 || !(*MsgDest)) {
# # # # ]
114 [ # # # # : 0 : if (pnode >= 0 && pnode == ippl::Comm->rank()) {
# # ]
115 [ # # # # : 0 : std::cerr << "Inform: Cannot open file '" << fname << "'." << std::endl;
# # # # ]
116 : : }
117 : 0 : NeedClose = false;
118 : 0 : MsgDest = &std::cout;
119 : 0 : OpenedSuccessfully = false;
120 : : } else {
121 : 0 : NeedClose = true;
122 : : }
123 : :
124 : : // perform all other needed initialization
125 [ # # ]: 0 : setup(myname, pnode);
126 : 0 : }
127 : :
128 : : /////////////////////////////////////////////////////////////////////
129 : : // class constructor specifying an output stream to use
130 : 1672 : Inform::Inform(const char* myname, std::ostream& os, int pnode)
131 [ + - ]: 1672 : : FormatBuf(std::ios::out)
132 : 1672 : , OpenedSuccessfully(true) {
133 : : // just store a ref to the provided stream
134 : 1672 : NeedClose = false;
135 : 1672 : MsgDest = &os;
136 : :
137 : : // perform all other needed initialization
138 [ + - ]: 1672 : setup(myname, pnode);
139 : 1672 : }
140 : :
141 : : /////////////////////////////////////////////////////////////////////
142 : : // class constructor specifying an other Inform instance
143 : 0 : Inform::Inform(const char* myname, const Inform& os, int pnode)
144 [ # # ]: 0 : : FormatBuf(std::ios::out)
145 : 0 : , MsgDest(os.MsgDest)
146 : 0 : , OpenedSuccessfully(true) {
147 : : // just store a ref to the provided stream
148 : 0 : NeedClose = false;
149 : :
150 : : // perform all other needed initialization
151 [ # # ]: 0 : setup(myname, pnode);
152 : 0 : }
153 : :
154 : : /////////////////////////////////////////////////////////////////////
155 : : // class destructor ... frees up space
156 : 2520 : Inform::~Inform(void) {
157 [ + - ]: 2520 : delete[] Name;
158 [ - + ]: 2520 : if (NeedClose)
159 [ # # ]: 0 : delete MsgDest;
160 : 2520 : }
161 : :
162 : : // print out just a single line, from the given buffer
163 : 0 : void Inform::display_single_line(char* buf) {
164 : : // output the prefix name if necessary ... if no name was given, do
165 : : // not print any prefix at all
166 [ # # ]: 0 : if (Name != 0) {
167 : 0 : *MsgDest << Name;
168 : :
169 : : // output the node number if necessary
170 [ # # ]: 0 : if (ippl::Comm->size() > 1)
171 : 0 : *MsgDest << "{" << ippl::Comm->rank() << "}";
172 : :
173 : : // output the message level number if necessary
174 [ # # ]: 0 : if (MsgLevel > 1)
175 : 0 : *MsgDest << "[" << MsgLevel << "]";
176 : :
177 : : // output the end of the prefix string if necessary
178 [ # # ]: 0 : if (Name != 0)
179 : 0 : *MsgDest << "> ";
180 : : }
181 : :
182 : : // finally, print out the message itself
183 : 0 : *MsgDest << buf << std::endl;
184 : 0 : }
185 : :
186 : : /////////////////////////////////////////////////////////////////////
187 : : // Print out the message in the given buffer.
188 : 0 : void Inform::display_message(char* buf) {
189 : : // check if we should even print out the message
190 [ # # # # : 0 : if (On && MsgLevel <= OutputLevel && buf != 0) {
# # ]
191 : : // get location of final string term char
192 : 0 : char* stend = buf + strlen(buf);
193 : :
194 : : // print blank lines for leading endlines
195 [ # # ]: 0 : while (*buf == '\n') {
196 : 0 : *buf = '\0';
197 : 0 : display_single_line(buf++);
198 : : }
199 : :
200 : : // print out all lines in the string now
201 [ # # ]: 0 : while ((buf = strtok(buf, "\n")) != 0) {
202 : 0 : display_single_line(buf);
203 : 0 : buf += strlen(buf);
204 [ # # ]: 0 : if (buf < stend)
205 : 0 : buf++;
206 : :
207 : : // print out contiguous blank lines, if any
208 [ # # ]: 0 : while (*buf == '\n') {
209 : 0 : *buf = '\0';
210 : 0 : display_single_line(buf++);
211 : : }
212 : : }
213 : : }
214 : 0 : MsgLevel = MIN_INFORM_LEVEL;
215 : 0 : }
216 : :
217 : 0 : void Inform::setDestination(std::ostream& dest) {
218 [ # # ]: 0 : if (NeedClose)
219 [ # # ]: 0 : delete MsgDest;
220 : :
221 : 0 : MsgDest = &dest;
222 : :
223 : 0 : NeedClose = false;
224 : 0 : }
225 : :
226 : : /////////////////////////////////////////////////////////////////////
227 : : // Set the current output level for this Inform object.
228 : 2508 : Inform& Inform::setOutputLevel(const int ol) {
229 [ + - + - ]: 2508 : if (ol >= (MIN_INFORM_LEVEL - 1) && ol <= MAX_INFORM_LEVEL)
230 : 2508 : OutputLevel = ol;
231 : 2508 : return *this;
232 : : }
233 : :
234 : : /////////////////////////////////////////////////////////////////////
235 : : // Set the current message level for the current message in this Inform object.
236 : 0 : Inform& Inform::setMessageLevel(const int ol) {
237 [ # # # # ]: 0 : if (ol >= MIN_INFORM_LEVEL && ol <= MAX_INFORM_LEVEL)
238 : 0 : MsgLevel = ol;
239 : 0 : return *this;
240 : : }
241 : :
242 : : /////////////////////////////////////////////////////////////////////
243 : : // the signal has been given ... process the message. Return ref to object.
244 : 0 : Inform& Inform::outputMessage(void) {
245 : : // print out the message (only if this is the master node)
246 [ # # # # : 0 : if (PrintNode < 0 || PrintNode == ippl::Comm->rank()) {
# # ]
247 : 0 : FormatBuf << std::ends;
248 : : // extract C string and display
249 [ # # ]: 0 : MsgBuf = FormatBuf.str();
250 : 0 : char* cstring = const_cast<char*>(MsgBuf.c_str());
251 : 0 : display_message(cstring);
252 : : // clear buffer contents
253 : : // MsgBuf = string("");
254 : : // FormatBuf.str(MsgBuf);
255 : : }
256 : :
257 : : // reset this ostrstream to the start
258 : 0 : FormatBuf.seekp(0, std::ios::beg);
259 : 0 : return *this;
260 : : }
261 : :
262 : : /////////////////////////////////////////////////////////////////////
263 : : // test program
264 : :
265 : : #ifdef DEBUG_INFORM_CLASS
266 : :
267 : : int main(int argc, char* argv[]) {
268 : : int i;
269 : :
270 : : // create an Inform instance
271 : : Inform inf("Inform Test");
272 : :
273 : : // copy in the argv's ... then print them out
274 : : for (i = 0; i < argc; i++)
275 : : inf << "Argument " << i << " = " << argv[i] << "\n";
276 : : inf << endl << endl;
277 : :
278 : : // do another one to make sure
279 : : inf.setOutputLevel(3);
280 : : inf << level2 << "This is the second test." << endl;
281 : :
282 : : return 0;
283 : : }
284 : :
285 : : #endif
286 : :
287 : : /***************************************************************************
288 : : * $RCSfile: Inform.cpp,v $ $Author: adelmann $
289 : : * $Revision: 1.1.1.1 $ $Date: 2003/01/23 07:40:33 $
290 : : * IPPL_VERSION_ID: $Id: Inform.cpp,v 1.1.1.1 2003/01/23 07:40:33 adelmann Exp $
291 : : ***************************************************************************/
|