Eclipse SUMO - Simulation of Urban MObility
Loading...
Searching...
No Matches
MsgHandler.cpp
Go to the documentation of this file.
1/****************************************************************************/
2// Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3// Copyright (C) 2001-2023 German Aerospace Center (DLR) and others.
4// This program and the accompanying materials are made available under the
5// terms of the Eclipse Public License 2.0 which is available at
6// https://www.eclipse.org/legal/epl-2.0/
7// This Source Code may also be made available under the following Secondary
8// Licenses when the conditions for such availability set forth in the Eclipse
9// Public License 2.0 are satisfied: GNU General Public License, version 2
10// or later which is available at
11// https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html
12// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later
13/****************************************************************************/
20// Retrieves messages about the process and gives them further to output
21/****************************************************************************/
22#include <config.h>
23
24#include <string>
25#include <cassert>
26#include <vector>
27#include <algorithm>
28#include <iostream>
32#include "MsgHandler.h"
33
34
35// ===========================================================================
36// static member variables
37// ===========================================================================
47
48
49// ===========================================================================
50// method definitions
51// ===========================================================================
52
64
65
77
78
86
87
95
96
104
105
106void
110
111void
115
116
117std::string
118MsgHandler::insertLineBreaks(std::string msg, int lineWidth) {
119 // TODO: check what FXFont::getTextWidth can do
120 //int textWidth = getApp()->getNormalFont()->getTextWidth
121 if ((int)msg.size() <= lineWidth) {
122 return msg;
123 }
124 size_t pos = 0;
125 size_t nextLineBreak = msg.find('\n');
126 size_t spaceAfterLine = msg.find(' ', lineWidth);
127 while (spaceAfterLine != std::string::npos) {
128 if (nextLineBreak == std::string::npos || nextLineBreak > spaceAfterLine) {
129 msg = msg.replace(spaceAfterLine, 1, "\n");
130 pos = spaceAfterLine + 1;
131 } else {
132 pos = nextLineBreak + 1;
133 }
134 spaceAfterLine = msg.find(' ', pos + lineWidth);
135 nextLineBreak = msg.find('\n', pos);
136 }
137 return msg;
138}
139
140
141void
142MsgHandler::inform(std::string msg, bool addType) {
143 if (addType && !myInitialMessages.empty() && myInitialMessages.size() < 5) {
144 myInitialMessages.push_back(msg);
145 }
146 // beautify progress output
148 myAmProcessingProcess = false;
150 }
151 msg = build(msg, addType);
152 // inform all receivers
153 for (auto i : myRetrievers) {
154 i->inform(msg);
155 }
156 // set the information that something occurred
157 myWasInformed = true;
158}
159
160
161void
162MsgHandler::beginProcessMsg(std::string msg, bool addType) {
163 msg = build(msg, addType);
164 // inform all other receivers
165 for (auto i : myRetrievers) {
166 i->inform(msg, ' ');
168 }
169 // set the information that something occurred
170 myWasInformed = true;
171}
172
173
174void
175MsgHandler::endProcessMsg2(bool success, long duration) {
176 if (success) {
177 if (duration > -1) {
178 endProcessMsg(TLF("done (%ms).", toString(duration)));
179 } else {
180 endProcessMsg(TL("done."));
181 }
182 } else {
183 endProcessMsg(TL("failed."));
184 }
185}
186
187
188void
190 // inform all other receivers
191 for (auto i : myRetrievers) {
192 i->inform(msg);
193 }
194 // set the information that something occurred
195 myWasInformed = true;
196 myAmProcessingProcess = false;
197}
198
199
200void
201MsgHandler::clear(bool resetInformed) {
202 if (myAggregationThreshold >= 0) {
203 for (const auto& i : myAggregationCount) {
204 if (i.second > myAggregationThreshold) {
205 inform(toString(i.second) + " total messages of type: " + i.first);
206 }
207 }
208 }
209 myAggregationCount.clear();
210 if (!resetInformed && myInitialMessages.size() > 1) {
211 const bool wasInformed = myWasInformed;
212 for (const std::string& msg : myInitialMessages) {
213 inform(msg, false);
214 }
215 myInitialMessages.clear();
217 }
218 if (resetInformed) {
219 myWasInformed = false;
220 }
221}
222
223
224void
226 if (!isRetriever(retriever)) {
227 myRetrievers.push_back(retriever);
228 }
229}
230
231
232void
234 std::vector<OutputDevice*>::iterator i = find(myRetrievers.begin(), myRetrievers.end(), retriever);
235 if (i != myRetrievers.end()) {
236 myRetrievers.erase(i);
237 }
238}
239
240
241bool
243 return std::find(myRetrievers.begin(), myRetrievers.end(), retriever) != myRetrievers.end();
244}
245
246
247void
249 if (myDebugInstance != nullptr) {
251 }
252 if (myGLDebugInstance != nullptr) {
254 }
255 if (myErrorInstance != nullptr) {
257 }
258 if (myWarningInstance != nullptr) {
260 }
261 if (myMessageInstance != nullptr) {
263 }
264}
265
266
267void
268MsgHandler::setupI18n(const std::string& locale) {
269#ifdef HAVE_INTL
270 if (locale != "") {
271#ifdef WIN32
272 _putenv_s("LANGUAGE", locale.data());
273#else
274 setenv("LANGUAGE", locale.data(), true);
275#endif
276 }
277 if (!setlocale(LC_MESSAGES, "")) {
278 WRITE_WARNINGF(TL("Could not set locale to '%'."), locale);
279 }
280 const char* sumoPath = getenv("SUMO_HOME");
281 if (sumoPath == nullptr) {
282 if (!bindtextdomain("sumo", nullptr)) {
283 WRITE_WARNING(TL("Environment variable SUMO_HOME is not set, could not find localized messages."));
284 return;
285 }
286 } else {
287 const std::string path = sumoPath + std::string("/data/locale/");
288 if (!bindtextdomain("sumo", path.data())) {
289 WRITE_WARNING(TL("Could not find localized messages."));
290 return;
291 }
292 }
293 bind_textdomain_codeset("sumo", "UTF-8");
294 textdomain("sumo");
295#else
296 UNUSED_PARAMETER(locale);
297#endif
298}
299
300
301void
303 // initialize console properly
304 OutputDevice::getDevice("stdout");
305 OutputDevice::getDevice("stderr");
307 getWarningInstance()->setAggregationThreshold(oc.getInt("aggregate-warnings"));
308 getErrorInstance()->setAggregationThreshold(oc.getInt("aggregate-warnings"));
309 if (oc.getBool("no-warnings")) {
311 }
312 // build the logger if possible
313 if (oc.isSet("log", false)) {
314 OutputDevice* logFile = &OutputDevice::getDevice(oc.getString("log"));
315 getErrorInstance()->addRetriever(logFile);
316 if (!oc.getBool("no-warnings")) {
318 }
320 }
321 if (oc.isSet("message-log", false)) {
322 OutputDevice* logFile = &OutputDevice::getDevice(oc.getString("message-log"));
324 }
325 if (oc.isSet("error-log", false)) {
326 OutputDevice* logFile = &OutputDevice::getDevice(oc.getString("error-log"));
327 getErrorInstance()->addRetriever(logFile);
329 }
330 if (oc.getBool("verbose")) {
331 getErrorInstance()->myInitialMessages.push_back("Repeating initial error messages:");
332 } else {
334 }
335}
336
337
338void
340 delete myMessageInstance;
341 myMessageInstance = nullptr;
342 delete myWarningInstance;
343 myWarningInstance = nullptr;
344 delete myErrorInstance;
345 myErrorInstance = nullptr;
346 delete myDebugInstance;
347 myDebugInstance = nullptr;
348 delete myGLDebugInstance;
349 myGLDebugInstance = nullptr;
350}
351
352
354 myType(type), myWasInformed(false), myAggregationThreshold(-1) {
355 if (type == MsgType::MT_MESSAGE) {
357 } else {
359 }
360}
361
362
365
366
367bool
369 return myWasInformed;
370}
371
372
373/****************************************************************************/
#define WRITE_WARNINGF(...)
Definition MsgHandler.h:271
#define WRITE_WARNING(msg)
Definition MsgHandler.h:270
#define TL(string)
Definition MsgHandler.h:287
#define TLF(string,...)
Definition MsgHandler.h:288
#define UNUSED_PARAMETER(x)
Definition StdDefs.h:30
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition ToString.h:46
virtual void addRetriever(OutputDevice *retriever)
Adds a further retriever to the instance responsible for a certain msg type.
std::vector< std::string > myInitialMessages
storage for initial messages
Definition MsgHandler.h:249
static MsgHandler * getGLDebugInstance()
Returns the instance to add GLdebug to.
bool wasInformed() const
Returns the information whether any messages were added.
static MsgHandler * getErrorInstance()
Returns the instance to add errors to.
virtual void inform(std::string msg, bool addType=true)
adds a new error to the list
static void enableDebugGLMessages(bool enable)
enable/disable gl-debug messages
static MsgHandler * myGLDebugInstance
The instance to handle glDebug.
Definition MsgHandler.h:218
static std::string insertLineBreaks(std::string msg, int lineWidth)
reformats a long string to contain newline after a certain line length in px (depending on the curren...
virtual void endProcessMsg(std::string msg)
Ends a process information.
std::string build(const std::string &msg, bool addType)
Builds the string which includes the mml-message type.
Definition MsgHandler.h:172
static Factory myFactory
The function to call for new MsgHandlers, nullptr means use default constructor.
Definition MsgHandler.h:212
bool myWasInformed
information whether an output occurred at all
Definition MsgHandler.h:237
static void setupI18n(const std::string &locale="")
set up gettext stuff
static void initOutputOptions()
init output options
static MsgHandler * myErrorInstance
The instance to handle errors.
Definition MsgHandler.h:221
static MsgHandler * getDebugInstance()
Returns the instance to add debug to.
static MsgHandler * myMessageInstance
The instance to handle normal messages.
Definition MsgHandler.h:227
bool isRetriever(OutputDevice *retriever) const
Returns whether the given output device retrieves messages from the handler.
static MsgHandler * getWarningInstance()
Returns the instance to add warnings to.
std::map< const std::string, int > myAggregationCount
count for messages of the same type
Definition MsgHandler.h:243
static void enableDebugMessages(bool enable)
enable/disable debug messages
static bool myAmProcessingProcess
Information whether a process information is printed to cout.
Definition MsgHandler.h:230
std::vector< OutputDevice * > myRetrievers
The list of retrievers that shall be informed about new messages or errors.
Definition MsgHandler.h:246
MsgHandler *(* Factory)(MsgType)
Definition MsgHandler.h:60
virtual ~MsgHandler()
destructor
virtual void clear(bool resetInformed=true)
Clears information whether an error occurred previously and print aggregated message summary.
static MsgHandler * myDebugInstance
The instance to handle debug.
Definition MsgHandler.h:215
void setAggregationThreshold(const int thresh)
Definition MsgHandler.h:200
static MsgHandler * myWarningInstance
The instance to handle warnings.
Definition MsgHandler.h:224
virtual void endProcessMsg2(bool success, long duration=-1)
Ends a process information with predefined messages.
virtual void beginProcessMsg(std::string msg, bool addType=true)
Begins a process information.
static bool myWriteDebugMessages
Flag to enable or disable debug GL Functions.
Definition MsgHandler.h:262
static bool myWriteDebugGLMessages
Definition MsgHandler.h:263
static void cleanupOnEnd()
Removes pending handler.
static void removeRetrieverFromAllInstances(OutputDevice *out)
ensure that that given output device is no longer used as retriever by any instance
virtual void removeRetriever(OutputDevice *retriever)
Removes the retriever from the handler.
int myAggregationThreshold
do not output more messages of the same type if the count exceeds this threshold
Definition MsgHandler.h:240
@ MT_GLDEBUG
The message is GL debug output.
@ MT_DEBUG
The message is debug output.
@ MT_MESSAGE
The message is only something to show.
@ MT_ERROR
The message is an error.
@ MT_WARNING
The message is a warning.
MsgHandler(MsgType type)
standard constructor
static MsgHandler * getMessageInstance()
Returns the instance to add normal messages to.
A storage for options typed value containers)
Definition OptionsCont.h:89
bool isSet(const std::string &name, bool failOnNonExistant=true) const
Returns the information whether the named option is set.
int getInt(const std::string &name) const
Returns the int-value of the named option (only for Option_Integer)
std::string getString(const std::string &name) const
Returns the string-value of the named option (only for Option_String)
bool getBool(const std::string &name) const
Returns the boolean-value of the named option (only for Option_Bool)
static OptionsCont & getOptions()
Retrieves the options.
Static storage of an output device and its base (abstract) implementation.
static OutputDevice & getDevice(const std::string &name, bool usePrefix=true)
Returns the described OutputDevice.