]> granicus.if.org Git - graphviz/commitdiff
add agregister() and idregister to id discipline
authorJohn Ellson <ellson@research.att.com>
Tue, 14 Aug 2012 03:28:18 +0000 (23:28 -0400)
committerJohn Ellson <ellson@research.att.com>
Tue, 14 Aug 2012 03:28:18 +0000 (23:28 -0400)
lib/cgraph/cghdr.h
lib/cgraph/cgraph.h
lib/cgraph/edge.c
lib/cgraph/id.c
lib/cgraph/node.c
lib/cgraph/obj.c
lib/cgraph/subg.c
tclpkg/tcldot/tcldot-graphcmd.c
tclpkg/tcldot/tcldot.c
tclpkg/tcldot/tcldot.h

index 611873e0de13f3d3eae0140e9b045f136671793a..a07ada07c2ff341bbd1450123896ea98b907e81b 100644 (file)
@@ -157,6 +157,7 @@ void aginternalmapinsert(Agraph_t * g, int objtype, char *str,
 char *aginternalmapprint(Agraph_t * g, int objtype, unsigned long id);
 int aginternalmapdelete(Agraph_t * g, int objtype, unsigned long id);
 void aginternalmapclose(Agraph_t * g);
+void agregister(Agraph_t * g, int objtype, void *obj);
 
        /* internal set operations */
 void agedgesetop(Agraph_t * g, Agedge_t * e, int insertion);
index c7f5db1459d224cd1d492329131b3ab65173fc64..7e68126e119c05caaaf922d471aaf9a16fdca56a 100644 (file)
@@ -163,6 +163,7 @@ struct Agiddisc_s {         /* object ID allocator */
     void (*free) (void *state, int objtype, unsigned long id);
     char *(*print) (void *state, int objtype, unsigned long id);
     void (*close) (void *state);
+    void (*idregister) (void *state, int objtype, void *obj);
 };
 
 struct Agiodisc_s {
index 3828dd4f326980e1bde845405cd47f17011652c7..f8cae4fdb14b89c27842d921e191c2ed0e45d10e 100644 (file)
@@ -313,8 +313,10 @@ Agedge_t *agedge(Agraph_t * g, Agnode_t * t, Agnode_t * h, char *name,
     }
 
     if (cflag && ok_to_make_edge(g, t, h)
-       && agmapnametoid(g, AGEDGE, name, &id, TRUE))   /* reserve id */
+       && agmapnametoid(g, AGEDGE, name, &id, TRUE)) { /* reserve id */
        e = newedge(g, t, h, id);
+       agregister(g, AGEDGE, e); /* register new object in external namespace */
+    }
     else
        e = NILedge;
     return e;
index c4b5d71c8c7730d3aba943edc64454e4c3e1c725..cde61ada747c5773d397ff1a966f43cf8bfb1a59 100644 (file)
@@ -74,13 +74,21 @@ static void idclose(void *state)
     NOTUSED(state);
 }
 
+static void idregister(void *state, int objtype, void *obj)
+{
+    NOTUSED(state);
+    NOTUSED(objtype);
+    NOTUSED(obj);
+}
+
 Agiddisc_t AgIdDisc = {
     idopen,
     idmap,
     idalloc,
     idfree,
     idprint,
-    idclose
+    idclose,
+    idregister
 };
 
 /* aux functions incl. support for disciplines with anonymous IDs */
@@ -156,3 +164,9 @@ char *agnameof(void *obj)
        rv = 0;
     return rv;
 }
+
+/* register a graph object in an external namespace */
+void agregister(Agraph_t * g, int objtype, void *obj)
+{
+       AGDISC(g, id)->idregister(AGCLOS(g, id), objtype, obj);
+}
index 168b067f2c8bfce3ced71159c1acbbd8700b0ea7..3d9c483ba0c83d202e4304aad0617f9db40fee50 100644 (file)
@@ -162,6 +162,7 @@ Agnode_t *agnode(Agraph_t * g, char *name, int cflag)
        installnodetoroot(g, n);
        initnode(g, n);
        assert(agsubrep(g,n));
+       agregister(g, AGNODE, n); /* register in external namespace */
        return n;
     }
 
@@ -244,6 +245,7 @@ int agrelabel_node(Agnode_t * n, char *newname)
        } else {
            agfreeid(g, AGNODE, new_id);        /* couldn't use it after all */
        }
+        /* obj* is unchanged, so no need to re agregister() */
     }
     return FAILURE;
 }
index ae0918b43137617d8d969ae085edb114a46a6b69..b5141aa04f138052c66f01fb20e9216e493dca2f 100755 (executable)
@@ -52,6 +52,7 @@ int agrename(Agobj_t * obj, char *newname)
        if (agmapnametoid(agroot(g), AGTYPE(obj), newname,
                          &new_id, TRUE) == 0)
            return FAILURE;
+        /* obj* is unchanged, so no need to re agregister() */
        if (agparent(g) && agidsubg(agparent(g), new_id, 0))
            return FAILURE;
        agfreeid(g, AGRAPH, old_id);
index da4ceb17dc92300855289a97d60e3fd894b26449..6ef5d02d29f533f586476ff58e0176aab2a76df4 100644 (file)
@@ -60,8 +60,11 @@ Agraph_t *agsubg(Agraph_t * g, char *name, int cflag)
            return subg;
     }
 
-    if (cflag && agmapnametoid(g, AGRAPH, name, &id, TRUE))    /* reserve id */
-       return localsubg(g, id);
+    if (cflag && agmapnametoid(g, AGRAPH, name, &id, TRUE)) {  /* reserve id */
+       subg = localsubg(g, id);
+       agregister(g, AGRAPH, subg);
+       return subg;
+    }
 
     return NILgraph;
 }
index a5d2328407f505a94258324ccd9365eaf5eb784f..bd9f1fae225d4df91038db27cbe967c16ad31e8c 100644 (file)
 
 #include "tcldot.h"
 
+Agraph_t *cmd2g(gctx_t *gctx, char *cmd) {
+    unsigned long int id;
+    Agraph_t *g;
+
+    if (sscanf(cmd, "graph%lu", &id) != 1) {
+       Tcl_AppendResult(gctx->ictx->interp, " \"", cmd, "\" doesn't sscanf for graph object", NULL);
+       return NULL;
+    }
+    g = agidsubg(gctx->g, id, FALSE);
+    if (!g) {
+       Tcl_AppendResult(gctx->ictx->interp, " \"", cmd, "\" not found", NULL);
+       return NULL;
+    }
+    return g;
+}
+Agnode_t *cmd2n(gctx_t *gctx, char *cmd) {
+    unsigned long int id;
+    Agnode_t *n;
+
+    if (sscanf(cmd, "node%lu", &id) != 1) {
+       Tcl_AppendResult(gctx->ictx->interp, " \"", cmd, "\" doesn't sscanf for node object", NULL);
+       return NULL;
+    }
+    n = agidnode(gctx->g, id, FALSE);
+    if (!n) {
+       Tcl_AppendResult(gctx->ictx->interp, " \"", cmd, "\" not found", NULL);
+       return NULL;
+    }
+    return n;
+}
+Agedge_t *cmd2e(gctx_t *gctx, char *cmd) {
+    unsigned long int id;
+    Agedge_t *e;
+// FIXME
+    Agnode_t *t=NULL, *h=NULL;
+
+    if (sscanf(cmd, "edge%lu", &id) != 1) {
+       Tcl_AppendResult(gctx->ictx->interp, " \"", cmd, "\" doesn't sscanf for edge object", NULL);
+       return NULL;
+    }
+    e = agidedge(gctx->g, t, h, id, FALSE);
+    if (!e) {
+       Tcl_AppendResult(gctx->ictx->interp, " \"", cmd, "\" not found", NULL);
+       return NULL;
+    }
+    return e;
+}
+
 int graphcmd(ClientData clientData, Tcl_Interp * interp,
 #ifndef TCLOBJ
                    int argc, char *argv[]
@@ -22,14 +70,25 @@ int graphcmd(ClientData clientData, Tcl_Interp * interp,
     )
 {
 
-    Agraph_t *g, **gp, *sg, **sgp;
-    Agnode_t **np, *n, *tail, *head;
-    Agedge_t **ep, *e;
+    Agraph_t *g, *sg;
+    Agnode_t *n, *tail, *head;
+    Agedge_t *e;
+// FIXME #ifndef WITH_CGRAPH
+    Agraph_t **sgp;
+    Agnode_t **np;
+//       #endif
+#ifndef WITH_CGRAPH
+    Agraph_t **gp;
+    Agedge_t **ep;
+    ictx_t *ictx = (ictx_t *)clientData;
+    unsigned long id;
+#else
+    gctx_t *gctx = (gctx_t *)clientData;
+    ictx_t *ictx = gctx->ictx;
+#endif
     Agsym_t *a;
     char c, buf[256], **argv2;
     int i, j, length, argc2, rc;
-    unsigned long id;
-    ictx_t *ictx = (ictx_t *)clientData;
     GVC_t *gvc = ictx->gvc;
     GVJ_t *job = gvc->job;
 
@@ -39,12 +98,17 @@ int graphcmd(ClientData clientData, Tcl_Interp * interp,
                         NULL);
        return TCL_ERROR;
     }
+#ifndef WITH_CGRAPH
     if (!(gp = (Agraph_t **) tclhandleXlate(ictx->graphTblPtr, argv[0]))) {
        Tcl_AppendResult(interp, " \"", argv[0], "\"", NULL);
        return TCL_ERROR;
     }
-
     g = *gp;
+#else
+    g = cmd2g(gctx,argv[0]);
+    if (!g)
+       return TCL_ERROR;
+#endif
 
     c = argv[1][0];
     length = strlen(argv[1]);
@@ -56,28 +120,48 @@ int graphcmd(ClientData clientData, Tcl_Interp * interp,
                             NULL);
            return TCL_ERROR;
        }
