Skip to content
Browse files

Merge pull request #1 from enthought/feature-explanation

Explain errors with the LinearConstraints that caused them
  • Loading branch information...
2 parents 4227213 + 7d63abf commit c4706256f81dda7c9a2c9d0c09b2dc9dede0cf2d @rkern rkern committed Apr 5, 2012
Showing with 2,414 additions and 1,650 deletions.
  1. +2,328 −1,644 casuarius.cpp
  2. +56 −2 casuarius.pyx
  3. +26 −0 cysw_support.cc
  4. +4 −4 cysw_support.h
View
3,972 casuarius.cpp
2,328 additions, 1,644 deletions not shown because the diff is too large. Please use a local Git client to view these changes.
View
58 casuarius.pyx
@@ -2,6 +2,7 @@
"""
from cython.operator cimport dereference as deref
+from cython.operator cimport preincrement as inc
from libc.math cimport fabs
from libcpp.string cimport string
from libcpp.vector cimport vector
@@ -12,14 +13,51 @@ from collections import defaultdict
cdef extern from "cysw_support.h":
string get_cpp_exception_message()
+ vector[size_t] get_cpp_exception_constraint_pointers()
class CassowaryError(Exception):
- pass
+ """ An error raised from Cassowary.
+ """
+
+class ExplainedCassowaryError(CassowaryError):
+ """ An error raised from Cassowary with a list of constraints that
+ are involved in the error.
+
+ Use the .explains() method with a list of LinearConstraints to get
+ a filtered list of LinearConstraints that explain this error.
+ """
+ # SORRY: Yes, it's an awkward API. Best I can do right now.
+
+ def explains(self, linear_constraints):
+ """ Filter a list of LinearConstraints to return only those
+ LinearConstraints that caused the error.
+ """
+ filtered = []
+ for cn in linear_constraints:
+ if cn.explains_exception(self):
+ filtered.append(cn)
+ return filtered
cdef int raise_cassowary_error() except *:
- raise CassowaryError(get_cpp_exception_message().c_str())
+ cdef string message
+ cdef vector[size_t] constraint_pointers
+
+ message = get_cpp_exception_message()
+ constraint_pointers = get_cpp_exception_constraint_pointers()
+ if constraint_pointers.size() > 0:
+ e = ExplainedCassowaryError(message.c_str())
+ e.explanation_constraint_pointers = []
+ else:
+ e = CassowaryError(message.c_str())
+
+ cdef vector[size_t].iterator it = constraint_pointers.begin()
+ while it != constraint_pointers.end():
+ e.explanation_constraint_pointers.append(deref(it))
+ inc(it)
+
+ raise e
cdef extern from "cassowary/SymbolicWeight.h":
@@ -71,6 +109,9 @@ cdef extern from "cassowary/Constraint.h":
cnLT = 3
cnGT = -3
+cdef extern from "cysw_support.h":
+ size_t get_P_Constraint_addr(P_Constraint *pcn)
+
cdef extern from "cassowary/LinearEquation.h":
cdef cppclass ClLinearEquation "LinearEquation":
pass
@@ -589,6 +630,19 @@ cdef class LinearConstraint:
self._weight = weight
deref(self.cl_linear_constraint).ChangeWeight(weight)
+ cpdef bint explains_exception(self, object e):
+ """ Returns True if this constraint is in the explanation list
+ of the exception.
+ """
+ if self.cl_linear_constraint == NULL or not isinstance(e, CassowaryError):
+ return False
+ cdef size_t addr = get_P_Constraint_addr(self.cl_linear_constraint)
+ cdef size_t ptr
+ for ptr in e.explanation_constraint_pointers:
+ if ptr == addr:
+ return True
+ return False
+
def __or__(self, other):
cdef Strength strength = self.strength
cdef double weight = self.weight
View
26 cysw_support.cc
@@ -1,9 +1,35 @@
// Support functions for cysw.
+#include <sstream>
+
#include "cysw_support.h"
#include "cassowary/LinearEquation.h"
#include "cassowary/LinearInequality.h"
+#include "cassowary/Errors.h"
+
+
+size_t get_P_Constraint_addr(P_Constraint *pcn) {
+ return reinterpret_cast<size_t>(pcn->ptr());
+}
+
+std::vector<size_t> get_cpp_exception_constraint_pointers() {
+ std::vector<size_t> constraint_pointers;
+ try {
+ // Re-throw the exception.
+ throw;
+ }
+ catch (const ExCLError &exn) {
+ const ConstraintSet* cset = exn.explanation();
+ if (cset != NULL) {
+ ConstraintSet::const_iterator it = cset->begin();
+ for (; it != cset->end(); ++it) {
+ constraint_pointers.push_back(reinterpret_cast<size_t>((*it).ptr()));
+ }
+ }
+ }
+ return constraint_pointers;
+}
std::string get_cpp_exception_message() {
std::string message;
View
8 cysw_support.h
@@ -1,16 +1,16 @@
+#include "stdint.h"
#include <string>
-#include <sstream>
+#include <vector>
#include "cassowary/SimplexSolver.h"
-#include "cassowary/Errors.h"
#include "cassowary/LinearExpression.h"
#include "cassowary/Constraint.h"
-
+std::vector<size_t> get_cpp_exception_constraint_pointers();
std::string get_cpp_exception_message();
std::string solver_str(SimplexSolver *solver);
P_Constraint *newLinearEquation(const P_LinearExpression &lhs, const P_LinearExpression &rhs, const Strength &strength, double weight);
P_Constraint *newLinearInequality(const P_LinearExpression &lhs, CnRelation op, const P_LinearExpression &rhs, const Strength &strength, double weight);
P_LinearExpression newLinearExpression(double constant);
void delete_P_Constraint(P_Constraint *pcn);
-
+size_t get_P_Constraint_addr(P_Constraint *pcn);

0 comments on commit c470625

Please sign in to comment.
Something went wrong with that request. Please try again.