diff --git a/src/config.rs b/src/config.rs new file mode 100644 index 0000000..aece3da --- /dev/null +++ b/src/config.rs @@ -0,0 +1,43 @@ +use core::panic; + +use toml::{Table, Value}; + +#[derive(Debug, Clone)] +pub struct Config { + pub build_dir: String, + pub compile_commands: bool, +} + +impl Config { + pub fn get_default() -> Self { + Config { + build_dir: String::from("build"), + compile_commands: false, + } + } + pub fn new(table: &Table) -> Self { + let mut ret = Self::get_default(); + + for k in table.keys() { + match &*k.to_owned() { + "build_dir" => { + if let Value::String(s) = table.get(k).unwrap() { + ret.build_dir = s.to_owned(); + } else { + panic!("fatal: {k} invalid type, must be a string."); + } + } + "compile_commands" => { + if let Value::Boolean(b) = table.get(k).unwrap() { + eprintln!("warn: config.compile_commands has no functionality (yet)"); + ret.compile_commands = *b; + } else { + panic!("fatal: {k} invalid type, must be a boolean."); + } + } + _ => panic!("fatal: unrecognized key {k}."), + } + } + ret + } +} diff --git a/src/main.rs b/src/main.rs index 48884fd..654566a 100644 --- a/src/main.rs +++ b/src/main.rs @@ -3,8 +3,11 @@ use core::panic; use std::fs::{read, write}; use toml::{Table, Value}; -mod target_config; -use target_config::*; +mod target; +use target::*; + +mod config; +use config::*; #[derive(Parser)] struct Args { @@ -15,8 +18,9 @@ struct Args { output_file: String, } -fn target_generator(config: &TargetConfig) -> String { +fn gen_ninja_code(config: &Target) -> String { let mut ret = String::from("\n"); + let name = &config.name; let outfile = &config.outfile; let compiler = &config.compiler; @@ -80,19 +84,28 @@ fn main() { let parsed_config = toml::from_str::(&config_file_string) .unwrap_or_else(|e| panic!("fatal: could not parse config file: {e}")); - let mut targets: Vec = Vec::new(); - targets.push(TargetConfig::new(&parsed_config, "noname", None)); + let mut config = Config::get_default(); + + let mut targets: Vec = Vec::new(); + targets.push(Target::new(&parsed_config, "main", None)); for k in parsed_config.keys() { if let Value::Table(t) = parsed_config.get(k).unwrap() { - targets.push(TargetConfig::new(&t, k, Some(&targets[0]))); + if k == "config" { + config = Config::new(&t); + } else { + targets.push(Target::new(&t, k, Some(&targets[0]))); + } } } - let mut ninjafile = String::from( + let build_dir = config.build_dir; + let _compile_commands = config.compile_commands; + + let mut ninjafile = format!( "\ # Generated by ngen. Do not modify by hand. -builddir = build +builddir = {build_dir} rule mkdir command = mkdir -p $out @@ -111,7 +124,7 @@ rule regen )); for t in targets { - ninjafile.push_str(&target_generator(&t)); + ninjafile.push_str(&gen_ninja_code(&t)); } write(output_file, ninjafile) diff --git a/src/target_config.rs b/src/target.rs similarity index 95% rename from src/target_config.rs rename to src/target.rs index 7af69cf..469350a 100644 --- a/src/target_config.rs +++ b/src/target.rs @@ -1,7 +1,7 @@ use toml::{Table, Value}; #[derive(Debug, Clone)] -pub struct TargetConfig { +pub struct Target { pub name: String, pub outfile: String, pub compiler: String, @@ -13,10 +13,10 @@ pub struct TargetConfig { pub is_default: bool, } -impl TargetConfig { +impl Target { fn get_default() -> Self { - TargetConfig { - name: String::from("noname"), + Target { + name: String::from(""), outfile: String::from("a.out"), compiler: String::from("cc"), compiler_flags: Vec::new(), @@ -27,12 +27,12 @@ impl TargetConfig { is_default: false, } } - pub fn new(table: &Table, name: &str, global_conf: Option<&Self>) -> Self { + pub fn new(table: &Table, name: &str, inherit_from: Option<&Self>) -> Self { let mut ret: Self; let mut linker_set = false; - if let Some(global) = global_conf { - ret = global.clone(); + if let Some(t) = inherit_from { + ret = t.clone(); } else { ret = Self::get_default(); }