+#ifndef WITH_CGRAPH
        if (!(np = (Agnode_t **) tclhandleXlate(ictx->nodeTblPtr, argv[2]))) {
            if (!(tail = agfindnode(g, argv[2]))) {
                Tcl_AppendResult(interp, "Tail node \"", argv[2],
                                 "\" not found.", NULL);
                return TCL_ERROR;
            }
-       } else {
+        }
+#else
+        tail = cmd2n(gctx,argv[2]);
+        if (!tail) {
+           return TCL_ERROR;
+        }
+#endif
+       else {
+#ifndef WITH_CGRAPH
            tail = *np;
+#endif
            if (agroot(g) != agroot(agraphof(tail))) {
                Tcl_AppendResult(interp, "Node ", argv[2],
                                 " is not in the graph.", NULL);
                return TCL_ERROR;
            }
        }
+#ifndef WITH_CGRAPH
        if (!(np = (Agnode_t **) tclhandleXlate(ictx->nodeTblPtr, argv[3]))) {
            if (!(head = agfindnode(g, argv[3]))) {
                Tcl_AppendResult(interp, "Head node \"", argv[3],
                                 "\" not found.", NULL);
                return TCL_ERROR;
            }
-       } else {
+       }
+#else
+        head = cmd2n(gctx,argv[2]);
+        if (!head) {
+           return TCL_ERROR;
+        }
+#endif
+       else {
+#ifndef WITH_CGRAPH
            head = *np;
+#endif
            if (agroot(g) != agroot(agraphof(head))) {
                Tcl_AppendResult(interp, "Node ", argv[3],
                                 " is not in the graph.", NULL);
@@ -89,6 +173,7 @@ int graphcmd(ClientData clientData, Tcl_Interp * interp,
 #else
        e = agedge(g, tail, head);
 #endif
+#ifndef WITH_CGRAPH
        if (!(ep = (Agedge_t **) tclhandleXlateIndex(ictx->edgeTblPtr, AGID(e))) || *ep != e) {
            ep = (Agedge_t **) tclhandleAlloc(ictx->edgeTblPtr, Tcl_GetStringResult(interp), &id);
            *ep = e;
@@ -103,6 +188,7 @@ int graphcmd(ClientData clientData, Tcl_Interp * interp,
        } else {
            tclhandleString(ictx->edgeTblPtr, Tcl_GetStringResult(interp), AGID(e));
        }
+#endif
        setedgeattributes(agroot(g), e, &argv[4], argc - 4);
        reset_layout(gvc, g);
        return TCL_OK;
index ee8746efab432e2d01a5882567b0b47750f670ef..4f963b9ae87bb2878f6e1cd161459dcf02e15c66 100644 (file)
 
 // Agiddisc functions
 static void *myiddisc_open(Agraph_t *g, Agdisc_t *disc) {
-       fprintf(stderr,"myiddisc_open:\n");
-        return (void *)disc;
+    ictx_t *ictx = (ictx_t *)disc;
+    gctx_t *gctx;
+
+    gctx = (gctx_t *)malloc(sizeof(gctx_t));
+    gctx->g = g;
+    gctx->ictx = ictx;
+    return (void *)gctx;
 }
 static long myiddisc_map(void *state, int objtype, char *str, unsigned long *id, int createflag) {
-       ictx_t *ictx = (ictx_t *)state;
-       Tcl_Interp *interp = ictx->interp;
-       Tcl_CmdProc *proc = NULL;
-       void *tclhandleTblPtr = NULL;
-       int rc = 1; // init to success
-
-        switch (objtype) {
-                case AGRAPH: tclhandleTblPtr = ictx->graphTblPtr; proc = graphcmd; break;
-                case AGNODE: tclhandleTblPtr = ictx->nodeTblPtr; proc = nodecmd; break;
-                case AGINEDGE:
-                case AGOUTEDGE: tclhandleTblPtr = ictx->edgeTblPtr; proc=edgecmd; break;
-        }
-       if (createflag) {
-               tclhandleAlloc(tclhandleTblPtr, Tcl_GetStringResult(interp), id);
+    gctx_t *gctx = (gctx_t *)state;
+    ictx_t *ictx = gctx->ictx;
+    Tcl_Interp *interp = ictx->interp;
+    Tcl_CmdProc *proc = NULL;
+    Agraph_t *g = NULL;
+    char *s, buf[30] = "";
+
+    if (str) {
+        if (createflag)
+            s = agstrdup(g, str);
+        else
+            s = agstrbind(g, str);
+        *id = (unsigned long) s;
+    } else {
+        *id = ictx->ctr;
+        ictx->ctr += 2;
+    }
+    switch (objtype) {
+        case AGRAPH: sprintf(buf,"graph%lu",*id); proc=graphcmd; break;
+        case AGNODE: sprintf(buf,"node%lu",*id); proc=nodecmd; break;
+        case AGINEDGE:
+        case AGOUTEDGE: sprintf(buf,"edge%lu",*id); proc=edgecmd; break;
+    }
+    Tcl_AppendResult(interp, buf, NULL);
+    if (createflag) {
 #ifndef TCLOBJ
-               Tcl_CreateCommand(interp, Tcl_GetStringResult(interp), proc, (ClientData) ictx, (Tcl_CmdDeleteProc *) NULL);
+       Tcl_CreateCommand(interp, Tcl_GetStringResult(interp), proc, (ClientData) gctx, (Tcl_CmdDeleteProc *) NULL);
 #else
-               Tcl_CreateObjCommand(interp, Tcl_GetStringResult(interp), proc, (ClientData) ictx, (Tcl_CmdDeleteProc *) NULL);
+       Tcl_CreateObjCommand(interp, Tcl_GetStringResult(interp), proc, (ClientData) gctx, (Tcl_CmdDeleteProc *) NULL);
 #endif           
-       }
-       else {
-               rc = 0;    // FIXME  - not sure about this
-       }
-        fprintf(stderr,"myiddisc_map: objtype %d, str \"%s\", id %lu, createflag %d, rc = %d\n", objtype, str, *id, createflag, rc);
-        return rc;
+    }
+    return TRUE;
 }
-static long myiddisc_alloc(void *state, int objtype, unsigned long id) {
-//     ictx_t *ictx = (ictx_t *)state;
-
-        switch (objtype) {
-                case AGRAPH: break;
-                case AGNODE: break;
-                case AGINEDGE:
-                case AGOUTEDGE: break;
-        }
-        fprintf(stderr,"myiddisc_alloc: objtype %d, id %lu\n", objtype, id);
-        return 0;
+/* we don't allow users to explicitly set IDs, either */
+static long myiddisc_alloc(void *state, int objtype, unsigned long request_id) {
+    NOTUSED(state);
+    NOTUSED(objtype);
+    NOTUSED(request_id);
+    return FALSE;
 }
 static void myiddisc_free(void *state, int objtype, unsigned long id) {
-       ictx_t *ictx = (ictx_t *)state;
-       Tcl_Interp *interp = ictx->interp;
-       char buf[32];
-       void *tclhandleTblePtr = NULL;
-
-        switch (objtype) {
-                case AGRAPH: tclhandleTblePtr = ictx->graphTblPtr; break;
-                case AGNODE: tclhandleTblePtr = ictx->nodeTblPtr; break;
-                case AGINEDGE:
-                case AGOUTEDGE: tclhandleTblePtr = ictx->edgeTblPtr; break;
-        }
-       tclhandleString(tclhandleTblePtr, buf, id);
-       Tcl_DeleteCommand(interp, buf);
-       tclhandleFreeIndex(tclhandleTblePtr, id);
-        fprintf(stderr,"myiddisc_free: objtype %d, id %lu\n", objtype, id);
+    gctx_t *gctx = (gctx_t *)state;
+    ictx_t *ictx = gctx->ictx;
+    char buf[30] = "";
+
+    switch (objtype) {
+        case AGRAPH: sprintf(buf,"graph%lu",id); break;
+        case AGNODE: sprintf(buf,"node%lu",id); break;
+        case AGINEDGE:
+        case AGOUTEDGE: sprintf(buf,"edge%lu",id); break;
+    }
+    Tcl_DeleteCommand(ictx->interp, buf);
+    if (id % 2 == 0)
+        agstrfree((Agraph_t *) state, (char *) id);
 }
 static char *myiddisc_print(void *state, int objtype, unsigned long id) {
-//     ictx_t *ictx = (ictx_t *)state;
-#if 0
-        static char buf[64];
-        switch (objtype) {
-                case AGRAPH: sprintf(buf, "graph%lu", id); break;
-                case AGNODE: sprintf(buf, "node%lu", id); break;
-                case AGINEDGE:
-                case AGOUTEDGE: sprintf(buf, "edge%lu", id); break;
-        }
-        fprintf(stderr,"myiddisc_print: objtype %d, id %lu\n", objtype, id);
-        return buf;
-#else
-       return NIL(char*);
-#endif
+    NOTUSED(state);
+    NOTUSED(objtype);
+    if (id % 2 == 0)
+        return (char *) id;
+    else
+        return "";
 }
 static void myiddisc_close(void *state) {
-//     ictx_t *ictx = (ictx_t *)state;
-        fprintf(stderr,"myiddisc_close:\n");
+    free(state);
 }
 static Agiddisc_t myiddisc = {
-        myiddisc_open,
-        myiddisc_map,
-        myiddisc_alloc,
-        myiddisc_free,
-        myiddisc_print,
-        myiddisc_close
+    myiddisc_open,
+    myiddisc_map,
+    myiddisc_alloc,
+    myiddisc_free,
+    myiddisc_print,
+    myiddisc_close
 };
 
 #endif // WITH_CGRAPH
@@ -117,10 +113,11 @@ static int dotnew(ClientData clientData, Tcl_Interp * interp,
     )
 {
     ictx_t *ictx = (ictx_t *)clientData;
-    Agraph_t *g, **gp;
+    Agraph_t *g;
     char c;
     int i, length;
 #ifndef WITH_CGRAPH
+    Agraph_t **gp;
     int kind;
     unsigned long id;
 #else
@@ -196,12 +193,6 @@ static int dotnew(ClientData clientData, Tcl_Interp * interp,
 #ifndef WITH_CGRAPH
     *gp = g;
     AGID(g) = id;
-#else
-    gp = (Agraph_t **)tclhandleXlateIndex(ictx->graphTblPtr, AGID(g));
-    *gp = g;
-#endif
-
-#ifndef WITH_CGRAPH
 #ifndef TCLOBJ
     Tcl_CreateCommand(interp, Tcl_GetStringResult(interp), graphcmd,
                      (ClientData) ictx, (Tcl_CmdDeleteProc *) NULL);
@@ -434,6 +425,7 @@ int Tcldot_Init(Tcl_Interp * interp)
     ictx->interp = interp;
 #ifdef WITH_CGRAPH    
     ictx->mydisc.id = &myiddisc;
+    ictx->ctr = 1;  /* init to first odd number,  increment by 2 */
 #endif
 
 #ifdef USE_TCL_STUBS
index 3719c8b4124067d31e8d42a3dd5b85fa8ca94261..007d9c38d50c20989e77dabeea4ba0710a4e4b48 100644 (file)
@@ -45,11 +45,11 @@ Tcl_GetString(Tcl_Obj *obj) {
  */
 typedef struct {
 #ifdef WITH_CGRAPH
-    Agdisc_t mydisc;    // must be first to allow casting mydisc to ictx
+    Agdisc_t mydisc;    /* must be first to allow casting mydisc to ictx */
+    unsigned long int ctr; /* odd number counter for anon objects over all g's in interp */
 #endif
-    void *graphTblPtr;
 /* **FIXME**  #ifndef WITH_CGRAPH */
-    void *nodeTblPtr, *edgeTblPtr;
+    void *graphTblPtr, *nodeTblPtr, *edgeTblPtr;
 /*            #endif */
     Tcl_Interp *interp;
     GVC_t *gvc;
@@ -61,7 +61,8 @@ typedef struct {
  */
 typedef struct {
     Agraph_t *g;        /* the graph */
-    ictx_t *ictx;   /* refer back to top context */
+    ictx_t *ictx;
+    unsigned long int idx; 
 } gctx_t;
 #endif