📄 dot2l.c
字号:
if (flag) { sprintf (buf, "\t\tid = %d", i); IOwriteline (ioi, buf); } IOwriteline (ioi, "\t]"); } } IOwriteline (ioi, "}");}static void writesgraph (int ioi, Tobj graph, int gn, int nn, char *buf) { Tobj nodes, node, sgraphs, sgraph, so, to; char *s1, *s2, *s3; int i; Tinss (graph, "wmark", Tinteger (1)); s1 = buf + strlen (buf); if (!(so = Tfinds (graph, "name")) || !T_ISSTRING (so)) sprintf (s1, "{"); else { strcat (s1, "subgraph "); quotestring (s1, so); strcat (s1, " {"); } IOwriteline (ioi, buf); s2 = s1 + 1; s3 = s2 + 1; *s1 = '\t', *s2 = 0; if ((to = Tfinds (graph, "graphattr")) && T_ISTABLE (to)) { strcat (s1, "graph ["); IOwriteline (ioi, buf); *s2 = '\t', *s3 = 0; writeattr (ioi, to, buf); *s2 = 0; strcat (s1, "]"); IOwriteline (ioi, buf); *s2 = 0; } if ((to = Tfinds (graph, "nodeattr")) && T_ISTABLE (to)) { strcat (s1, "node ["); IOwriteline (ioi, buf); *s2 = '\t', *s3 = 0; writeattr (ioi, to, buf); *s2 = 0; strcat (s1, "]"); IOwriteline (ioi, buf); *s2 = 0; } if ((to = Tfinds (graph, "edgeattr")) && T_ISTABLE (to)) { strcat (s1, "edge ["); IOwriteline (ioi, buf); *s2 = '\t', *s3 = 0; writeattr (ioi, to, buf); *s2 = 0; strcat (s1, "]"); IOwriteline (ioi, buf); *s2 = 0; } if ((nodes = Tfinds (graph, "nodes"))) { for (i = 0; i < nn; i++) { *s2 = 0; if (!(node = Tfindi (nodes, i))) continue; quotestring (buf, Tfinds (node, "name")); IOwriteline (ioi, buf); } } if ((sgraphs = Tfinds (graph, "graphs"))) { for (i = 0; i < gn; i++) { if (!(sgraph = Tfindi (sgraphs, i)) || Tfinds (sgraph, "wmark")) continue; *s2 = 0; writesgraph (ioi, sgraph, gn, nn, buf); } } *s1 = '}', *s2 = 0; IOwriteline (ioi, buf); *s1 = 0;}static void writeattr (int ioi, Tobj to, char *buf) { Tkvindex_t tkvi; char *s1, *s2, *s3; int htmlflag; s1 = buf + strlen (buf); for (Tgetfirst (to, &tkvi); tkvi.kvp; Tgetnext (&tkvi)) { switch (Tgettype (tkvi.kvp->ko)) { case T_INTEGER: sprintf (s1, "%ld = ", Tgetinteger (tkvi.kvp->ko)); break; case T_REAL: sprintf (s1, "%lf = ", Tgetreal (tkvi.kvp->ko)); break; case T_STRING: sprintf (s1, "%s = ", Tgetstring (tkvi.kvp->ko)); break; } s2 = buf + strlen (buf); switch (Tgettype (tkvi.kvp->vo)) { case T_INTEGER: sprintf (s2, "\"%ld\"", Tgetinteger (tkvi.kvp->vo)); break; case T_REAL: sprintf (s2, "\"%lf\"", Tgetreal (tkvi.kvp->vo)); break; case T_STRING: *s2++ = '"', htmlflag = FALSE; if ( *(s3 = Tgetstring (tkvi.kvp->vo)) == '>' && s3[strlen (s3) - 1] == '<' ) *(s2 - 1) = '<', s3++, htmlflag = TRUE; for ( ; *s3; s3++) if (!htmlflag && *s3 == '"') *s2++ = '\\', *s2++ = *s3; else *s2++ = *s3; if (!htmlflag) *s2++ = '"', *s2 = 0; else *(s2 - 1) = '>', *s2 = 0; break; default: sprintf (s2, "\"\""); break; } IOwriteline (ioi, buf); } *s1 = 0;}static void quotestring (char *buf, Tobj so) { char *s1, *s2; s1 = buf + strlen (buf); *s1++ = '"'; if (so && T_ISSTRING (so)) for (s2 = Tgetstring (so); *s2; s2++) { if (*s2 == '"') *s1++ = '\\', *s1++ = *s2; else *s1++ = *s2; } *s1++ = '"', *s1 = 0;}void D2Lbegin (char *name) { newgid = neweid = newnid = 0; attrclass = GRAPH; if (!(gstack = Mallocate (sizeof (graphframe_t)))) panic1 (POS, "D2Lbegingraph", "cannot allocate graph stack"); gstack->next = NULL; gstack->estack = NULL; topgframe = gstack; gmark = Mpushmark ((gstack->g = Ttable (12))); Tinss (gstack->g, "type", Tstring (gtype)); Tinss (gstack->g, "name", Tstring (name)); /* the dictionaries */ Tinss (gstack->g, "graphdict", (gdict = Ttable (10))); Tinss (gstack->g, "nodedict", (ndict = Ttable (10))); Tinss (gstack->g, "edgedict", (edict = Ttable (10))); /* this graph's nodes, edges, subgraphs */ Tinss (gstack->g, "nodes", (allnodes = gstack->nodes = Ttable (10))); Tinss (gstack->g, "graphs", (allgraphs = gstack->graphs = Ttable (10))); Tinss (gstack->g, "edges", (alledges = gstack->edges = Ttable (10))); /* attributes */ gstack->gattr = gstack->nattr = gstack->eattr = NULL; if (protogo) { gstack->gattr = Tfinds (protogo, "graphattr"); gstack->nattr = Tfinds (protogo, "nodeattr"); gstack->eattr = Tfinds (protogo, "edgeattr"); } gstack->gattr = (gstack->gattr ? Tcopy (gstack->gattr) : Ttable (10)); Tinss (gstack->g, "graphattr", gstack->gattr); gstack->nattr = (gstack->nattr ? Tcopy (gstack->nattr) : Ttable (10)); Tinss (gstack->g, "nodeattr", gstack->nattr); gstack->eattr = (gstack->eattr ? Tcopy (gstack->eattr) : Ttable (10)); Tinss (gstack->g, "edgeattr", gstack->eattr); gstack->ecopy = gstack->eattr;}void D2Lend (void) { if (gmark != -1) Mpopmark (gmark); gmark = -1; yaccdone = TRUE;}void D2Labort (void) { if (gmark != -1) Mpopmark (gmark); errflag = TRUE; yaccdone = TRUE;}void D2Lpushgraph (char *name) { graphframe_t *gframe; Tobj g, idobj, nameobj; long gid; if (!(gframe = Mallocate (sizeof (graphframe_t)))) panic1 (POS, "D2Lpushgraph", "cannot allocate graph stack"); gframe->next = gstack, gstack = gframe; gstack->estack = NULL; if (name && (idobj = Tfinds (gdict, name))) { gid = Tgetnumber (idobj), gstack->g = g = Tfindi (allgraphs, gid); gstack->nodes = Tfinds (g, "nodes"); gstack->graphs = Tfinds (g, "graphs"); gstack->edges = Tfinds (g, "edges"); gstack->gattr = Tfinds (g, "graphattr"); gstack->nattr = Tfinds (g, "nodeattr"); gstack->ecopy = gstack->eattr = Tfinds (g, "edgeattr"); return; } if (!name) { gid = newgid++; nameobj = Tinteger (gid); Tinso (gdict, nameobj, nameobj); } else Tinso (gdict, (nameobj = Tstring (name)), Tinteger ((gid = newgid++))); Tinsi (allgraphs, gid, (gstack->g = g = Ttable (10))); Tinss (g, "name", nameobj); Tinss (g, "nodes", (gstack->nodes = Ttable (10))); Tinss (g, "graphs", (gstack->graphs = Ttable (10))); Tinss (g, "edges", (gstack->edges = Ttable (10))); Tinss (g, "graphattr", (gstack->gattr = Tcopy (gstack->next->gattr))); Tinss (g, "nodeattr", (gstack->nattr = Tcopy (gstack->next->nattr))); Tinss ( g, "edgeattr", (gstack->ecopy = gstack->eattr = Tcopy (gstack->next->eattr)) ); for ( gframe = gstack->next; gframe->graphs != allgraphs; gframe = gframe->next ) { if (Tfindi (gframe->graphs, gid)) break; Tinsi (gframe->graphs, gid, g); } return;}Tobj D2Lpopgraph (void) { graphframe_t *gframe; Tobj g; gframe = gstack, gstack = gstack->next; g = gframe->g; Mfree (gframe, M_BYTE2SIZE (sizeof (graphframe_t))); return g;}Tobj D2Linsertnode (char *name) { graphframe_t *gframe; Tobj n, idobj, nameobj; long nid, m; if ((idobj = Tfinds (ndict, name))) { nid = Tgetnumber (idobj), n = Tfindi (allnodes, nid); } else { m = Mpushmark ((nameobj = Tstring (name))); Tinso (ndict, nameobj, Tinteger ((nid = newnid++))); Mpopmark (m); Tinsi (allnodes, nid, (n = Ttable (3))); Tinso (n, nameo, nameobj); Tinso (n, attro, Tcopy (gstack->nattr)); Tinso (n, edgeso, Ttable (2)); } for (gframe = gstack; gframe->nodes != allnodes; gframe = gframe->next) { if (Tfindi (gframe->nodes, nid)) break; Tinsi (gframe->nodes, nid, n); } N = n; return n;}void D2Linsertedge (Tobj tail, char *tport, Tobj head, char *hport) { graphframe_t *gframe; Tobj e; long eid; Tinsi ( alledges, (eid = neweid++), (e = Ttable ((long) (3 + (tport ? 1 : 0) + (hport ? 1 : 0)))) ); Tinso (e, tailo, tail); if (tport && tport[0]) Tinso (e, tporto, Tstring (tport)); Tinso (e, heado, head); if (hport && hport[0]) Tinso (e, hporto, Tstring (hport)); Tinso (e, attro, Tcopy (gstack->ecopy)); Tinsi (Tfinds (head, "edges"), eid, e); Tinsi (Tfinds (tail, "edges"), eid, e); for (gframe = gstack; gframe->edges != alledges; gframe = gframe->next) Tinsi (gframe->edges, eid, e);}void D2Lbeginedge (int type, Tobj obj, char *port) { if (!(gstack->estack = Mallocate (sizeof (edgeframe_t)))) panic1 (POS, "D2Lbeginedge", "cannot allocate edge stack"); gstack->estack->next = NULL; gstack->estack->type = type; gstack->estack->obj = obj; gstack->estack->port = strdup (port); gstack->emark = Mpushmark ((gstack->ecopy = Tcopy (gstack->eattr)));}void D2Lmidedge (int type, Tobj obj, char *port) { edgeframe_t *eframe; if (!(eframe = Mallocate (sizeof (edgeframe_t)))) panic1 (POS, "D2Lmidedge", "cannot allocate edge stack"); eframe->next = gstack->estack, gstack->estack = eframe; gstack->estack->type = type; gstack->estack->obj = obj; gstack->estack->port = strdup (port);}void D2Lendedge (void) { edgeframe_t *eframe, *hframe, *tframe; Tobj tnodes, hnodes; Tkvindex_t tkvi, hkvi; for (eframe = gstack->estack; eframe->next; eframe = tframe) { hframe = eframe, tframe = eframe->next; if (hframe->type == NODE && tframe->type == NODE) { D2Linsertedge ( tframe->obj, tframe->port, hframe->obj, hframe->port ); } else if (hframe->type == NODE && tframe->type == GRAPH) { tnodes = Tfinds (tframe->obj, "nodes"); for (Tgetfirst (tnodes, &tkvi); tkvi.kvp; Tgetnext (&tkvi)) D2Linsertedge (tkvi.kvp->vo, NULL, hframe->obj, hframe->port); } else if (eframe->type == GRAPH && eframe->next->type == NODE) { hnodes = Tfinds (hframe->obj, "nodes"); for (Tgetfirst (hnodes, &hkvi); hkvi.kvp; Tgetnext (&hkvi)) D2Linsertedge (tframe->obj, tframe->port, hkvi.kvp->vo, NULL); } else { tnodes = Tfinds (tframe->obj, "nodes"); hnodes = Tfinds (hframe->obj, "nodes"); for (Tgetfirst (tnodes, &tkvi); tkvi.kvp; Tgetnext (&tkvi)) for (Tgetfirst (hnodes, &hkvi); hkvi.kvp; Tgetnext (&hkvi)) D2Linsertedge (tkvi.kvp->vo, NULL, hkvi.kvp->vo, NULL); } free (eframe->port); Mfree (eframe, M_BYTE2SIZE (sizeof (edgeframe_t))); } free (eframe->port); Mfree (eframe, M_BYTE2SIZE (sizeof (edgeframe_t))); Mpopmark (gstack->emark); gstack->estack = NULL;}void D2Lsetattr (char *name, char *value) { if (inattrstmt) { switch (attrclass) { case NODE: Tinss (gstack->nattr, name, Tstring (value)); break; case EDGE: Tinss (gstack->eattr, name, Tstring (value)); break; case GRAPH: Tinss (gstack->gattr, name, Tstring (value)); break; } return; } switch (attrclass) { case NODE: Tinss (Tfinds (N, "attr"), name, Tstring (value)); break; case EDGE: Tinss (gstack->ecopy, name, Tstring (value)); break; /* a subgraph cannot have optional attrs? */ case GRAPH: Tinss (gstack->gattr, name, Tstring (value)); break; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -