18 #define EMPTY(s) ((s == 0) || (s)[0] == '\0')
19 #define MAX(a,b) ((a)>(b)?(a):(b))
20 #define CHKRV(v) {if ((v) == EOF) return EOF;}
26 return AGDISC(g, io)->putstr(ofile, str);
30 #define MAX_OUTPUTLINE 128
31 #define MIN_OUTPUTLINE 60
35 static unsigned char Attrs_not_written_flag;
36 static Agsym_t *Tailport, *Headport;
41 for (i = Level; i > 0; i--)
42 CHKRV(ioput(g, ofile,
"\t"));
46 #ifndef HAVE_STRCASECMP
50 static int strcasecmp(
const char *
s1,
const char *s2)
53 && (tolower(*(
unsigned char *) s1) ==
54 tolower(*(
unsigned char *) s2))) {
59 return tolower(*(
unsigned char *) s1) - tolower(*(
unsigned char *) s2);
64 #define is_id_char(c) (isalnum(c) || ((c) == '.') || ((c) == '-') || !isascii(c))
70 static char *_agstrcanon(
char *arg,
char *buf)
74 int cnt = 0, dotcnt = 0;
75 int needs_quotes =
FALSE;
77 int backslash_pending =
FALSE;
78 static const char *tokenlist[]
79 = {
"node",
"edge",
"strict",
"graph",
"digraph",
"subgraph",
89 uc = *(
unsigned char *) s++;
90 maybe_num = isdigit(uc) || (uc ==
'.') || (uc ==
'-');
103 else if (uc ==
'.') {
109 else if (!isdigit(uc)) {
117 uc = *(
unsigned char *) s++;
123 if (Max_outputline) {
128 backslash_pending =
FALSE;
130 }
else if (uc && (cnt >= Max_outputline)) {
137 backslash_pending =
TRUE;
144 if (needs_quotes || ((cnt == 1) && ((*arg ==
'.') || (*arg ==
'-'))))
149 for (tok = tokenlist; *tok; tok++)
150 if (!strcasecmp(*tok, arg))
158 static char *agcanonhtmlstr(
char *arg,
char *buf)
180 return agcanonhtmlstr(arg, buf);
182 return _agstrcanon(arg, buf);
185 static char *getoutputbuffer(
char *
str)
188 static size_t len = 0;
191 req =
MAX(2 * strlen(str) + 2, BUFSIZ);
194 rv = realloc(rv, req);
219 char* buf = getoutputbuffer(str);
221 return agcanonhtmlstr(str, buf);
223 return _agstrcanon(str, buf);
232 str = _agstrcanon(str, getoutputbuffer(str));
233 return ioput(g, ofile, str);
238 return _write_canonstr(g, ofile, str,
TRUE);
263 CHKRV(indent(g, ofile));
264 CHKRV(ioput(g, ofile, name));
265 CHKRV(ioput(g, ofile,
" ["));
268 CHKRV(ioput(g, ofile,
",\n"));
269 CHKRV(indent(g, ofile));
271 CHKRV(write_canonstr(g, ofile, sym->
name));
272 CHKRV(ioput(g, ofile,
"="));
278 CHKRV(ioput(g, ofile,
"\n"));
279 CHKRV(indent(g, ofile));
281 CHKRV(ioput(g, ofile,
"];\n"));
292 CHKRV(write_dict(g, ofile,
"graph", def->
dict.
g, top));
293 CHKRV(write_dict(g, ofile,
"node", def->
dict.
n, top));
294 CHKRV(write_dict(g, ofile,
"edge", def->
dict.
e, top));
301 char *name, *sep, *kind, *strict;
305 Attrs_not_written_flag =
AGATTRWF(g);
326 CHKRV(indent(g, ofile));
327 CHKRV(ioput(g, ofile, strict));
330 if (root || hasName) {
331 CHKRV(ioput(g, ofile, kind));
332 CHKRV(ioput(g, ofile,
"graph "));
335 CHKRV(write_canonstr(g, ofile, name));
336 CHKRV(ioput(g, ofile, sep));
337 CHKRV(ioput(g, ofile,
"{\n"));
339 CHKRV(write_dicts(g, ofile, top));
348 CHKRV(indent(g, ofile));
349 CHKRV(ioput(g, ofile,
"}\n"));
353 static int irrelevant_subgraph(
Agraph_t * g)
367 for (i = 0; i < n; i++)
368 if (sdata->
str[i] && pdata->
str[i]
369 && strcmp(sdata->
str[i], pdata->
str[i]))
385 if (irrelevant_subgraph(subg))
433 if (irrelevant_subgraph(subg)) {
434 write_subgs(subg, ofile);
438 CHKRV(write_body(subg, ofile));
439 CHKRV(write_trl(subg, ofile));
457 CHKRV(ioput(g, ofile,
"\t[key="));
458 CHKRV(write_canonstr(g, ofile, p));
460 CHKRV(ioput(g, ofile,
"]"));
468 static int write_nondefault_attrs(
void *obj,
iochan_t * ofile,
478 CHKRV(rv = write_edge_name(obj, ofile,
FALSE));
488 if (Tailport && (sym->
id == Tailport->
id))
490 if (Headport && (sym->
id == Headport->
id))
495 CHKRV(ioput(g, ofile,
"\t["));
498 CHKRV(ioput(g, ofile,
",\n"));
499 CHKRV(indent(g, ofile));
501 CHKRV(write_canonstr(g, ofile, sym->
name));
502 CHKRV(ioput(g, ofile,
"="));
503 CHKRV(write_canonstr(g, ofile, data->
str[sym->
id]));
507 CHKRV(ioput(g, ofile,
"]"));
522 CHKRV(write_canonstr(g, ofile, name));
524 sprintf(buf,
"_%ld_SUSPECT",
AGID(n));
525 CHKRV(ioput(g, ofile, buf));
530 static int attrs_written(
void *obj)
540 CHKRV(indent(g, ofile));
541 CHKRV(write_nodename(n, ofile));
542 if (
NOT(attrs_written(n)))
543 CHKRV(write_nondefault_attrs(n, ofile, d));
544 return ioput(g, ofile,
";\n");
554 if (
NOT(
node_in_subg(g, n)) && has_no_predecessor_below(g, n, pred_id)) {
555 if (has_no_edges(g, n) || not_default_attrs(g, n))
573 CHKRV(ioput(g, ofile,
":"));
575 CHKRV(write_canonstr(g, ofile, val));
577 char *s = strchr(val,
':');
581 CHKRV(ioput(g, ofile,
":"));
582 CHKRV(_write_canonstr(g, ofile, s + 1,
FALSE));
597 if (irrelevant_subgraph(subg))
613 CHKRV(indent(g, ofile));
614 CHKRV(write_nodename(t, ofile));
615 CHKRV(write_port(e, ofile, Tailport));
617 CHKRV(write_nodename(h, ofile));
618 CHKRV(write_port(e, ofile, Headport));
619 if (
NOT(attrs_written(e))) {
620 CHKRV(write_nondefault_attrs(e, ofile, d));
624 return ioput(g, ofile,
";\n");
636 CHKRV(write_subgs(g, ofile));
639 if (write_node_test(g, n,
AGSEQ(n)))
640 CHKRV(write_node(n, ofile, dd ? dd->
dict.
n : 0));
648 if (write_edge_test(g, e))
649 CHKRV(write_edge(e, ofile, dd ? dd->
dict.
e : 0));
656 static void set_attrwf(
Agraph_t * g,
int toplevel,
int value)
664 set_attrwf(subg,
FALSE, value);
683 if ((s =
agget(g,
"linelength")) && isdigit(*s)) {
684 len = (
int)strtol(s, (
char **)
NULL, 10);
686 Max_outputline = len;
690 CHKRV(write_body(g, ofile));
691 CHKRV(write_trl(g, ofile));
693 return AGDISC(g, io)->flush(ofile);
void s1(graph_t *, node_t *)
Agsym_t * agattr(Agraph_t *g, int kind, char *name, char *value)
struct Agdatadict_s::@3 dict
CGRAPH_API int aghtmlstr(char *)
CGRAPH_API char * agcanonStr(char *str)
CGRAPH_API Agedge_t * agfstin(Agraph_t *g, Agnode_t *n)
CDT_API Dt_t * dtview(Dt_t *, Dt_t *)
CGRAPH_API int agisdirected(Agraph_t *g)
CGRAPH_API int agwrite(Agraph_t *g, void *chan)
CGRAPH_API Agraph_t * agfstsubg(Agraph_t *g)
CGRAPH_API Agraph_t * agroot(void *obj)
CGRAPH_API Agedge_t * agfstout(Agraph_t *g, Agnode_t *n)
Agdatadict_t * agdatadict(Agraph_t *g, int cflag)
CGRAPH_API char * agcanon(char *, int)
char * agget(void *obj, char *name)
CGRAPH_API Agraph_t * agraphof(void *obj)
CGRAPH_API Agraph_t * agnxtsubg(Agraph_t *subg)
CGRAPH_API Agnode_t * agnxtnode(Agraph_t *g, Agnode_t *n)
CGRAPH_API int agisstrict(Agraph_t *g)
CGRAPH_API Agnode_t * aghead(Agedge_t *e)
CGRAPH_API char * agnameof(void *)
CGRAPH_API Agraph_t * agparent(Agraph_t *g)
CGRAPH_API Agedge_t * agsubedge(Agraph_t *g, Agedge_t *e, int createflag)
CGRAPH_API char * agstrcanon(char *, char *)
CDT_API int dtsize(Dt_t *)
CGRAPH_API Agnode_t * agfstnode(Agraph_t *g)
Agattr_t * agattrrec(void *obj)
CGRAPH_API Agedge_t * agnxtin(Agraph_t *g, Agedge_t *e)
char * agxget(void *obj, Agsym_t *sym)
CGRAPH_API Agedge_t * agnxtout(Agraph_t *g, Agedge_t *e)
int node_in_subg(Agraph_t *g, Agnode_t *n)
CGRAPH_API Agnode_t * agsubnode(Agraph_t *g, Agnode_t *n, int createflag)