diff --git a/src/main.rs b/src/main.rs index 1b2547a..5ac3bbb 100644 --- a/src/main.rs +++ b/src/main.rs @@ -25,7 +25,192 @@ fn recurse_through_c_files(dir: &str) -> io::Result<()> { todo!() } +<<<<<<< Updated upstream Ok(()) +======= + fn contains_objdir_def(&self) -> bool { + let re = Regex::new(r"\s+OBJDIR = ").unwrap(); + re.is_match(&(self.prologue)) || re.is_match(&(self.epilogue)) + } + + fn write_new_generated_content(&self, generated_content: String) -> std::io::Result<()> { + let content = [&self.prologue, START_KEY, &generated_content, END_KEY, &self.epilogue].concat(); + + fs::write(&self.path, &content)?; + + Ok(()) + } +} + +fn join_build_rule_vec(vector: &Vec, seperator: &str) -> String{ + let mut ret = String::new(); + + for (i, rule) in vector.iter().enumerate() { + if i != 0 { + ret.push_str(seperator); + } + ret.push_str(&rule.to_string()); + } + + ret +} + +impl ToString for RuleList { + fn to_string(&self) -> String { + let targets = join_build_rule_vec(&self.get_target_rules(), ""); + let objects = join_build_rule_vec(&self.get_object_rules(), ""); + let directories = join_build_rule_vec(&self.get_directory_rules(), ""); + let conveniences = join_build_rule_vec(&self.get_convenience_rules(), ""); + + [targets, objects, directories, conveniences].concat() + } +} + +impl RuleList { + fn new() -> RuleList{ + RuleList(vec![]) + } + + fn recursively_gen_objects(&mut self, proj_dir_path: &str) -> std::io::Result<()>{ + let files = fs::read_dir(proj_dir_path)?; + for file in files { + let file = file?; + let is_dir = file.metadata()?.is_dir(); + + // ignore hidden files + if file_is_hidden(&file) { + continue; + } + + let path = file.path(); + + if is_dir { + self.recursively_gen_objects(path.to_str().unwrap())?; + } else { + match path.extension() { + Some(v) => { + let v = v.to_str().unwrap(); + if v != "c" { + continue; + } + let path = path.to_str().unwrap(); + self.0.push(BuildRuleKind::Object(BuildRule::new_from_c_file(path))); + }, + None => { + continue; + }, + } + } + } + Ok(()) + } + + fn get_obj_targets(&self) -> Vec{ + let mut ret: Vec = Vec::new(); + for rule in &self.0 { + match rule { + BuildRuleKind::Object(r) => ret.push(r.target.clone()), + _ => break, + } + } + ret + } + + fn add_target_rule(&mut self) { + let mut objects = self.get_obj_targets(); + let target_comm = String::from( + format!("$(CC) $(LDFLAGS) -o $(BUILDDIR)/$(TARGET) {} $(LDLIBS)", objects.join(" ")) + ); + + objects.push(String::from("| $(OBJDIR) $(BUILDDIR)")); + let prereqs = objects; + + self.0.push(BuildRuleKind::Target(BuildRule { + target: String::from("$(BUILDDIR)/$(TARGET)"), + prerequisites: prereqs, + recipe_commands: vec![target_comm], + })) + } + + fn add_directory_rule(&mut self, dir: &str) { + self.0.push(BuildRuleKind::Directory(BuildRule { + target: dir.to_string(), + prerequisites: vec![], + recipe_commands: vec![format!("mkdir -p {dir}").to_string()] + })); + } + + fn add_clean_rule(&mut self) { + self.0.push(BuildRuleKind::Convenience(BuildRule { + target: String::from(".PHONY: clean\nclean"), + prerequisites: vec![], + recipe_commands: vec![String::from("rm -r $(OBJDIR)"), String::from("rm -r $(BUILDDIR)")] + })); + } + + fn add_run_rule(&mut self) { + self.0.push(BuildRuleKind::Convenience(BuildRule { + target: String::from(".PHONY: run\nrun"), + prerequisites: vec![String::from("$(BUILDDIR)/$(TARGET)")], + recipe_commands: vec![String::from("./$(BUILDDIR)/$(TARGET) $(args)")] + })); + } + + fn get_target_rules(&self) -> Vec { + let mut ret: Vec = Vec::new(); + for rule in &self.0 { + match rule { + BuildRuleKind::Target(r) => ret.push(r.clone()), + _ => continue, + } + } + ret + } + + fn get_object_rules(&self) -> Vec { + let mut ret: Vec = Vec::new(); + for rule in &self.0 { + match rule { + BuildRuleKind::Object(r) => ret.push(r.clone()), + _ => continue, + } + } + ret + } + + fn get_directory_rules(&self) -> Vec { + let mut ret: Vec = Vec::new(); + for rule in &self.0 { + match rule { + BuildRuleKind::Directory(r) => ret.push(r.clone()), + _ => continue, + } + } + ret + } + + fn get_convenience_rules(&self) -> Vec { + let mut ret: Vec = Vec::new(); + for rule in &self.0 { + match rule { + BuildRuleKind::Convenience(r) => ret.push(r.clone()), + _ => continue, + } + } + ret + } +} + +fn file_is_hidden(file: &DirEntry) -> bool{ + let file_name = file.file_name(); + let str_name = file_name.to_str().unwrap(); + let first_char = str_name.chars().nth(0).unwrap(); + if first_char == '.' { + true + } else { + false + } +>>>>>>> Stashed changes } fn main() {