diff options
Diffstat (limited to 'src/makefile/target.rs')
| -rw-r--r-- | src/makefile/target.rs | 81 | 
1 files changed, 79 insertions, 2 deletions
diff --git a/src/makefile/target.rs b/src/makefile/target.rs index 506bde8..5de280d 100644 --- a/src/makefile/target.rs +++ b/src/makefile/target.rs @@ -1,6 +1,8 @@ -use std::cell::Cell; +use std::cell::{Cell, RefCell}; +use std::collections::HashMap;  use std::fmt;  use std::fs::metadata; +use std::rc::Rc;  use std::time::SystemTime;  use eyre::{Result, WrapErr}; @@ -19,6 +21,17 @@ pub struct Target {  }  impl Target { +    pub fn extend(&mut self, other: Target) { +        assert_eq!(&self.name, &other.name); +        self.prerequisites.extend(other.prerequisites); +        assert!(self.commands.is_empty() || other.commands.is_empty()); +        self.commands.extend(other.commands); +        assert!(self.stem.is_none() || other.stem.is_none()); +        self.stem = self.stem.take().or(other.stem); +        let already_updated = self.already_updated.get() || other.already_updated.get(); +        self.already_updated.set(already_updated); +    } +      fn modified_time(&self) -> Option<SystemTime> {          metadata(&self.name)              .and_then(|metadata| metadata.modified()) @@ -55,7 +68,7 @@ impl Target {                  .unwrap_or(false)          });          log::trace!( -            "{:>50} exists: {}, newer than dependencies: {}", +            "{:} exists: {}, newer than dependencies: {}",              self.name,              exists,              newer_than_all_dependencies @@ -64,6 +77,7 @@ impl Target {      }      pub fn update(&self, file: &Makefile) -> Result<()> { +        log::info!("{}: {:?}", &self.name, &self.prerequisites);          for prereq in &self.prerequisites {              file.update_target(prereq)                  .wrap_err_with(|| format!("as a dependency for target {}", self.name))?; @@ -101,3 +115,66 @@ impl fmt::Display for Target {          Ok(())      }  } + +// for targets that won't change out from under us (don't need refcelling) +#[derive(Clone, Default)] +pub struct StaticTargetSet { +    data: HashMap<String, Target>, +} + +impl StaticTargetSet { +    pub fn get(&self, name: &str) -> Option<&Target> { +        self.data.get(name) +    } + +    pub fn put(&mut self, target: Target) { +        if target.name == ".SUFFIXES" && target.prerequisites.is_empty() { +            self.data.remove(&target.name); +        } +        if let Some(existing_target) = self.data.get_mut(&target.name) { +            existing_target.extend(target); +        } else { +            self.data.insert(target.name.clone(), target); +        } +    } +} + +impl Into<HashMap<String, Target>> for StaticTargetSet { +    fn into(self) -> HashMap<String, Target> { +        self.data +    } +} + +// for targets that might become updated and so need refcelling +#[derive(Clone, Default)] +pub struct DynamicTargetSet { +    data: HashMap<String, Rc<RefCell<Target>>>, +} + +impl DynamicTargetSet { +    pub fn get(&self, name: &str) -> Option<Rc<RefCell<Target>>> { +        self.data.get(name).map(|x| Rc::clone(x)) +    } + +    pub fn put(&mut self, target: Target) { +        if let Some(existing_target) = self.data.get_mut(&target.name) { +            existing_target.borrow_mut().extend(target); +        } else { +            self.data +                .insert(target.name.clone(), Rc::new(RefCell::new(target))); +        } +    } + +    pub fn has(&self, name: &str) -> bool { +        self.data.contains_key(name) +    } +} + +impl fmt::Display for DynamicTargetSet { +    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { +        for target in self.data.values() { +            writeln!(f, "{}", target.borrow())?; +        } +        Ok(()) +    } +}  |