]> granicus.if.org Git - graphviz/commitdiff
Replace setjmp/longjmp with simple returns;
authorEmden Gansner <erg@research.att.com>
Fri, 2 Mar 2012 20:51:06 +0000 (15:51 -0500)
committerEmden Gansner <erg@research.att.com>
Fri, 2 Mar 2012 20:51:06 +0000 (15:51 -0500)
give name of edge if box reclamation fails.

lib/common/routespl.c

index 055bddd9ea111b9d0647c5b5fdcaf6035d71a5d0..70e19390cc218b5fe5ffe36d1f0f0450c120d119 100644 (file)
@@ -33,7 +33,6 @@ static edge_t *origedge;
 #endif
 
 static int nedges, nboxes; /* total no. of edges and boxes used in routing */
-static jmp_buf jbuf;
 
 static int routeinit;
 /* static data used across multiple edges */
@@ -44,7 +43,7 @@ static int polypointn;        /* size of polypoints[] */
 static Pedge_t *edges;        /* polygon edges passed to Proutespline */
 static int edgen;             /* size of edges[] */
 
-static void checkpath(int, boxf*, path*);
+static int checkpath(int, boxf*, path*);
 static int mkspacep(int size);
 static void printpath(path * pp);
 #ifdef DEBUG
@@ -369,6 +368,25 @@ limitBoxes (boxf* boxes, int boxn, pointf *pps, int pn, int delta)
 #define INIT_DELTA 10 
 #define LOOP_TRIES 15  /* number of times to try to limiting boxes to regain space, using smaller divisions */
 
+/* routesplines:
+ * Route a path using the path info in pp. This includes start and end points
+ * plus a collection of contiguous boxes contain the terminal points. The boxes
+ * are converted into a containing polygon. A shortest path is constructed within
+ * the polygon from between the terminal points. If polyline is true, this path
+ * is converted to a spline representation. Otherwise, we call the path planner to
+ * convert the polyline into a smooth spline staying within the polygon. In both
+ * cases, the function returns an array of the computed control points. The number
+ * of these points is given in npoints.
+ *
+ * Note that the returned points are stored in a single array, so the points must be
+ * used before another call to this function.
+ *
+ * During cleanup, the function determines the x-extent of the spline in the box, so
+ * the box can be shrunk to the minimum width. The extra space can then be used by other
+ * edges. 
+ *
+ * If a catastrophic error, return NULL.
+ */
 static pointf *_routesplines(path * pp, int *npoints, int polyline)
 {
     Ppoly_t poly;
@@ -396,13 +414,14 @@ static pointf *_routesplines(path * pp, int *npoints, int polyline)
         realedge = ED_to_orig(realedge));
     if (!realedge) {
        agerr(AGERR, "in routesplines, cannot find NORMAL edge\n");
-       longjmp (jbuf, 1);
+       return NULL;
     }
 
     boxes = pp->boxes;
     boxn = pp->nbox;
 
-    checkpath(boxn, boxes, pp);
+    if (checkpath(boxn, boxes, pp))
+       return NULL;
 
 #ifdef DEBUG
     if (debugleveln(realedge, 1))
@@ -459,7 +478,7 @@ static pointf *_routesplines(path * pp, int *npoints, int polyline)
            else {
                if (!(prev == -1 && next == -1)) {
                    agerr(AGERR, "in routesplines, illegal values of prev %d and next %d, line %d\n", prev, next, __LINE__);
-                   longjmp (jbuf, 1);
+                   return NULL;
                }
            }
        }
@@ -492,8 +511,7 @@ static pointf *_routesplines(path * pp, int *npoints, int polyline)
                if (!(prev == -1 && next == -1)) {
                    /* it went badly, e.g. degenerate box in boxlist */
                    agerr(AGERR, "in routesplines, illegal values of prev %d and next %d, line %d\n", prev, next, __LINE__);
-                   longjmp (jbuf, 1); /* for correctness sake, it's best to just stop */
-                   return ps;  /* could also be reported as a lost edge (no spline) */
+                   return NULL; /* for correctness sake, it's best to just stop */
                }
                polypoints[pi].x = boxes[bi].UR.x;
                polypoints[pi++].y = boxes[bi].LL.y;
