later).
Expose agstrdup and agstrfree in graph.h; remove raw declarations from emit.c
}
/* support for stderr_once */
-/* #include "libgraph.h" to get agstrdup, agstrfree */
-extern char *agstrdup(char *);
-extern void agstrfree(char *);
-
static void free_string_entry(Dict_t * dict, char *key, Dtdisc_t * disc)
{
agstrfree(key);
*/
static edge_t *cloneEdge(edge_t * e, node_t * ct, node_t * ch)
{
- extern Agdict_t *agdictof(void *);
- Agdict_t *d = agdictof(e);
- Agsym_t **list = d->list;
- Agsym_t *sym;
graph_t *g = ct->graph;
edge_t *ce = agedge(g, ct, ch);
-
- while ((sym = *list++)) {
- if (sym->index == 0) continue;
- agxset(ce, sym->index, agxget(e, sym->index));
- }
+ agcopyattr(e, ce);
return ce;
}
} else
return -1;
}
+
+/* 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;
+}
+
extern Agsym_t *agnodeattr(Agraph_t *, char *, char *);
extern Agsym_t *agedgeattr(Agraph_t *, char *, char *);
extern Agsym_t *agfindattr(void *, char *);
+ extern int agcopyattr(void *, void *);
typedef enum { AGWARN, AGERR, AGMAX, AGPREV } agerrlevel_t;
extern agerrlevel_t agerrno;
extern void agerrorf(char *fmt, ...);
extern void agwarningf(char *fmt, ...);
+ extern char *agstrdup(char *);
+ extern void agstrfree(char *);
+
typedef enum { AGNODE = 1, AGEDGE, AGGRAPH } agobjkind_t;
#define agobjkind(p) ((agobjkind_t)(((Agraph_t*)(p))->tag))
int agparse(void);
void agpopproto(Agraph_t *);
void agpushproto(Agraph_t *);
- char *agstrdup(char *);
char *agstrdup_html(char *s);
- void agstrfree(char *);
int agtoken(char *);
void agwredge(Agraph_t *, FILE *, Agedge_t *, int);
void agwrnode(Agraph_t *, FILE *, Agnode_t *, int, int);