diff options
Diffstat (limited to '')
-rw-r--r-- | vendor/gsgdt/src/node.rs | 118 |
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 + ) + } +} |