rust-analyzer format

This commit is contained in:
Noah Swerhun 2023-12-20 15:22:45 -06:00
parent 0c73dd3f56
commit 3eafbff7f9
4 changed files with 115 additions and 63 deletions

View file

@ -1,4 +1,4 @@
use std::{path::PathBuf, fs};
use std::{fs, path::PathBuf};
use path_clean::PathClean;
use regex::Regex;
@ -15,7 +15,7 @@ pub enum BuildRuleKind<T> {
Convenience(T),
}
#[derive(Debug,Clone)]
#[derive(Debug, Clone)]
pub struct BuildRule {
pub target: String,
pub prerequisites: Vec<String>,
@ -40,7 +40,7 @@ impl BuildRule {
true => {
headers.push(String::from(path.to_str().unwrap()));
continue;
},
}
false => (),
}
@ -51,7 +51,7 @@ impl BuildRule {
true => {
headers.push(String::from(path.to_str().unwrap()));
continue 'fileloop;
},
}
false => (),
}
}
@ -63,7 +63,6 @@ impl BuildRule {
headers
}
pub fn new_from_c_file(path: &str, makefile: &Makefile) -> BuildRule {
let mut prerequisites: Vec<String> = Vec::new();
prerequisites.push((PathBuf::from(path)).clean().to_str().unwrap().to_string());
@ -82,7 +81,11 @@ impl BuildRule {
let compile_command = format!("$(CC) $(CFLAGS) $(INCS) -o {} -c {}", obj_path, path);
BuildRule { target: String::from(obj_path), prerequisites, recipe_commands: vec![compile_command] }
BuildRule {
target: String::from(obj_path),
prerequisites,
recipe_commands: vec![compile_command],
}
}
}

View file

