Skip to content

Commit 5896bea

Browse files
committed
Add --print=check-cfg parsing
1 parent 77f537a commit 5896bea

File tree

2 files changed

+76
-1
lines changed

2 files changed

+76
-1
lines changed

src/cargo/core/compiler/build_context/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ use std::collections::{HashMap, HashSet};
1313

1414
mod target_info;
1515
pub use self::target_info::{
16-
FileFlavor, FileType, RustDocFingerprint, RustcTargetData, TargetInfo,
16+
CheckCfg, ExpectedValues, FileFlavor, FileType, RustDocFingerprint, RustcTargetData, TargetInfo,
1717
};
1818

1919
/// The build context, containing complete information needed for a build task

src/cargo/core/compiler/build_context/target_info.rs

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ use cargo_util::{paths, ProcessBuilder};
1919
use serde::{Deserialize, Serialize};
2020
use std::cell::RefCell;
2121
use std::collections::hash_map::{Entry, HashMap};
22+
use std::collections::HashSet;
2223
use std::path::{Path, PathBuf};
2324
use std::rc::Rc;
2425
use std::str::{self, FromStr};
@@ -56,6 +57,80 @@ pub struct TargetInfo {
5657
pub rustdocflags: Rc<[String]>,
5758
}
5859

60+
/// Check Config (aka `--print=check-cfg` representation)
61+
#[derive(Debug, Default, Clone)]
62+
pub struct CheckCfg {
63+
/// Is --check-cfg activated
64+
pub exhaustive: bool,
65+
/// List of expected cfgs
66+
pub expecteds: HashMap<String, ExpectedValues<String>>,
67+
}
68+
69+
/// List of expected check-cfg values
70+
#[derive(Debug, Clone)]
71+
pub enum ExpectedValues<T> {
72+
/// List of expected values
73+
Some(HashSet<Option<T>>),
74+
/// All values expected
75+
Any,
76+
}
77+
78+
impl CheckCfg {
79+
fn process_line(&mut self, line: &str) {
80+
if line == "any()=any()" || line == "any()" {
81+
self.exhaustive = false;
82+
} else {
83+
if let Some((name, val)) = line.split_once('=') {
84+
let name = name.to_string();
85+
86+
// strip "" around the value, e.g. "linux" -> linux
87+
let val = val
88+
.strip_prefix('"')
89+
.map(|v| v.strip_suffix('"'))
90+
.flatten()
91+
.unwrap_or(val);
92+
93+
self.expecteds
94+
.entry(name)
95+
.and_modify(|v| match v {
96+
ExpectedValues::Some(_) if val.is_empty() => {}
97+
ExpectedValues::Some(_) if val == "any()" => {
98+
*v = ExpectedValues::Any;
99+
}
100+
ExpectedValues::Some(v) => {
101+
v.insert(Some(val.to_string()));
102+
}
103+
ExpectedValues::Any => {}
104+
})
105+
.or_insert_with(|| {
106+
if val.is_empty() {
107+
// no value to add
108+
ExpectedValues::Some(Default::default())
109+
} else if val == "any()" {
110+
ExpectedValues::Any
111+
} else {
112+
let values = HashSet::from([Some(val.to_string())]);
113+
ExpectedValues::Some(values)
114+
}
115+
});
116+
} else {
117+
let cfg = line.to_string();
118+
119+
self.expecteds
120+
.entry(cfg)
121+
.and_modify(|v| match v {
122+
ExpectedValues::Some(v) => v.extend(None),
123+
ExpectedValues::Any => {}
124+
})
125+
.or_insert_with(|| {
126+
let values = HashSet::from([None]);
127+
ExpectedValues::Some(values)
128+
});
129+
}
130+
}
131+
}
132+
}
133+
59134
/// Kind of each file generated by a Unit, part of `FileType`.
60135
#[derive(Clone, PartialEq, Eq, Debug)]
61136
pub enum FileFlavor {

0 commit comments

Comments
 (0)