minor refactor + config table

This commit is contained in:
Noah Swerhun 2024-03-04 23:29:12 -06:00
parent 5c7893f278
commit be088d3f14
3 changed files with 72 additions and 16 deletions

43
src/config.rs Normal file
View file

@ -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
}
}

View file

@ -3,8 +3,11 @@ use core::panic;
use std::fs::{read, write}; use std::fs::{read, write};
use toml::{Table, Value}; use toml::{Table, Value};
mod target_config; mod target;
use target_config::*; use target::*;
mod config;
use config::*;
#[derive(Parser)] #[derive(Parser)]
struct Args { struct Args {
@ -15,8 +18,9 @@ struct Args {
output_file: String, output_file: String,
} }
fn target_generator(config: &TargetConfig) -> String { fn gen_ninja_code(config: &Target) -> String {
let mut ret = String::from("\n"); let mut ret = String::from("\n");
let name = &config.name; let name = &config.name;
let outfile = &config.outfile; let outfile = &config.outfile;
let compiler = &config.compiler; let compiler = &config.compiler;
@ -80,19 +84,28 @@ fn main() {
let parsed_config = toml::from_str::<Table>(&config_file_string) let parsed_config = toml::from_str::<Table>(&config_file_string)
.unwrap_or_else(|e| panic!("fatal: could not parse config file: {e}")); .unwrap_or_else(|e| panic!("fatal: could not parse config file: {e}"));
let mut targets: Vec<TargetConfig> = Vec::new(); let mut config = Config::get_default();
targets.push(TargetConfig::new(&parsed_config, "noname", None));
let mut targets: Vec<Target> = Vec::new();
targets.push(Target::new(&parsed_config, "main", None));
for k in parsed_config.keys() { for k in parsed_config.keys() {
if let Value::Table(t) = parsed_config.get(k).unwrap() { 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. # Generated by ngen. Do not modify by hand.
builddir = build builddir = {build_dir}
rule mkdir rule mkdir
command = mkdir -p $out command = mkdir -p $out
@ -111,7 +124,7 @@ rule regen
)); ));
for t in targets { for t in targets {
ninjafile.push_str(&target_generator(&t)); ninjafile.push_str(&gen_ninja_code(&t));
} }
write(output_file, ninjafile) write(output_file, ninjafile)

View file

@ -1,7 +1,7 @@
use toml::{Table, Value}; use toml::{Table, Value};
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct TargetConfig { pub struct Target {
pub name: String, pub name: String,
pub outfile: String, pub outfile: String,
pub compiler: String, pub compiler: String,
@ -13,10 +13,10 @@ pub struct TargetConfig {
pub is_default: bool, pub is_default: bool,
} }
impl TargetConfig { impl Target {
fn get_default() -> Self { fn get_default() -> Self {
TargetConfig { Target {
name: String::from("noname"), name: String::from(""),
outfile: String::from("a.out"), outfile: String::from("a.out"),
compiler: String::from("cc"), compiler: String::from("cc"),
compiler_flags: Vec::new(), compiler_flags: Vec::new(),
@ -27,12 +27,12 @@ impl TargetConfig {
is_default: false, 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 ret: Self;
let mut linker_set = false; let mut linker_set = false;
if let Some(global) = global_conf { if let Some(t) = inherit_from {
ret = global.clone(); ret = t.clone();
} else { } else {
ret = Self::get_default(); ret = Self::get_default();
} }