0022921: Adding macros for convenient inclusion of run-time asserts
authorKGV <>
Wed, 22 Feb 2012 12:40:11 +0000 (12:40 +0000)
committerbugmaster <bugmaster@opencascade.com>
Mon, 5 Mar 2012 15:33:03 +0000 (19:33 +0400)
src/AIS2D/AIS2D_ProjShape.cxx
src/QANewDBRepNaming/QANewDBRepNaming_FeatureCommands.cxx
src/QANewDBRepNaming/QANewDBRepNaming_PrimitiveCommands.cxx
src/QAUsinor/QAUsinor.cxx
src/Standard/FILES
src/Standard/Standard_Assert.hxx [new file with mode: 0644]

index 3bfad7e..f98fba9 100755 (executable)
@@ -1,4 +1,3 @@
-#include "assert.h"
 #include <AIS2D_ProjShape.ixx>
 #include <TopExp_Explorer.hxx>  
 #include <TopoDS.hxx>
@@ -16,6 +15,7 @@
 #include <HLRBRep_HLRToShape.hxx>
 #include <TopTools_ListIteratorOfListOfShape.hxx>
 #include <TopLoc_Location.hxx>
+#include <Standard_Assert.hxx>
 
 #include <V2d_Viewer.hxx>
 
@@ -297,14 +297,12 @@ void AIS2D_ProjShape::DrawCurves( const TopoDS_Shape& aShape,
   while ( theExp.More() ) {
 
     const TopoDS_Edge& CurrentEdge = TopoDS::Edge( theExp.Current() );
-    assert(CurrentEdge.Location().IsIdentity());
     BRep_Tool::CurveOnSurface( CurrentEdge, aCurve, aSurface, theLoc, f, l );
-    assert(theLoc.IsIdentity());
+    Standard_ASSERT (theLoc.IsIdentity(), "Unexpected edge with non-identity location", continue);
+    Standard_ASSERT (! aCurve.IsNull(), "Null PCurve", continue);
     Handle(Geom2d_TrimmedCurve) theCurve = new Geom2d_TrimmedCurve(aCurve,f,l);
-    assert( ! theCurve.IsNull() );
-       aSofC->Add(theCurve);
+    aSofC->Add(theCurve);
     theExp.Next();
-
   }
 }
 
index 4248bb4..fe5b615 100755 (executable)
@@ -48,7 +48,7 @@
 #include <QANewModTopOpe_Limitation.hxx>
 #include <QANewModTopOpe_Intersection.hxx>
 
-#include <assert.h>
+#include <Standard_Assert.hxx>
 
 #include <BRepBuilderAPI_MakeEdge.hxx>
 #include <BRepBuilderAPI_MakeFace.hxx>
