📄 dot2l.c
字号:
/* $Id: dot2l.c,v 1.5 2006/06/27 12:43:47 ellson Exp $ $Revision: 1.5 $ *//* vim:set shiftwidth=4 ts=8: *//*********************************************************** This software is part of the graphviz package ** http://www.graphviz.org/ ** ** Copyright (c) 1994-2004 AT&T Corp. ** and is licensed under the ** Common Public License, Version 1.0 ** by AT&T Corp. ** ** Information and Software Systems Research ** AT&T Research, Florham Park NJ ***********************************************************/#include "common.h"#include "mem.h"#include "io.h"#include "code.h"#include "tbl.h"#include "dot2l.h"extern void lex_begin (int);char *gtype, *etype;int yaccdone;int attrclass;int inattrstmt;static graphframe_t *gstack, *topgframe;static Tobj allgraphs, alledges, allnodes;static Tobj gdict, edict, ndict, N;static long newgid, neweid, newnid, gmark = -1, errflag;static jmp_buf ljbuf;static void filllabeltable (Tobj, int);static void filllabelrect (Tobj);static char *lsp, *rsp;static void writesgraph (int, Tobj, int, int, char *);static void writeattr (int, Tobj, char *);static void quotestring (char *, Tobj);Tobj D2Lparsegraphlabel (Tobj lo, Tobj ro) { volatile long lm; volatile Tobj to; lm = Mpushmark (lo); Mpushmark (ro); to = Ttable (4); Mpushmark (to); lsp = Tgetstring (lo); if (ro && T_ISSTRING (ro)) rsp = Tgetstring (ro); else rsp = NULL; if (setjmp (ljbuf)) { to = NULL; fprintf (stderr, "error in label >>%s<<\n", lsp); } else filllabeltable (to, TRUE); Mpopmark (lm); return to;}#define HASTEXT 1#define HASPORT 2#define HASTABLE 4#define INTEXT 8#define INPORT 16#define ISCTRL(c) ( \ (c) == '{' || (c) == '}' || (c) == '|' || (c) == '<' || (c) == '>' \)static void filllabeltable (Tobj to, int flag) { Tobj cto, fo; char *tsp, *psp, *hstsp, *hspsp; char text[10240], port[256]; long cti; int mode, wflag, ishardspace; mode = 0; cti = 0; Tinsi (to, cti++, (cto = Ttable (2))); hstsp = tsp = &text[0], hspsp = psp = &port[0]; wflag = TRUE; ishardspace = FALSE; while (wflag) { switch (*lsp) { case '<': if (mode & (HASTABLE | HASPORT)) longjmp (ljbuf, 1); /* DOESN'T RETURN */ mode &= ~INTEXT; mode |= (HASPORT | INPORT); lsp++; break; case '>': if (!(mode & INPORT)) longjmp (ljbuf, 1); /* DOESN'T RETURN */ mode &= ~INPORT; lsp++; break; case '{': lsp++; if (mode != 0 || !*lsp) longjmp (ljbuf, 1); /* DOESN'T RETURN */ Tinss (cto, "fields", (fo = Ttable (2))); mode = HASTABLE; filllabeltable (fo, FALSE); break; case '}': case '|': case '\000': if ((!*lsp && !flag) || (mode & INPORT)) longjmp (ljbuf, 1); /* DOESN'T RETURN */ if (mode & HASPORT) { if (psp > &port[0] + 1 && psp - 1 != hspsp && *(psp - 1) == ' ') psp--; *psp = '\000'; Tinss (cto, "port", Tstring (&port[0])); hspsp = psp = &port[0]; } if (!(mode & (HASTEXT | HASTABLE))) mode |= HASTEXT, *tsp++ = ' '; if (mode & HASTEXT) { if (tsp > &text[0] + 1 && tsp - 1 != hstsp && *(tsp - 1) == ' ') tsp--; *tsp = '\000'; Tinss (cto, "text", Tstring (&text[0])); hstsp = tsp = &text[0]; } if (mode & (HASTEXT | HASPORT)) filllabelrect (cto); if (*lsp) { if (*lsp == '}') { lsp++; return; } Tinsi (to, cti++, (cto = Ttable (2))); mode = 0; lsp++; } else wflag = FALSE; break; case '\\': if (*(lsp + 1)) { if (ISCTRL (*(lsp + 1))) lsp++; else if (*(lsp + 1) == ' ') ishardspace = TRUE, lsp++; } /* falling through ... */ default: if ((mode & HASTABLE) && *lsp != ' ') longjmp (ljbuf, 1); /* DOESN'T RETURN */ if (!(mode & (INTEXT | INPORT)) && (ishardspace || *lsp != ' ')) mode |= (INTEXT | HASTEXT); if (mode & INTEXT) { if (!(*lsp == ' ' && !ishardspace && *(tsp - 1) == ' ')) *tsp++ = *lsp; if (ishardspace) hstsp = tsp - 1; } else if (mode & INPORT) { if ( !(*lsp == ' ' && !ishardspace && (psp == &port[0] || *(psp - 1) == ' ')) ) *psp++ = *lsp; if (ishardspace) hspsp = psp - 1; } ishardspace = FALSE; lsp++; break; } } return;}static void filllabelrect (Tobj to) { Tobj ro, p0o, p1o; char *s2, *s3; char c, c2; int i; if (!rsp) return; for (s2 = rsp; *s2 && *s2 != ' '; s2++) ; c = *s2, *s2 = 0; Tinss (to, "rect", (ro = Ttable (2))); Tinsi (ro, 0, (p0o = Ttable (2))); Tinsi (ro, 1, (p1o = Ttable (2))); for (i = 0; i < 4; i++) { for (s3 = rsp; *s3 && *s3 != ','; s3++) ; c2 = *s3, *s3 = 0; if (s3 == rsp) longjmp (ljbuf, 1); /* DOESN'T RETURN */ switch (i) { case 0: Tinss (p0o, "x", Tinteger ((long) atoi (rsp))); break; case 1: Tinss (p0o, "y", Tinteger ((long) atoi (rsp))); break; case 2: Tinss (p1o, "x", Tinteger ((long) atoi (rsp))); break; case 3: Tinss (p1o, "y", Tinteger ((long) atoi (rsp))); break; } *s3 = c2; rsp = s3; if (*rsp == ',') rsp++; } *s2 = c; rsp = s2 + 1;}static Tobj nameo, attro, edgeso, hporto, tporto, heado, tailo, protogo;Tobj D2Lreadgraph (int ioi, Tobj protograph) { graphframe_t *gframe, *tgframe; edgeframe_t *eframe, *teframe; Tobj graph; long m; protogo = protograph; nameo = Tstring ("name"); m = Mpushmark (nameo); attro = Tstring ("attr"); Mpushmark (attro); edgeso = Tstring ("edges"); Mpushmark (edgeso); hporto = Tstring ("hport"); Mpushmark (hporto); tporto = Tstring ("tport"); Mpushmark (tporto); heado = Tstring ("head"); Mpushmark (heado); tailo = Tstring ("tail"); Mpushmark (tailo); yaccdone = FALSE; gstack = topgframe = NULL; errflag = FALSE; lex_begin (ioi); yyparse (); graph = NULL; if (topgframe) { graph = (errflag) ? NULL : topgframe->g; for (gframe = gstack; gframe; gframe = tgframe) { for (eframe = gframe->estack; eframe; eframe = teframe) { teframe = eframe->next; Mfree (eframe, M_BYTE2SIZE (sizeof (edgeframe_t))); } tgframe = gframe->next; Mfree (gframe, M_BYTE2SIZE (sizeof (graphframe_t))); } goto done; }done: Mpopmark (m); return graph;}void D2Lwritegraph (int ioi, Tobj graph, int flag) { Tobj nodes, node, sgraphs, sgraph, edges, edge, tail, head, tport, hport; Tobj so, no, eo, to; char buf[10240]; char *s; int isdag, n, nn, i; if (!(so = Tfinds (graph, "type")) || !T_ISSTRING (so)) s = "digraph"; else { s = Tgetstring (so); if (!*s) s = "digraph"; } strcpy (buf, s); if (strcmp (s, "digraph") == 0 || strcmp (s, "strict digraph") == 0) isdag = 1; else isdag = 0; if (!(so = Tfinds (graph, "name")) || !T_ISSTRING (so)) s = "g"; else { s = Tgetstring (so); if (!*s) s = "g"; } strcat (buf, " "); quotestring (buf, Tstring (s)); strcat (buf, " {"); IOwriteline (ioi, buf); buf[0] = '\t', buf[1] = '\t', buf[2] = 0; if ((to = Tfinds (graph, "graphattr")) && T_ISTABLE (to)) { IOwriteline (ioi, "\tgraph ["); writeattr (ioi, to, buf); IOwriteline (ioi, "\t]"); } if ((to = Tfinds (graph, "nodeattr")) && T_ISTABLE (to)) { IOwriteline (ioi, "\tnode ["); writeattr (ioi, to, buf); IOwriteline (ioi, "\t]"); } if ((to = Tfinds (graph, "edgeattr")) && T_ISTABLE (to)) { IOwriteline (ioi, "\tedge ["); writeattr (ioi, to, buf); IOwriteline (ioi, "\t]"); } n = 0; if ((nodes = Tfinds (graph, "nodes"))) { if (!(no = Tfinds (graph, "maxnid")) || !T_ISNUMBER (no)) n = 100 * Tgettablen (nodes); else n = Tgetnumber (no); for (i = 0; i < n; i++) { if (!(node = Tfindi (nodes, i))) continue; buf[0] = '\t', buf[1] = 0; quotestring (buf, Tfinds (node, "name")); strcat (buf, " ["); IOwriteline (ioi, buf); buf[0] = '\t', buf[1] = '\t', buf[2] = 0; if ((to = Tfinds (node, "attr"))) writeattr (ioi, to, buf); IOwriteline (ioi, "\t]"); } } nn = n; if ((sgraphs = Tfinds (graph, "graphs"))) { if (!(no = Tfinds (graph, "maxgid")) || !T_ISNUMBER (no)) n = 100 * Tgettablen (sgraphs); else n = Tgetnumber (no); for (i = 0; i < n; i++) { if (!(sgraph = Tfindi (sgraphs, i)) || Tfinds (sgraph, "wmark")) continue; buf[0] = '\t', buf[1] = 0; writesgraph (ioi, sgraph, n, nn, buf); } for (i = 0; i < n; i++) { if (!(sgraph = Tfindi (sgraphs, i))) continue; Tdels (sgraph, "wmark"); } } if ((edges = Tfinds (graph, "edges"))) { if (!(eo = Tfinds (graph, "maxeid")) || !T_ISNUMBER (eo)) n = 100 * Tgettablen (edges); else n = Tgetnumber (eo); for (i = 0; i < n; i++) { if (!(edge = Tfindi (edges, i))) continue; if (!(tail = Tfinds (edge, "tail"))) continue; if (!(head = Tfinds (edge, "head"))) continue; tport = Tfinds (edge, "tport"); hport = Tfinds (edge, "hport"); buf[0] = '\t', buf[1] = 0; quotestring (buf, Tfinds (tail, "name")); if (tport && T_ISSTRING (tport)) { strcat (buf, ":"); quotestring (buf, tport); } strcat (buf, isdag ? " -> " : " -- "); quotestring (buf, Tfinds (head, "name")); if (hport && T_ISSTRING (hport)) { strcat (buf, ":"); quotestring (buf, hport); } strcat (buf, " ["); IOwriteline (ioi, buf); buf[0] = '\t', buf[1] = '\t', buf[2] = 0; if ((to = Tfinds (edge, "attr"))) writeattr (ioi, to, buf);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -