Version: 8.3.0
LinkInfo.cxx
Go to the documentation of this file.
1 // Copyright (C) 2006-2016 CEA/DEN, EDF R&D
2 //
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
7 //
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 // Lesser General Public License for more details.
12 //
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16 //
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
18 //
19 
20 #include "LinkInfo.hxx"
21 #include "Switch.hxx"
22 
23 #include <sstream>
24 
25 using namespace std;
26 using namespace YACS::ENGINE;
27 
28 static const char GLOBAL_MESSAGE1[]="Global report : \n";
29 
30 static const char LINK_REPR[]="link";
31 
32 LinkInfo::LinkInfo(unsigned char level):_levelOfInfo(level),_level(0)
33 {
34 }
35 
37 {
38  _level=0;
39  _unsetInPort.clear();
40  _onlyBackDefined.clear();
41  _uselessLinks.clear();
42  _infos.clear();
43  _collapse.clear();
44  _errors.clear();
45  _errorsOnSwitchCases.clear();
46 }
47 
49 {
50  _level++;
51 }
52 
54 {
55  if(--_level==0)
56  {
59  throw Exception(getGlobalRepr());
62  throw Exception(getErrRepr());
63  }
64 }
65 
67 {
68  _pov=pov;
69 }
70 
71 void LinkInfo::pushInfoLink(OutPort *semStart, InPort *end, InfoReason reason)
72 {
73  _infos[reason].push_back(pair<OutPort *, InPort *>(semStart,end));
74 }
75 
76 void LinkInfo::pushWarnLink(OutPort *semStart, InPort *end, WarnReason reason)
77 {
78  if(_collapse[reason].empty())
79  _collapse[reason].push_back(vector< pair<OutPort *,InPort *> >());
80  else
81  if(_collapse[reason].back()[0].second!=end)
82  _collapse[reason].push_back(vector< pair<OutPort *,InPort *> >());
83  _collapse[reason].back().push_back(pair<OutPort *,InPort *>(semStart,end));
84 }
85 
86 void LinkInfo::pushErrLink(OutPort *semStart, InPort *end, ErrReason reason) throw(YACS::Exception)
87 {
88  if(reason==E_NEVER_SET_INPUTPORT)
89  _unsetInPort.push_back(end);
90  else if(reason==E_ONLY_BACKWARD_DEFINED)
91  _onlyBackDefined.push_back(end);
92  else
93  _errors[reason].push_back(pair<OutPort *, InPort *>(semStart,end));
94  if(_level==0)
95  if(_levelOfInfo==ALL_STOP_ASAP || _levelOfInfo==WARN_ONLY_DONT_STOP)
96  throw Exception(getErrRepr());
97 }
98 
100 {
101  _errorsOnSwitchCases.push_back(collector);
102  if(_level==0)
103  if(_levelOfInfo==ALL_STOP_ASAP || _levelOfInfo==WARN_ONLY_DONT_STOP)
104  throw Exception(getErrRepr());
105 }
106 
108 {
109  _uselessLinks.insert(pair<Node *,Node *>(start,end));
110 }
111 
113 {
114  if(!_errors.empty())
115  throw Exception(getErrRepr());
116 }
117 
118 std::string LinkInfo::getGlobalRepr() const
119 {
120  ostringstream retS; retS << GLOBAL_MESSAGE1;
121  retS << printThereIsAre(getNumberOfErrLinks(E_ALL),"error") << ".\n";
122  retS << printThereIsAre(getNumberOfWarnLinksGrp(W_ALL),"warning") << ".\n";
123  retS << printThereIsAre(getNumberOfInfoLinks(I_ALL),"info") << ".\n";
125  {
126  retS << "****** ERRORS ******" << endl;
127  retS << getErrRepr() << endl;
128  }
130  {
131  retS << "****** WARNINGS ******" << endl;
132  retS << getWarnRepr() << endl;
133  }
135  {
136  retS << "****** INFO ******" << endl;
137  retS << getInfoRepr() << endl;
138  }
139  return retS.str();
140 }
141 
142 std::string LinkInfo::getInfoRepr() const
143 {
144  map<InfoReason, vector< pair<OutPort *,InPort *> > >::const_iterator iter;
145  ostringstream stream;
146  for(iter=_infos.begin();iter!=_infos.end();iter++)
147  {
148  for(vector< pair<OutPort *,InPort *> >::const_iterator iter2=(*iter).second.begin();iter2!=(*iter).second.end();iter2++)
149  {
150  stream << getStringReprOfI((*iter).first) << " between \"" << _pov->getOutPortName((*iter2).first);
151  stream << "\" and \"" << _pov->getInPortName((*iter2).second) << "\"." << endl;
152  }
153  }
154  set< pair<Node *, Node *> >::const_iterator iter3;
155  for(iter3=_uselessLinks.begin();iter3!=_uselessLinks.end();iter3++)
156  {
157  stream << "Useless CF link between \"" << _pov->getChildName((*iter3).first);
158  stream << "\" and \"" << _pov->getChildName((*iter3).second) << "\"." << endl;
159  }
160  return stream.str();
161 }
162 
163 std::string LinkInfo::getWarnRepr() const
164 {
165  map<WarnReason, vector< vector< pair<OutPort *,InPort *> > > >::const_iterator iter;
166  ostringstream stream;
167  unsigned i=0;
168  for(iter=_collapse.begin();iter!=_collapse.end();iter++)
169  {
170  stream << getStringReprOfW((*iter).first) << " for group containing following group links: ";
171  vector< vector< pair<OutPort *,InPort *> > >::const_iterator iter2=(*iter).second.begin();
172  for(;iter2!=(*iter).second.end();iter2++)
173  {
174  stream << " Group # " << i++ << " : " << endl;
175  for(vector< pair<OutPort *,InPort *> >::const_iterator iter3=(*iter2).begin();iter3!=(*iter2).end();iter3++)
176  stream << " \"" << _pov->getOutPortName((*iter3).first) << "\" and \"" << _pov->getInPortName((*iter3).second) << endl;
177  }
178  }
179  return stream.str();
180 }
181 
182 std::string LinkInfo::getErrRepr() const
183 {
184  vector<InPort *>::const_iterator iter;
185  ostringstream stream;
186  for(iter=_unsetInPort.begin();iter!=_unsetInPort.end();iter++)
187  stream << getStringReprOfE(E_NEVER_SET_INPUTPORT) << "\"" << _pov->getInPortName(*iter) << "\"." << endl;
188  for(iter=_onlyBackDefined.begin();iter!=_onlyBackDefined.end();iter++)
189  stream << getStringReprOfE(E_ONLY_BACKWARD_DEFINED) << "\"" << _pov->getInPortName(*iter) << "\"." << endl;
190  map<ErrReason, vector< pair<OutPort *,InPort *> > >::const_iterator iter2;
191  for(iter2=_errors.begin();iter2!=_errors.end();iter2++)
192  for(vector< pair<OutPort *,InPort *> >::const_iterator iter3=(*iter2).second.begin();iter3!=(*iter2).second.end();iter3++)
193  stream << getStringReprOfE((*iter2).first) << " between \"" <<_pov->getOutPortName((*iter3).first) << "\" and \"" << _pov->getInPortName((*iter3).second) << endl;
194  for(vector<CollectorSwOutPort *>::const_iterator iter3=_errorsOnSwitchCases.begin();iter3!=_errorsOnSwitchCases.end();iter3++)
195  (*iter3)->getHumanReprOfIncompleteCases(stream);
196  return stream.str();
197 }
198 
200 {
201  return (getNumberOfWarnLinksGrp(W_ALL)!=0) || (getNumberOfErrLinks(E_ALL)!=0) || !_unsetInPort.empty() || !_onlyBackDefined.empty();
202 }
203 
208 {
209  if(reason==I_ALL)
210  {
211  map<InfoReason, vector< pair<OutPort *,InPort *> > >::const_iterator iter=_infos.begin();
212  unsigned val=0;
213  for(;iter!=_infos.end();iter++)
214  val+=(*iter).second.size();
215  return val+_uselessLinks.size();
216  }
217  if(reason==I_CF_USELESS)
218  return _uselessLinks.size();
219  else
220  {
221  map<InfoReason, vector< pair<OutPort *,InPort *> > >::const_iterator iter=_infos.find(reason);
222  if(iter!=_infos.end())
223  return (*iter).second.size();
224  else
225  return 0;
226  }
227 }
228 
230 {
231  unsigned ret=0;
232  map<WarnReason, vector< vector< pair<OutPort *,InPort *> > > >::const_iterator iter;
233  if(reason==W_ALL)
234  {
235  for(iter=_collapse.begin();iter!=_collapse.end();iter++)
236  ret+=(*iter).second.size();
237  return ret;
238  }
239  map<WarnReason, vector< vector< pair<OutPort *,InPort *> > > >::const_iterator iter2=_collapse.find(reason);
240  if(iter2!=_collapse.end())
241  return (*iter2).second.size();
242  else
243  return 0;
244 }
245 
247 {
248  if(reason==E_ALL)
249  return _errors.size()+_onlyBackDefined.size()+_unsetInPort.size()+_errorsOnSwitchCases.size();
250  else if(reason==E_NEVER_SET_INPUTPORT)
251  return _unsetInPort.size();
252  else if(reason==E_ONLY_BACKWARD_DEFINED)
253  return _onlyBackDefined.size();
254  else if(reason==E_UNCOMPLETE_SW)
255  return _errorsOnSwitchCases.size();
256  else
257  {
258  map<ErrReason, vector< pair<OutPort *,InPort *> > >::const_iterator iter=_errors.find(reason);
259  if(iter!=_errors.end())
260  return (*iter).second.size();
261  else
262  return 0;
263  }
264 }
265 
266 std::set< std::pair<Node *, Node *> > LinkInfo::getInfoUselessLinks() const
267 {
268  return _uselessLinks;
269 }
270 
271 std::pair<OutPort *, InPort *> LinkInfo::getInfoLink(unsigned id, InfoReason reason) const
272 {
273  if(reason==I_CF_USELESS)
274  return pair<OutPort *, InPort *>();
275  map<InfoReason, vector< pair<OutPort *,InPort *> > >::const_iterator iter=_infos.find(reason);
276  if(iter!=_infos.end())
277  return (*iter).second[id];
278  else
279  return pair<OutPort *, InPort *>( reinterpret_cast<OutPort *>(0), reinterpret_cast<InPort *>(0) );
280 }
281 
282 std::vector< std::pair<OutPort *, InPort *> > LinkInfo::getWarnLink(unsigned id, WarnReason reason) const
283 {
284  map<WarnReason, vector< vector< pair<OutPort *,InPort *> > > >::const_iterator iter=_collapse.find(reason);
285  if(iter!=_collapse.end())
286  return (*iter).second[id];
287  else
288  return vector< pair<OutPort *, InPort *> >();
289 }
290 
291 std::pair<OutPort *, InPort *> LinkInfo::getErrLink(unsigned id, ErrReason reason) const
292 {
293  if(reason==E_NEVER_SET_INPUTPORT)
294  return pair<OutPort *, InPort *>( reinterpret_cast<OutPort *>(0), _unsetInPort[id] );
295  else if(reason==E_ONLY_BACKWARD_DEFINED)
296  return pair<OutPort *, InPort *>( reinterpret_cast<OutPort *>(0), _onlyBackDefined[id] );
297  else
298  {
299  map<ErrReason, vector< pair<OutPort *,InPort *> > >::const_iterator iter=_errors.find(reason);
300  if(iter!=_errors.end())
301  return (*iter).second[id];
302  else
303  return pair<OutPort *, InPort *>( reinterpret_cast<OutPort *>(0), reinterpret_cast<InPort *>(0) );
304  }
305 }
306 
308 {
309  string ret;
310  switch(reason)
311  {
312  case I_USELESS:
313  ret="Useless DF";
314  break;
315  case I_BACK:
316  ret="Back";
317  break;
318  case I_BACK_USELESS:
319  ret="Back and useless";
320  break;
321  case I_BACK_CRAZY:
322  ret+="Crazy back";
323  break;
324  case I_DFDS:
325  ret+="DF/DS";
326  }
327  ret+=" "; ret+=LINK_REPR;
328  return ret;
329 }
330 
332 {
333  string ret;
334  switch(reason)
335  {
336  case W_COLLAPSE:
337  ret="Collapse";
338  break;
340  ret="Collapse and useless";
341  break;
342  case W_COLLAPSE_EL:
343  ret="Collapse on ElementaryNode";
344  break;
346  ret+="Collapse on ElementaryNode and useless";
347  break;
348  case W_BACK_COLLAPSE:
349  ret+="Back collapse";
350  break;
352  ret+="Back collapse and useless";
353  break;
354  case W_BACK_COLLAPSE_EL:
355  ret+="Back collapse on ElementaryNode";
356  break;
358  ret+="Back collapse and useless on ElementaryNode";
359  }
360  ret+=" "; ret+=LINK_REPR;
361  return ret;
362 }
363 
365 {
366  string ret;
367  if(reason==E_NEVER_SET_INPUTPORT)
368  return "Never set InPort ";
369  if(reason==E_ONLY_BACKWARD_DEFINED)
370  return "Never set InPort only back defined ";
371  switch(reason)
372  {
374  ret="DS unestablishable";
375  break;
376  case E_COLLAPSE_DFDS:
377  ret="DF/DS collapse";
378  break;
379  case E_COLLAPSE_DS:
380  ret="Inter DS collapse";
381  break;
382  case E_UNPREDICTABLE_FED:
383  ret="Unpredictable fed";
384  }
385  ret+=" "; ret+=LINK_REPR;
386  return ret;
387 }
388 
389 std::string LinkInfo::printThereIsAre(unsigned val, const std::string& other)
390 {
391  ostringstream ret;
392  ret << "There ";
393  if(val==0)
394  ret << "are no";
395  else if(val==1)
396  ret << "is one";
397  else
398  ret << "are " << val;
399  ret << " " << other;
400  if(val==0 || val>1)
401  ret << "s";
402  return ret.str();
403 }