Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Class Members | File Members

bk_messages.hh

Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 1999-2003 Bert Kampes
00003  * Copyright (c) 1999-2003 Delft University of Technology, The Netherlands
00004  *
00005  * This file is part of Doris, the Delft o-o radar interferometric software.
00006  *
00007  * Doris program is free software; you can redistribute it and/or modify
00008  * it under the terms of the GNU General Public License as published by
00009  * the Free Software Foundation; either version 2 of the License, or
00010  * (at your option) any later version.
00011  *
00012  * Doris is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  * GNU General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU General Public License
00018  * along with this program; if not, write to the Free Software
00019  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00020  *
00021  * Publications that contain results produced by the Doris software should
00022  * contain an acknowledgment. (For example: The interferometric processing
00023  * was performed using the freely available Doris software package developed
00024  * by the Delft Institute for Earth-Oriented Space Research (DEOS), Delft
00025  * University of Technology, or include a reference to: Bert Kampes and
00026  * Stefania Usai. \"Doris: The Delft Object-oriented Radar Interferometric
00027  * software.\" In: proceedings 2nd ITC ORS symposium, August 1999. (cdrom)).
00028  *
00029  */
00030 /****************************************************************
00031  * $Source: /users/kampes/DEVELOP/DORIS/doris/src/RCS/bk_messages.hh,v $ *
00032  * $Revision: 3.9 $ *
00033  * $Date: 2005/04/06 15:29:03 $ *
00034  * $Author: kampes $ *
00035  *
00036  * definition of bk_message class *
00037  #%// BK 10-Apr-2003
00038  ****************************************************************/
00039 
00040 #ifndef BK_MESSAGES_H
00041 #define BK_MESSAGES_H
00042 using namespace std;
00043 
00044 #include <iostream>    // cout
00045 #include <iomanip>     // setw()
00046 #include <strstream>   // mem.buf
00047 #include <cstring>     // strcpy()
00048 #include <cstdlib>     // exit()
00049 
00050 // #if majorversion>3 and g++
00051 //#include <stringstream>   // new mem.buf
00052 //#include <string>
00053 
00054 
00055 
00056 // ---------------------------------------------------------------- 
00057 // --- Choice was either to make something like:
00058 // --- message ERROR;
00059 // --- message DEBUG;
00060 // --- message INFO;
00061 // --- with functions like: ERROR.doprint(1); ERROR.setidentifyer("ERROR"); 
00062 // ---                      ERROR << "dsaada" << 4.5 << setw(4) << nw;
00063 // ---                      ERROR.print();
00064 // --- with separate bufs, or to combine them in a single object
00065 // --- like:
00066 // --- messages logging;
00067 // --- logging.setlevel("INFO");
00068 // --- logging << "dsaada" << 4.5 << setw(4) << nw;
00069 // --- logging.info();
00070 // --- The first is nice, different separated bufs, and easy to change 
00071 // --- existing code.  However,
00072 // --- The latter is better with Doris, since it allows things like
00073 // --- if (good) then logging.info() else logging.warning();
00074 // --- But by using construction like 
00075 // --- WARNING.print(INFO.get_str()); this is solved
00076 // --- #%// BK 10-Apr-2003
00077 //
00078 // most important member functions:
00079 //   get_str():       leave buffer unaffected, pointer to a copy
00080 //   print("sss"):    leave buffer unaffected, print a copy
00081 //   print():         leave buffer unaffected, terminate buffer, rewind buffer;
00082 // this means that you have to rrewind the buffer yourself if you misuse it
00083 // as storage, like TRACE.rewind();
00084 // INFO.precision(10); /* permanent */  INFO << setp(13)<<q;// once
00085 // INFO.width(11);
00086 // INFO.reset();
00087 // ---------------------------------------------------------------- 
00088 // EXAMPLE USEAGE:
00089 // ---------------------------------------------------------------- 
00090 // in code simply change with a define calls to ERROR to give a WARNING summary, etc.
00091 // #define printERROR cout<<"this is defined...\n"; warning.summary(); error<<" ("<<__FILE__<<": "<<__LINE__<<")"; error.print();
00092 //
00093 // ---------------------------------------------------------------- 
00094 // in globals, put them as extern to access them everywhere
00095 // #include "globals.h"
00096 // --- declaration of global info message object ---
00097 // bk_messages error;
00098 //bk_messages INFO;
00099 //bk_messages DEBUG;
00100 //int main( int argc, char* argv[])
00101 //  {
00102 //  DEBUG.setidentifyer("DEBUG");
00103 //  INFO.setidentifyer("INFO");
00104 //  INFO.doprint(1);
00105 //  INFO.dostderr(0);
00106 //  INFO.bellrings(2);
00107 //  DEBUG << 421;
00108 //  DEBUG << " dsadsaa: " << 433 ;
00109 //  DEBUG << 421.1;
00110 //  DEBUG << setw(20) << double(421.1) << ";;;";
00111 //  DEBUG.print();
00112 //  INFO << "this is a info message";
00113 //  INFO.print();
00114 //  INFO.print("this is a another info message");
00115 //  INFO.summary();
00116 //  return 0;
00117 //  }
00118 
00119 
00120 
00121 // ---------------------------------------------------------------- 
00122 // ---------------------------------------------------------------- 
00123 // ---------------------------------------------------------------- 
00124 class bk_messages
00125   {
00126   // ______ Private data of bk_message class ______
00127   private:
00128     bool print_cout;//    switch to print or not to cout
00129     bool print_cerr;//    switch to print or not to cerr
00130     bool do_exit_;//      switch to exit after print or not
00131     int  ringbell_;//     number of times to ring bell.
00132     int  strwidth;//      original str.width();
00133     int  strprecision;//  original str.precision();
00134     char name_[10];//     identifyer, <9 chars (PROGRESS)
00135     ostrstream buf;//     message buffer stream
00136     int nummessages;//    counter
00137     char first_messages[6][256];// summary first 6 at end or at exit;
00138 
00139   // ______ Public function of bk_message class ______
00140   public:
00141     // ___Constructor/Destructor___
00142     bk_messages()
00143       {
00144       //cerr << "YOU ARE IN THE CONSTRUCTOR\n";
00145       print_cout  = true;//  default do print;
00146       print_cerr  = false;// default no print to cerr;
00147       do_exit_    = false;// default no exit after print
00148       ringbell_   = 0;//     default no bell;
00149       strwidth    = buf.width();
00150       strprecision= buf.precision();
00151       strcpy(name_,"???????");// default identifyer
00152       nummessages = 0;
00153       // --- allocate enough space, then freeze it?, and keep this
00154       // --- stream as is ---
00155       // --- this is required, at g++, and can't really hurt ---
00156       buf.seekp(0);
00157       buf << ends
00158           << "This is the constructor...This is the constructor..."
00159           << "This is the constructor...This is the constructor..."
00160           << "This is the constructor...This is the constructor..."
00161           << "This is the constructor...This is the constructor..."
00162           << "This is the constructor...This is the constructor..."
00163           << ends;
00164       buf.seekp(0);// reset pointer
00165       //      //buf.rdbuf()->freeze(0); // Unfreeze
00166       //      //buf.rdbuf()->freeze(); // freeze string, keep allocated mem
00167       //      buf.freeze();// freeze string, keep allocated memory ???
00168       }
00169 
00170     // ___Constructor/Destructor___
00171     ~bk_messages()                 //{;}// nothing to destruct
00172       {
00173       delete []buf.str();
00174       }// dealloc
00175 
00176     // ___Helper functions___
00177     void terminate()            {buf<<ends;}
00178     void rewind()               {buf.seekp(0);}
00179     char* get_id()              {return name_;}
00180     void dostderr(bool s)       {print_cerr = s;}
00181     void doprint(bool s)        {print_cout = s;}
00182     void doexit(bool s)         {do_exit_   = s;}
00183     void bellrings(int s)       {ringbell_  = s;}
00184     int  width()          const {return int(buf.width());}
00185     void width(int s)           {buf.width(s);}
00186     int  precision()      const {return int(buf.precision());}
00187     void precision(int s)       {buf.precision(s);}
00188     //void setiosflags(long s)    {buf.setiosflags(s);}
00189     //void resetiosflags(long s)  {buf.resetiosflags(s);}
00190     //void unsetf(long s)         {buf.unsetf(s);} // is this standard?
00191     void reset()                {// what does resetiosflags do?
00192                                  // add all flags?
00193                                  buf << resetiosflags(
00194                                         ios::fixed       |
00195                                         ios::showpoint   | 
00196                                         ios::skipws      |
00197                                         ios::showpos     |
00198                                         ios::scientific  |
00199                                         ios::left        |
00200                                         ios::right       |
00201                                         ios::floatfield  |
00202                                         ios::adjustfield);
00203                                  width(strwidth);
00204                                  precision(strprecision);
00205                                  terminate();
00206                                  rewind();
00207                                 }
00208 
00209     // ___Set a name to prepend to message string___
00210     void setidentifyer(const char *id)
00211       {
00212       // ___ only use first 9 of ID string ___
00213       if (strlen(id)>=10)
00214         {
00215         strncpy(name_,id, 9);
00216         strcat(name_,'\0');// terminate id
00217         }
00218       else
00219         {
00220         strcpy(name_,id);// identifyer
00221         }
00222       // ___ default message behavior for some identifyers ___
00223       if (!strcmp(id,"ERROR"))
00224         {
00225         do_exit_   = true;// default message behavior
00226         print_cerr = true;
00227         ringbell_  = 3;
00228         }
00229       else if (!strcmp(id,"WARNING"))
00230         {
00231         ringbell_ = 2;
00232         print_cerr = true;
00233         }
00234       else if (!strcmp(id,"PROGRESS"))
00235         {
00236         ringbell_ = 1;
00237         print_cerr = true;
00238         }
00239       }
00240 
00241     // ___ problem that buf.str() empties string buffer, thus do cp ___
00242     // ___ append a null, since common use will be to get a copy after written fully ___
00243     // ___ this returns a pointer to buf, thus, that may be changed afterwards ___
00244     // ___ use immediately? ___
00245     //char* get_str() {return buf.str();}
00246     char* get_str()
00247       {
00248       char *s = buf.str();
00249       buf.freeze(0);// unfreeze, since str() freezes it (does not seem to work?) 
00250       return s;
00251       }
00252 
00253     // ___What it is all about, print the message___
00254     // ___the buffer pointer is set to (0), but the message is not deleted___
00255     // ___so people can access the buffer multiple times___
00256     // ___but you cannot add to it later...____
00257     void print()
00258       {
00259       // --- Allways rewind string to prevent unlimited growth ---
00260       // --- Only terminate it when new info is there ------------
00261       //cerr << "pcount: " << buf.pcount() << endl;
00262       if (buf.pcount()>0) {terminate(); rewind();}
00263       print(buf.str());
00264       buf.freeze();
00265       }
00266 
00267     // ___What it is all about, print the message___
00268     // ___the buffer pointer is set to (0), but the message is not deleted___
00269     // ___so people can access the buffer multiple times___
00270     // ___but you cannot add to it later...____
00271     void print(const char *s)
00272       {
00273       if (nummessages<6) strcpy(first_messages[nummessages],s);
00274       nummessages++;
00275       // --- only print if level has been set ----------------------
00276       if(print_cout==true)
00277         {
00278         if (do_exit_==true) 
00279           cout << endl << "!!! ABNORMAL TERMINATION !!!" << endl;
00280         cout << setw(8) << setiosflags(ios::left) << name_ << ": " << s << endl;
00281         if (print_cerr==true)
00282           cerr << setw(8) << setiosflags(ios::left) << name_ << ": " << s << endl;
00283         // --- Ring bell -----------------------------------------
00284         for (int i=0;i<ringbell_;++i) cerr << "\a";
00285         // --- Exit ----------------------------------------------
00286         if (do_exit_==true) 
00287           {
00288           /* with a define you can print other stuff at exit...
00289            * #define printERROR cout<<"this is defined...\n"; \
00290            * warning.summary(); error<<" ("<<__FILE__<<": "
00291            *  <<__LINE__<<")"; error.print();
00292            */
00293           cerr << endl << "!!! ABNORMAL TERMINATION !!!" << endl;
00294           exit(9999);
00295           // Bert Kampes, 31-Mar-2005: throw relevant exception
00296           //cerr << "throwing string exception" << endl;
00297           //throw("!!! ABNORMAL TERMINATION !!!");// handle exception as string
00298           }
00299         }
00300       }
00301 
00302 
00303     // --- SUMMARY OF FIRST 6 MESSAGES ----------------------------
00304     // --- on stderr and stdout -----------------------------------
00305     void summary()
00306       {
00307       for (int i=0;i<ringbell_;++i) cerr << "\a";
00308       cout << endl << " --- " << setiosflags(ios::left) << name_ << " SUMMARY ---" << endl;
00309       //if (print_cerr==true)
00310       cerr << endl << " --- " << setiosflags(ios::left) << name_ << " SUMMARY ---" << endl;
00311       switch (nummessages)
00312         {
00313         case 0:
00314           cout << "There were no messages." << endl;
00315           cerr << "There were no messages." << endl;
00316         break;
00317         case 1:
00318           cout << "There was 1 message:" << endl
00319                << " 1: " << first_messages[0] << endl;
00320           cerr << "There was 1 message:" << endl
00321                << " 1: " << first_messages[0] << endl;
00322         break;
00323         default:
00324           cout << "There were " << nummessages << " messages:" << endl;
00325           cerr << "There were " << nummessages << " messages:" << endl;
00326           for (int i=0; i<nummessages; ++i)
00327             {
00328             if (i==6) 
00329               {
00330               cout << " " << i+1 << ": [...]" << endl;
00331               cerr << " " << i+1 << ": [...]" << endl;
00332               break; // only first six
00333               }
00334             cout << " " << i+1 << ": " << first_messages[i] << endl;
00335             cerr << " " << i+1 << ": " << first_messages[i] << endl;
00336             }
00337         }// switch nummessages
00338      }
00339 
00340     // ___Operator to build string from different types___
00341     // ostream& operator << (const int    X) {return buf << X;} 
00342     template <class Type> 
00343       ostream& operator << (const Type X) {return buf << X;}
00344 
00345     // ___ e.g., cout  << info; ___
00346     // ___ e.g., ofile << info; ___
00347     // friend ostream& operator << (ostream& s)
00348     // ostream& operator << (ostream& s, const bk_message &X)
00349     //    {
00350     //      if(print_cout==true)
00351     //        {
00352     //       X.terminate();
00353     //  s << X.getid() << ": " << X.getstr() << endl;
00354     //  X.rewind();
00355     //        buf << ends;
00356     //        s << name_ << ": " << buf.str() << endl;
00357     //        buf.seekp(0);
00358     //        }
00359     //      return s;
00360     //      }
00361 
00362   };// eof class
00363 
00364 
00365 #endif // BK_MESSAGES_H
00366 

Generated on Fri Apr 22 15:57:48 2005 for Doris by doxygen 1.3.6