]> granicus.if.org Git - graphviz/commitdiff
Add new function for iterating over defined attributes for a given
authorerg <devnull@localhost>
Sat, 6 Sep 2008 23:45:18 +0000 (23:45 +0000)
committererg <devnull@localhost>
Sat, 6 Sep 2008 23:45:18 +0000 (23:45 +0000)
object class.

cmd/gvpr/actions.c
cmd/gvpr/compile.c
cmd/gvpr/gprdata
cmd/gvpr/gvpr.1

index bb704513b3fd36bd716b9dfb8bd45a39cc78050b..fdf01e8267dcf0489ad86e96bbe59a0a11ffabf3 100644 (file)
@@ -134,7 +134,7 @@ int copyAttr(Agobj_t * src, Agobj_t * tgt)
     while ((sym = agnxtattr(srcg, skind, sym))) {
        tsym = agattrsym(tgt, sym->name);
        if (!tsym)
-           tsym = agattr(tgtg, tkind, sym->name, "");
+           tsym = agattr(tgtg, tkind, sym->name, sym->defval);
        val = agxget(src, sym);
        if (aghtmlstr (val)) {
            val = agstrdup_html (tgtg, val);
index ff95d269382a952f692c2cdcac4bced46b10b22b..47802ac9ff2cdeed64c9f1ab880adb5021c6ea96 100644 (file)
@@ -485,7 +485,7 @@ setDfltAttr (Agraph_t *gp, char* k, char* name, char* value)
  * Map string to object kind
  */
 static int
-toKind (char* k)
+toKind (char* k, char* fn)
 {
     int      kind;
 
@@ -500,22 +500,46 @@ toKind (char* k)
        kind = AGNODE;
        break;
     default :
-       error(ERROR_FATAL, "Unknown kind \"%s\" passed to getDflt()", k);
+       error(ERROR_FATAL, "Unknown kind \"%s\" passed to %s()", k, fn);
        break;
     }
     return kind;
 }
 
+/* nxtAttr:
+ */
+static char*
+nxtAttr (Agraph_t *gp, char* k, char* name)
+{
+    char* fn = (name ? "nxtAttr" : "fstAttr");
+    int kind = toKind (k, fn);
+    Agsym_t* sym;
+
+    if (name) {
+       sym = agattr (gp, kind, name, 0);
+       if (!sym) {
+           error(ERROR_FATAL, "Third argument \"%s\" in nxtAttr() must be the name of an existing attribute", name); 
+       }
+       
+    }
+    else sym = NULL;
+    
+    sym = agnxtattr (gp, kind, sym);
+    if (sym) return sym->name; 
+    else return "";
+}
+
 /* getDfltAttr:
  */
 static char*
 getDfltAttr (Agraph_t *gp, char* k, char* name)
 {
-    int kind = toKind (k);
+    int kind = toKind (k, "getDflt");
     Agsym_t* sym = agattr (gp, kind, name, 0);
     if (!sym) {
        sym = agattr(gp, kind, name, "");
-       error(ERROR_WARNING, "Uninitialized %s attribute \"%s\" in getDflt", kindToStr (kind), name);
+       error(ERROR_WARNING, "Uninitialized %s attribute \"%s\" in %s", 
+           kindToStr (kind), name, "getDflt");
     }
     return sym->defval; 
 }
@@ -1202,6 +1226,21 @@ getval(Expr_t * pgm, Exnode_t * node, Exid_t * sym, Exref_t * ref,
                v.integer = 0;
            }
            break;
+       case F_fstattr:
+           gp = INT2PTR(Agraph_t *, args[0].integer);
+           if (gp) {
+               char* kind = args[1].string;
+               if (!kind) {
+                   error(ERROR_FATAL,"NULL kind passed to fstAttr()");
+               }
+               else {
+                   v.string = nxtAttr (gp, kind, NULL);
+               }
+           } else {
+               error(ERROR_FATAL, "NULL graph passed to fstAttr()");
+           }
+           break;
+       case F_nxtattr:
        case F_isattr:
        case F_dget:
            gp = INT2PTR(Agraph_t *, args[0].integer);
@@ -1209,19 +1248,22 @@ getval(Expr_t * pgm, Exnode_t * node, Exid_t * sym, Exref_t * ref,
                char* kind = args[1].string;
                char* name = args[2].string;
                if (!name) {
-                   error(ERROR_FATAL,"NULL name passed to getDflt()/isAttr()");
+                   error(ERROR_FATAL,"NULL name passed to %s", sym->name);
                }
                else if (!kind) {
-                   error(ERROR_FATAL,"NULL kind passed to getDflt()/isAttr()");
+                   error(ERROR_FATAL,"NULL kind passed to %s", sym->name);
                }
                else if (sym->index == F_isattr) {
-                   v.integer = (agattr(gp, toKind (kind), name, 0) != NULL);
+                   v.integer = (agattr(gp, toKind (kind, sym->name), name, 0) != NULL);
+               }
+               else if (sym->index == F_nxtattr) {
+                   v.string = nxtAttr (gp, kind, name);
                }
                else {
                    v.string = getDfltAttr(gp, kind, name);
                }
            } else {
-               error(ERROR_FATAL, "NULL graph passed to getDflt()/isAttr()");
+               error(ERROR_FATAL, "NULL graph passed to %s", sym->name);
            }
            break;
        case F_canon:
index 1cf7c5f538c9e8188883ed904d0166b36be8e0e4..114b7940443a81321df133662f594b5b39b2aa60 100644 (file)
@@ -100,6 +100,8 @@ F_dget      "getDflt"      FUNCTION S|A(1,G)|A(2,S)|A(3,S)
 F_dset      "setDflt"      FUNCTION I|A(1,G)|A(2,S)|A(3,S)|A(4,S)
 F_hasattr   "hasAttr"      FUNCTION I|A(1,O)|A(2,S)
 F_isattr    "isAttr"       FUNCTION I|A(1,G)|A(2,S)|A(3,S)
+F_fstattr   "fstAttr"      FUNCTION S|A(1,G)|A(2,S)
+F_nxtattr   "nxtAttr"      FUNCTION S|A(1,G)|A(2,S)|A(3,S)
 C_flat      "TV_flat"   CONSTANT T_tvtyp
 C_dfs       "TV_dfs"    CONSTANT T_tvtyp
 C_bfs       "TV_bfs"    CONSTANT T_tvtyp
index ff68143d0f0bc38f3f15d4941058b8b17903d9c4..ad294a18240d0442607d943db6f67744d0f5c115 100644 (file)
@@ -537,6 +537,22 @@ the given \fIkind\fP. For nodes, edges, and graphs, \fIkind\fP
 should be "N", "E", and "G", respectively.
 Returns 0 on success, non\(hyzero on failure. See \fBgetDflt\fP above.
 .TP
+\fBfstAttr\fP(\fIg\fP : \fBgraph_t\fP, \fIkind\fP : \fBstring\fP) : \fBstring\fP
+returns the name of the first attribute of objects in \fIg\fP of
+the given \fIkind\fP. For nodes, edges, and graphs, \fIkind\fP
+should be "N", "E", and "G", respectively.
+If there are no attributes, the string "" is returned.
+.TP
+\fBnxtAttr\fP(\fIg\fP : \fBgraph_t\fP, \fIkind\fP : \fBstring\fP, \fIname\fP : \fBstring\fP) : \fBstring\fP
+returns the name of the next attribute of objects in \fIg\fP of
+the given \fIkind\fP after the attribute \fIname\fP. 
+The argument \fIname\fP must be the name of an existing attribute; it will
+typically be the return value of an previous call to \fBfstAttr\fP or
+\fBnxtAttr\fP.
+For nodes, edges, and graphs, \fIkind\fP
+should be "N", "E", and "G", respectively.
+If there are no attributes left, the string "" is returned.
+.TP
 \fBcompOf\fP(\fIg\fP : \fBgraph_t\fP, \fIn\fP : \fBnode_t\fP) : \fBgraph_t\fP
 returns the connected component of the graph \fIg\fP containing node \fIn\fP,
 as a subgraph of \fIg\fP. The subgraph only contains the nodes. One can