@ -1,5 +1,5 @@
use std::process::exit;
use clap::Parser;
use std::process::exit;
mod build_rule;
mod makefile;
@ -52,9 +52,11 @@ fn main() {
let makefile = Makefile::new_from_path(&makefile_name);
let mut rule_list = RuleList::new();
rule_list.recursively_gen_objects(".", &makefile).unwrap_or_else(|e| {
panic!("error: problem in recursive search: {e}");
});
rule_list
.recursively_gen_objects(".", &makefile)
.unwrap_or_else(|e| {
panic!("error: problem in recursive search: {e}");
});
if rule_list.0.is_empty() {
eprintln!("no source files found, nothing to do. exiting...");
@ -65,12 +67,12 @@ fn main() {
// Only include directory defaults if the user has not specified them
let mut dirdefwritten = false;
if ! makefile.contains_builddir_def() {
if !makefile.contains_builddir_def() {
generated_content.push_str("BUILDDIR = build\n");
dirdefwritten = true;
}
if ! makefile.contains_objdir_def() {
if !makefile.contains_objdir_def() {
generated_content.push_str("OBJDIR = $(BUILDDIR)/obj\n");
dirdefwritten = true;
}
@ -81,8 +83,10 @@ fn main() {
ARGS.with(|args| {
if args.dynamic_library {
generated_content.push_str("# dynamic library\nCFLAGS += -fPIC\nLDFLAGS += -shared\n\n");
} else {}
generated_content
.push_str("# dynamic library\nCFLAGS += -fPIC\nLDFLAGS += -shared\n\n");
} else {
}
});
rule_list.add_target_rule();
@ -101,7 +105,9 @@ fn main() {
generated_content.push_str(&rule_list.to_string());
// Write makefile
makefile.write_new_generated_content(generated_content).unwrap_or_else(|e| {
panic!("error: could not write makefile at {}: {e}", makefile.path);
});
makefile
.write_new_generated_content(generated_content)
.unwrap_or_else(|e| {
panic!("error: could not write makefile at {}: {e}", makefile.path);
});
}

View file

@ -1,5 +1,5 @@
use std::{fs, io::ErrorKind};
use regex::Regex;
use std::{fs, io::ErrorKind};
const START_KEY: &str = "#=mgen_start=#\n";
const END_KEY: &str = "\n#=mgen_end=#";
@ -21,26 +21,35 @@ impl Makefile {
Err(e) => match e.kind() {
// doesn't matter if the file doesn't exist, it will be created
// later.
ErrorKind::NotFound => return Makefile {
path: String::from(path), prologue: String::from(""),
mgen_zone: String::from(""), epilogue: String::from(""),
include_dirs: vec![String::from("")] },
_ => panic!("error: cannot read makefile: {e}")
}
ErrorKind::NotFound => {
return Makefile {
path: String::from(path),
prologue: String::from(""),
mgen_zone: String::from(""),
epilogue: String::from(""),
include_dirs: vec![String::from("")],
}
}
_ => panic!("error: cannot read makefile: {e}"),
},
};
let contains_start = contents.find(START_KEY).is_some();
let contains_end = contents.find(END_KEY).is_some();
if (contains_start && !contains_end) || (!contains_start &&
contains_end) {
if (contains_start && !contains_end) || (!contains_start && contains_end) {
panic!("error: makefile contains one mgen guard but not the other. cannot continue.");
}
if !(contains_start && contains_end) {
let include_dirs = Makefile::get_include_dirs(&contents);
return Makefile { path: String::from(path), prologue: contents,
mgen_zone: String::from(""), epilogue: String::from(""), include_dirs };
return Makefile {
path: String::from(path),
prologue: contents,
mgen_zone: String::from(""),
epilogue: String::from(""),
include_dirs,
};
}
// contains the part before the start key and everything after
@ -55,7 +64,7 @@ impl Makefile {
prologue: String::from(pre_and_after[0]),
mgen_zone: String::from(gen_and_post[0]),
epilogue: String::from(gen_and_post[1]),
include_dirs
include_dirs,
}
}
@ -66,20 +75,15 @@ impl Makefile {
let caps = makefile_regex.captures_iter(search);
let dirlist = match caps.map(|c| c.extract()).last() {
Some((_, [v])) => v,
None => {
return include_dirs
}
,
None => return include_dirs,
};
let incdir_regex = Regex::new(r"\s*-I\s*(.*?)(?:[\s]|$)").unwrap();
let caps = incdir_regex.captures_iter(&dirlist);
for (_, [dir]) in caps.map(|c| c.extract()) {
include_dirs.push(String::from(dir));
}
include_dirs
}
@ -94,7 +98,14 @@ impl Makefile {
}
pub 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();
let content = [
&self.prologue,
START_KEY,
&generated_content,
END_KEY,
&self.epilogue,
]
.concat();
fs::write(&self.path, &content)?;

View file

@ -9,11 +9,15 @@ use crate::ARGS;
pub struct RuleList(pub Vec<BuildRuleKind<BuildRule>>);
impl RuleList {
pub fn new() -> RuleList{
pub fn new() -> RuleList {
RuleList(vec![])
}
pub fn recursively_gen_objects(&mut self, proj_dir_path: &str, makefile: &Makefile) -> std::io::Result<()>{
pub fn recursively_gen_objects(
&mut self,
proj_dir_path: &str,
makefile: &Makefile,
) -> std::io::Result<()> {
let files = fs::read_dir(proj_dir_path)?;
for file in files {
let file = file?;
@ -36,18 +40,21 @@ impl RuleList {
continue;
}
let path = path.to_str().unwrap();
self.0.push(BuildRuleKind::Object(BuildRule::new_from_c_file(path, makefile)));
},
self.0
.push(BuildRuleKind::Object(BuildRule::new_from_c_file(
path, makefile,
)));
}
None => {
continue;
},
}
}
}
}
Ok(())
}
pub fn get_obj_targets(&self) -> Vec<String>{
pub fn get_obj_targets(&self) -> Vec<String> {
let mut ret: Vec<String> = Vec::new();
for rule in &self.0 {
match rule {
@ -63,13 +70,15 @@ impl RuleList {
let mut target_comm = String::new();
ARGS.with(|args| {
if args.static_library {
target_comm = String::from(
format!("$(AR) $(ARFLAGS) $(BUILDDIR)/$(TARGET) {}", objects.join(" "))
);
target_comm = String::from(format!(
"$(AR) $(ARFLAGS) $(BUILDDIR)/$(TARGET) {}",
objects.join(" ")
));
} else {
target_comm = String::from(
format!("$(CC) $(LDFLAGS) $(INCS) -o $(BUILDDIR)/$(TARGET) {} $(LDLIBS)", objects.join(" "))
);
target_comm = String::from(format!(
"$(CC) $(LDFLAGS) $(INCS) -o $(BUILDDIR)/$(TARGET) {} $(LDLIBS)",
objects.join(" ")
));
}
});
@ -87,7 +96,7 @@ impl RuleList {
self.0.push(BuildRuleKind::Directory(BuildRule {
target: dir.to_string(),
prerequisites: vec![],
recipe_commands: vec![format!("mkdir -p {dir}").to_string()]
recipe_commands: vec![format!("mkdir -p {dir}").to_string()],
}));
}
@ -95,7 +104,10 @@ impl RuleList {
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)")]
recipe_commands: vec![
String::from("rm -r $(OBJDIR)"),
String::from("rm -r $(BUILDDIR)"),
],
}));
}
@ -103,7 +115,7 @@ impl RuleList {
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)")]
recipe_commands: vec![String::from("./$(BUILDDIR)/$(TARGET)")],
}));
}
@ -152,7 +164,7 @@ impl RuleList {
}
}
fn file_is_hidden(file: &DirEntry) -> bool{
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();
@ -165,10 +177,30 @@ fn file_is_hidden(file: &DirEntry) -> bool{
impl ToString for RuleList {
fn to_string(&self) -> String {
let targets = &self.get_target_rules().iter().map(|v| v.to_string()).collect::<Vec<_>>().join("\n");
let objects = &self.get_object_rules().iter().map(|v| v.to_string()).collect::<Vec<_>>().join("\n");
let directories = &self.get_directory_rules().iter().map(|v| v.to_string()).collect::<Vec<_>>().join("\n");
let conveniences = &self.get_convenience_rules().iter().map(|v| v.to_string()).collect::<Vec<_>>().join("\n");
let targets = &self
.get_target_rules()
.iter()
.map(|v| v.to_string())
.collect::<Vec<_>>()
.join("\n");
let objects = &self
.get_object_rules()
.iter()
.map(|v| v.to_string())
.collect::<Vec<_>>()
.join("\n");
let directories = &self
.get_directory_rules()
.iter()
.map(|v| v.to_string())
.collect::<Vec<_>>()
.join("\n");
let conveniences = &self
.get_convenience_rules()
.iter()
.map(|v| v.to_string())
.collect::<Vec<_>>()
.join("\n");
let all = [targets, objects, directories, conveniences];
let mut nonzero: Vec<String> = Vec::new();