My Project
OSOutput.cpp
Go to the documentation of this file.
1/* $Id: OSOutput.cpp 3172 2012-11-12 04:59:24Z Gassmann $ */
16#include "OSConfig.h"
17#include "OSErrorClass.h"
18#include "OSParameters.h"
19#include "OSOutput.h"
20
21#include <string>
22#include <vector>
23#include <iostream>
24#include <sstream>
25
26#ifdef HAVE_CSTDIO
27# include <cstdio>
28#else
29# ifdef HAVE_STDIO_H
30# include <stdio.h>
31# else
32# error "don't have header file for stdio"
33# endif
34#endif
35
36
37// define the osoutput instance that takes care of all output (see ticket 14)
38// It is declared here as a global variable so as to minimize the changes to the API
39const OSSmartPtr</*const*/ OSOutput> osoutput = new OSOutput();
40
41
43{
44 this->name = name;
45 for (int i=0; i<ENUM_OUTPUT_AREA_NUMBER_OF_AREAS; i++)
47 if (this->name != "stderr" && this->name != "stdout")
48 {
49 this->file = fopen (this->name.c_str(), "w+" );
50 std::string temp = ("Could not open file " + this->name);
51 if (this->file == NULL) throw ErrorClass(temp);
52 }
53}
54
58
60{
61 return name;
62}
63
65{
66#ifdef NDEBUG
67 if (level > ENUM_OUTPUT_LEVEL_debug)
68 throw ErrorClass("Encountered print level not supported in production code.\n Recompile with debug enabled.");
69#endif
70 printLevel[area] = level;
71 return true;
72}
73
75{
76#ifdef NDEBUG
77 if (level > ENUM_OUTPUT_LEVEL_debug)
78 throw ErrorClass("Encountered print level not supported in production code.\n Recompile with debug enabled.");
79#endif
80 for (int i=0; i < ENUM_OUTPUT_AREA_NUMBER_OF_AREAS; i++)
81 printLevel[i] = level;
82 return true;
83
84}
85
92{
93 if (dim < 0)
94 throw ErrorClass("Array of output levels must have nonnegative size.");
96 for (int i=0; i < n; i++)
97 {
98#ifdef NDEBUG
99 if (level[i] > ENUM_OUTPUT_LEVEL_debug)
100 throw ErrorClass("Encountered print level not supported in production code.\n Recompile with debug enabled.");
101#endif
102 printLevel[i] = level[i];
103 }
104 for (int i=n+1; i < ENUM_OUTPUT_AREA_NUMBER_OF_AREAS; i++)
106 return true;
107 }
108
110{
111 return (level <= printLevel[area]);
112}
113
115{
116 if (isAccepted(area,level))
117 {
118 if (this->name == "stderr")
119 fprintf(stderr, "%s\n", str.c_str());
120 else if (this->name == "stdout")
121 printf("%s\n", str.c_str());
122 else
123 if (this->file != NULL)
124 fprintf(file, "%s\n", str.c_str());
125 else
126 throw ErrorClass("File not open for output");
127 return;
128 }
129}
130
132{
133 if (file != NULL)
134 fflush(file);
135 else
136 throw ErrorClass("File not open for output");
137 return;
138}
139
141{
142 if (name == "stdout")
143 {
144 file = stdout;
145 return true;
146 }
147 if (name == "stderr")
148 {
149 file = stderr;
150 return true;
151 }
152 if (file != NULL)
153 throw ErrorClass ("File previously opened.");
154 file = fopen(name.c_str(), "w");
155 if (file != NULL)
156 return true;
157 return false;
158}
159
160
162{
163 std::string temp = "stdout";
164 nOfOutputs = 1;
166 outputChannel[0] = new OSOutputChannel(temp);
167}
168
170{
171 for (int i=0; i < nOfOutputs; i++)
172 delete outputChannel[i];
173 delete [] outputChannel;
174 outputChannel = NULL;
175 nOfOutputs = 0;
176}
177
178bool OSOutput::OSPrint(ENUM_OUTPUT_AREA area, ENUM_OUTPUT_LEVEL level, std::string outStr)
179{
180 for (int i=0; i < nOfOutputs; i++)
181 {
182 if (outputChannel[i]->isAccepted(area,level))
183 outputChannel[i]->OSPrintf(area, level, outStr);
184 }
185 return true;
186}
187
189{
190 for (int i=0; i < nOfOutputs; i++)
191 outputChannel[i]->flushBuffer();
192}
193
194bool OSOutput::SetPrintLevel(std::string name, ENUM_OUTPUT_LEVEL* level, int dim)
195{
196 int k = FindChannel(name);
197 if (k < 0)
198 throw ErrorClass("Device was not defined before");
199 for (int i=1; i<dim; i++)
200 {
201 if (level[i] < 0)
202 throw ErrorClass("printLevel must be nonnegative");
203 else if (level[i] >= ENUM_OUTPUT_LEVEL_NUMBER_OF_LEVELS)
204 throw ErrorClass("illegal printLevel specified");
205 }
206 return (outputChannel[k]->setAllPrintLevels(level, dim));
207}
208
209bool OSOutput::SetPrintLevel(std::string name, ENUM_OUTPUT_LEVEL level)
210{
211 int aLevel, area;
212 int k = FindChannel(name);
213 if (k < 0)
214 throw ErrorClass("Device was not defined before");
215 if (level < 0)
216 throw ErrorClass("printLevel must be nonnegative");
217 if (level < 100)
219 throw ErrorClass("illegal printLevel specified");
220 else
221 return (outputChannel[k]->setAllPrintLevels((ENUM_OUTPUT_LEVEL)level));
222 else
223 {
224 aLevel = level % 100;
225 area = level / 100;
227 throw ErrorClass("illegal printLevel specified");
228 else
229 return (outputChannel[k]->setPrintLevel((ENUM_OUTPUT_AREA)area, (ENUM_OUTPUT_LEVEL)aLevel));
230 }
231}
232
233int OSOutput::AddChannel(std::string name)
234{
235 if (FindChannel(name) >= 0)
236 {
237 if (name == "stdout")
238 return 0;
239 else
240 return 1;
241 }
242
243 bool noMem = false;
244
245 try
246 {
247 int ndev;
248 int i;
249
250 if (this->outputChannel == NULL)
251 ndev = 0;
252 else
253 ndev = this->nOfOutputs;
254
255 noMem = true;
256 OSOutputChannel** temp = new OSOutputChannel*[ndev+1]; //Allocate the new pointers
257 noMem = false;
258 for (i = 0; i < ndev; i++)
259 temp[i] = this->outputChannel[i]; //copy the pointers
260
261 delete[] this->outputChannel; //delete old pointers
262
263// add in the new element
264 noMem = true;
265 temp[ndev] = new OSOutputChannel(name);
266 noMem = false;
267
268 this->outputChannel = temp; //hook the new pointers into the data structure
269 this->nOfOutputs = ++ndev;
270 return 0;
271 }
272 catch(const ErrorClass& eclass)
273 {
274 if (noMem)
275 return 2;
276 return 3;
277 }
278}// AddChannel
279
280bool OSOutput::DeleteChannel(std::string name)
281{
282 int k = FindChannel(name);
283 if (k < 0)
284 return false;
285 delete this->outputChannel[k];
286
287 int ndev = this->nOfOutputs;
288 int i;
289
290 if (ndev == 1)
291 {
292 delete[] this->outputChannel;
293 this->outputChannel = NULL;
294 }
295 else
296 {
297 OSOutputChannel** temp = new OSOutputChannel*[ndev-1]; //Allocate the new pointers
298 for (i = 0; i < k; i++)
299 temp[i] = this->outputChannel[i]; //copy the pointers
300 for (i = k+1; i < ndev; i++)
301 temp[i] = this->outputChannel[i+1]; //skip the deleted channel
302
303 delete[] this->outputChannel; //delete old pointers
304
305 this->outputChannel = temp; //hook the new pointers into the data structure
306 }
307
308 this->nOfOutputs = ++ndev;
309 return true;
310}// DeleteChannel
311
312int OSOutput::FindChannel(std::string name)
313{
314 for (int i=0; i < nOfOutputs; i++)
315 if (outputChannel[i]->Name() == name) return i;
316 return -1;
317}
318
const OSSmartPtr< OSOutput > osoutput
Definition OSOutput.cpp:39
used for throwing exceptions.
a class that holds information about one output channel (file, device, stream, peripheral,...
Definition OSOutput.h:42
bool setAllPrintLevels(ENUM_OUTPUT_LEVEL level)
Set the print level for all areas.
Definition OSOutput.cpp:74
~OSOutputChannel()
Destructor.
Definition OSOutput.cpp:55
int printLevel[ENUM_OUTPUT_AREA_NUMBER_OF_AREAS]
vector of integers indicating the level for each area
Definition OSOutput.h:57
std::string name
used to give a name to the file or device
Definition OSOutput.h:47
void flushBuffer()
Flush output buffer.
Definition OSOutput.cpp:131
FILE * file
holds a pointer to the file or device
Definition OSOutput.h:52
void OSPrintf(ENUM_OUTPUT_AREA area, ENUM_OUTPUT_LEVEL level, std::string str)
Send one string to the output device provided that the output device "accepts" the output (i....
Definition OSOutput.cpp:114
std::string Name()
Get the name of the output channel.
Definition OSOutput.cpp:59
bool isAccepted(ENUM_OUTPUT_AREA area, ENUM_OUTPUT_LEVEL level)
Test if the device accepts a particular combination of print level and area (i.e.,...
Definition OSOutput.cpp:109
bool setPrintLevel(ENUM_OUTPUT_AREA area, ENUM_OUTPUT_LEVEL level)
Set the print level for a particular area.
Definition OSOutput.cpp:64
OSOutputChannel(std::string name)
Constructor.
Definition OSOutput.cpp:42
This class handles all the output from OSSolverService, OSAmplClient and other executables derived fr...
Definition OSOutput.h:147
~OSOutput()
Destructor.
Definition OSOutput.cpp:169
int nOfOutputs
The number of output channels that have been defined.
Definition OSOutput.h:223
int FindChannel(std::string name)
Find the position of a channel within the array *outputChannel.
Definition OSOutput.cpp:312
int AddChannel(std::string name)
Add a channel to the array outputChannel.
Definition OSOutput.cpp:233
OSOutputChannel ** outputChannel
The array of output channels currently in use.
Definition OSOutput.h:228
bool DeleteChannel(std::string name)
Delete a channel from the array outputChannel.
Definition OSOutput.cpp:280
OSOutput()
Constructor.
Definition OSOutput.cpp:161
bool OSPrint(ENUM_OUTPUT_AREA area, ENUM_OUTPUT_LEVEL level, std::string outStr)
This is the main method to output a string All output generated by the program should ultimately use ...
Definition OSOutput.cpp:178
void FlushAllBuffers()
Flush all buffers.
Definition OSOutput.cpp:188
bool SetPrintLevel(std::string name, ENUM_OUTPUT_LEVEL *level, int dim)
Modify all print levels associated with a channel.
Definition OSOutput.cpp:194
Template class for Smart Pointers.
#define DEFAULT_OUTPUT_LEVEL
ENUM_OUTPUT_LEVEL
Enumeration for the different verbosity levels that can be used in producing output.
@ ENUM_OUTPUT_LEVEL_debug
@ ENUM_OUTPUT_LEVEL_error
@ ENUM_OUTPUT_LEVEL_NUMBER_OF_LEVELS
ENUM_OUTPUT_AREA
Enumeration for the different areas that can produce output.
@ ENUM_OUTPUT_AREA_NUMBER_OF_AREAS