static Agsym_t *dcl_attr(void *obj, char *name, char *value) { Agsym_t *rv; rv = agfindattr(obj, name); if (rv) { if (strcmp(rv->value, value)) { agerr(AGWARN, "Attribute %s=\"%s\" cannot be redeclared as \"%s\"\n", name, rv->value, value); } return rv; } rv = agNEWsym(agdictof(obj), name, value); if (rv) { switch (TAG_OF(obj)) { case TAG_GRAPH: add_graph_attr((Agraph_t *) obj, rv); break; case TAG_NODE: add_node_attr(((Agnode_t *) obj)->graph, rv); break; case TAG_EDGE: add_edge_attr(((Agedge_t *) obj)->head->graph, rv); break; } } return rv; }
/* agcopyattr: * Assumes attributes have already been declared. * Do not copy key attribute for edges, as this must be distinct. * Returns non-zero on failure or if objects have different type. */ int agcopyattr(void *oldobj, void *newobj) { Agdict_t *d = agdictof(oldobj); Agsym_t **list = d->list; Agsym_t *sym; Agsym_t *newsym; int r = 0; int isEdge = (TAG_OF(oldobj) == TAG_EDGE); if (TAG_OF(oldobj) != TAG_OF(newobj)) return 1; while (!r && (sym = *list++)) { if (isEdge && sym->index == KEYX) continue; newsym = agfindattr(newobj,sym->name); if (!newsym) return 1; r = agxset(newobj, newsym->index, agxget(oldobj, sym->index)); } return r; }
Agdict_t *agdictof(void *obj) { Agdict_t *d = NULL; switch (TAG_OF(obj)) { case TAG_GRAPH: d = ((Agraph_t *) obj)->univ->globattr; break; case TAG_NODE: d = ((Agnode_t *) obj)->graph->univ->nodeattr; break; case TAG_EDGE: d = ((Agedge_t *) obj)->tail->graph->univ->edgeattr; break; } return d; }
int agsafeset(void* obj, char* name, char* value, char* def) { Agsym_t* a = agfindattr(obj, name); if (a == NULL) { if (!def) def = ""; switch (TAG_OF(obj)) { case TAG_GRAPH: a = agraphattr(((Agraph_t*)obj)->root, name, def); break; case TAG_NODE: a = agnodeattr(((Agnode_t*)obj)->graph, name, def); break; case TAG_EDGE: a = agedgeattr(((Agedge_t*)obj)->head->graph, name, def); break; } } return agxset(obj, a->index, value); }
static void end_edgestmt(void) { objstack_t *old_SP; objlist_t *tailptr,*headptr,*freeptr; Agraph_t *t_graph,*h_graph; Agnode_t *t_node,*h_node,*t_first,*h_first; Agedge_t *e; char *tport,*hport; for (tailptr = SP->list; tailptr->link; tailptr = tailptr->link) { headptr = tailptr->link; tport = tailptr->data.port; hport = headptr->data.port; if (TAG_OF(tailptr->data.obj) == TAG_NODE) { t_graph = NULL; t_first = (Agnode_t*)(tailptr->data.obj); } else { t_graph = (Agraph_t*)(tailptr->data.obj); t_first = agfstnode(t_graph); } if (TAG_OF(headptr->data.obj) == TAG_NODE) { h_graph = NULL; h_first = (Agnode_t*)(headptr->data.obj); } else { h_graph = (Agraph_t*)(headptr->data.obj); h_first = agfstnode(h_graph); } for (t_node = t_first; t_node; t_node = t_graph ? agnxtnode(t_graph,t_node) : NULL) { for (h_node = h_first; h_node; h_node = h_graph ? agnxtnode(h_graph,h_node) : NULL ) { e = agedge(G,t_node,h_node); if (e) { char *tp = tport; char *hp = hport; if ((e->tail != e->head) && (e->head == t_node)) { /* could happen with an undirected edge */ char *temp; temp = tp; tp = hp; hp = temp; } if (tp && tp[0]) { agxset(e,TAILX,tp); agstrfree(tp); } if (hp && hp[0]) { agxset(e,HEADX,hp); agstrfree(hp); } } } } } tailptr = SP->list; while (tailptr) { freeptr = tailptr; tailptr = tailptr->link; if (TAG_OF(freeptr->data.obj) == TAG_NODE) free(freeptr); } if (G != SP->subg) abort(); agpopproto(G); In_edge_stmt = SP->in_edge_stmt; old_SP = SP; SP = SP->link; In_decl = FALSE; free(old_SP); Current_class = TAG_GRAPH; }