src/Utility/Inform.cpp

Go to the documentation of this file.
00001 // -*- C++ -*-
00002 /***************************************************************************
00003  *
00004  * The IPPL Framework
00005  * 
00006  * This program was prepared by PSI. 
00007  * All rights in the program are reserved by PSI.
00008  * Neither PSI nor the author(s)
00009  * makes any warranty, express or implied, or assumes any liability or
00010  * responsibility for the use of this software
00011  *
00012  * Visit http://www.acl.lanl.gov/POOMS for more details
00013  *
00014  ***************************************************************************/
00015 
00016 // -*- C++ -*-
00017 /***************************************************************************
00018  *
00019  * The IPPL Framework
00020  * 
00021  *
00022  * Visit http://people.web.psi.ch/adelmann/ for more details
00023  *
00024  ***************************************************************************/
00025 
00026 // include files
00027 #include "Utility/Inform.h"
00028 #include "Profile/Profiler.h"
00029 #include "Utility/IpplInfo.h"
00030 
00031 #ifdef IPPL_USE_STANDARD_HEADERS
00032 #include <fstream>
00033 using namespace std;
00034 #else
00035 #include <fstream.h>
00036 #endif
00037 
00038 #include <string.h>
00039 
00041 // manipulator functions
00042 
00043 // signal we wish to send the message
00044 Inform& endl(Inform& inf)   { inf << '\n'; return inf.outputMessage(); }
00045 
00046 // set the current msg level
00047 Inform& level1(Inform& inf) { return inf.setMessageLevel(1); }
00048 Inform& level2(Inform& inf) { return inf.setMessageLevel(2); }
00049 Inform& level3(Inform& inf) { return inf.setMessageLevel(3); }
00050 Inform& level4(Inform& inf) { return inf.setMessageLevel(4); }
00051 Inform& level5(Inform& inf) { return inf.setMessageLevel(5); }
00052 
00053 
00055 // perform initialization for this object; called by the constructors.
00056 // arguments = prefix string, print node
00057 void Inform::setup(const char *myname, int pnode) {
00058   TAU_PROFILE("Inform::setup()", "void (char *, int)", TAU_UTILITY | TAU_IO);
00059   On = true;
00060   OutputLevel = MsgLevel = MIN_INFORM_LEVEL;
00061   PrintNode = pnode;
00062 
00063   if ( myname != 0 )
00064     Name = strcpy(new char[strlen(myname) + 1], myname);
00065   else
00066     Name = 0;
00067 }
00068 
00069 
00071 // class constructor
00072 Inform::Inform(const char *myname, int pnode)
00073 #ifdef IPPL_NO_STRINGSTREAM
00074     : FormatBuf(ios::out), OpenedSuccessfully(true) {
00075 #else
00076     : FormatBuf(MsgBuf, MAX_INFORM_MSG_SIZE, ios::out), 
00077         OpenedSuccessfully(true) {
00078 #endif
00079   TAU_PROFILE("Inform::Inform()", "void (char *, int)", TAU_UTILITY | TAU_IO);
00080 
00081   // in this case, the default destination stream is cout
00082   NeedClose = false;
00083   MsgDest = &cout;
00084 
00085   // perform all other needed initialization
00086   setup(myname, pnode);
00087 }
00088 
00089 
00091 // class constructor specifying a file to open
00092 Inform::Inform(const char *myname, const char *fname, const WriteMode opnmode,
00093                int pnode)
00094 #ifdef IPPL_NO_STRINGSTREAM
00095     : FormatBuf(ios::out), OpenedSuccessfully(true) {
00096 #else
00097     : FormatBuf(MsgBuf, MAX_INFORM_MSG_SIZE, ios::out), 
00098         OpenedSuccessfully(true) {
00099 #endif
00100   TAU_PROFILE("Inform::Inform()", "void (char *, char *, WriteMode, int)", 
00101     TAU_UTILITY | TAU_IO);
00102 
00103   // only open a file if we're on the proper node
00104   MsgDest = 0;
00105   if (pnode >= 0 && pnode == Ippl::myNode()) {
00106     if (opnmode == OVERWRITE)
00107       MsgDest = new ofstream(fname, ios::out);
00108     else
00109       MsgDest = new ofstream(fname, ios::app);
00110   }
00111 
00112   // make sure it was opened properly
00113   if ( MsgDest == 0 || ! (*MsgDest) ) {
00114     if (pnode >= 0 && pnode == Ippl::myNode()) {
00115       cerr << "Inform: Cannot open file '" << fname << "'." << endl;
00116     }
00117     NeedClose = false;
00118     MsgDest = &cout;
00119     OpenedSuccessfully = false;
00120   } else {
00121     NeedClose = true;
00122   }
00123 
00124   // perform all other needed initialization
00125   setup(myname, pnode);
00126 }
00127 
00128 
00130 // class constructor specifying an output stream to use
00131 Inform::Inform(const char *myname, ostream& os, int pnode)
00132 #ifdef IPPL_NO_STRINGSTREAM
00133   : FormatBuf(ios::out), OpenedSuccessfully(true) {
00134 #else
00135   : FormatBuf(MsgBuf, MAX_INFORM_MSG_SIZE, ios::out), 
00136       OpenedSuccessfully(true) {
00137 #endif
00138   TAU_PROFILE("Inform::Inform()", "void (char *, ostream, int)", 
00139     TAU_UTILITY | TAU_IO);
00140 
00141   // just store a ref to the provided stream
00142   NeedClose = false;
00143   MsgDest = &os;
00144 
00145   // perform all other needed initialization
00146   setup(myname, pnode);
00147 }
00148 
00149 
00151 // class destructor ... frees up space
00152 Inform::~Inform(void) {
00153   TAU_PROFILE("Inform::~Inform()", "void ()", TAU_UTILITY | TAU_IO) ;
00154   delete [] Name;
00155   if ( NeedClose )
00156     delete MsgDest;
00157 }
00158 
00159 
00160 // print out just a single line, from the given buffer
00161 void Inform::display_single_line(char *buf) {
00162   TAU_PROFILE("Inform::display_single_line", "void (char *)", 
00163     TAU_UTILITY | TAU_IO);
00164 
00165   // output the prefix name if necessary ... if no name was given, do
00166   // not print any prefix at all
00167   if ( Name != 0 ) {
00168     *MsgDest << Name;
00169 
00170     // output the node number if necessary
00171     if (Ippl::getNodes() > 1)
00172       *MsgDest << "{" << Ippl::myNode() << "}";
00173 
00174     // output the message level number if necessary
00175     if ( MsgLevel > 1 )
00176       *MsgDest << "[" << MsgLevel << "]";
00177 
00178     // output the end of the prefix string if necessary
00179     if ( Name != 0)
00180       *MsgDest << "> ";
00181   }
00182 
00183   // finally, print out the message itself
00184   *MsgDest << buf << endl;
00185 }
00186 
00187 
00189 // Print out the message in the given buffer.
00190 void Inform::display_message(char *buf) {
00191   TAU_PROFILE("Inform::display_message()", "void (char *)", 
00192     TAU_UTILITY | TAU_IO);
00193 
00194   // check if we should even print out the message
00195   if ( On && MsgLevel <= OutputLevel && buf != 0 ) {
00196     // get location of final string term char
00197     char *stend = buf + strlen(buf);
00198 
00199     // print blank lines for leading endlines
00200     while (*buf == '\n') {
00201       *buf = '\0';
00202       display_single_line(buf++);
00203     }
00204 
00205     // print out all lines in the string now
00206     while ( (buf = strtok(buf, "\n")) != 0 ) {
00207       display_single_line(buf);
00208       buf += strlen(buf);
00209       if (buf < stend)
00210         buf++;
00211 
00212       // print out contiguous blank lines, if any
00213       while (*buf == '\n') {
00214         *buf = '\0';
00215         display_single_line(buf++);
00216       }
00217     }
00218   }
00219 }
00220 
00222 // Set the current output level for this Inform object.
00223 Inform& Inform::setOutputLevel(const int ol) {
00224   TAU_PROFILE("Inform::setOutputLevel()", "Inform (int)", TAU_UTILITY | TAU_IO);
00225 
00226   if ( ol >= (MIN_INFORM_LEVEL-1) && ol <= MAX_INFORM_LEVEL )
00227     OutputLevel = ol;
00228   return *this;
00229 }
00230 
00231 
00233 // Set the current message level for the current message in this Inform object.
00234 Inform& Inform::setMessageLevel(const int ol) {
00235   TAU_PROFILE("Inform::setMessageLevel()", "Inform (int)",TAU_UTILITY | TAU_IO);
00236   if ( ol >= MIN_INFORM_LEVEL && ol <= MAX_INFORM_LEVEL )
00237     MsgLevel = ol;
00238   return *this;
00239 }
00240 
00241 
00243 // the signal has been given ... process the message.  Return ref to object.
00244 Inform& Inform::outputMessage(void) {
00245   TAU_PROFILE("Inform::setMessageLevel()", "Inform ()", TAU_UTILITY | TAU_IO);
00246   // print out the message (only if this is the master node)
00247   if (PrintNode < 0 || PrintNode == Ippl::myNode()) {
00248     FormatBuf << ends;
00249 #ifdef IPPL_NO_STRINGSTREAM
00250     // extract C string and display
00251     MsgBuf = FormatBuf.str();
00252     char* cstring = const_cast<char*>(MsgBuf.c_str());
00253     display_message(cstring);
00254     // clear buffer contents
00255     // MsgBuf = string("");
00256     // FormatBuf.str(MsgBuf);
00257 #else
00258     display_message(MsgBuf);
00259 #endif
00260   }
00261 
00262   // reset this ostrstream to the start
00263   FormatBuf.seekp(0, ios::beg);
00264   return *this;
00265 }
00266 
00267 
00269 // test program
00270 
00271 #ifdef DEBUG_INFORM_CLASS
00272 
00273 int main(int argc, char *argv[]) {
00274   TAU_PROFILE("main()", "int (int, char **)", TAU_DEFAULT);
00275   int i;
00276 
00277   // create an Inform instance
00278   Inform inf("Inform Test");
00279 
00280   // copy in the argv's ... then print them out
00281   for ( i=0; i < argc ; i++)
00282     inf << "Argument " << i << " = " << argv[i] << "\n";
00283   inf << endl << endl;
00284 
00285    // do another one to make sure
00286   inf.setOutputLevel(3);
00287   inf << level2 << "This is the second test." << endl;
00288 
00289   return 0;
00290 }
00291 
00292 #endif
00293 
00294 /***************************************************************************
00295  * $RCSfile: Inform.cpp,v $   $Author: adelmann $
00296  * $Revision: 1.1.1.1 $   $Date: 2003/01/23 07:40:33 $
00297  * IPPL_VERSION_ID: $Id: Inform.cpp,v 1.1.1.1 2003/01/23 07:40:33 adelmann Exp $ 
00298  ***************************************************************************/

Generated on Mon Jan 16 13:23:58 2006 for IPPL by  doxygen 1.4.6