Skip to content

Commit

Permalink
Rustfmt
Browse files Browse the repository at this point in the history
  • Loading branch information
rdvdev2 committed Feb 8, 2022
1 parent 1272772 commit 04a2d84
Show file tree
Hide file tree
Showing 18 changed files with 535 additions and 261 deletions.
79 changes: 58 additions & 21 deletions src/compilation/compiler.rs
Original file line number Diff line number Diff line change
@@ -1,16 +1,25 @@
use std::{fmt, io, path, process};
use crate::{debug, problem};
use std::{fmt, io, path, process};

pub static P1XX: Compiler = Compiler {
command: "g++",
flags1: &["-D_JUDGE_", "-DNDEBUG", "-O2", "-Wall", "-Wextra", "-Werror", "-Wno-sign-compare", "-Wshadow"],
flags2: &["-D_JUDGE_", "-DNDEBUG", "-O2"]
flags1: &[
"-D_JUDGE_",
"-DNDEBUG",
"-O2",
"-Wall",
"-Wextra",
"-Werror",
"-Wno-sign-compare",
"-Wshadow",
],
flags2: &["-D_JUDGE_", "-DNDEBUG", "-O2"],
};

pub struct Compiler<'a> {
command: &'a str,
flags1: &'a[&'a str],
flags2: &'a[&'a str]
flags1: &'a [&'a str],
flags2: &'a [&'a str],
}

pub enum CompilationError {
Expand All @@ -19,7 +28,7 @@ pub enum CompilationError {
OutputIsADir,
ExecutionError(io::Error),
CompilerError(String),
MissingOutput
MissingOutput,
}

impl fmt::Display for CompilationError {
Expand All @@ -29,15 +38,17 @@ impl fmt::Display for CompilationError {
CompilationError::SourceIsADir => write!(f, "Source is a directory!"),
CompilationError::OutputIsADir => write!(f, "Output is a directory!"),
CompilationError::ExecutionError(e) => write!(f, "Command execution error: {}", e),
CompilationError::CompilerError(stderr) => write!(f, "The compiler raised an error:\n{}", stderr),
CompilationError::MissingOutput => write!(f, "Can't find the compiler output!")
CompilationError::CompilerError(stderr) => {
write!(f, "The compiler raised an error:\n{}", stderr)
}
CompilationError::MissingOutput => write!(f, "Can't find the compiler output!"),
}
}
}

pub struct CompileProcessError {
pub pass: u8,
pub error: CompilationError
pub error: CompilationError,
}

