static void printptf(FILE * f, pointf pt)
{
- fprintf(f, " %.5g %.5g", PS2INCH(pt.x), PS2INCH(YDIR(pt.y)));
+ agfprintf(f, " %.5g %.5g", PS2INCH(pt.x), PS2INCH(YDIR(pt.y)));
}
/* setYInvert:
#else
name = agcanonStr (agnameof(node));
#endif
- fprintf(fp, "%s", name); /* slimey i know */
+ agfprintf(fp, "%s", name); /* slimey i know */
if (port && *port)
#ifndef WITH_CGRAPH
- fprintf(fp, ":%s", agcanonical(port));
+ agfprintf(fp, ":%s", agcanonical(port));
#else
- fprintf(fp, ":%s", agcanonStr(port));
+ agfprintf(fp, ":%s", agcanonStr(port));
#endif
}
// setup_graph(job, g);
setYInvert(g);
pt = GD_bb(g).UR;
- fprintf(f, "graph %.5g %.5g %.5g\n", job->zoom, PS2INCH(pt.x), PS2INCH(pt.y));
+ agfprintf(f, "graph %.5g %.5g %.5g\n", job->zoom, PS2INCH(pt.x), PS2INCH(pt.y));
for (n = agfstnode(g); n; n = agnxtnode(g, n)) {
if (IS_CLUST_NODE(n))
continue;
#ifndef WITH_CGRAPH
- fprintf(f, "node %s ", agcanonical(agnameof(n)));
+ agfprintf(f, "node %s ", agcanonical(agnameof(n)));
#else
- fprintf(f, "node %s ", agcanonStr(agnameof(n)));
+ agfprintf(f, "node %s ", agcanonStr(agnameof(n)));
#endif
printptf(f, ND_coord(n));
if (ND_label(n)->html) /* if html, get original text */
#endif
else
lbl = canon(agraphof(n),ND_label(n)->text);
- fprintf(f, " %.5g %.5g %s %s %s %s %s\n",
+ agfprintf(f, " %.5g %.5g %s %s %s %s %s\n",
ND_width(n), ND_height(n), lbl,
late_nnstring(n, N_style, "solid"),
ND_shape(n)->name,
bz = ED_spl(e)->list[i];
splinePoints += bz.size;
}
- fprintf(f, "edge ");
+ agfprintf(f, "edge ");
writenodeandport(f, agtail(e), tport);
- fprintf(f, " ");
+ agfprintf(f, " ");
writenodeandport(f, aghead(e), hport);
- fprintf(f, " %d", splinePoints);
+ agfprintf(f, " %d", splinePoints);
for (i = 0; i < ED_spl(e)->size; i++) {
bz = ED_spl(e)->list[i];
for (j = 0; j < bz.size; j++)
}
}
if (ED_label(e)) {
- fprintf(f, " %s", canon(agraphof(agtail(e)),ED_label(e)->text));
+ agfprintf(f, " %s", canon(agraphof(agtail(e)),ED_label(e)->text));
printptf(f, ED_label(e)->pos);
}
- fprintf(f, " %s %s\n", late_nnstring(e, E_style, "solid"),
+ agfprintf(f, " %s %s\n", late_nnstring(e, E_style, "solid"),
late_nnstring(e, E_color, DEFAULT_COLOR));
}
}
- fprintf(f, "stop\n");
+ agfprintf(f, "stop\n");
}
static void set_record_rects(node_t * n, field_t * f, agxbuf * xb)
#include "libgraph.h"
-
-#ifdef DMALLOC
-#include "dmalloc.h"
-#endif
+#include <string.h>
typedef struct printdict_t {
Dict_t *nodesleft, *edgesleft, *subgleft, *e_insubg, *n_insubg;
return (_agstrcanon(arg, buf));
}
+void agsetodisc(size_t (*fwrite) (FILE *fp, const char *s, size_t len), int (*ferror) (FILE *fp))
+{
+ AG.fwrite = fwrite;
+ AG.ferror = ferror;
+}
+
+/* agfprintf:
+ * Note that this function is unsafe due to the fixed buffer size.
+ * It should only be used when the caller is sure the input will not
+ * overflow the buffer. In particular, it should be avoided for
+ * input coming from users. Also, if vsnprintf is available, the
+ * code should check for return values to use it safely.
+ */
+void agfprintf(FILE *fp, const char *format, ...)
+{
+ char buf[BUFSIZ];
+ size_t len;
+ va_list argp;
+
+ va_start(argp, format);
+#ifdef HAVE_VSNPRINTF
+ len = vsnprintf((char *)buf, sizeof(buf), format, argp);
+#else
+ len = vsprintf((char *)buf, format, argp);
+#endif
+ va_end(argp);
+
+ AG.fwrite(fp, buf, len);
+}
+
+int agputs(const char *s, FILE *fp)
+{
+ size_t len = strlen(s);
+
+ if (AG.fwrite(fp, s, len) != len) {
+ return EOF;
+ }
+ return +1;
+}
+
+
+int agputc(int c, FILE *fp)
+{
+ const char cc = c;
+
+ if (AG.fwrite (fp, &cc, 1) != 1) {
+ return EOF;
+ }
+ return c;
+}
static void tabover(FILE * fp, int tab)
{
while (tab--)
- putc('\t', fp);
+ agputc('\t', fp);
}
static char *getoutputbuffer(char *str)
a = dict->list[i];
if (ISEMPTYSTR(a->value) == FALSE) {
if (cnt++ == 0)
- fprintf(fp, "\t%s [", dict->name);
+ agfprintf(fp, "\t%s [", dict->name);
else
- fprintf(fp, ", ");
- fprintf(fp, "%s=%s", a->name, agcanonical(a->value));
+ agfprintf(fp, ", ");
+ agfprintf(fp, "%s=%s", a->name, agcanonical(a->value));
}
}
if (cnt > 0)
- fprintf(fp, "];\n");
+ agfprintf(fp, "];\n");
}
static void write_diffattr(FILE * fp, int indent, void *obj, void *par,
if (strcmp(p, q)) {
if (cnt++ == 0) {
tabover(fp, indent);
- fprintf(fp, "%s [", dict->name);
+ agfprintf(fp, "%s [", dict->name);
} else {
- fprintf(fp, ",\n");
+ agfprintf(fp, ",\n");
tabover(fp, indent + 1);
}
- fprintf(fp, "%s=", agcanonical(a->name));
- fprintf(fp, "%s", agcanonical(p));
+ agfprintf(fp, "%s=", agcanonical(a->name));
+ agfprintf(fp, "%s", agcanonical(p));
}
}
if (cnt > 0)
- fprintf(fp, "];\n");
+ agfprintf(fp, "];\n");
}
static void writeattr(FILE * fp, int *npp, char *name, char *val)
{
- fprintf(fp, ++(*npp) > 1 ? ", " : " [");
- fprintf(fp, "%s=", agcanonical(name));
- fprintf(fp, "%s", agcanonical(val));
+ agfprintf(fp, ++(*npp) > 1 ? ", " : " [");
+ agfprintf(fp, "%s=", agcanonical(name));
+ agfprintf(fp, "%s", agcanonical(val));
}
void agwrnode(Agraph_t * g, FILE * fp, Agnode_t * n, int full, int indent)
if (strcmp(defval, myval)) {
if (didwrite == FALSE) {
tabover(fp, indent);
- fprintf(fp, "%s", agcanonical(n->name));
+ agfprintf(fp, "%s", agcanonical(n->name));
didwrite = TRUE;
}
writeattr(fp, &nprint, a->name, myval);
}
}
if (didwrite) {
- fprintf(fp, (nprint > 0 ? "];\n" : ";\n"));
+ agfprintf(fp, (nprint > 0 ? "];\n" : ";\n"));
return;
}
}
if ((agfstout(g, n) == NULL) && (agfstin(g, n) == NULL)) {
tabover(fp, indent);
- fprintf(fp, "%s;\n", agcanonical(n->name));
+ agfprintf(fp, "%s;\n", agcanonical(n->name));
}
}
static void writenodeandport(FILE * fp, char *node, char *port)
{
char *ss;
- fprintf(fp, "%s", agcanonical(node)); /* slimey i know */
+ agfprintf(fp, "%s", agcanonical(node)); /* slimey i know */
if (port && *port) {
if (aghtmlstr(port)) {
- fprintf(fp, ":%s", agstrcanon(port, getoutputbuffer(port)));
+ agfprintf(fp, ":%s", agstrcanon(port, getoutputbuffer(port)));
}
else {
ss = strchr (port, ':');
if (ss) {
*ss = '\0';
- fprintf(fp, ":%s",
+ agfprintf(fp, ":%s",
_agstrcanon(port, getoutputbuffer(port)));
- fprintf(fp, ":%s",
+ agfprintf(fp, ":%s",
_agstrcanon(ss+1, getoutputbuffer(ss+1)));
*ss = ':';
}
else {
- fprintf(fp, ":%s", _agstrcanon(port, getoutputbuffer(port)));
+ agfprintf(fp, ":%s", _agstrcanon(port, getoutputbuffer(port)));
}
}
}
else
edgeop = "--";
writenodeandport(fp, e->tail->name, tport);
- fprintf(fp, " %s ", edgeop);
+ agfprintf(fp, " %s ", edgeop);
writenodeandport(fp, e->head->name, hport);
if (list_all) {
for (i = 0; i < dtsize(d->dict); i++) {
writeattr(fp, &nprint, a->name, myval);
}
}
- fprintf(fp, (nprint > 0 ? "];\n" : ";\n"));
+ agfprintf(fp, (nprint > 0 ? "];\n" : ";\n"));
}
Dtdisc_t agEdgedisc = {
tabover(fp, indent++);
if (dtsearch(state->subgleft, g->meta_node)) {
if (strncmp(g->name, "_anonymous", 10))
- fprintf(fp, "subgraph %s {\n", agcanonical(g->name));
+ agfprintf(fp, "subgraph %s {\n", agcanonical(g->name));
else
- fprintf(fp, "{\n"); /* no name printed for anonymous subg */
+ agfprintf(fp, "{\n"); /* 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
write_diffattr(fp, indent, g->proto->e, pe, g->univ->edgeattr);
dtdelete(state->subgleft, g->meta_node);
} else {
- fprintf(fp, "subgraph %s;\n", agcanonical(g->name));
+ agfprintf(fp, "subgraph %s;\n", agcanonical(g->name));
return;
}
} else
if (indent > 1) {
tabover(fp, indent - 1);
- fprintf(fp, "}\n");
+ agfprintf(fp, "}\n");
}
}
t0 = (AG_IS_STRICT(g)) ? "strict " : "";
t1 = (AG_IS_DIRECTED(g)) ? "digraph" : "graph";
if (strncmp(g->name, "_anonymous", 10))
- fprintf(fp, "%s%s %s {\n", t0, t1, agcanonical(g->name));
+ agfprintf(fp, "%s%s %s {\n", t0, t1, agcanonical(g->name));
else
- fprintf(fp, "%s%s {\n", t0, t1);
+ agfprintf(fp, "%s%s {\n", t0, t1);
/* write the top level attribute defs */
write_dict(g->univ->globattr, fp);
/* write the graph contents */
p = new_printdict_t(g);
write_subg(g, fp, (Agraph_t *) 0, 0, p);
- fprintf(fp, "}\n");
+ agfprintf(fp, "}\n");
free_printdict_t(p);
- return ferror(fp);
+ return AG.ferror(fp);
}