YARP
Yet Another Robot Platform
 
Loading...
Searching...
No Matches
utility.cpp
Go to the documentation of this file.
1/*
2 * SPDX-FileCopyrightText: 2006-2021 Istituto Italiano di Tecnologia (IIT)
3 * SPDX-License-Identifier: BSD-3-Clause
4 */
5
11
12#include <cstdio>
13#include <fstream>
14
15
16using namespace yarp::manager;
17
18
19//#if defined(_MSC_VER) && (_MSC_VER == 1600)
20
21StrStream::StrStream() = default;
22
23StrStream::StrStream(const std::string str) {
24 dummyStr = str;
25}
26
27StrStream::~StrStream() = default;
28
29std::string StrStream::str() {
30 return dummyStr;
31}
32
34 dummyStr += oss.str();
35 return *this;
36}
37
38StrStream& StrStream::operator<<(const std::string &str) {
39 dummyStr += str;
40 return *this;
41}
42
44 char buff[64];
45 sprintf(buff, "%d", n);
46 dummyStr += std::string(buff);
47 return *this;
48}
49
51 char buff[64];
52 sprintf(buff, "%.2f", n);
53 dummyStr += std::string(buff);
54 return *this;
55}
56
57
59 dummyStr = std::string(sz);
60 return *this;
61}
62
64 dummyStr = std::string(sz);
65 return *this;
66}
67
68StrStream& StrStream::operator = (const std::string &str) {
69 dummyStr = str;
70 return *this;
71}
72
74 dummyStr = oss.str();
75 return *this;
76}
77
79 char buff[64];
80 sprintf(buff, "%d", n);
81 dummyStr = std::string(buff);
82 return *this;
83}
84
85std::ostream& operator << (std::ostream &os , StrStream& sstr)
86{
87 std::cout<<sstr.str();
88 return os;
89}
90
91//#endif
92
93
99{
100 static ErrorLogger instance;
101 return &instance;
102}
103
104void ErrorLogger::addWarning(const char* szWarning) {
105 if (szWarning) {
107 std::string elapsedTime = getElapsedTimeString(clock.getStartTime());
108 std::string timeinfo = "[time: " + elapsedTime + "] ";
109 std::string szWarningWithTime = timeinfo + szWarning;
110 warnings.emplace_back(szWarningWithTime);
111 }
112}
113
114void ErrorLogger::addWarning(const std::string &str) {
116 std::string elapsedTime = getElapsedTimeString(clock.getStartTime());
117 std::string timeinfo = "[time: " + elapsedTime + "] ";
118 std::string strWithTime = timeinfo + str;
119 warnings.push_back(strWithTime);
120}
121
123 addWarning(stream.str());
124}
125
126void ErrorLogger::addError(const char* szError) {
127 if (szError) {
129 std::string elapsedTime = getElapsedTimeString(clock.getStartTime());
130 std::string timeinfo = "[time: " + elapsedTime + "] ";
131 std::string szErrorWithTime = timeinfo + szError;
132 errors.emplace_back(szErrorWithTime);
133 }
134}
135
136void ErrorLogger::addError(const std::string &str) {
138 std::string elapsedTime = getElapsedTimeString(clock.getStartTime());
139 std::string timeinfo = "[time: " + elapsedTime + "] ";
140 std::string strWithTime = timeinfo + str;
141 errors.push_back(strWithTime);
142}
143
145 addError(stream.str());
146}
147
149 if (errors.empty()) {
150 return nullptr;
151 }
152 static std::string msg;
153 msg = errors.back();
154 errors.pop_back();
155 return msg.c_str();
156}
157
159 static std::string msgs;
160 char* err;
161 while ((err = (char*)getLastError()) != nullptr) {
162 msgs += std::string(err) + " ";
163 }
164 return msgs.c_str();
165}
166
168 if (warnings.empty()) {
169 return nullptr;
170 }
171 static std::string msg;
172 msg = warnings.back();
173 warnings.pop_back();
174 return msg.c_str();
175}
176
178 static std::string msgs;
179 char* err;
180 while ((err = (char*)getLastWarning()) != nullptr) {
181 msgs += std::string(err) + " ";
182 }
183 return msgs.c_str();
184}
185
186
188 errors.clear(); warnings.clear();
189}
190
192 return errors.size();
193}
194
196
197 return warnings.size();
198}
199
200
201const std::string GRAPH_LEGEND =
202"{"
203" rank=sink;"
204" style=filled;"
205" color=lightgrey;"
206" Legend [shape=none, margin=0, label=<"
207" <TABLE BORDER=\"0\" CELLBORDER=\"1\" CELLSPACING=\"0\" CELLPADDING=\"4\" bgcolor=\"white\">"
208" <TR>"
209" <TD COLSPAN=\"2\"><B>Legend</B></TD>"
210" </TR>"
211" <TR>"
212" <TD align=\"left\">Application</TD>"
213" <TD CELLPADDING=\"4\">"
214" <TABLE BORDER=\"1\" CELLBORDER=\"0\" CELLSPACING=\"0\" CELLPADDING=\"0\">"
215" <TR>"
216" <TD BGCOLOR=\"darkseagreen\"> </TD>"
217" </TR>"
218" </TABLE>"
219" </TD>"
220" </TR>"
221" <TR>"
222" <TD align=\"left\">Module</TD>"
223" <TD CELLPADDING=\"4\">"
224" <TABLE BORDER=\"1\" CELLBORDER=\"0\" CELLSPACING=\"0\" CELLPADDING=\"0\">"
225" <TR>"
226" <TD BGCOLOR=\"lightslategrey\"> </TD>"
227" </TR>"
228" </TABLE>"
229" </TD>"
230" </TR>"
231" <TR>"
232" <TD align=\"left\">Res. Dependency</TD>"
233" <TD CELLPADDING=\"4\">"
234" <TABLE BORDER=\"1\" CELLBORDER=\"0\" CELLSPACING=\"0\" CELLPADDING=\"0\">"
235" <TR>"
236" <TD BGCOLOR=\"salmon\"> </TD>"
237" </TR>"
238" </TABLE>"
239" </TD>"
240" </TR>"
241" <TR>"
242" <TD align=\"left\">Res. Provider</TD>"
243" <TD CELLPADDING=\"4\">"
244" <TABLE BORDER=\"1\" CELLBORDER=\"0\" CELLSPACING=\"0\" CELLPADDING=\"0\">"
245" <TR>"
246" <TD BGCOLOR=\"indianred\"> </TD>"
247" </TR>"
248" </TABLE>"
249" </TD>"
250" </TR>"
251" <TR>"
252" <TD align=\"left\">Input data</TD>"
253" <TD CELLPADDING=\"4\">"
254" <TABLE BORDER=\"1\" CELLBORDER=\"0\" CELLSPACING=\"0\" CELLPADDING=\"0\">"
255" <TR>"
256" <TD BGCOLOR=\"lightgrey\"> </TD>"
257" </TR>"
258" </TABLE>"
259" </TD>"
260" </TR>"
261" <TR>"
262" <TD align=\"left\">Output data</TD>"
263" <TD CELLPADDING=\"4\">"
264" <TABLE BORDER=\"1\" CELLBORDER=\"0\" CELLSPACING=\"0\" CELLPADDING=\"0\">"
265" <TR>"
266" <TD BGCOLOR=\"wheat\"> </TD>"
267" </TR>"
268" </TABLE>"
269" </TD>"
270" </TR>"
271" </TABLE>"
272" >];"
273"}";
274
275
276/*
277Carrier strToCarrier(const char* szCar)
278{
279 if(szCar)
280 {
281 if(compareString(szCar, "TCP"))
282 return TCP;
283 if(compareString(szCar, "UDP"))
284 return UDP;
285 if(compareString(szCar, "MCAST"))
286 return MCAST;
287 if(compareString(szCar, "SHMEM"))
288 return SHMEM;
289 if(compareString(szCar, "TEXT"))
290 return TEXT;
291 }
292 return UNKNOWN;
293}
294
295const char* carrierToStr(Carrier cr)
296{
297 switch(cr){
298 case TCP:{return("tcp");}
299 case UDP:{return("udp");}
300 case MCAST:{return("mcast");}
301 case SHMEM:{return("shmem");}
302 case TEXT:{return("text");}
303 default:{return("tcp");}
304 };
305}
306*/
307
308OS yarp::manager::strToOS(const char* szOS)
309{
310 if(szOS)
311 {
312 if (compareString(szOS, "LINUX")) {
313 return LINUX;
314 }
315 if (compareString(szOS, "WINDOWS")) {
316 return WINDOWS;
317 }
318 if (compareString(szOS, "MAC")) {
319 return MAC;
320 }
321 }
322 return OTHER;
323}
324
325
326bool yarp::manager::compareString(const char* szFirst, const char* szSecond)
327{
328 if (!szFirst && !szSecond) {
329 return true;
330 }
331 if (!szFirst || !szSecond) {
332 return false;
333 }
334
335 std::string strFirst(szFirst);
336 std::string strSecond(szSecond);
337 transform(strFirst.begin(), strFirst.end(), strFirst.begin(),
338 (int(*)(int))toupper);
339 transform(strSecond.begin(), strSecond.end(), strSecond.begin(),
340 (int(*)(int))toupper);
341 if (strFirst == strSecond) {
342 return true;
343 }
344 return false;
345}
346
348 auto now = std::chrono::system_clock::now();
349 std::time_t currentTime = std::chrono::system_clock::to_time_t(now);
350
351 std::tm localTime;
352#ifdef _WIN32
353 localtime_s(&localTime, &currentTime); // Windows
354#else
355 localtime_r(&currentTime, &localTime); // POSIX
356#endif
357 std::ostringstream oss;
358 oss << std::put_time(&localTime, "%H:%M:%S");
359 return oss.str();
360}
361
362std::string yarp::manager::getElapsedTimeString(const std::string& startTimeStr) {
363 std::tm startTime{};
364 std::istringstream iss(startTimeStr);
365 iss >> std::get_time(&startTime, "%H:%M:%S");
366 if (iss.fail()) {
367 throw std::invalid_argument("Invalid time format. Expected %H:%M:%S");
368 }
369
370 auto now = std::chrono::system_clock::now();
371 std::time_t currentTime = std::chrono::system_clock::to_time_t(now);
372
373 std::tm localTime;
374#ifdef _WIN32
375 localtime_s(&localTime, &currentTime); // Windows
376#else
377 localtime_r(&currentTime, &localTime); // POSIX
378#endif
379
380 localTime.tm_hour = startTime.tm_hour;
381 localTime.tm_min = startTime.tm_min;
382 localTime.tm_sec = startTime.tm_sec;
383
384 std::time_t startTimestamp = std::mktime(&localTime);
385
386 auto elapsedSeconds = std::difftime(currentTime, startTimestamp);
387 if (elapsedSeconds < 0) {
388 elapsedSeconds += 24 * 60 * 60; // Handle cases where the start time is on the previous day
389 }
390
391 int hours = static_cast<int>(elapsedSeconds) / 3600;
392 int minutes = (static_cast<int>(elapsedSeconds) % 3600) / 60;
393 int seconds = static_cast<int>(elapsedSeconds) % 60;
394
395 std::ostringstream oss;
396 oss << std::setfill('0') << std::setw(2) << hours << ":"
397 << std::setfill('0') << std::setw(2) << minutes << ":"
398 << std::setfill('0') << std::setw(2) << seconds;
399
400 return oss.str();
401}
402
403void yarp::manager::trimString(std::string& str)
404{
405 std::string::size_type pos = str.find_last_not_of(' ');
406 if(pos != std::string::npos)
407 {
408 str.erase(pos + 1);
409 pos = str.find_first_not_of(' ');
410 if (pos != std::string::npos) {
411 str.erase(0, pos);
412 }
413 } else {
414 str.erase(str.begin(), str.end());
415 }
416}
417
418
419bool yarp::manager::exportDotGraph(Graph& graph, const char* szFileName)
420{
421 std::ofstream dot;
422 dot.open(szFileName);
423 if (!dot.is_open()) {
424 return false;
425 }
426
427 dot<<"digraph G {\n";
428 dot<<"rankdir=LR\n;";
429 dot<<"ranksep=0.0\n;";
430 dot<<"nodesep=0.2\n;";
431
432 for(GraphIterator itr=graph.begin(); itr!=graph.end(); itr++)
433 {
434 switch((*itr)->getType()) {
435 case MODULE: {
436 auto* mod = (Module*)(*itr);
437 dot<<"\""<<mod->getLabel()<<"\"";
438 dot<<" [label=\""<< mod->getName()<<"\"";
439 dot<<" shape=component, color=midnightblue, fillcolor=lightslategrey, peripheries=1, style=filled, penwidth=2];\n";
440 for(int i=0; i<mod->sucCount(); i++)
441 {
442 Link l = mod->getLinkAt(i);
443 auto* in = (InputData*)l.to();
444 dot<<"\""<<mod->getLabel()<<"\" -> ";
445 dot<<"\""<<in->getLabel()<<"\"";
446 if (!l.isVirtual()) {
447 dot<<" [label=\"\"];\n";
448 } else {
449 dot << " [label=\"\" style=dashed];\n";
450 }
451 }
452
453 break;
454 }
455 case INPUTD:{
456 auto* in = (InputData*)(*itr);
457 dot<<"\""<<in->getLabel()<<"\"";
458 if(in->withPriority())
459 {
460 dot<<" [color=red, fillcolor=lightgrey, peripheries=1, style=filled";
461 dot<<" label=\""<< in->getName()<<"\\n"<<in->getPort()<<"\"];\n";
462 }
463 else
464 {
465 dot<<" [color=black, fillcolor=lightgrey, peripheries=1, style=filled";
466 dot<<" label=\""<< in->getName()<<"\\n"<<in->getPort()<<"\"];\n";
467 }
468 for(int i=0; i<in->sucCount(); i++)
469 {
470 Link l = in->getLinkAt(i);
471 auto* out = (OutputData*)l.to();
472 dot<<"\""<<in->getLabel()<<"\" -> ";
473 dot<<"\""<<out->getLabel()<<"\"";
474 if (!l.isVirtual()) {
475 dot<<" [label=\""<<l.weight()<<"\"];\n";
476 } else {
477 dot << " [label=\"" << l.weight() << "\" style=dashed];\n";
478 }
479 }
480
481 break;
482 }
483 case OUTPUTD:{
484 auto* out = (OutputData*)(*itr);
485 dot<<"\""<<out->getLabel()<<"\"";
486 dot<<" [color=black, fillcolor=wheat, peripheries=1, style=filled";
487 dot<<" label=\""<< out->getName()<<"\\n"<<out->getPort()<<"\"];\n";
488 for(int i=0; i<out->sucCount(); i++)
489 {
490 Link l = out->getLinkAt(i);
491 auto* mod = (Module*)l.to();
492 dot<<"\""<<out->getLabel()<<"\" -> ";
493 dot<<"\""<<mod->getLabel()<<"\"";
494 dot<<" [label=\"\" arrowhead=none];\n";
495 }
496
497 break;
498 }
499
500 case APPLICATION:{
501 auto* app = (Application*)(*itr);
502 dot<<"\""<<app->getLabel()<<"\"";
503 dot<<" [shape=folder, color=darkgreen, fillcolor=darkseagreen, peripheries=1, style=filled, penwidth=2";
504 dot<<" label=\""<<app->getLabel()<<"\""<<"];\n";
505 for(int i=0; i<app->sucCount(); i++)
506 {
507 Link l = app->getLinkAt(i);
508 auto* mod = (Module*)l.to();
509 dot<<"\""<<app->getLabel()<<"\" -> ";
510 dot<<"\""<<mod->getLabel()<<"\"";
511 if (!l.isVirtual()) {
512 dot<<" [label=\"\"];\n";
513 } else {
514 dot << " [label=\"\" style=dashed];\n";
515 }
516 }
517 break;
518 }
519
520 case RESOURCE:{
521 auto* res = (GenericResource*)(*itr);
522 dot<<"\""<<res->getLabel()<<"\"";
523 if (res->owner()) {
524 dot<<" [shape=rect, color=black, fillcolor=salmon, peripheries=1, style=filled ";
525 } else {
526 dot << " [shape=house, color=maroon, fillcolor=indianred, peripheries=1, style=filled, penwidth=2";
527 }
528 dot<<" label=\""<<res->getName()<<"\""<<"];\n";
529 for(int i=0; i<res->sucCount(); i++)
530 {
531 Link l = res->getLinkAt(i);
532 Node* prov = l.to();
533 dot<<"\""<<res->getLabel()<<"\" -> ";
534 dot<<"\""<<prov->getLabel()<<"\"";
535 dot<<" [label=\""<<l.weight()<<"\"];\n";
536 }
537
538 break;
539 }
540
541 default:
542 break;
543 };
544 }
545
546 dot<<GRAPH_LEGEND;
547 dot<<"}\n";
548 dot.close();
549 return true;
550}
Class Application.
Singleton class For storing execution start time.
Definition utility.h:86
static ClockStart & getInstance()
Definition utility.h:88
std::string getStartTime() const
Get the starting time as a string in HH:MM:SS format.
Definition utility.h:100
Singleton class ErrorLogger.
Definition utility.h:58
const char * getLastError()
Definition utility.cpp:148
const char * getFormatedErrorString()
Definition utility.cpp:158
void addError(const char *szError)
Definition utility.cpp:126
void addWarning(const char *szWarning)
Definition utility.cpp:104
static ErrorLogger * Instance()
Singleton class ErrorLogger.
Definition utility.cpp:98
const char * getLastWarning()
Definition utility.cpp:167
const char * getFormatedWarningString()
Definition utility.cpp:177
Class GraphIterator.
Definition graph.h:66
Class Graph.
Definition graph.h:27
GraphIterator begin()
Definition graph.cpp:165
GraphIterator end()
Definition graph.cpp:172
Class InputData.
Definition data.h:21
Class Module.
Definition module.h:99
a Node of a Graph
Definition node.h:64
const char * getLabel()
Definition node.h:93
StrStream & operator=(const char *sz)
Definition utility.cpp:58
friend std::ostream & operator<<(std::ostream &os, StrStream &sstr)
Definition utility.cpp:85
bool compareString(const char *szFirst, const char *szSecond)
Definition utility.cpp:326
void trimString(std::string &str)
Definition utility.cpp:403
std::stringstream OSTRINGSTREAM
Definition utility.h:50
OS strToOS(const char *szOS)
Definition utility.cpp:308
std::string getElapsedTimeString(const std::string &startTimeStr)
Definition utility.cpp:362
bool exportDotGraph(Graph &graph, const char *szFileName)
Definition utility.cpp:419
std::string getCurrentTimeString()
Definition utility.cpp:347
enum yarp::manager::__OS OS
const std::string GRAPH_LEGEND
Definition utility.cpp:201
std::ostream & operator<<(std::ostream &os, StrStream &sstr)
Definition utility.cpp:85