impl fmt::Display for CompileProcessError {
Expand All @@ -48,11 +59,17 @@ impl fmt::Display for CompileProcessError {

enum CompilationType {
Object,
Binary
Binary,
}

impl Compiler<'_> {
fn run(&self, source: &path::Path, output: &path::Path, compilation_type: CompilationType, flags: &[&str]) -> Result<(), CompilationError>{
fn run(
&self,
source: &path::Path,
output: &path::Path,
compilation_type: CompilationType,
flags: &[&str],
) -> Result<(), CompilationError> {
if !source.exists() {
Err(CompilationError::SourceDoesNotExist)
} else if source.is_dir() {
Expand All @@ -61,12 +78,13 @@ impl Compiler<'_> {
Err(CompilationError::OutputIsADir)
} else {
let mut command = process::Command::new(&self.command);
command.args(flags)
command
.args(flags)
.args(["-o", output.to_string_lossy().as_ref()]);

match compilation_type {
CompilationType::Object => command.args(["-c", source.to_string_lossy().as_ref()]),
CompilationType::Binary => command.arg(source.to_string_lossy().to_string())
CompilationType::Binary => command.arg(source.to_string_lossy().to_string()),
};

debug!("Running command: {:?}", command);
Expand All @@ -79,35 +97,54 @@ impl Compiler<'_> {
Err(CompilationError::MissingOutput)
}
} else {
Err(CompilationError::CompilerError(String::from_utf8_lossy(&command.stderr).to_string()))
Err(CompilationError::CompilerError(
String::from_utf8_lossy(&command.stderr).to_string(),
))
}
}
}

fn compile_first_pass(&self, source: &path::Path, output: &path::Path) -> Result<(), CompilationError> {
fn compile_first_pass(
&self,
source: &path::Path,
output: &path::Path,
) -> Result<(), CompilationError> {
self.run(source, output, CompilationType::Object, self.flags1)
}

fn compile_and_link_first_pass(&self, source: &path::Path, output: &path::Path) -> Result<(), CompilationError> {
fn compile_and_link_first_pass(
&self,
source: &path::Path,
output: &path::Path,
) -> Result<(), CompilationError> {
self.run(source, output, CompilationType::Binary, self.flags1)
}

fn compile_and_link_second_pass(&self, source: &path::Path, output: &path::Path) -> Result<(), CompilationError> {
fn compile_and_link_second_pass(
&self,
source: &path::Path,
output: &path::Path,
) -> Result<(), CompilationError> {
self.run(source, output, CompilationType::Binary, self.flags2)
}

pub fn compile_problem(&self, problem: &problem::Problem, generated_source: &path::Path) -> Result<(), CompileProcessError>{
pub fn compile_problem(
&self,
problem: &problem::Problem,
generated_source: &path::Path,
) -> Result<(), CompileProcessError> {
debug!("Running the first pass compilation (P1++ checks)");
if problem.has_main {
let output = problem.tmp_dir.join("main.x");
self.compile_and_link_first_pass(problem.source.as_path(), output.as_path())
} else {
let output = problem.tmp_dir.join("main.o");
self.compile_first_pass(problem.source.as_path(), output.as_path())
}.map_err(|error| CompileProcessError {pass: 1, error})?;
}
.map_err(|error| CompileProcessError { pass: 1, error })?;

debug!("Running the second pass compilation (G++ binary)");
self.compile_and_link_second_pass(generated_source, problem.output.as_path())
.map_err(|error| CompileProcessError {pass: 2, error})
.map_err(|error| CompileProcessError { pass: 2, error })
}
}
}
2 changes: 1 addition & 1 deletion src/compilation/mod.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
mod compiler;
mod template;

pub use compiler::CompilationError as Error;
pub use compiler::P1XX;
pub use template::generate_main;
pub use compiler::CompilationError as Error;
83 changes: 55 additions & 28 deletions src/compilation/template.rs
Original file line number Diff line number Diff line change
@@ -1,25 +1,31 @@
use crate::{debug, problem};
use std::{env, io, path, fs, fmt};
use std::io::Write;
use std::{env, fmt, fs, io, path};

macro_rules! get_template {
($template:expr) => {
include_str!(concat!(env!("CARGO_MANIFEST_DIR"), "/templates/", $template))
}
include_str!(concat!(
env!("CARGO_MANIFEST_DIR"),
"/templates/",
$template
))
};
}

fn apply_normal_template(original: &str) -> String {
format!(get_template!("normal.cc.in"),
original=original,
stub=get_template!("stub.cc.in")
format!(
get_template!("normal.cc.in"),
original = original,
stub = get_template!("stub.cc.in")
)
}

fn apply_nomain_template(original: &str, main: &str) -> String {
format!(get_template!("nomain.cc.in"),
original=original,
stub=get_template!("stub.cc.in"),
main=main
format!(
get_template!("nomain.cc.in"),
original = original,
stub = get_template!("stub.cc.in"),
main = main
)
}

Expand All @@ -28,17 +34,21 @@ pub enum Error {
ErrorCreatingFile(io::Error),
CantReadSources(io::Error),
CantReadDownloadedMain(io::Error),
ErrorWritingFile(io::Error)
ErrorWritingFile(io::Error),
}

impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Error::ErrorCreatingTmpFolder(e) => write!(f, "Couldn't create a temporal folder: {}", e),
Error::ErrorCreatingTmpFolder(e) => {
write!(f, "Couldn't create a temporal folder: {}", e)
}
Error::ErrorCreatingFile(e) => write!(f, "Couldn't create the file: {}", e),
Error::CantReadSources(e) => write!(f, "Couldn't read your sources: {}", e),
Error::CantReadDownloadedMain(e) => write!(f, "Couldn't read the downloaded sources: {}", e),
Error::ErrorWritingFile(e) => write!(f, "Unable to write the file: {}", e)
Error::CantReadDownloadedMain(e) => {
write!(f, "Couldn't read the downloaded sources: {}", e)
}
Error::ErrorWritingFile(e) => write!(f, "Unable to write the file: {}", e),
}
}
}
Expand All @@ -47,7 +57,7 @@ impl From<Error> for crate::Error {
fn from(e: Error) -> Self {
crate::Error {
description: format!("Couldn't generate a main.cc file to compile: {}", e),
exitcode: exitcode::DATAERR
exitcode: exitcode::DATAERR,
}
}
}
Expand All @@ -58,12 +68,11 @@ pub fn generate_main(problem: &problem::Problem) -> Result<path::PathBuf, Error>
debug!("Creating {}...", generated_main_path.to_string_lossy());
fs::create_dir_all(generated_main_path.parent().unwrap())
.map_err(Error::ErrorCreatingTmpFolder)?;
let mut generated_main = fs::File::create(&generated_main_path)
.map_err(Error::ErrorCreatingFile)?;
let mut generated_main =
fs::File::create(&generated_main_path).map_err(Error::ErrorCreatingFile)?;

