use crate::{compiler::Compiler, LDPLResult};
use std::{fs, path::Path, process::Command, str};
impl Compiler {
pub fn build(&self, path: &str, outfile: Option<String>) -> LDPLResult<String> {
if !self.expected_defs.is_empty() {
for (sub, _) in &self.expected_defs {
return error!("The subprocedure {} is called but never declared.", sub);
}
}
let path = Path::new(&path);
let target = if outfile.is_none() {
format!(
"{}/{}",
path.parent()
.and_then(|d| Some(d.to_string_lossy()))
.unwrap_or(".".into()),
path.file_stem()
.and_then(|f| Some(format!("{}-bin", f.to_string_lossy())))
.unwrap_or("ldpl-output-bin".into())
)
.trim_matches('/')
.to_string()
} else {
outfile.unwrap().to_string()
};
let filename = "ldpl-temp.cpp";
if Path::new(filename).exists() {
fs::remove_file(filename)?;
}
fs::write(filename, self.to_string())?;
let mut cmd = Command::new("c++");
let mut cmd = cmd
.arg("ldpl-temp.cpp")
.arg("-std=gnu++11")
.arg("-w")
.arg("-o")
.arg(&target);
for flag in &self.flags {
cmd = cmd.arg(flag);
}
for ext in &self.exts {
cmd = cmd.arg(ext);
}
let cmd = cmd.output();
fs::remove_file(filename)?;
let output = cmd?;
if !output.stderr.is_empty() {
return error!(
"C++ Error compiling {}: \n{}",
filename,
str::from_utf8(&output.stderr).unwrap_or("UTF-8 Error in C++ output")
);
}
Ok(target)
}
}