0031501: Foundation Classes, Message_Printer - remove theToPutEndl argument -- prepar...
[occt.git] / src / Interface / Interface_CheckTool.cxx
1 // Copyright (c) 1999-2014 OPEN CASCADE SAS
2 //
3 // This file is part of Open CASCADE Technology software library.
4 //
5 // This library is free software; you can redistribute it and/or modify it under
6 // the terms of the GNU Lesser General Public License version 2.1 as published
7 // by the Free Software Foundation, with special exception defined in the file
8 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
9 // distribution for complete text of the license and disclaimer of any warranty.
10 //
11 // Alternatively, this file may be used under the terms of Open CASCADE
12 // commercial license or contractual agreement.
13
14
15 #include <Interface_Check.hxx>
16 #include <Interface_CheckFailure.hxx>
17 #include <Interface_CheckIterator.hxx>
18 #include <Interface_CheckTool.hxx>
19 #include <Interface_EntityIterator.hxx>
20 #include <Interface_GeneralModule.hxx>
21 #include <Interface_Graph.hxx>
22 #include <Interface_GTool.hxx>
23 #include <Interface_HGraph.hxx>
24 #include <Interface_InterfaceModel.hxx>
25 #include <Interface_Macros.hxx>
26 #include <Interface_Protocol.hxx>
27 #include <Interface_ReportEntity.hxx>
28 #include <Interface_ShareTool.hxx>
29 #include <Standard_ErrorHandler.hxx>
30 #include <Standard_Failure.hxx>
31 #include <Standard_Transient.hxx>
32 #include <TCollection_HAsciiString.hxx>
33
34 #ifdef _WIN32
35 #include <OSD_Exception.hxx>
36 #else
37 #include <OSD_Signal.hxx>
38 #endif
39 #include <stdio.h>
40
41 static int errh = 1;
42
43
44 static void raisecheck (Standard_Failure& theException,Handle(Interface_Check)& ach)
45 {
46   char mess[100];
47   sprintf (mess,"** Exception Raised during Check : %s **",
48            theException.DynamicType()->Name());
49   ach->AddFail(mess);
50 #ifdef _WIN32
51   if (theException.IsKind(STANDARD_TYPE(OSD_Exception))) {
52 #else
53   if (theException.IsKind(STANDARD_TYPE(OSD_Signal))) {
54 #endif
55     theException.SetMessageString("System Signal received, check interrupt");
56     throw theException;
57   }
58 }
59
60
61   //  thestat : evite a CheckSuccess de refaire un calcul prealablement fait :
62   //  bit valeur 1 : Verify  fait, valeur 4 : et ilya des erreurs
63   //  bit valeur 2 : Analyse fait, valeur 8 : et ilya des erreurs
64
65
66 //=======================================================================
67 //function : Interface_CheckTool
68 //purpose  : 
69 //=======================================================================
70
71 Interface_CheckTool::Interface_CheckTool(const Handle(Interface_InterfaceModel)& model,
72                                          const Handle(Interface_Protocol)& protocol)
73      :  thegtool ( new Interface_GTool(protocol,model->NbEntities()) ) ,
74        theshare (model,protocol)
75 {
76   thestat = 0;
77 }
78
79
80 //=======================================================================
81 //function : Interface_CheckTool
82 //purpose  : 
83 //=======================================================================
84
85 Interface_CheckTool::Interface_CheckTool(const Handle(Interface_InterfaceModel)& model)
86      :  thegtool(model->GTool()) , theshare (model,model->GTool())
87 {
88   thestat = 0;
89   thegtool->Reservate(model->NbEntities());
90 }
91
92
93 //=======================================================================
94 //function : Interface_CheckTool
95 //purpose  : 
96 //=======================================================================
97
98 Interface_CheckTool::Interface_CheckTool(const Interface_Graph& graph)
99      : thegtool(graph.Model()->GTool()) , theshare (graph)
100 {
101 }
102
103
104 //=======================================================================
105 //function : Interface_CheckTool
106 //purpose  : 
107 //=======================================================================
108
109 Interface_CheckTool::Interface_CheckTool(const Handle(Interface_HGraph)& hgraph)
110      : thegtool(hgraph->Graph().Model()->GTool()) , theshare (hgraph)
111 {
112 }
113
114
115 //=======================================================================
116 //function : FillCheck
117 //purpose  : 
118 //=======================================================================
119
120 void Interface_CheckTool::FillCheck(const Handle(Standard_Transient)& ent,
121                                     const Interface_ShareTool& sh,
122                                     Handle(Interface_Check)& ach)
123 {
124   Handle(Interface_GeneralModule) module;
125   Standard_Integer CN;
126   if (thegtool->Select(ent,module,CN)) {
127 //    Sans try/catch (fait par l appelant, evite try/catch en boucle)
128     if (!errh) {
129       module->CheckCase(CN,ent,sh,ach);
130       return;
131     }
132 //    Avec try/catch
133     try {
134       OCC_CATCH_SIGNALS
135       module->CheckCase(CN,ent,sh,ach);
136     }
137     catch (Standard_Failure& anException) {
138       raisecheck(anException,ach);
139     }
140   }
141   else {
142     DeclareAndCast(Interface_ReportEntity,rep,ent);
143     if (rep.IsNull()) return;
144     ach = rep->Check();
145   }
146   if (theshare.Graph().HasShareErrors(ent))
147     ach->AddFail("** Shared Items unknown from the containing Model");
148 }
149
150
151 //=======================================================================
152 //function : Print
153 //purpose  : 
154 //=======================================================================
155
156 void Interface_CheckTool::Print(const Handle(Interface_Check)& ach,
157                                 Standard_OStream& S) const 
158 {
159   Standard_Integer i, nb;
160   nb = ach->NbFails();
161   if (nb > 0) S << " Fail Messages : " << nb << " :\n";
162   for (i = 1; i <= nb; i ++) {
163     S << ach->Fail(i)->String() << "\n";
164   }
165   nb = ach->NbWarnings();
166   if (nb > 0) S << " Warning Messages : " << nb << " :\n";
167   for (i = 1; i <= nb; i ++) {
168     S << ach->Warning(i)->String() << "\n";
169   }
170 }
171
172
173 //=======================================================================
174 //function : Print
175 //purpose  : 
176 //=======================================================================
177
178 void Interface_CheckTool::Print(const Interface_CheckIterator& list,
179                                 Standard_OStream& S) const 
180 {
181   Handle(Interface_InterfaceModel) model = theshare.Model();
182   list.Print(S,model,Standard_False);
183 }
184
185
186 //  ....                Check General sur un Modele                ....
187
188
189 // Check : Une Entite d un Modele, designee par son rang
190
191
192 //=======================================================================
193 //function : Check
194 //purpose  : 
195 //=======================================================================
196
197 Handle(Interface_Check) Interface_CheckTool::Check(const Standard_Integer num)
198 {
199   Handle(Interface_InterfaceModel) model = theshare.Model();
200   Handle(Standard_Transient) ent = model->Value(num);
201   Handle(Interface_Check) ach = new Interface_Check(ent);  // non filtre par "Warning" : tel quel
202   errh = 1;
203   FillCheck(ent,theshare,ach);
204   return ach;
205 }
206
207
208 //  CheckSuccess : test passe-passe pas, sur CheckList(Fail) des Entites
209
210
211 //=======================================================================
212 //function : CheckSuccess
213 //purpose  : 
214 //=======================================================================
215
216 void Interface_CheckTool::CheckSuccess (const Standard_Boolean reset)
217 {
218   if (reset) thestat = 0;
219   if (thestat > 3) throw Interface_CheckFailure    // deja teste avec erreur
220     ("Interface Model : Global Check");
221   Handle(Interface_InterfaceModel) model = theshare.Model();
222   if (model->GlobalCheck()->NbFails() > 0) throw Interface_CheckFailure("Interface Model : Global Check");
223   Handle(Interface_Check) modchk = new Interface_Check;
224   model->VerifyCheck(modchk);
225   if (!model->Protocol().IsNull()) model->Protocol()->GlobalCheck (theshare.Graph(),modchk);
226   if (modchk->HasFailed())  throw Interface_CheckFailure("Interface Model : Verify Check");
227   if (thestat == 3) return;                    // tout teste et ca passe
228
229   errh = 0;  // Pas de try/catch, car justement on raise
230   Standard_Integer nb = model->NbEntities();
231   for (Standard_Integer i = 1; i <= nb; i ++) {
232     if (model->IsErrorEntity(i)) throw Interface_CheckFailure("Interface Model : an Entity is recorded as Erroneous");
233     Handle(Standard_Transient) ent = model->Value(i);
234     if (thestat & 1) {
235       if (!model->IsErrorEntity(i)) continue;    // deja verify, reste analyse
236     }
237     if (thestat & 2) {
238       if ( model->IsErrorEntity(i)) continue;    // deja analyse, reste verify
239     }
240
241     Handle(Interface_Check) ach = new Interface_Check(ent);
242     FillCheck(ent,theshare,ach);
243     if (ach->HasFailed()) throw Interface_CheckFailure("Interface Model : Check on an Entity has Failed");
244   }
245 }
246
247
248 //  CompleteCheckList : Tous Tests : GlobalCheck, Analyse-Verify en Fail ou en
249 //  Warning; plus les Unknown Entities (par Check vide)
250
251
252 //=======================================================================
253 //function : CompleteCheckList
254 //purpose  : 
255 //=======================================================================
256
257 Interface_CheckIterator Interface_CheckTool::CompleteCheckList ()
258 {
259   thestat = 3;
260   Handle(Interface_InterfaceModel) model = theshare.Model();
261   Interface_CheckIterator res;
262   res.SetModel(model);
263   Handle(Interface_Check) globch = model->GlobalCheck();    // GlobalCheck Statique
264   if (!model->Protocol().IsNull()) model->Protocol()->GlobalCheck (theshare.Graph(),globch);
265   model->VerifyCheck(globch);                       // GlobalCheck Dynamique
266   if (globch->HasFailed() || globch->HasWarnings()) res.Add(globch,0);
267   if (globch->HasFailed()) thestat |= 12;
268
269   Standard_Integer i=0,n0 = 1, nb = model->NbEntities();
270   errh = 0;
271   while (n0 <= nb) {
272     Handle(Interface_Check) ach = new Interface_Check;
273     Handle(Standard_Transient) ent;
274     try {
275       OCC_CATCH_SIGNALS
276       for (i = n0; i <= nb; i ++) {
277         ach->Clear();
278         ent = model->Value(i);
279         ach->SetEntity(ent);
280         if (model->IsReportEntity(i)) {
281           ach = model->ReportEntity(i)->Check();  // INCLUT Unknown
282           if (ach->HasFailed())      // FAIL : pas de Check semantique
283           {  res.Add(ach,i);  ach = new Interface_Check;  thestat |= 12;  continue;  }
284         }
285         if (!model->HasSemanticChecks()) FillCheck(ent,theshare,ach);
286         else ach->GetMessages (model->Check (i,Standard_False));
287         if (ach->HasFailed() || ach->HasWarnings())
288         { res.Add(ach,i);  ach = new Interface_Check;  if (ach->HasFailed())  thestat |= 12; }
289       }
290       n0 = nb+1;
291     }
292     catch(Standard_Failure& anException) {
293       n0 = i+1;
294       raisecheck(anException,ach);
295       res.Add(ach,i);  thestat |= 12;
296     }
297   }
298   return res;
299 }
300
301
302 //  CheckList : Check Fail sur Entites, en Analyse (Read time) ou Verify
303
304
305 //=======================================================================
306 //function : CheckList
307 //purpose  : 
308 //=======================================================================
309
310 Interface_CheckIterator Interface_CheckTool::CheckList ()
311 {
312   thestat = 3;
313   Handle(Interface_InterfaceModel) model = theshare.Model();
314   Interface_CheckIterator res;
315   res.SetModel(model);
316   Standard_Integer i=0, n0 = 1, nb = model->NbEntities();
317   Handle(Interface_Check) globch = model->GlobalCheck();
318   if (!model->Protocol().IsNull()) model->Protocol()->GlobalCheck (theshare.Graph(),globch);
319   model->VerifyCheck(globch);
320   if (globch->HasFailed()) {  thestat |= 12;  res.Add(globch,0);  }
321
322   errh = 0;
323   while (n0 <= nb) {
324     Handle(Interface_Check) ach = new Interface_Check; 
325     Handle(Standard_Transient) ent;
326     try {
327       OCC_CATCH_SIGNALS
328       for (i = n0; i <= nb; i ++) {
329         if (model->IsReportEntity(i)) {
330           ach = model->ReportEntity(i)->Check();
331           if (ach->HasFailed()) {  thestat |= 12;  res.Add(ach,i);  }
332         }
333         else {
334           ent = model->Value(i);
335           ach->Clear();
336           ach->SetEntity(ent);
337           if (!model->HasSemanticChecks()) FillCheck(ent,theshare,ach);
338           else ach = model->Check (i,Standard_False);
339           if (ach->HasFailed()) {  thestat |= 12;  res.Add(ach,i);  }
340         }
341       }
342       n0 = nb+1;
343     }
344     catch(Standard_Failure& anException) {
345       n0 = i+1;
346       raisecheck(anException,ach);
347       res.Add(ach,i);  thestat |= 12;
348     }
349   }
350   return res;
351 }
352
353
354 //  AnalyseCheckList : Fail au chargement des Entites (Read time)
355
356
357 //=======================================================================
358 //function : AnalyseCheckList
359 //purpose  : 
360 //=======================================================================
361
362 Interface_CheckIterator Interface_CheckTool::AnalyseCheckList ()
363 {
364   thestat = 2;
365   Handle(Interface_InterfaceModel) model = theshare.Model();
366   Interface_CheckIterator res;
367   res.SetModel(model);
368   Standard_Integer i=0, n0 = 1, nb = model->NbEntities();
369
370   errh = 0;
371   while (n0 <= nb) {
372     Handle(Interface_Check) ach = new Interface_Check;
373     try {
374       OCC_CATCH_SIGNALS
375       for (i = n0; i <= nb; i ++) {
376         if (!model->IsReportEntity(i)) continue;
377         Handle(Interface_ReportEntity) rep = model->ReportEntity(i);
378         ach = rep->Check();
379         if (ach->HasFailed() || ach->HasWarnings())
380           {  thestat |=  8;  res.Add(ach,i);  }
381       }
382       n0 = nb+1;
383     }
384     catch(Standard_Failure& anException) {
385       n0 = i+1;
386       raisecheck(anException,ach);
387       res.Add(ach,i);  thestat |= 8;
388     }
389   }
390   return res;
391 }
392
393
394 //  VerifyCheckList : Fail/Warning sur Analyse (Entites chargees OK. Valides ?)
395
396
397 //=======================================================================
398 //function : VerifyCheckList
399 //purpose  : 
400 //=======================================================================
401
402 Interface_CheckIterator Interface_CheckTool::VerifyCheckList ()
403 {
404   thestat = 1;
405   Handle(Interface_InterfaceModel) model = theshare.Model();
406   Interface_CheckIterator res;
407   res.SetModel(model);
408   Standard_Integer i=0, n0 = 1, nb = model->NbEntities();
409
410   errh = 0;
411   while (n0 <= nb) {
412     Handle(Standard_Transient) ent;
413     Handle(Interface_Check) ach = new Interface_Check;
414     try {
415       OCC_CATCH_SIGNALS
416       for (i = n0; i <= nb; i ++) {
417         if (model->IsErrorEntity(i)) continue;
418         ent = model->Value(i);
419         ach->Clear();
420         ach->SetEntity(ent);
421         if (!model->HasSemanticChecks()) FillCheck(ent,theshare,ach);
422         else ach = model->Check (i,Standard_False);
423         if (ach->HasFailed() || ach->HasWarnings())
424           {  thestat |=  4;  res.Add(ach,i);  }
425       }
426       n0 = nb+1;
427     }
428     catch(Standard_Failure& anException) {
429       n0 = i+1;
430       raisecheck(anException,ach);
431       res.Add(ach,i);  thestat |= 4;
432     }
433   }
434   return res;
435 }
436
437
438 //  Warnings sur Entites (Read time ou apres)
439
440
441 //=======================================================================
442 //function : WarningCheckList
443 //purpose  : 
444 //=======================================================================
445
446 Interface_CheckIterator Interface_CheckTool::WarningCheckList ()
447 {
448   thestat = 3;
449   Handle(Interface_InterfaceModel) model = theshare.Model();
450   Interface_CheckIterator res;
451   res.SetModel(model);
452   Standard_Integer i=0, n0 = 1, nb = model->NbEntities();
453
454   errh = 0;
455   while (n0 <= nb) {
456     Handle(Interface_Check) ach = new Interface_Check;
457     Handle(Standard_Transient) ent;
458     try {
459       OCC_CATCH_SIGNALS
460       for (i = n0; i <= nb; i ++) {
461         ach->Clear();
462         ach->SetEntity (ent);
463         if (model->IsReportEntity(i)) {
464           Handle(Interface_ReportEntity) rep = model->ReportEntity(i);
465           if (rep->IsError()) {  thestat |= 12;  continue;  }
466           ach = rep->Check();
467         }
468         ent = model->Value(i);
469         if (!model->HasSemanticChecks()) FillCheck(ent,theshare,ach);
470         else ach = model->Check (i,Standard_False);
471         if (ach->HasFailed()) thestat |= 12;
472         else if (ach->HasWarnings()) res.Add(ach,i);
473       }
474       n0 = nb+1;
475     }
476     catch(Standard_Failure& anException) {
477       n0 = i+1;
478       raisecheck(anException,ach);
479       res.Add(ach,i);  thestat |= 12;
480     }
481   }
482
483   return res;
484 }
485
486
487 //=======================================================================
488 //function : UnknownEntities
489 //purpose  : 
490 //=======================================================================
491
492 Interface_EntityIterator Interface_CheckTool::UnknownEntities ()
493 {
494   Handle(Interface_InterfaceModel) model = theshare.Model();
495   Interface_EntityIterator res;
496   Standard_Integer nb = model->NbEntities();
497   for (Standard_Integer i = 1; i <= nb; i ++) {
498     if (model->IsUnknownEntity(i)) res.GetOneItem(model->Value(i));
499   }
500   return res;
501 }