void agwredge(Agraph_t * g, FILE * fp, Agedge_t * e, int list_all) { char *myval, *defval, *tport, *hport; int i, nprint = 0; Agdict_t *d = e->tail->graph->univ->edgeattr; Agsym_t *a; if (e->attr) { tport = e->attr[TAILX]; hport = e->attr[HEADX]; } else tport = hport = ""; writenodeandport(fp, e->tail->name, tport); agputs(((g->kind & AGFLAG_DIRECTED) ? " -> " : " -- "), fp); writenodeandport(fp, e->head->name, hport); if (list_all) { for (i = 0; i < dtsize(d->dict); i++) { a = d->list[i]; if ((a->printed == FALSE) || ((i == KEYX) && (e->printkey != MUSTPRINT))) continue; myval = agget(e, a->name); if (g == g->root) defval = a->value; else defval = agget(g->proto->e, a->name); if (strcmp(defval, myval)) writeattr(fp, &nprint, a->name, myval); } } agputs(nprint > 0 ? "];\n" : ";\n", fp); }
/* writenodeandport: */ static void writenodeandport(FILE * fp, char *node, char *port) { char *ss; agputs(agcanonical(node), fp); /* slimey i know */ if (port && *port) { if (aghtmlstr(port)) { agputc(':', fp); agputs(agstrcanon(port, getoutputbuffer(port)), fp); } else { ss = strchr (port, ':'); if (ss) { *ss = '\0'; agputc(':', fp); agputs(_agstrcanon(port, getoutputbuffer(port)), fp); agputc(':', fp); agputs(_agstrcanon(ss+1, getoutputbuffer(ss+1)), fp); *ss = ':'; } else { agputc(':', fp); agputs(_agstrcanon(port, getoutputbuffer(port)), fp); } } } }
static void writeattr(FILE * fp, int *npp, char *name, char *val) { agputs(++(*npp) > 1 ? ", " : " [", fp); agputs(agcanonical(name), fp); agputc('=', fp); agputs(agcanonical(val), fp); }
static void printdouble(FILE * f, char *prefix, double v) { char buf[BUFSIZ]; if (prefix) agputs(prefix, f); sprintf(buf, "%.5g", v); agputs(buf, f); }
static void printint(FILE * f, char *prefix, int i) { char buf[BUFSIZ]; if (prefix) agputs(prefix, f); sprintf(buf, "%d", i); agputs(buf, f); }
static void write_diffattr(FILE * fp, int indent, void *obj, void *par, Agdict_t * dict) { Agsym_t *a; int i; char *p, *q; int cnt = 0; for (i = 0; i < dtsize(dict->dict); i++) { a = dict->list[i]; if (a->printed == FALSE) continue; p = agxget(obj, a->index); if (par) q = agxget(par, a->index); else q = a->value; if (strcmp(p, q)) { if (cnt++ == 0) { tabover(fp, indent); agputs(dict->name, fp); agputs(" [", fp); } else { agputs(",\n", fp); tabover(fp, indent + 1); } agputs(agcanonical(a->name), fp); agputc('=', fp); agputs(agcanonical(p), fp); } } if (cnt > 0) agputs("];\n", fp); }
int agwrite(Agraph_t * g, FILE * fp) { printdict_t *p; if (AG.fwrite == NULL) { AG.fwrite = fwrite; /* init to system version of fwrite() */ } if (AG.ferror == NULL) { #ifdef ferror #undef ferror /* if ferror is a macro, then use our wrapper function, but * undef the macro first so it doesn't subst in "AG.ferror" */ AG.ferror = agferror; /* init to ferror macro wrapper function */ #else AG.ferror = ferror; /* init to system version of ferror() */ #endif } /* write the graph header */ agputs((AG_IS_STRICT(g)) ? "strict " : "", fp); agputs((AG_IS_DIRECTED(g)) ? "digraph" : "graph", fp); if (strncmp(g->name, "_anonymous", 10)) { agputc(' ', fp); agputs(agcanonical(g->name), fp); } agputs(" {\n", fp); /* write the top level attribute defs */ write_dict(g->univ->globattr, fp); write_dict(g->univ->nodeattr, fp); write_dict(g->univ->edgeattr, fp); /* write the graph contents */ p = new_printdict_t(g); write_subg(g, fp, (Agraph_t *) 0, 0, p); agputs("}\n", fp); free_printdict_t(p); return AG.ferror(fp); }
void agwrnode(Agraph_t * g, FILE * fp, Agnode_t * n, int full, int indent) { char *myval, *defval; int i, didwrite = FALSE; int nprint = 0; Agdict_t *d = n->graph->univ->nodeattr; Agsym_t *a; if (full) { for (i = 0; i < dtsize(d->dict); i++) { a = d->list[i]; if (a->printed == FALSE) continue; myval = agget(n, a->name); if (g == n->graph) defval = a->value; else defval = agget(g->proto->n, a->name); if (strcmp(defval, myval)) { if (didwrite == FALSE) { tabover(fp, indent); agputs(agcanonical(n->name), fp); didwrite = TRUE; } writeattr(fp, &nprint, a->name, myval); } } if (didwrite) { agputs(nprint > 0 ? "];\n" : ";\n", fp); return; } } if ((agfstout(g, n) == NULL) && (agfstin(g, n) == NULL)) { tabover(fp, indent); agputs(agcanonical(n->name), fp); agputs(";\n", fp); } }
static void write_dict(Agdict_t * dict, FILE * fp) { int i, cnt = 0; Agsym_t *a; for (i = 0; i < dtsize(dict->dict); i++) { a = dict->list[i]; if (ISEMPTYSTR(a->value) == FALSE) { if (cnt++ == 0) { agputc('\t', fp); agputs(dict->name, fp); agputs(" [", fp); } else { agputs(", ", fp); } agputs(a->name, fp); agputc('=', fp); agputs(agcanonical(a->value), fp); } } if (cnt > 0) agputs("];\n", fp); }
static void printstring(FILE * f, char *prefix, char *s) { if (prefix) agputs(prefix, f); agputs(s, f); }
/* _write_plain: */ void write_plain(GVJ_t * job, graph_t * g, FILE * f, boolean extend) { int i, j, splinePoints; char *tport, *hport; node_t *n; edge_t *e; bezier bz; pointf pt; char *lbl; char* fillcolor; putstr = g->clos->disc.io->putstr; // setup_graph(job, g); setYInvert(g); pt = GD_bb(g).UR; printdouble(f, "graph ", job->zoom); printdouble(f, " ", PS2INCH(pt.x)); printdouble(f, " ", PS2INCH(pt.y)); agputc('\n', f); for (n = agfstnode(g); n; n = agnxtnode(g, n)) { if (IS_CLUST_NODE(n)) continue; printstring(f, "node ", agcanonStr(agnameof(n))); printpoint(f, ND_coord(n)); if (ND_label(n)->html) /* if html, get original text */ lbl = agcanonStr (agxget(n, N_label)); else lbl = canon(agraphof(n),ND_label(n)->text); printdouble(f, " ", ND_width(n)); printdouble(f, " ", ND_height(n)); printstring(f, " ", lbl); printstring(f, " ", late_nnstring(n, N_style, "solid")); printstring(f, " ", ND_shape(n)->name); printstring(f, " ", late_nnstring(n, N_color, DEFAULT_COLOR)); fillcolor = late_nnstring(n, N_fillcolor, ""); if (fillcolor[0] == '\0') fillcolor = late_nnstring(n, N_color, DEFAULT_FILL); printstring(f, " ", fillcolor); agputc('\n', f); } for (n = agfstnode(g); n; n = agnxtnode(g, n)) { for (e = agfstout(g, n); e; e = agnxtout(g, e)) { if (extend) { //assuming these two attrs have already been created by cgraph if (!(tport = agget(e,"tailport"))) tport = ""; if (!(hport = agget(e,"headport"))) hport = ""; } else tport = hport = ""; if (ED_spl(e)) { splinePoints = 0; for (i = 0; i < ED_spl(e)->size; i++) { bz = ED_spl(e)->list[i]; splinePoints += bz.size; } printstring(f, NULL, "edge"); writenodeandport(f, agtail(e), tport); writenodeandport(f, aghead(e), hport); printint(f, " ", splinePoints); for (i = 0; i < ED_spl(e)->size; i++) { bz = ED_spl(e)->list[i]; for (j = 0; j < bz.size; j++) printpoint(f, bz.list[j]); } } if (ED_label(e)) { printstring(f, " ", canon(agraphof(agtail(e)),ED_label(e)->text)); printpoint(f, ED_label(e)->pos); } printstring(f, " ", late_nnstring(e, E_style, "solid")); printstring(f, " ", late_nnstring(e, E_color, DEFAULT_COLOR)); agputc('\n', f); } } agputs("stop\n", f); }
static void write_subg(Agraph_t * g, FILE * fp, Agraph_t * par, int indent, printdict_t * state) { Agraph_t *subg, *meta; Agnode_t *n, *pn; Agedge_t *e, *pe; Dt_t *save_e, *save_n; if (indent) { tabover(fp, indent++); if (dtsearch(state->subgleft, g->meta_node)) { if (strncmp(g->name, "_anonymous", 10)) { agputs("subgraph ", fp); agputs(agcanonical(g->name), fp); agputs(" {\n", fp); } else { agputs("{\n", fp); /* no name printed for anonymous subg */ } write_diffattr(fp, indent, g, par, g->univ->globattr); /* The root node and edge environment use the dictionaries, * not the proto node or edge, so the next level down must * record differences with the dictionaries. */ if (par == g->root) { pn = NULL; pe = NULL; } else { pn = par->proto->n; pe = par->proto->e; } write_diffattr(fp, indent, g->proto->n, pn, g->univ->nodeattr); write_diffattr(fp, indent, g->proto->e, pe, g->univ->edgeattr); dtdelete(state->subgleft, g->meta_node); } else { agputs("subgraph ", fp); agputs(agcanonical(g->name), fp); agputs(";\n", fp); return; } } else write_diffattr(fp, ++indent, g, NULL, g->univ->globattr); save_n = state->n_insubg; save_e = state->e_insubg; meta = g->meta_node->graph; state->n_insubg = dtopen(&agNamedisc, Dtoset); state->e_insubg = dtopen(&agOutdisc, Dtoset); for (e = agfstout(meta, g->meta_node); e; e = agnxtout(meta, e)) { subg = agusergraph(e->head); write_subg(subg, fp, g, indent, state); } for (n = agfstnode(g); n; n = agnxtnode(g, n)) { if (dtsearch(state->nodesleft, n)) { agwrnode(g, fp, n, TRUE, indent); dtdelete(state->nodesleft, n); } else { if (dtsearch(state->n_insubg, n) == NULL) { agwrnode(g, fp, n, FALSE, indent); } } dtinsert(save_n, n); } dtdisc(g->outedges, &agEdgedisc, 0); /* sort by id */ for (e = (Agedge_t *) dtfirst(g->outedges); e; e = (Agedge_t *) dtnext(g->outedges, e)) { if (dtsearch(state->edgesleft, e)) { tabover(fp, indent); agwredge(g, fp, e, TRUE); dtdelete(state->edgesleft, e); } else { if (dtsearch(state->e_insubg, e) == NULL) { tabover(fp, indent); agwredge(g, fp, e, FALSE); } } dtinsert(save_e, e); } dtdisc(g->outedges, &agOutdisc, 0); /* sort by name */ dtclose(state->n_insubg); state->n_insubg = save_n; dtclose(state->e_insubg); state->e_insubg = save_e; if (indent > 1) { tabover(fp, indent - 1); agputs("}\n", fp); } }