Răsfoiți Sursa

Merge pull request #29003 from Xrayez/clipper-6.4.2-exceptions-fix

Build Clipper with `tools=no` and patch it to auto-disable exceptions
Rémi Verschelde 6 ani în urmă
părinte
comite
fa5cc1da7a
5 a modificat fișierele cu 202 adăugiri și 18 ștergeri
  1. 1 0
      core/SCsub
  2. 0 3
      editor/SCsub
  3. 1 1
      thirdparty/README.md
  4. 154 0
      thirdparty/misc/clipper-exceptions.patch
  5. 46 14
      thirdparty/misc/clipper.cpp

+ 1 - 0
core/SCsub

@@ -58,6 +58,7 @@ thirdparty_misc_sources = [
     "md5.cpp",
     "pcg.cpp",
     "triangulator.cpp",
+    "clipper.cpp",
 ]
 thirdparty_misc_sources = [thirdparty_misc_dir + file for file in thirdparty_misc_sources]
 env_thirdparty.add_source_files(env.core_sources, thirdparty_misc_sources)

+ 0 - 3
editor/SCsub

@@ -79,9 +79,6 @@ if env['tools']:
     env.CommandNoCache('#editor/builtin_fonts.gen.h', flist, run_in_subprocess(editor_builders.make_fonts_header))
 
     env.add_source_files(env.editor_sources, "*.cpp")
-    env_thirdparty = env.Clone()
-    env_thirdparty.disable_warnings()
-    env_thirdparty.add_source_files(env.editor_sources, ["#thirdparty/misc/clipper.cpp"])
 
     SConscript('collada/SCsub')
     SConscript('doc/SCsub')

+ 1 - 1
thirdparty/README.md

@@ -346,7 +346,7 @@ Collection of single-file libraries used in Godot components.
   * License: Public Domain
  - `clipper.{cpp,hpp}`
   * Upstream: https://sourceforge.net/projects/polyclipping
-  * Version: 6.4.2
+  * Version: 6.4.2 + Godot changes (added optional exceptions handling)
   * License: BSL-1.0
 - `fastlz.{c,h}`
   * Upstream: https://github.com/ariya/FastLZ

+ 154 - 0
thirdparty/misc/clipper-exceptions.patch

@@ -0,0 +1,154 @@
+diff --git a/thirdparty/misc/clipper.cpp b/thirdparty/misc/clipper.cpp
+index 8c3a59c4ca..c67045d113 100644
+--- a/thirdparty/misc/clipper.cpp
++++ b/thirdparty/misc/clipper.cpp
+@@ -48,6 +48,38 @@
+ #include <ostream>
+ #include <functional>
+ 
++//Explicitly disables exceptions handling for target platform
++//#define CLIPPER_NOEXCEPTION
++
++#define CLIPPER_THROW(exception) std::abort()
++#define CLIPPER_TRY if(true)
++#define CLIPPER_CATCH(exception) if(false)
++
++#if defined(__cpp_exceptions) || defined(__EXCEPTIONS) || defined(_CPPUNWIND)
++  #ifndef CLIPPER_NOEXCEPTION
++    #undef CLIPPER_THROW
++    #define CLIPPER_THROW(exception) throw exception
++    #undef CLIPPER_TRY
++    #define CLIPPER_TRY try
++    #undef CLIPPER_CATCH
++    #define CLIPPER_CATCH(exception) catch(exception)
++  #endif
++#endif
++
++//Optionally allows to override exception macros
++#if defined(CLIPPER_THROW_USER)
++	#undef CLIPPER_THROW
++	#define CLIPPER_THROW CLIPPER_THROW_USER
++#endif
++#if defined(CLIPPER_TRY_USER)
++	#undef CLIPPER_TRY
++	#define CLIPPER_TRY CLIPPER_TRY_USER
++#endif
++#if defined(CLIPPER_CATCH_USER)
++	#undef CLIPPER_CATCH
++	#define CLIPPER_CATCH CLIPPER_CATCH_USER
++#endif
++
+ namespace ClipperLib {
+ 
+ static double const pi = 3.141592653589793238;
+@@ -898,7 +930,7 @@ void RangeTest(const IntPoint& Pt, bool& useFullRange)
+   if (useFullRange)
+   {
+     if (Pt.X > hiRange || Pt.Y > hiRange || -Pt.X > hiRange || -Pt.Y > hiRange) 
+-      throw clipperException("Coordinate outside allowed range");
++      CLIPPER_THROW(clipperException("Coordinate outside allowed range"));
+   }
+   else if (Pt.X > loRange|| Pt.Y > loRange || -Pt.X > loRange || -Pt.Y > loRange) 
+   {
+@@ -1046,10 +1078,10 @@ bool ClipperBase::AddPath(const Path &pg, PolyType PolyTyp, bool Closed)
+ {
+ #ifdef use_lines
+   if (!Closed && PolyTyp == ptClip)
+-    throw clipperException("AddPath: Open paths must be subject.");
++    CLIPPER_THROW(clipperException("AddPath: Open paths must be subject."));
+ #else
+   if (!Closed)
+-    throw clipperException("AddPath: Open paths have been disabled.");
++    CLIPPER_THROW(clipperException("AddPath: Open paths have been disabled."));
+ #endif
+ 
+   int highI = (int)pg.size() -1;
+@@ -1062,7 +1094,7 @@ bool ClipperBase::AddPath(const Path &pg, PolyType PolyTyp, bool Closed)
+ 
+   bool IsFlat = true;
+   //1. Basic (first) edge initialization ...
+-  try
++  CLIPPER_TRY
+   {
+     edges[1].Curr = pg[1];
+     RangeTest(pg[0], m_UseFullRange);
+@@ -1075,10 +1107,10 @@ bool ClipperBase::AddPath(const Path &pg, PolyType PolyTyp, bool Closed)
+       InitEdge(&edges[i], &edges[i+1], &edges[i-1], pg[i]);
+     }
+   }
+-  catch(...)
++  CLIPPER_CATCH(...)
+   {
+     delete [] edges;
+-    throw; //range test fails
++    CLIPPER_THROW(); //range test fails
+   }
+   TEdge *eStart = &edges[0];
+ 
+@@ -1442,7 +1474,7 @@ void ClipperBase::SwapPositionsInAEL(TEdge *Edge1, TEdge *Edge2)
+ void ClipperBase::UpdateEdgeIntoAEL(TEdge *&e)
+ {
+   if (!e->NextInLML) 
+-    throw clipperException("UpdateEdgeIntoAEL: invalid call");
++    CLIPPER_THROW(clipperException("UpdateEdgeIntoAEL: invalid call"));
+ 
+   e->NextInLML->OutIdx = e->OutIdx;
+   TEdge* AelPrev = e->PrevInAEL;
+@@ -1510,7 +1542,7 @@ bool Clipper::Execute(ClipType clipType, Paths &solution,
+ {
+   if( m_ExecuteLocked ) return false;
+   if (m_HasOpenPaths)
+-    throw clipperException("Error: PolyTree struct is needed for open path clipping.");
++    CLIPPER_THROW(clipperException("Error: PolyTree struct is needed for open path clipping."));
+   m_ExecuteLocked = true;
+   solution.resize(0);
+   m_SubjFillType = subjFillType;
+@@ -1560,7 +1592,7 @@ void Clipper::FixHoleLinkage(OutRec &outrec)
+ bool Clipper::ExecuteInternal()
+ {
+   bool succeeded = true;
+-  try {
++  CLIPPER_TRY {
+     Reset();
+     m_Maxima = MaximaList();
+     m_SortedEdges = 0;
+@@ -1583,7 +1615,7 @@ bool Clipper::ExecuteInternal()
+       InsertLocalMinimaIntoAEL(botY);
+     }
+   }
+-  catch(...) 
++  CLIPPER_CATCH(...) 
+   {
+     succeeded = false;
+   }
+@@ -2827,18 +2859,18 @@ void Clipper::ProcessHorizontal(TEdge *horzEdge)
+ bool Clipper::ProcessIntersections(const cInt topY)
+ {
+   if( !m_ActiveEdges ) return true;
+-  try {
++  CLIPPER_TRY {
+     BuildIntersectList(topY);
+     size_t IlSize = m_IntersectList.size();
+     if (IlSize == 0) return true;
+     if (IlSize == 1 || FixupIntersectionOrder()) ProcessIntersectList();
+     else return false;
+   }
+-  catch(...) 
++  CLIPPER_CATCH(...) 
+   {
+     m_SortedEdges = 0;
+     DisposeIntersectNodes();
+-    throw clipperException("ProcessIntersections error");
++    CLIPPER_THROW(clipperException("ProcessIntersections error"));
+   }
+   m_SortedEdges = 0;
+   return true;
+@@ -3002,7 +3034,7 @@ void Clipper::DoMaxima(TEdge *e)
+     DeleteFromAEL(eMaxPair);
+   } 
+ #endif
+-  else throw clipperException("DoMaxima error");
++  else CLIPPER_THROW(clipperException("DoMaxima error"));
+ }
+ //------------------------------------------------------------------------------
+ 

+ 46 - 14
thirdparty/misc/clipper.cpp

@@ -48,6 +48,38 @@
 #include <ostream>
 #include <functional>
 
+//Explicitly disables exceptions handling for target platform
+//#define CLIPPER_NOEXCEPTION
+
+#define CLIPPER_THROW(exception) std::abort()
+#define CLIPPER_TRY if(true)
+#define CLIPPER_CATCH(exception) if(false)
+
+#if defined(__cpp_exceptions) || defined(__EXCEPTIONS) || defined(_CPPUNWIND)
+  #ifndef CLIPPER_NOEXCEPTION
+    #undef CLIPPER_THROW
+    #define CLIPPER_THROW(exception) throw exception
+    #undef CLIPPER_TRY
+    #define CLIPPER_TRY try
+    #undef CLIPPER_CATCH
+    #define CLIPPER_CATCH(exception) catch(exception)
+  #endif
+#endif
+
+//Optionally allows to override exception macros
+#if defined(CLIPPER_THROW_USER)
+	#undef CLIPPER_THROW
+	#define CLIPPER_THROW CLIPPER_THROW_USER
+#endif
+#if defined(CLIPPER_TRY_USER)
+	#undef CLIPPER_TRY
+	#define CLIPPER_TRY CLIPPER_TRY_USER
+#endif
+#if defined(CLIPPER_CATCH_USER)
+	#undef CLIPPER_CATCH
+	#define CLIPPER_CATCH CLIPPER_CATCH_USER
+#endif
+
 namespace ClipperLib {
 
 static double const pi = 3.141592653589793238;
@@ -898,7 +930,7 @@ void RangeTest(const IntPoint& Pt, bool& useFullRange)
   if (useFullRange)
   {
     if (Pt.X > hiRange || Pt.Y > hiRange || -Pt.X > hiRange || -Pt.Y > hiRange) 
-      throw clipperException("Coordinate outside allowed range");
+      CLIPPER_THROW(clipperException("Coordinate outside allowed range"));
   }
   else if (Pt.X > loRange|| Pt.Y > loRange || -Pt.X > loRange || -Pt.Y > loRange) 
   {
@@ -1046,10 +1078,10 @@ bool ClipperBase::AddPath(const Path &pg, PolyType PolyTyp, bool Closed)
 {
 #ifdef use_lines
   if (!Closed && PolyTyp == ptClip)
-    throw clipperException("AddPath: Open paths must be subject.");
+    CLIPPER_THROW(clipperException("AddPath: Open paths must be subject."));
 #else
   if (!Closed)
-    throw clipperException("AddPath: Open paths have been disabled.");
+    CLIPPER_THROW(clipperException("AddPath: Open paths have been disabled."));
 #endif
 
   int highI = (int)pg.size() -1;
@@ -1062,7 +1094,7 @@ bool ClipperBase::AddPath(const Path &pg, PolyType PolyTyp, bool Closed)
 
   bool IsFlat = true;
   //1. Basic (first) edge initialization ...
-  try
+  CLIPPER_TRY
   {
     edges[1].Curr = pg[1];
     RangeTest(pg[0], m_UseFullRange);
@@ -1075,10 +1107,10 @@ bool ClipperBase::AddPath(const Path &pg, PolyType PolyTyp, bool Closed)
       InitEdge(&edges[i], &edges[i+1], &edges[i-1], pg[i]);
     }
   }
-  catch(...)
+  CLIPPER_CATCH(...)
   {
     delete [] edges;
-    throw; //range test fails
+    CLIPPER_THROW(); //range test fails
   }
   TEdge *eStart = &edges[0];
 
@@ -1442,7 +1474,7 @@ void ClipperBase::SwapPositionsInAEL(TEdge *Edge1, TEdge *Edge2)
 void ClipperBase::UpdateEdgeIntoAEL(TEdge *&e)
 {
   if (!e->NextInLML) 
-    throw clipperException("UpdateEdgeIntoAEL: invalid call");
+    CLIPPER_THROW(clipperException("UpdateEdgeIntoAEL: invalid call"));
 
   e->NextInLML->OutIdx = e->OutIdx;
   TEdge* AelPrev = e->PrevInAEL;
@@ -1510,7 +1542,7 @@ bool Clipper::Execute(ClipType clipType, Paths &solution,
 {
   if( m_ExecuteLocked ) return false;
   if (m_HasOpenPaths)
-    throw clipperException("Error: PolyTree struct is needed for open path clipping.");
+    CLIPPER_THROW(clipperException("Error: PolyTree struct is needed for open path clipping."));
   m_ExecuteLocked = true;
   solution.resize(0);
   m_SubjFillType = subjFillType;
@@ -1560,7 +1592,7 @@ void Clipper::FixHoleLinkage(OutRec &outrec)
 bool Clipper::ExecuteInternal()
 {
   bool succeeded = true;
-  try {
+  CLIPPER_TRY {
     Reset();
     m_Maxima = MaximaList();
     m_SortedEdges = 0;
@@ -1583,7 +1615,7 @@ bool Clipper::ExecuteInternal()
       InsertLocalMinimaIntoAEL(botY);
     }
   }
-  catch(...) 
+  CLIPPER_CATCH(...) 
   {
     succeeded = false;
   }
@@ -2827,18 +2859,18 @@ void Clipper::ProcessHorizontal(TEdge *horzEdge)
 bool Clipper::ProcessIntersections(const cInt topY)
 {
   if( !m_ActiveEdges ) return true;
-  try {
+  CLIPPER_TRY {
     BuildIntersectList(topY);
     size_t IlSize = m_IntersectList.size();
     if (IlSize == 0) return true;
     if (IlSize == 1 || FixupIntersectionOrder()) ProcessIntersectList();
     else return false;
   }
-  catch(...) 
+  CLIPPER_CATCH(...) 
   {
     m_SortedEdges = 0;
     DisposeIntersectNodes();
-    throw clipperException("ProcessIntersections error");
+    CLIPPER_THROW(clipperException("ProcessIntersections error"));
   }
   m_SortedEdges = 0;
   return true;
@@ -3002,7 +3034,7 @@ void Clipper::DoMaxima(TEdge *e)
     DeleteFromAEL(eMaxPair);
   } 
 #endif
-  else throw clipperException("DoMaxima error");
+  else CLIPPER_THROW(clipperException("DoMaxima error"));
 }
 //------------------------------------------------------------------------------