summaryrefslogtreecommitdiffstats
path: root/vendor/gsgdt/src/node.rs
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/gsgdt/src/node.rs')
-rw-r--r--vendor/gsgdt/src/node.rs118
1 files changed, 118 insertions, 0 deletions
diff --git a/vendor/gsgdt/src/node.rs b/vendor/gsgdt/src/node.rs
new file mode 100644
index 000000000..c72925b7a
--- /dev/null
+++ b/vendor/gsgdt/src/node.rs
@@ -0,0 +1,118 @@
+use crate::util::escape_html;
+use std::io::{self, Write};
+use serde::{Deserialize, Serialize};
+
+/// NodeStyle defines some style of [Node](struct.Node.html)
+#[derive(Clone, Serialize, Deserialize)]
+pub struct NodeStyle {
+ /// Override the title color of the title
+ /// To color the title of the node differently in graphviz
+ pub title_bg: Option<String>,
+
+ /// Print a seperator b/w the rest of the statements and the last one
+ pub last_stmt_sep: bool,
+}
+
+impl Default for NodeStyle {
+ fn default() -> NodeStyle {
+ NodeStyle {
+ title_bg: None,
+ last_stmt_sep: false,
+ }
+ }
+}
+
+/// A graph node
+#[derive(Clone, Serialize, Deserialize)]
+pub struct Node {
+ /// A list of statements.
+ pub stmts: Vec<String>,
+
+ /// A unique identifier for the given node.
+ pub label: String,
+
+ /// The title is printed on the top of BB, the index of the basic block
+ pub(crate) title: String,
+
+ /// Can be used to override the default styles
+ pub(crate) style: NodeStyle,
+}
+
+impl Node {
+ pub fn new(stmts: Vec<String>, label: String, title: String, style: NodeStyle) -> Node {
+ Node {
+ stmts,
+ label,
+ title,
+ style,
+ }
+ }
+
+ pub fn to_dot<W: Write>(&self, w: &mut W) -> io::Result<()> {
+ write!(w, r#"<table border="0" cellborder="1" cellspacing="0">"#)?;
+
+ let bg_attr = match &self.style.title_bg {
+ Some(color) => format!(r#"bgcolor="{}""#, color),
+ None => "".into(),
+ };
+ write!(
+ w,
+ r#"<tr><td {bg_attr} {attrs} colspan="{colspan}">{blk}</td></tr>"#,
+ attrs = r#"align="center""#,
+ // TODO: Not sure what this is for
+ colspan = 1,
+ blk = self.title,
+ bg_attr = bg_attr
+ )?;
+
+ let stmts_len = self.stmts.len();
+ if !self.stmts.is_empty() {
+ if self.stmts.len() > 1 {
+ write!(w, r#"<tr><td align="left" balign="left">"#)?;
+ for statement in &self.stmts[..stmts_len - 1] {
+ write!(w, "{}<br/>", escape_html(statement))?;
+ }
+ write!(w, "</td></tr>")?;
+ }
+
+ if !self.style.last_stmt_sep {
+ write!(w, r#"<tr><td align="left">"#)?;
+ write!(w, "{}", escape_html(&self.stmts[stmts_len - 1]))?;
+ } else {
+ write!(w, r#"<tr><td align="left" balign="left">"#)?;
+ write!(w, "{}", escape_html(&self.stmts[stmts_len - 1]))?;
+ }
+ write!(w, "</td></tr>")?;
+ }
+
+ write!(w, "</table>")
+ }
+}
+
+/// A directed graph edge
+#[derive(Clone, Serialize, Deserialize, Debug)]
+pub struct Edge {
+ /// The label of the source node of the edge.
+ pub from: String,
+
+ /// The label of the target node of the edge.
+ pub to: String,
+
+ /// The label (title) of the edge. This doesn't have to unique.
+ // TODO: Rename this to title?
+ pub label: String,
+}
+
+impl Edge {
+ pub fn new(from: String, to: String, label: String) -> Edge {
+ Edge { from, to, label }
+ }
+
+ pub fn to_dot<W: Write>(&self, w: &mut W) -> io::Result<()> {
+ writeln!(
+ w,
+ r#" {} -> {} [label="{}"];"#,
+ self.from, self.to, self.label
+ )
+ }
+}