attr->str[sym->id] = agstrdup(g, sym->defval);
}
+static Agsym_t *getattr(Agraph_t * g, int kind, char *name)
+{
+ Agsym_t *rv = 0;
+ Dict_t *dict;
+ dict = agdictof(g, kind);
+ if (dict)
+ rv = agdictsym(dict, name); /* viewpath up to root */
+ return rv;
+}
+
+static void unviewsubgraphsattr(Agraph_t *parent, char *name)
+{
+ Agraph_t *subg;
+ Agsym_t *psym, *lsym;
+ Dict_t *ldict;
+
+ psym = getattr(parent, AGRAPH, name);
+ if (!psym) return; // supposedly can't happen, see setattr()
+ for (subg = agfstsubg(parent); subg; subg = agnxtsubg(subg)) {
+ ldict = agdatadict(subg, TRUE)->dict.g;
+ lsym = aglocaldictsym(ldict, name);
+ if (lsym) continue;
+ lsym = agnewsym(agroot(subg), name, agxget(subg,psym), psym->id, AGRAPH);
+ dtinsert(ldict, lsym);
+ }
+}
static Agsym_t *setattr(Agraph_t * g, int kind, char *name, const char *value) {
Dict_t *ldict, *rdict;
if (lsym) { /* update old local definition */
if (g != root && streq(name, "layout"))
agerr(AGWARN, "layout attribute is invalid except on the root graph\n");
+ if (kind == AGRAPH) unviewsubgraphsattr(g,name);
agstrfree(g, lsym->defval);
lsym->defval = agstrdup(g, value);
rv = lsym;
return rv;
}
-static Agsym_t *getattr(Agraph_t * g, int kind, char *name)
-{
- Agsym_t *rv = 0;
- Dict_t *dict;
- dict = agdictof(g, kind);
- if (dict)
- rv = agdictsym(dict, name); /* viewpath up to root */
- return rv;
-}
-
/*
* create or update an existing attribute and return its descriptor.
* if the new value is NULL, this is only a search, no update.
"incorrect warning triggered"
@pytest.mark.skipif(shutil.which("nop") is None, reason="nop not available")
-@pytest.mark.xfail(strict=True) # FIXME
def test_2184_1():
"""
nop should not reposition labelled graph nodes
assert m is not None, \
"nop rearranged a graph in a not-semantically-preserving way"
-@pytest.mark.xfail(strict=True) # FIXME
def test_2184_2():
"""
canonicalization should not reposition labelled graph nodes