aboutsummaryrefslogtreecommitdiff
path: root/src/makefile/eval_context.rs
blob: 87edafd7a952efbfb51e564809c92fc835a0a5ec (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
use eyre::{Result, WrapErr};
use std::io::{BufRead, Cursor};
use std::rc::Rc;

use super::{FinishedMakefileReader, MacroSet, MakefileReader};

pub struct DeferredEvalContext<'parent, 'args, 'grandparent, R: BufRead> {
    parent: &'parent MakefileReader<'args, 'grandparent, R>,
    children: Vec<FinishedMakefileReader>,
}

impl<'parent, 'args, 'grandparent, R: BufRead>
    DeferredEvalContext<'parent, 'args, 'grandparent, R>
{
    pub const fn new(parent: &'parent MakefileReader<'args, 'grandparent, R>) -> Self {
        Self {
            parent,
            children: Vec::new(),
        }
    }

    pub fn push(&mut self, child: FinishedMakefileReader) {
        self.children.push(child);
    }

    pub fn eval(&mut self, to_eval: String) -> Result<()> {
        let child_stack = self.parent.stack.with_scope(&self.parent.macros);
        let child_macros = MacroSet::new();
        let child = MakefileReader::read(
            self.parent.args,
            child_stack,
            child_macros,
            Cursor::new(to_eval),
            "<eval>",
            Rc::clone(&self.parent.file_names),
        )
        .context("while evaling")?
        .finish();
        self.push(child);
        Ok(())
    }
}

impl<'parent, 'args, 'grandparent, R: BufRead> IntoIterator
    for DeferredEvalContext<'parent, 'args, 'grandparent, R>
{
    type Item = FinishedMakefileReader;
    type IntoIter = std::vec::IntoIter<Self::Item>;

    fn into_iter(self) -> Self::IntoIter {
        self.children.into_iter()
    }
}