@@ -107,7 +107,7 @@ static Standard_Integer QANewDBRepNaming_NameBooleanOperationFeat (Draw_Interpre
     di <<  "BRepAlgoAPI_Fuse"  << "\n";
     BRepAlgoAPI_Fuse mkFuse(S1, S2);
 
-    assert(mkFuse.IsDone());
+    Standard_ASSERT_RAISE(mkFuse.IsDone(), "Fuse failed");
     QANewBRepNaming_Fuse nameBool(L);
     nameBool.Load(mkFuse);
     break;
@@ -116,7 +116,7 @@ static Standard_Integer QANewDBRepNaming_NameBooleanOperationFeat (Draw_Interpre
     di <<  "BRepAlgoAPI_Cut"  << "\n";
     BRepAlgoAPI_Cut mkCut(S1, S2);
 
-    assert(mkCut.IsDone());
+    Standard_ASSERT_RAISE(mkCut.IsDone(), "Cut failed");
     QANewBRepNaming_Cut nameBool(L);
     nameBool.Load(mkCut);
     break; 
@@ -125,14 +125,14 @@ static Standard_Integer QANewDBRepNaming_NameBooleanOperationFeat (Draw_Interpre
     di <<  "BRepAlgoAPI_Common"  << "\n";
     BRepAlgoAPI_Common mkCommon(S1, S2);
 
-    assert(mkCommon.IsDone());
+    Standard_ASSERT_RAISE(mkCommon.IsDone(), "Common failed");
     QANewBRepNaming_Common nameBool(L);
     nameBool.Load(mkCommon);
     break;
   }
   case 4: {
     QANewModTopOpe_Intersection mkSection(S1, S2);
-    assert(mkSection.IsDone());
+    Standard_ASSERT_RAISE(mkSection.IsDone(), "Section failed");
     QANewBRepNaming_Intersection nameBool(L);
     nameBool.Load(mkSection);
     break;
@@ -145,7 +145,7 @@ static Standard_Integer QANewDBRepNaming_NameBooleanOperationFeat (Draw_Interpre
 //     if (Orientation = 0) mkLimit.CutForward();
 //     else if (Orientation = 1) mkLimit.CutReversed();
 //     else if (Orientation = 2) mkLimit.CutBothSides();
-    assert(mkLimit.IsDone());
+    Standard_ASSERT_RAISE(mkLimit.IsDone(),"Limit failed");
     QANewBRepNaming_Limitation nameBool(L);
     nameBool.Load(mkLimit);
     break;
@@ -182,7 +182,7 @@ static Standard_Integer QANewDBRepNaming_NameFuse (Draw_Interpretor& di,
   di <<  "BRepAlgoAPI_Fuse"  << "\n";
   BRepAlgoAPI_Fuse mkFuse(S1, S2);
 
-  assert(mkFuse.IsDone());
+  Standard_ASSERT_RAISE(mkFuse.IsDone(), "Fuse failed");
   nameBool.Load(mkFuse);
   return 0;
 }    
@@ -219,7 +219,7 @@ static Standard_Integer QANewDBRepNaming_NameCut (Draw_Interpretor& di,
 // DBRep::Set("Shape1", mkCut.Shape1());
 // DBRep::Set("Shape2", mkCut.Shape2());
 // BRepTools::Write(mkCut.Shape1(), "/dn04/OS/SAMTECH/env/S1.brep");
-  assert(mkCut.IsDone());
+  Standard_ASSERT_RAISE(mkCut.IsDone(), "Cut failed");
   nameBool.Load(mkCut);
 // BRepTools::Write(mkCut.Shape1(), "/dn04/OS/SAMTECH/env/S2.brep");
   return 0;
@@ -250,7 +250,7 @@ static Standard_Integer QANewDBRepNaming_NameCommon (Draw_Interpretor& di,
   di <<  "BRepAlgoAPI_Common"  << "\n";
   BRepAlgoAPI_Common mkCommon(S1, S2);
 
-  assert(mkCommon.IsDone());
+  Standard_ASSERT_RAISE(mkCommon.IsDone(), "Common failed");
   nameBool.Load(mkCommon);
   return 0;
 }    
@@ -277,7 +277,7 @@ static Standard_Integer QANewDBRepNaming_NameIntersection (Draw_Interpretor& di,
   const TopoDS_Shape& S2 = DBRep::Get(arg[4]);
   QANewBRepNaming_Intersection nameBool(L);
   QANewModTopOpe_Intersection mkIntersection(S1, S2);
-  assert(mkIntersection.IsDone());
+  Standard_ASSERT_RAISE(mkIntersection.IsDone(), "Section failed");
   nameBool.Load(mkIntersection);
   return 0;
 }    
@@ -313,7 +313,7 @@ static Standard_Integer QANewDBRepNaming_NameLimit (Draw_Interpretor& di,
  //  if (Orientation == 0) mkLimit.CutForward();
 //   else if (Orientation == 1) mkLimit.CutReversed();
 //   else if (Orientation == 2) mkLimit.CutBothSides();
-  assert(mkLimit.IsDone());
+  Standard_ASSERT_RAISE(mkLimit.IsDone(), "Limit failed");
   nameBool.Load(mkLimit);
   return 0;
 }    
index e3d880a..16d04e9 100755 (executable)
@@ -46,7 +46,6 @@
 
 #include <BRep_Tool.hxx>
 
-#include <assert.h>
 #include <TopExp_Explorer.hxx>
 
 #include <QADNaming.hxx>
index 58c1488..0e517e2 100755 (executable)
@@ -56,7 +56,7 @@
 #include <Geom_Curve.hxx>
 #include <GCPnts_UniformAbscissa.hxx>
 #include <GeomAdaptor_Curve.hxx>
-#include <assert.h>
+#include <Standard_Assert.hxx>
 
 #define DEFAULT_COLOR    Quantity_NOC_GOLDENROD
 
@@ -266,7 +266,7 @@ static Standard_Integer OCC367 (Draw_Interpretor& di, Standard_Integer argc, con
     if (vw1.IsSame(ve1) || vw1.IsSame(ve2))
       vlast = vw1;
     else {
-      assert(vw2.IsSame(ve1) || vw2.IsSame(ve2));
+      Standard_ASSERT_RAISE(vw2.IsSame(ve1) || vw2.IsSame(ve2), "Disconnected vertices");
       vlast = vw2;
     }
   }
@@ -292,8 +292,8 @@ static Standard_Integer OCC367 (Draw_Interpretor& di, Standard_Integer argc, con
        }
       else
        {
-          assert(ve2.IsSame(vlast));
-          assert ( wire_exp.Orientation( ) == TopAbs_REVERSED );
+          Standard_ASSERT_RAISE(ve2.IsSame(vlast), "Not the same vertex");
+          Standard_ASSERT_RAISE(wire_exp.Orientation() == TopAbs_REVERSED, "Wire should be REVERSED");
           acurve = BRep_Tool::Curve( edge, ufirst, ulast );
           newufirst = acurve->ReversedParameter( ufirst );
           newulast  = acurve->ReversedParameter( ulast );
index 63c1140..7ade12e 100755 (executable)
@@ -72,3 +72,4 @@ Standard_Atomic.hxx
 Standard_DefineException.hxx
 Standard_MMgrTBBalloc.cxx
 Standard_MMgrTBBalloc.hxx
+Standard_Assert.hxx
diff --git a/src/Standard/Standard_Assert.hxx b/src/Standard/Standard_Assert.hxx
new file mode 100644 (file)
index 0000000..2a7c759
--- /dev/null
@@ -0,0 +1,146 @@
+// File:      Standard_Assert.hxx
+// Created:   20.03.01 19:01:48
+// Author:    Andrey BETENEV
+
+#ifndef Standard_Assert_HeaderFile
+#define Standard_Assert_HeaderFile
+
+#include <Standard_ProgramError.hxx>
+
+//!@file
+//! This header file defines a set of ASSERT macros intended for use
+//! in algorithms for debugging purposes and as a tool to organise
+//! checks for abnormal situations in the uniform way.
+//!
+//! In contrast to C assert() function that terminates the process, these
+//! macros provide choice of the action to be performed if assert failed,
+//! thus allowing execution to continue when possible.
+//! Except for the message for developer that appears only in Debug mode,
+//! the macros behave in the same way in both Release and Debug modes.
+//!
+//!
+//! The ASSERT macros differ in the way they react on a wrong situation:
+//! - Standard_ASSERT_RAISE:  raises exception Standard_ProgramError
+//! - Standard_ASSERT_RETURN: returns specified value (last argument may
+//!                           be left empty to return void)
+//! - Standard_ASSERT_SKIP:   does nothing
+//! - Standard_ASSERT_VOID:   does nothing; even does not evaluate first arg
+//!                           when in Release mode
+//! - Standard_ASSERT_INVOKE: causes unconditional assert
+//! - Standard_ASSERT:        base macro (used by other macros);
+//!                           does operation indicated in argument "todo"
+//!
+//! The assertion is assumed to fail if the first argument is
+//! evaluated to zero (false).
+//! The first argument is evaluated by all macros except Standard_ASSERT_VOID
+//! which does not evaluate first argument when in Release mode.
+//! The mode is triggered by preprocessor macro DEB: if it is defined,
+//! Debug mode is assumed, Release otherwise.
+//!
+//! In debug mode, if condition is not satisfied the macros call 
+//! Standard_ASSERT_INVOKE_ which:
+//! - on Windows (under VC++), stops code execution and prompts to attach 
+//!   debugger to the process immediately.
+//! - on POSIX systems, prints message to cerr and raises signal SIGTRAP to stop 
+//!   execution when under debugger (may terminate the process if not under debugger).
+//!
+//! The second argument (message) should be string constant ("...").
+//!
+//! The macros are formed as functions and require semicolon at the end.
+
+// Stub function used to make macros complete C++ operator 
+inline void Standard_ASSERT_DO_NOTHING() {}
+
+// User messages are activated in debug mode only
+#ifdef DEB
+  #if (defined(_WIN32) || defined(__WIN32__))
+    #if defined(_MSC_VER)
+      // VS-specific intrinsic
+      #define Standard_ASSERT_DBGBREAK_() __debugbreak()
+    #else
+      // WinAPI function
+      #include <windows.h>
+      #define Standard_ASSERT_DBGBREAK_() DebugBreak()
+    #endif
+  #else
+    // POSIX systems
+    #include <signal.h>
+    #define Standard_ASSERT_DBGBREAK_() raise(SIGTRAP)
+  #endif
+
+  #if defined(_MSC_VER) && defined(_DEBUG)
+    #include <crtdbg.h>
+    // use debug CRT built-in function that show up message box to user
+    // with formatted assert description and 3 possible actions
+    inline Standard_Boolean Standard_ASSERT_REPORT_ (const char* theFile,
+                                                     const int   theLine,
+                                                     const char* theExpr,
+                                                     const char* theDesc)
+    {
+      // 1 means user pressed Retry button
+      return _CrtDbgReport (_CRT_ASSERT, theFile, theLine, NULL,
+                            "%s\n(Condition: \"%s\")\n", theDesc, theExpr) == 1;
+    }
+  #else
+    // just log assertion description into standard error stream
+    inline Standard_Boolean Standard_ASSERT_REPORT_ (const char* theFile,
+                                                     const int   theLine,
+                                                     const char* theExpr,
+                                                     const char* theDesc)
+    {
+      std::cerr << "ERROR: statement '" << theExpr << "' is not TRUE!\n"
+                << "\nFile: '"   << theFile << "'"
+                << "\nLine: "    << theLine << "\n";
+      if (theDesc != NULL && *theDesc != '\0')
+        std::cerr << "Description: " << theDesc << "\n";
+
+      std::cerr << std::flush;
+      return Standard_True;
+    }
+  #endif
+
+  // report issue and add debug breakpoint or abort execution
+  #define Standard_ASSERT_INVOKE_(theExpr, theDesc) \
+    if (Standard_ASSERT_REPORT_ (__FILE__, __LINE__, #theExpr, theDesc)) { Standard_ASSERT_DBGBREAK_(); } \
+    else Standard_ASSERT_DO_NOTHING()
+
+  // Basic ASSERT macros
+  #define Standard_ASSERT(theExpr, theDesc, theAction)                        \
+    if (!(theExpr)) { Standard_ASSERT_INVOKE_(theExpr, theDesc); theAction; } \
+    else Standard_ASSERT_DO_NOTHING()
+  #define Standard_ASSERT_SKIP(theExpr, theDesc) \
+    Standard_ASSERT(theExpr, theDesc,)
+  #define Standard_ASSERT_VOID(theExpr, theDesc) \
+    Standard_ASSERT(theExpr, theDesc,)
+#else
+
+  // dummy block
+  #define Standard_ASSERT_INVOKE_(theExpr, theDesc) Standard_ASSERT_DO_NOTHING()
+
+  // Basic ASSERT macros
+  #define Standard_ASSERT(theExpr, theDesc, theAction) \
+    if (!(theExpr)) { theAction; }                     \
+    else Standard_ASSERT_DO_NOTHING()
+  #define Standard_ASSERT_SKIP(theExpr, theDesc) theExpr
+  #define Standard_ASSERT_VOID(theExpr, theDesc) Standard_ASSERT_DO_NOTHING()
+
+#endif
+
+//! Raise exception (Standard_ProgramError) with the provided message
+#define Standard_ASSERT_RAISE(theExpr, theDesc)                                  \
+  Standard_ASSERT(theExpr, theDesc, Standard_ProgramError::Raise(                \
+      "*** ERROR: ASSERT in file '" __FILE__ "': \n" theDesc " (" #theExpr ")" ) )
+
+//! Return from the current function with specified value (empty
+//! if the function returns void)
+#define Standard_ASSERT_RETURN(theExpr, theDesc, theReturnValue) \
+  Standard_ASSERT(theExpr, theDesc, return theReturnValue)
+
+//! Raise debug message
+#define Standard_ASSERT_INVOKE(theDesc) Standard_ASSERT_INVOKE_(always, theDesc)
+
+#endif // Standard_Assert_HeaderFile
+
+#ifdef _MSC_VER
+  #pragma once
+#endif