]> granicus.if.org Git - graphviz/commitdiff
Provide $tvnext to assist in setting up traversal roots. In particular,
authorEmden Gansner <erg@research.att.com>
Thu, 5 Jul 2012 17:39:28 +0000 (13:39 -0400)
committerEmden Gansner <erg@research.att.com>
Thu, 5 Jul 2012 17:39:28 +0000 (13:39 -0400)
one can set $tvnext == NULL at the beginning to get a single traversal.

cmd/gvpr/gvpr.1
lib/gvpr/compile.c
lib/gvpr/gprdata
lib/gvpr/gprstate.c
lib/gvpr/gprstate.h
lib/gvpr/gvpr.c
lib/gvpr/gvpr.h

index adf23c5f31d635fccc968b01e56242f2abb4323d..7833480a361b987e6f32bce72687cfdbb49d4ae0 100644 (file)
@@ -909,9 +909,19 @@ This variable may be set by the user.
 .TP
 \fB$tvroot\fP : \fBnode_t\fP
 indicates the starting node for a (directed or undirected)
-depth\(hyfirst traversal of the
+depth\(hyfirst or breadth\(hyfirst traversal of the
 graph (cf. \fB$tvtype\fP below).
 The default value is \fBNULL\fP for each input graph.
+After the traversal at the given root, if the value of \fB$tvroot\fP has changed,
+a new traversal will begin with the new value of \fB$tvroot\fP. Also, set \fB$tvnext\fP below.
+.TP
+\fB$tvnext\fP : \fBnode_t\fP
+indicates the next starting node for a (directed or undirected)
+depth\(hyfirst or breadth\(hyfirst traversal of the
+graph (cf. \fB$tvtype\fP below).
+If a traversal finishes and the \fB$tvroot\fP but the \fB$tvnext\fP has been
+set but not used, this node will be used as the next choice for \fB$tvroot\fP.
+The default value is \fBNULL\fP for each input graph.
 .TP
 \fB$tvedge\fP : \fBedge_t\fP
 For BFS and DFS traversals, this is set to the edge used to arrive at the
index 9897b2f34aa95aa3ec455a470fdcabf685509d23..73041c8390ae3dbeece294e13ef65ef92c4bfbff 100644 (file)
@@ -289,6 +289,10 @@ static Agobj_t *deref(Expr_t * pgm, Exnode_t * x, Exref_t * ref,
            return deref(pgm, x, ref->next, (Agobj_t *) state->tvroot,
                         state);
            break;
+       case V_travnext:
+           return deref(pgm, x, ref->next, (Agobj_t *) state->tvnext,
+                        state);
+           break;
        case M_head:
            if (!objp && !(objp = state->curobj)) {
                exerror("Current object $ not defined");
@@ -1497,6 +1501,9 @@ getval(Expr_t * pgm, Exnode_t * node, Exid_t * sym, Exref_t * ref,
        case V_travroot:
            v.integer = PTR2INT(state->tvroot);
            break;
+       case V_travnext:
+           v.integer = PTR2INT(state->tvnext);
+           break;
        case V_travedge:
            v.integer = PTR2INT(state->tvedge);
            break;
@@ -1574,6 +1581,16 @@ setval(Expr_t * pgm, Exnode_t * x, Exid_t * sym, Exref_t * ref,
                      agnameof(np));
            }
            break;
+       case V_travnext:
+           np = INT2PTR(Agnode_t *, v.integer);
+           if (!np || (agroot(np) == state->curgraph)) {
+               state->tvnext = np;
+               state->flags |= GV_NEXT_SET;
+           } else {
+               error(1, "cannot set $tvnext, node %s not in $G : ignored",
+                     agnameof(np));
+           }
+           break;
        case V_tgtname:
            if (!streq(state->tgtname, v.string)) {
                vmfree(pgm->vm, state->tgtname);
index 6df9ee13f20b827eeedc946dc7100ec6ad8c9769..595a7729e6868ed571c478853ee592b0bf5f4d17 100644 (file)
@@ -6,6 +6,7 @@ V_outgraph  "$O"           ID       T_graph            0           Y(G)
 V_tgtname   "$tgtname"     ID       STRING             0           Y(S)
 V_infname   "$F"           ID       STRING             0           Y(S)
 V_travroot  "$tvroot"      ID       T_node             0           Y(V)
+V_travnext  "$tvnext"      ID       T_node             0           Y(V)
 V_travedge  "$tvedge"      ID       T_edge             0           Y(E)
 V_travtype  "$tvtype"      ID       T_tvtyp            0           Y(TV)
 V_ARGC      "ARGC"         ID       INTEGER            0           Y(I)
index 6d5c1a77e71960f56e8fa3fda34eadcaa4b84f38..fb695814c5013afbb6f5f17fce83021560c01e4f 100644 (file)
@@ -56,6 +56,7 @@ Gpr_t *openGPRState(gpr_info* info)
     state->tvt = TV_flat;
     state->name_used = name_used;
     state->tvroot = 0;
+    state->tvnext = 0;
     state->tvedge = 0;
     state->outFile = info->outFile;
     state->argc = info->argc;
index 82ed5707aad01f59e93b56b7936852bcd3c36204..c7dcda15868afb7cbed76e2422f3699a88f0b35d 100644 (file)
@@ -32,6 +32,14 @@ extern "C" {
                    TV_prepostdfs, TV_prepostfwd, TV_prepostrev,
     } trav_type;
 
+/* Bits for flags variable. 
+ */
+  /* If set, gvpr calls exit() on errors */
+#define GV_USE_EXIT 1    
+  /* If set, gvpr stores output graphs in gvpropts */
+#define GV_USE_OUTGRAPH 2
+#define GV_USE_JUMP 4
+
     typedef struct {
        Agraph_t *curgraph;
        Agraph_t *nextgraph;
@@ -48,6 +56,7 @@ extern "C" {
        Agiodisc_t* dfltIO;
        trav_type tvt;
        Agnode_t *tvroot;
+       Agnode_t *tvnext;
        Agedge_t *tvedge;
        int name_used;
        int argc;
index f523dc89ffb830c0baa383501562ec7a929b809b..031c759cf275513bba5a9d32304ddf22e15bb957 100644 (file)
@@ -48,8 +48,6 @@
 #define DFLT_GVPRPATH    "."
 #endif
 
-#define GV_USE_JUMP 4
-
 static char *Info[] = {
     "gvpr",                     /* Program */
     VERSION,                    /* Version */
@@ -518,6 +516,9 @@ static Agnode_t *nextNode(Gpr_t * state, nodestream * nodes)
 
     if (state->tvroot != nodes->oldroot) {
        np = nodes->oldroot = state->tvroot;
+    } else if (state->flags & GV_NEXT_SET) {
+       np = nodes->oldroot = state->tvroot = state->tvnext;
+       state->flags &= ~GV_NEXT_SET;
     } else if (nodes->prev) {
        np = nodes->prev = agnxtnode(state->curgraph, nodes->prev);
     } else {
index 94f7a1400c5c682d9fe644e95caf3838516c3e1c..f89d87bca6046f45129d06080854dcc400b2a425 100644 (file)
@@ -21,10 +21,19 @@ extern "C" {
 #include "ast_common.h"
 #include "cgraph.h"
 
+/* Bits for flags variable in gvprstate_t.
+ * Included here so that calling programs can use the first
+ * two in gvpropts.flags
+ */
   /* If set, gvpr calls exit() on errors */
 #define GV_USE_EXIT 1    
   /* If set, gvpr stores output graphs in gvpropts */
 #define GV_USE_OUTGRAPH 2
+  /* Use longjmp to return to top-level call in gvpr */
+#define GV_USE_JUMP 4
+  /* $tvnext has been set but not used */
+#define GV_NEXT_SET 8
+
 
 typedef ssize_t (*gvprwr) (void*, const char *buf, size_t nbyte, void*);
 typedef int (*gvpruserfn) (char *);