This commit is contained in:
MeiK 2020-03-27 18:43:03 +08:00
parent 3a42503ae8
commit 66dcafd389
5 changed files with 138 additions and 11 deletions

View File

@ -8,3 +8,5 @@ edition = "2018"
[dependencies]
libc = "0.2"
handlebars = "3.0.1"
yaml-rust = "0.4"

View File

@ -16,12 +16,12 @@ judge_type: standard # standard / special
# language: cpp
extra_files:
- hello.txt
# code:
# file: main.c
# language: c
code:
file: main.cpp
language: cpp
file: main.c
language: c
# code:
# file: main.cpp
# language: cpp
# code:
# file: main.py
# language: python

104
src/config.rs Normal file
View File

@ -0,0 +1,104 @@
use std::result;
use yaml_rust::{ScanError, Yaml, YamlLoader};
#[derive(Debug)]
pub enum Error {
YamlScanError(ScanError),
YamlParseError(String),
}
pub type Result<T> = result::Result<T, Error>;
pub struct LanguageConfig {
pub language: String,
pub version: String,
pub compile_command: String,
pub run_command: String,
}
pub struct Config {
pub languages: Vec<LanguageConfig>,
}
impl Config {
fn load_yaml(yaml: &str) -> Result<Config> {
let docs = match YamlLoader::load_from_str(yaml) {
Ok(value) => value,
Err(err) => return Err(Error::YamlScanError(err)),
};
let doc = &docs[0];
// 读取语言配置
let mut languages: Vec<LanguageConfig> = vec![];
let yaml_languages = match &doc["languages"] {
Yaml::Array(value) => value,
Yaml::BadValue => {
return Err(Error::YamlParseError(
"解析错误,无法解析到 languages 字段".to_string(),
))
}
_ => {
return Err(Error::YamlParseError(
"解析错误languages 字段的类型应该为 Array".to_string(),
))
}
};
for yaml_language in yaml_languages {
let language = match &yaml_language["language"] {
Yaml::String(value) => value.clone(),
_ => {
return Err(Error::YamlParseError(
"解析错误language 字段的类型应该为 String".to_string(),
))
}
};
let version = match &yaml_language["version"] {
Yaml::String(value) => value.clone(),
_ => {
return Err(Error::YamlParseError(
"version 字段的类型应该为 String".to_string(),
))
}
};
let compile_command = match &yaml_language["compile_command"] {
Yaml::String(value) => value.clone(),
_ => {
return Err(Error::YamlParseError(
"compile_command 字段的类型应该为 String".to_string(),
))
}
};
let run_command = match &yaml_language["run_command"] {
Yaml::String(value) => value.clone(),
_ => {
return Err(Error::YamlParseError(
"run_command 字段的类型应该为 String".to_string(),
))
}
};
languages.push(LanguageConfig {
language,
version,
compile_command,
run_command,
});
}
Ok(Config { languages })
}
pub fn default() -> Result<Config> {
let config_yaml = "
languages:
- language: c
version: 7.5.0
compile_command: /usr/bin/gcc {{filename}} -o a.out
run_command: ./a.out
- language: python
version: 3.6.9
compile_command: /usr/bin/python3 -m compileall {{filename}}
run_command: /use/bin/python3 {{filename}}
";
let config = Config::load_yaml(config_yaml)?;
Ok(config)
}
}

View File

@ -1,8 +1,28 @@
extern crate libc;
use std::collections::BTreeMap;
use handlebars::Handlebars;
mod runner;
mod config;
fn main() {
let mut handlebars = Handlebars::new();
let source = "hello {{world}}";
let _ = handlebars.register_template_string("t1", source);
let mut data = BTreeMap::new();
data.insert("hello".to_string(), "你好".to_string());
data.insert("world".to_string(), "世界!".to_string());
println!("{}", handlebars.render("t1", &data).unwrap());
let _config = match config::Config::default() {
Ok(value) => value,
Err(err) => {
println!("{:?}", err);
return
}
};
process();
}
@ -11,7 +31,7 @@ fn process() {
unsafe {
pid = libc::fork();
}
let mut run_configs = runner::RunConfigs {
let mut run_configs = runner::JudgeConfigs {
exec_file: "/usr/bin/python3".to_string(),
exec_args: vec![
"/usr/bin/python3".to_string(),

View File

@ -29,7 +29,7 @@ pub enum TestCaseResult {
SystemError(String),
}
pub struct RunConfigs {
pub struct JudgeConfigs {
pub exec_file: String,
pub exec_args: Vec<String>,
pub test_cases: Vec<TestCase>,
@ -41,7 +41,7 @@ pub struct ExecArgs {
pub envp: *const *const libc::c_char,
}
impl RunConfigs {
impl JudgeConfigs {
/**
* exec
* Rust C
@ -74,11 +74,12 @@ impl RunConfigs {
mem::forget(env);
mem::forget(exec_file);
mem::forget(exec_args);
return Ok(ExecArgs {
Ok(ExecArgs {
pathname: exec_file_ptr,
argv: exec_args_ptr,
envp: env_ptr,
});
})
}
}
@ -88,7 +89,7 @@ mod tests {
#[test]
fn test_base() {
let run_args = RunConfigs {
let run_args = JudgeConfigs {
exec_file: "/bin/echo".to_string(),
exec_args: vec![
"/bin/echo".to_string(),