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