YARP
Yet Another Robot Platform
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 
6 #include <yarp/manager/utility.h>
7 #include <yarp/manager/graph.h>
8 #include <yarp/manager/module.h>
10 #include <yarp/manager/resource.h>
11 
12 #include <cstdio>
13 #include <fstream>
14 
15 
16 using namespace yarp::manager;
17 
18 
19 //#if defined(_MSC_VER) && (_MSC_VER == 1600)
20 
21 StrStream::StrStream() = default;
22 
23 StrStream::StrStream(const std::string str) {
24  dummyStr = str;
25 }
26 
27 StrStream::~StrStream() = default;
28 
29 std::string StrStream::str() {
30  return dummyStr;
31 }
32 
34  dummyStr += oss.str();
35  return *this;
36 }
37 
38 StrStream& 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 
68 StrStream& 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 
85 std::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 
104 void ErrorLogger::addWarning(const char* szWarning) {
105  if (szWarning) {
106  warnings.emplace_back(szWarning);
107  }
108 }
109 
110 void ErrorLogger::addWarning(const std::string &str) {
111  warnings.push_back(str);
112 }
113 
115  addWarning(stream.str());
116 }
117 
118 void ErrorLogger::addError(const char* szError) {
119  if (szError) {
120  errors.emplace_back(szError);
121  }
122 }
123 
124 void ErrorLogger::addError(const std::string &str) {
125  errors.push_back(str);
126 }
127 
129  addError(stream.str());
130 }
131 
133  if (errors.empty()) {
134  return nullptr;
135  }
136  static std::string msg;
137  msg = errors.back();
138  errors.pop_back();
139  return msg.c_str();
140 }
141 
143  static std::string msgs;
144  char* err;
145  while ((err = (char*)getLastError()) != nullptr) {
146  msgs += std::string(err) + " ";
147  }
148  return msgs.c_str();
149 }
150 
152  if (warnings.empty()) {
153  return nullptr;
154  }
155  static std::string msg;
156  msg = warnings.back();
157  warnings.pop_back();
158  return msg.c_str();
159 }
160 
162  static std::string msgs;
163  char* err;
164  while ((err = (char*)getLastWarning()) != nullptr) {
165  msgs += std::string(err) + " ";
166  }
167  return msgs.c_str();
168 }
169 
170 
172  errors.clear(); warnings.clear();
173 }
174 
176  return errors.size();
177 }
178 
180 
181  return warnings.size();
182 }
183 
184 
185 const std::string GRAPH_LEGEND =
186 "{"
187 " rank=sink;"
188 " style=filled;"
189 " color=lightgrey;"
190 " Legend [shape=none, margin=0, label=<"
191 " <TABLE BORDER=\"0\" CELLBORDER=\"1\" CELLSPACING=\"0\" CELLPADDING=\"4\" bgcolor=\"white\">"
192 " <TR>"
193 " <TD COLSPAN=\"2\"><B>Legend</B></TD>"
194 " </TR>"
195 " <TR>"
196 " <TD align=\"left\">Application</TD>"
197 " <TD CELLPADDING=\"4\">"
198 " <TABLE BORDER=\"1\" CELLBORDER=\"0\" CELLSPACING=\"0\" CELLPADDING=\"0\">"
199 " <TR>"
200 " <TD BGCOLOR=\"darkseagreen\"> </TD>"
201 " </TR>"
202 " </TABLE>"
203 " </TD>"
204 " </TR>"
205 " <TR>"
206 " <TD align=\"left\">Module</TD>"
207 " <TD CELLPADDING=\"4\">"
208 " <TABLE BORDER=\"1\" CELLBORDER=\"0\" CELLSPACING=\"0\" CELLPADDING=\"0\">"
209 " <TR>"
210 " <TD BGCOLOR=\"lightslategrey\"> </TD>"
211 " </TR>"
212 " </TABLE>"
213 " </TD>"
214 " </TR>"
215 " <TR>"
216 " <TD align=\"left\">Res. Dependency</TD>"
217 " <TD CELLPADDING=\"4\">"
218 " <TABLE BORDER=\"1\" CELLBORDER=\"0\" CELLSPACING=\"0\" CELLPADDING=\"0\">"
219 " <TR>"
220 " <TD BGCOLOR=\"salmon\"> </TD>"
221 " </TR>"
222 " </TABLE>"
223 " </TD>"
224 " </TR>"
225 " <TR>"
226 " <TD align=\"left\">Res. Provider</TD>"
227 " <TD CELLPADDING=\"4\">"
228 " <TABLE BORDER=\"1\" CELLBORDER=\"0\" CELLSPACING=\"0\" CELLPADDING=\"0\">"
229 " <TR>"
230 " <TD BGCOLOR=\"indianred\"> </TD>"
231 " </TR>"
232 " </TABLE>"
233 " </TD>"
234 " </TR>"
235 " <TR>"
236 " <TD align=\"left\">Input data</TD>"
237 " <TD CELLPADDING=\"4\">"
238 " <TABLE BORDER=\"1\" CELLBORDER=\"0\" CELLSPACING=\"0\" CELLPADDING=\"0\">"
239 " <TR>"
240 " <TD BGCOLOR=\"lightgrey\"> </TD>"
241 " </TR>"
242 " </TABLE>"
243 " </TD>"
244 " </TR>"
245 " <TR>"
246 " <TD align=\"left\">Output data</TD>"
247 " <TD CELLPADDING=\"4\">"
248 " <TABLE BORDER=\"1\" CELLBORDER=\"0\" CELLSPACING=\"0\" CELLPADDING=\"0\">"
249 " <TR>"
250 " <TD BGCOLOR=\"wheat\"> </TD>"
251 " </TR>"
252 " </TABLE>"
253 " </TD>"
254 " </TR>"
255 " </TABLE>"
256 " >];"
257 "}";
258 
259 
260 /*
261 Carrier strToCarrier(const char* szCar)
262 {
263  if(szCar)
264  {
265  if(compareString(szCar, "TCP"))
266  return TCP;
267  if(compareString(szCar, "UDP"))
268  return UDP;
269  if(compareString(szCar, "MCAST"))
270  return MCAST;
271  if(compareString(szCar, "SHMEM"))
272  return SHMEM;
273  if(compareString(szCar, "TEXT"))
274  return TEXT;
275  }
276  return UNKNOWN;
277 }
278 
279 const char* carrierToStr(Carrier cr)
280 {
281  switch(cr){
282  case TCP:{return("tcp");}
283  case UDP:{return("udp");}
284  case MCAST:{return("mcast");}
285  case SHMEM:{return("shmem");}
286  case TEXT:{return("text");}
287  default:{return("tcp");}
288  };
289 }
290 */
291 
292 OS yarp::manager::strToOS(const char* szOS)
293 {
294  if(szOS)
295  {
296  if (compareString(szOS, "LINUX")) {
297  return LINUX;
298  }
299  if (compareString(szOS, "WINDOWS")) {
300  return WINDOWS;
301  }
302  if (compareString(szOS, "MAC")) {
303  return MAC;
304  }
305  }
306  return OTHER;
307 }
308 
309 
310 bool yarp::manager::compareString(const char* szFirst, const char* szSecond)
311 {
312  if (!szFirst && !szSecond) {
313  return true;
314  }
315  if (!szFirst || !szSecond) {
316  return false;
317  }
318 
319  std::string strFirst(szFirst);
320  std::string strSecond(szSecond);
321  transform(strFirst.begin(), strFirst.end(), strFirst.begin(),
322  (int(*)(int))toupper);
323  transform(strSecond.begin(), strSecond.end(), strSecond.begin(),
324  (int(*)(int))toupper);
325  if (strFirst == strSecond) {
326  return true;
327  }
328  return false;
329 }
330 
331 void yarp::manager::trimString(std::string& str)
332 {
333  std::string::size_type pos = str.find_last_not_of(' ');
334  if(pos != std::string::npos)
335  {
336  str.erase(pos + 1);
337  pos = str.find_first_not_of(' ');
338  if (pos != std::string::npos) {
339  str.erase(0, pos);
340  }
341  } else {
342  str.erase(str.begin(), str.end());
343  }
344 }
345 
346 
347 bool yarp::manager::exportDotGraph(Graph& graph, const char* szFileName)
348 {
349  std::ofstream dot;
350  dot.open(szFileName);
351  if (!dot.is_open()) {
352  return false;
353  }
354 
355  dot<<"digraph G {\n";
356  dot<<"rankdir=LR\n;";
357  dot<<"ranksep=0.0\n;";
358  dot<<"nodesep=0.2\n;";
359 
360  for(GraphIterator itr=graph.begin(); itr!=graph.end(); itr++)
361  {
362  switch((*itr)->getType()) {
363  case MODULE: {
364  auto* mod = (Module*)(*itr);
365  dot<<"\""<<mod->getLabel()<<"\"";
366  dot<<" [label=\""<< mod->getName()<<"\"";
367  dot<<" shape=component, color=midnightblue, fillcolor=lightslategrey, peripheries=1, style=filled, penwidth=2];\n";
368  for(int i=0; i<mod->sucCount(); i++)
369  {
370  Link l = mod->getLinkAt(i);
371  auto* in = (InputData*)l.to();
372  dot<<"\""<<mod->getLabel()<<"\" -> ";
373  dot<<"\""<<in->getLabel()<<"\"";
374  if (!l.isVirtual()) {
375  dot<<" [label=\"\"];\n";
376  } else {
377  dot << " [label=\"\" style=dashed];\n";
378  }
379  }
380 
381  break;
382  }
383  case INPUTD:{
384  auto* in = (InputData*)(*itr);
385  dot<<"\""<<in->getLabel()<<"\"";
386  if(in->withPriority())
387  {
388  dot<<" [color=red, fillcolor=lightgrey, peripheries=1, style=filled";
389  dot<<" label=\""<< in->getName()<<"\\n"<<in->getPort()<<"\"];\n";
390  }
391  else
392  {
393  dot<<" [color=black, fillcolor=lightgrey, peripheries=1, style=filled";
394  dot<<" label=\""<< in->getName()<<"\\n"<<in->getPort()<<"\"];\n";
395  }
396  for(int i=0; i<in->sucCount(); i++)
397  {
398  Link l = in->getLinkAt(i);
399  auto* out = (OutputData*)l.to();
400  dot<<"\""<<in->getLabel()<<"\" -> ";
401  dot<<"\""<<out->getLabel()<<"\"";
402  if (!l.isVirtual()) {
403  dot<<" [label=\""<<l.weight()<<"\"];\n";
404  } else {
405  dot << " [label=\"" << l.weight() << "\" style=dashed];\n";
406  }
407  }
408 
409  break;
410  }
411  case OUTPUTD:{
412  auto* out = (OutputData*)(*itr);
413  dot<<"\""<<out->getLabel()<<"\"";
414  dot<<" [color=black, fillcolor=wheat, peripheries=1, style=filled";
415  dot<<" label=\""<< out->getName()<<"\\n"<<out->getPort()<<"\"];\n";
416  for(int i=0; i<out->sucCount(); i++)
417  {
418  Link l = out->getLinkAt(i);
419  auto* mod = (Module*)l.to();
420  dot<<"\""<<out->getLabel()<<"\" -> ";
421  dot<<"\""<<mod->getLabel()<<"\"";
422  dot<<" [label=\"\" arrowhead=none];\n";
423  }
424 
425  break;
426  }
427 
428  case APPLICATION:{
429  auto* app = (Application*)(*itr);
430  dot<<"\""<<app->getLabel()<<"\"";
431  dot<<" [shape=folder, color=darkgreen, fillcolor=darkseagreen, peripheries=1, style=filled, penwidth=2";
432  dot<<" label=\""<<app->getLabel()<<"\""<<"];\n";
433  for(int i=0; i<app->sucCount(); i++)
434  {
435  Link l = app->getLinkAt(i);
436  auto* mod = (Module*)l.to();
437  dot<<"\""<<app->getLabel()<<"\" -> ";
438  dot<<"\""<<mod->getLabel()<<"\"";
439  if (!l.isVirtual()) {
440  dot<<" [label=\"\"];\n";
441  } else {
442  dot << " [label=\"\" style=dashed];\n";
443  }
444  }
445  break;
446  }
447 
448  case RESOURCE:{
449  auto* res = (GenericResource*)(*itr);
450  dot<<"\""<<res->getLabel()<<"\"";
451  if (res->owner()) {
452  dot<<" [shape=rect, color=black, fillcolor=salmon, peripheries=1, style=filled ";
453  } else {
454  dot << " [shape=house, color=maroon, fillcolor=indianred, peripheries=1, style=filled, penwidth=2";
455  }
456  dot<<" label=\""<<res->getName()<<"\""<<"];\n";
457  for(int i=0; i<res->sucCount(); i++)
458  {
459  Link l = res->getLinkAt(i);
460  Node* prov = l.to();
461  dot<<"\""<<res->getLabel()<<"\" -> ";
462  dot<<"\""<<prov->getLabel()<<"\"";
463  dot<<" [label=\""<<l.weight()<<"\"];\n";
464  }
465 
466  break;
467  }
468 
469  default:
470  break;
471  };
472  }
473 
474  dot<<GRAPH_LEGEND;
475  dot<<"}\n";
476  dot.close();
477  return true;
478 }
Class Application.
Definition: application.h:289
Singleton class ErrorLogger.
Definition: utility.h:57
const char * getLastError()
Definition: utility.cpp:132
const char * getFormatedErrorString()
Definition: utility.cpp:142
void addError(const char *szError)
Definition: utility.cpp:118
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:151
const char * getFormatedWarningString()
Definition: utility.cpp:161
Class GraphIterator.
Definition: graph.h:67
Class Graph.
Definition: graph.h:28
GraphIterator begin()
Definition: graph.cpp:165
GraphIterator end()
Definition: graph.cpp:172
Class InputData.
Definition: data.h:22
Class Module.
Definition: module.h:100
a Node of a Graph
Definition: node.h:65
const char * getLabel()
Definition: node.h:94
StrStream & operator<<(StrStream &oss)
Definition: utility.cpp:33
std::string str()
Definition: utility.cpp:29
StrStream & operator=(const char *sz)
Definition: utility.cpp:58
bool compareString(const char *szFirst, const char *szSecond)
Definition: utility.cpp:310
void trimString(std::string &str)
Definition: utility.cpp:331
std::stringstream OSTRINGSTREAM
Definition: utility.h:49
OS strToOS(const char *szOS)
Definition: utility.cpp:292
bool exportDotGraph(Graph &graph, const char *szFileName)
Definition: utility.cpp:347
enum yarp::manager::__OS OS
double dot(const yarp::sig::Vector &a, const yarp::sig::Vector &b)
Scalar product between vectors (defined in Math.h).
Definition: math.cpp:475
std::ostream & operator<<(std::ostream &os, StrStream &sstr)
Definition: utility.cpp:85
const std::string GRAPH_LEGEND
Definition: utility.cpp:185