Line data Source code
1 : // -*- C++ -*-
2 : /***************************************************************************
3 : *
4 : * The IPPL Framework
5 : *
6 : *
7 : * Visit http://people.web.psi.ch/adelmann/ for more details
8 : *
9 : ***************************************************************************/
10 :
11 : #ifndef INFORM_H
12 : #define INFORM_H
13 :
14 : /*
15 : * Inform - takes messages and displays them to the given ostream.
16 : * A message is sent to an Inform object by treating it as an ostream,
17 : * then ending the message by sending the 'inform' manipulator. In
18 : * fact, Inform works much like an ostream, although it may actually
19 : * just use stdio for I/O.
20 : *
21 : * Each message is assigned the current 'level of interest'; the lower
22 : * the level, the more important it is. Each Inform object is also
23 : * set for a current level; messages with a level <= the current level
24 : * are displayed. Levels run from 1 ... 5. Thus, setting the level of
25 : * Inform object to 0 will turn off printing of all messages.
26 : *
27 : * By default, a new Inform object will only print out the message on
28 : * node 0. You may change the node on which this prints with the
29 : * 'setPrintNode(int)' method; if the argument is 'INFORM_ALL_NODES',
30 : * the message will be printed on ALL nodes, not just one. The final
31 : * argument to the constructor may also be set to the node to print on.
32 : */
33 :
34 : #include <iomanip>
35 : #include <iostream>
36 : #include <sstream>
37 :
38 : #define INFORM_ALL_NODES (-1)
39 :
40 : class Inform {
41 : public:
42 : // enumeration listing the ways in which a file may be opened for writing
43 : enum WriteMode {
44 : OVERWRITE,
45 : APPEND
46 : };
47 :
48 : public:
49 : // constructor: arguments = name, print node
50 : Inform(const char* = 0, int = 0);
51 :
52 : // second constructor: this specifies the name of a file as well as
53 : // a prefix and a mode for opening the file (i.e. OVERWRITE or APPEND).
54 : // The final argument is the print node.
55 : Inform(const char* prefix, const char* fname, const WriteMode, int = 0);
56 :
57 : // third constructor: this specifies the prefix and an ostream object
58 : // to write to, as well as as the print node
59 : Inform(const char*, std::ostream&, int = 0);
60 :
61 : // fourth constructor: this specifies the prefix and an Inform instance
62 : // from which the ostream object is copied, as well as as the print node
63 : Inform(const char* myname, const Inform& os, int pnode = 0);
64 :
65 : // destructor
66 : ~Inform();
67 :
68 : // turn messages on/off
69 : void on(const bool o) { On = o; }
70 : bool isOn() const { return On; }
71 :
72 : // change output destination
73 : void setDestination(std::ostream& dest);
74 0 : std::ostream& getDestination() { return *MsgDest; }
75 :
76 : // get/set the current output level
77 : Inform& setOutputLevel(const int);
78 1684 : int getOutputLevel(void) const { return OutputLevel; }
79 :
80 : // get/set the current message level
81 : Inform& setMessageLevel(const int);
82 : int getMessageLevel(void) const { return MsgLevel; }
83 :
84 : // get/set the printing node. If set to a value < 0, all nodes print.
85 : int getPrintNode() const { return PrintNode; }
86 : void setPrintNode(int n = (-1)) { PrintNode = n; }
87 :
88 : // return a reference to the internal ostream used to print messages
89 0 : std::ostream& getStream() { return FormatBuf; }
90 :
91 : // Was the stream opened successfully on construction?
92 : bool openedSuccessfully() { return OpenedSuccessfully; }
93 :
94 : // the signal has been given, print out the message. Return ref to object.
95 : Inform& outputMessage(void);
96 :
97 : // functions used to change format state; used just as for iostreams
98 :
99 : typedef std::ios_base::fmtflags FmtFlags_t;
100 :
101 0 : FmtFlags_t setf(FmtFlags_t setbits, FmtFlags_t field) { return FormatBuf.setf(setbits, field); }
102 :
103 : FmtFlags_t setf(FmtFlags_t f) { return FormatBuf.setf(f); }
104 : void /*long*/ unsetf(FmtFlags_t f) { FormatBuf.unsetf(f); }
105 : FmtFlags_t flags() const { return FormatBuf.flags(); }
106 : FmtFlags_t flags(FmtFlags_t f) { return FormatBuf.flags(f); }
107 : int width() const { return FormatBuf.width(); }
108 : int width(int w) { return FormatBuf.width(w); }
109 : char fill() const { return FormatBuf.fill(); }
110 : char fill(char c) { return FormatBuf.fill(c); }
111 : int precision() const { return FormatBuf.precision(); }
112 0 : int precision(int p) { return FormatBuf.precision(p); }
113 0 : void flush() { MsgDest->flush(); }
114 :
115 : private:
116 : // name of this object; put at the start of each message.
117 : char* Name;
118 :
119 : // storage for the message text
120 : std::string MsgBuf;
121 : // an ostringstream used to format the messages
122 : std::ostringstream FormatBuf;
123 :
124 : // where to put the messages; can be changed, by default = cout
125 : std::ostream* MsgDest;
126 :
127 : // do we need to close the destination stream?
128 : bool NeedClose;
129 :
130 : // Was the stream opened successfully on construction?
131 : bool OpenedSuccessfully;
132 :
133 : // do we output the message?
134 : bool On;
135 :
136 : // limit printing only to this node (if < 0, all nodes print)
137 : int PrintNode;
138 :
139 : // output level of this Inform object; messages with a level <= the output
140 : // level are printed. Setting this to < 1 turns off messages.
141 : int OutputLevel;
142 :
143 : // current message level; this is set by the 'levelN' manipulators, or
144 : // by the routine setMsgLevel(int). After a message is printed, the current
145 : // message level is reset to the minimum.
146 : int MsgLevel;
147 :
148 : // print out the message in the given buffer. Will modify the string,
149 : // so beware. Arguments: string
150 : void display_message(char*);
151 :
152 : // print out just a single line of the message.
153 : void display_single_line(char*);
154 :
155 : // perform initialization for this object; called by the constructors.
156 : // arguments = prefix string, print node
157 : void setup(const char*, int);
158 : };
159 :
160 : // manipulator for signaling we want to send the message.
161 : extern Inform& endl(Inform&);
162 :
163 : // manipulators for setting the current msg level
164 : extern Inform& level1(Inform&);
165 : extern Inform& level2(Inform&);
166 : extern Inform& level3(Inform&);
167 : extern Inform& level4(Inform&);
168 : extern Inform& level5(Inform&);
169 :
170 : // templated version of operator<< for Inform objects
171 : template <class T>
172 0 : inline Inform& operator<<(Inform& o, const T& val) {
173 0 : o.getStream() << val;
174 0 : return o;
175 : }
176 :
177 : // specialized version of operator<< to handle Inform-specific manipulators
178 0 : inline Inform& operator<<(Inform& o, Inform& (*d)(Inform&)) {
179 0 : return d(o);
180 : }
181 :
182 : // specialized version of operator<< to handle void * arguments
183 : inline Inform& operator<<(Inform& o, const void* val) {
184 : Inform::FmtFlags_t oldformat = o.setf(std::ios::hex, std::ios::basefield);
185 : o.getStream() << "0x" << (long)val;
186 : o.setf(oldformat, std::ios::basefield);
187 : return o;
188 : }
189 :
190 : // specialized version of operator<< to handle long long type (KCC workaround)
191 : inline Inform& operator<<(Inform& o, const long long& val) {
192 : o.getStream() << val;
193 : return o;
194 : }
195 :
196 : // specialized function for sending strings to Inform object
197 0 : inline Inform& operator<<(Inform& out, const std::string& s) {
198 0 : out << s.c_str();
199 0 : return out;
200 : }
201 :
202 : #endif // INFORM_H
203 :
204 : /***************************************************************************
205 : * $RCSfile: Inform.h,v $ $Author: adelmann $
206 : * $Revision: 1.1.1.1 $ $Date: 2003/01/23 07:40:33 $
207 : * IPPL_VERSION_ID: $Id: Inform.h,v 1.1.1.1 2003/01/23 07:40:33 adelmann Exp $
208 : ***************************************************************************/
|