From 91a16bc7b4c20cf1f6679844b921c5e161c6987c Mon Sep 17 00:00:00 2001 From: KGV <> Date: Wed, 22 Feb 2012 12:40:11 +0000 Subject: [PATCH] 0022921: Adding macros for convenient inclusion of run-time asserts --- src/AIS2D/AIS2D_ProjShape.cxx | 10 +- .../QANewDBRepNaming_FeatureCommands.cxx | 22 +-- .../QANewDBRepNaming_PrimitiveCommands.cxx | 1 - src/QAUsinor/QAUsinor.cxx | 8 +- src/Standard/FILES | 1 + src/Standard/Standard_Assert.hxx | 146 ++++++++++++++++++ 6 files changed, 166 insertions(+), 22 deletions(-) create mode 100644 src/Standard/Standard_Assert.hxx diff --git a/src/AIS2D/AIS2D_ProjShape.cxx b/src/AIS2D/AIS2D_ProjShape.cxx index 3bfad7eec1..f98fba9499 100755 --- a/src/AIS2D/AIS2D_ProjShape.cxx +++ b/src/AIS2D/AIS2D_ProjShape.cxx @@ -1,4 +1,3 @@ -#include "assert.h" #include #include #include @@ -16,6 +15,7 @@ #include #include #include +#include #include @@ -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(); - } } diff --git a/src/QANewDBRepNaming/QANewDBRepNaming_FeatureCommands.cxx b/src/QANewDBRepNaming/QANewDBRepNaming_FeatureCommands.cxx index 4248bb47f2..fe5b615bef 100755 --- a/src/QANewDBRepNaming/QANewDBRepNaming_FeatureCommands.cxx +++ b/src/QANewDBRepNaming/QANewDBRepNaming_FeatureCommands.cxx @@ -48,7 +48,7 @@ #include #include -#include +#include #include #include @@ -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; } diff --git a/src/QANewDBRepNaming/QANewDBRepNaming_PrimitiveCommands.cxx b/src/QANewDBRepNaming/QANewDBRepNaming_PrimitiveCommands.cxx index e3d880a952..16d04e96e1 100755 --- a/src/QANewDBRepNaming/QANewDBRepNaming_PrimitiveCommands.cxx +++ b/src/QANewDBRepNaming/QANewDBRepNaming_PrimitiveCommands.cxx @@ -46,7 +46,6 @@ #include -#include #include #include diff --git a/src/QAUsinor/QAUsinor.cxx b/src/QAUsinor/QAUsinor.cxx index 58c1488203..0e517e270d 100755 --- a/src/QAUsinor/QAUsinor.cxx +++ b/src/QAUsinor/QAUsinor.cxx @@ -56,7 +56,7 @@ #include #include #include -#include +#include #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 ); diff --git a/src/Standard/FILES b/src/Standard/FILES index 63c1140d7b..7ade12e486 100755 --- a/src/Standard/FILES +++ b/src/Standard/FILES @@ -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 index 0000000000..2a7c7594b8 --- /dev/null +++ b/src/Standard/Standard_Assert.hxx @@ -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 + +//!@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 + #define Standard_ASSERT_DBGBREAK_() DebugBreak() + #endif + #else + // POSIX systems + #include + #define Standard_ASSERT_DBGBREAK_() raise(SIGTRAP) + #endif + + #if defined(_MSC_VER) && defined(_DEBUG) + #include + // 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 -- 2.20.1