OPAL (Object Oriented Parallel Accelerator Library)  2.2.0
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
35 constexpr int MIN_INFORM_LEVEL = 1;
36 constexpr int MAX_INFORM_LEVEL = 5;
37 
39 // manipulator functions
40 
41 // signal we wish to send the message
42 Inform& endl(Inform& inf) { inf << '\n'; return inf.outputMessage(); }
43 
44 // set the current msg level
45 Inform& level1(Inform& inf) { return inf.setMessageLevel(1); }
46 Inform& level2(Inform& inf) { return inf.setMessageLevel(2); }
47 Inform& level3(Inform& inf) { return inf.setMessageLevel(3); }
48 Inform& level4(Inform& inf) { return inf.setMessageLevel(4); }
49 Inform& 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
55 void 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
77 Inform::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
91 Inform::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
123 Inform::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
137 Inform::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.
186 void 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 ) {
201  display_single_line(buf);
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 
216 void 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  ***************************************************************************/
static int getNodes()
Definition: IpplInfo.cpp:773
std::string MsgBuf
Definition: Inform.h:123
Inform(const char *=0, int=0)
Definition: Inform.cpp:77
Inform & level5(Inform &inf)
Definition: Inform.cpp:49
int getOutputLevel(void) const
Definition: Inform.h:77
constexpr int MIN_INFORM_LEVEL
Definition: Inform.cpp:35
char * Name
Definition: Inform.h:120
std::ostringstream FormatBuf
Definition: Inform.h:125
Inform & setMessageLevel(const int)
Definition: Inform.cpp:238
static int myNode()
Definition: IpplInfo.cpp:794
Inform & level4(Inform &inf)
Definition: Inform.cpp:48
Inform & outputMessage(void)
Definition: Inform.cpp:248
void setDestination(std::ostream &dest)
Definition: Inform.cpp:216
int MsgLevel
Definition: Inform.h:149
Inform & level2(Inform &inf)
Definition: Inform.cpp:46
void display_single_line(char *)
Definition: Inform.cpp:159
bool NeedClose
Definition: Inform.h:131
void display_message(char *)
Definition: Inform.cpp:186
Inform & setOutputLevel(const int)
Definition: Inform.cpp:228
void setup(const char *, int)
Definition: Inform.cpp:55
static Inform * Info
Definition: IpplInfo.h:87
~Inform()
Definition: Inform.cpp:150
int main(int argc, char *argv[])
Definition: Main.cpp:107
int PrintNode
Definition: Inform.h:140
bool OpenedSuccessfully
Definition: Inform.h:134
Inform & level3(Inform &inf)
Definition: Inform.cpp:47
constexpr int MAX_INFORM_LEVEL
Definition: Inform.cpp:36
std::ostream * MsgDest
Definition: Inform.h:128
int OutputLevel
Definition: Inform.h:144
Definition: Inform.h:41
WriteMode
Definition: Inform.h:45
Inform & level1(Inform &inf)
Definition: Inform.cpp:45
bool On
Definition: Inform.h:137
Inform & endl(Inform &inf)
Definition: Inform.cpp:42