summaryrefslogtreecommitdiff
path: root/fuzz/atom/parser/gencorpus.rs
blob: 299835a861cdc42bd5785128773bab8a009cb90f (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
54
55
56
57
58
59
60
61
62
63
64
use std::{
    env,
    error::Error,
    fs::{self, OpenOptions},
    io::Write,
    path::PathBuf,
};

use gentoo_utils::{
    atom::Atom,
    repo::{Repo, ebuild::Depend},
};

fn main() -> Result<(), Box<dyn Error>> {
    let corpus_dir = PathBuf::from(
        env::args()
            .nth(1)
            .expect("expected corpus directory as first argument"),
    );

    fs::create_dir_all(&corpus_dir)?;

    let repo = Repo::new("/var/db/repos/gentoo");
    let mut atoms = Vec::new();

    for category in repo.categories()? {
        for ebuild in category?.ebuilds()? {
            let depend = ebuild?.depend().to_vec();

            for expr in depend {
                walk_expr(&mut atoms, &expr);
            }
        }
    }

    for (i, atom) in atoms.iter().enumerate() {
        let path = corpus_dir.as_path().join(i.to_string());
        let mut file = OpenOptions::new()
            .write(true)
            .truncate(true)
            .create(true)
            .open(path)?;

        write!(file, "{atom}")?;
    }

    Ok(())
}

fn walk_expr(atoms: &mut Vec<Atom>, depend: &Depend<Atom>) {
    match depend {
        Depend::Element(atom) => {
            atoms.push(atom.clone());
        }
        Depend::AllOf(exprs)
        | Depend::OneOf(exprs)
        | Depend::AnyOf(exprs)
        | Depend::ConditionalGroup(_, exprs) => {
            for expr in exprs {
                walk_expr(atoms, expr);
            }
        }
    }
}