@@ -508,7 +526,7 @@ static pointf *_routesplines(path * pp, int *npoints, int polyline)
     }
     else {
        agerr(AGERR, "in routesplines, edge is a loop at %s\n", agnameof(aghead(realedge)));
-       longjmp (jbuf, 1);
+       return NULL;
     }
 
     if (flip) {
@@ -529,7 +547,7 @@ static pointf *_routesplines(path * pp, int *npoints, int polyline)
     eps[1].x = pp->end.p.x, eps[1].y = pp->end.p.y;
     if (Pshortestpath(&poly, eps, &pl) < 0) {
        agerr(AGERR, "in routesplines, Pshortestpath failed\n");
-       longjmp (jbuf, 1);
+       return NULL;
     }
 #ifdef DEBUG
     if (debugleveln(realedge, 3)) {
@@ -563,7 +581,7 @@ static pointf *_routesplines(path * pp, int *npoints, int polyline)
 
        if (Proutespline(edges, poly.pn, pl, evs, &spl) < 0) {
            agerr(AGERR, "in routesplines, Proutespline failed\n");
-           longjmp (jbuf, 1);
+           return NULL;
        }
 #ifdef DEBUG
        if (debugleveln(realedge, 3)) {
@@ -573,7 +591,7 @@ static pointf *_routesplines(path * pp, int *npoints, int polyline)
 #endif
     }
     if (mkspacep(spl.pn))
-       longjmp (jbuf, 1);  /* Bailout if no memory left */
+       return NULL;  /* Bailout if no memory left */
 
     for (bi = 0; bi < boxn; bi++) {
        boxes[bi].LL.x = INT_MAX;
@@ -612,7 +630,7 @@ static pointf *_routesplines(path * pp, int *npoints, int polyline)
         * loop and we can see the bad edge, and even use the showboxes scaffolding.
         */
        Ppolyline_t polyspl;
-       agerr(AGWARN, "Unable to reclaim box space in spline routing. Something is probably seriously wrong.\n");
+       agerr(AGWARN, "Unable to reclaim box space in spline routing for edge \"%s\" -> \"%s\". Something is probably seriously wrong.\n", agnameof(agtail(realedge)), agnameof(aghead(realedge)));
        make_polyline (pl, &polyspl);
        limitBoxes (boxes, boxn, polyspl.ps, polyspl.pn, INIT_DELTA);
        free (polyspl.ps);
@@ -634,19 +652,11 @@ static pointf *_routesplines(path * pp, int *npoints, int polyline)
 
 pointf *routesplines(path * pp, int *npoints)
 {
-    if (setjmp (jbuf)) {
-       *npoints = 0;
-       return NULL;
-    }
     return _routesplines (pp, npoints, 0);
 }
 
 pointf *routepolylines(path * pp, int *npoints)
 {
-    if (setjmp (jbuf)) {
-       *npoints = 0;
-       return NULL;
-    }
     return _routesplines (pp, npoints, 1);
 }
 
@@ -671,8 +681,10 @@ static int overlap(int i0, int i1, int j0, int j1)
  * audit process in the 5E control program - if you've given up on
  * fixing all the bugs, at least try to engineer around them!
  * in postmodern CS, we could call this "self-healing code."
+ *
+ * Return 1 on failure; 0 on success.
  */
-static void checkpath(int boxn, boxf* boxes, path* thepath)
+static int checkpath(int boxn, boxf* boxes, path* thepath)
 {
     boxf *ba, *bb;
     int bi, i, errs, l, r, d, u;
@@ -697,7 +709,7 @@ static void checkpath(int boxn, boxf* boxes, path* thepath)
     if (ba->LL.x > ba->UR.x || ba->LL.y > ba->UR.y) {
        agerr(AGERR, "in checkpath, box 0 has LL coord > UR coord\n");
        printpath(thepath);
-       longjmp (jbuf, 1);
+       return 1;
     }
     for (bi = 0; bi < boxn - 1; bi++) {
        ba = &boxes[bi], bb = &boxes[bi + 1];
@@ -705,7 +717,7 @@ static void checkpath(int boxn, boxf* boxes, path* thepath)
            agerr(AGERR, "in checkpath, box %d has LL coord > UR coord\n",
                  bi + 1);
            printpath(thepath);
-           longjmp (jbuf, 1);
+           return 1;
        }
        l = (ba->UR.x < bb->LL.x) ? 1 : 0;
        r = (ba->LL.x > bb->UR.x) ? 1 : 0;
@@ -827,6 +839,7 @@ static void checkpath(int boxn, boxf* boxes, path* thepath)
        abort();
 #endif
     }
+    return 0;
 }
 
 static int mkspacep(int size)