debug!("Reading {}...", problem.source.to_string_lossy());
let original = fs::read_to_string(problem.source.as_path())
.map_err(Error::CantReadSources)?;
let original = fs::read_to_string(problem.source.as_path()).map_err(Error::CantReadSources)?;

debug!("Generating contents...");
let generated_main_contents = if problem.has_main {
Expand All @@ -74,8 +83,12 @@ pub fn generate_main(problem: &problem::Problem) -> Result<path::PathBuf, Error>
apply_nomain_template(original.as_str(), main.as_str())
};

debug!("Writing contents to {}...", generated_main_path.to_string_lossy());
generated_main.write_all(generated_main_contents.as_ref())
debug!(
"Writing contents to {}...",
generated_main_path.to_string_lossy()
);
generated_main
.write_all(generated_main_contents.as_ref())
.map_err(Error::ErrorWritingFile)?;
Ok(generated_main_path)
}
Expand All @@ -87,17 +100,31 @@ mod test {
#[test]
fn apply_normal_template_test() {
let original = "// I'M THE ORIGINAL ONE";
let expected_output = env::current_dir().unwrap().join("tests").join("resources").join("normal.cc");

assert_eq!(apply_normal_template(original), fs::read_to_string(expected_output).unwrap());
let expected_output = env::current_dir()
.unwrap()
.join("tests")
.join("resources")
.join("normal.cc");

assert_eq!(
apply_normal_template(original),
fs::read_to_string(expected_output).unwrap()
);
}

#[test]
fn apply_nomain_template_test() {
let original = "// I'M THE ORIGINAL ONE";
let main = "// I'M THE MAIN ONE";
let expected_output = env::current_dir().unwrap().join("tests").join("resources").join("nomain.cc");

assert_eq!(apply_nomain_template(original, main), fs::read_to_string(expected_output).unwrap());
let expected_output = env::current_dir()
.unwrap()
.join("tests")
.join("resources")
.join("nomain.cc");

assert_eq!(
apply_nomain_template(original, main),
fs::read_to_string(expected_output).unwrap()
);
}
}
}
Loading

0 comments on commit 04a2d84

Please sign in to comment.