-
-
Save thomcc/6e2589c8304858dae9d4f32f953dace4 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
macro_rules! target_cfg { | |
($key:ident = $value:expr) => {{ | |
const _: () = if !$crate::cfg::__internal::validate_cfg(stringify!($key)) { | |
panic!(concat!( | |
"bug: invalid use of `target_cfg!(", | |
stringify!($key), | |
" = ", | |
stringify!($value), | |
")`", | |
)); | |
}; | |
$crate::cfg::__internal::cfg_test(stringify!($key), Some($value)) | |
}}; | |
($key:ident) => {{ | |
const _: () = if !$crate::cfg::__internal::validate_cfg(stringify!($key)) { | |
panic!(concat!( | |
"bug: invalid use of `target_cfg!(", | |
stringify!($key), | |
")`" | |
)); | |
}; | |
$crate::cfg::__internal::cfg_test(stringify!($key), None) | |
}}; | |
} | |
#[doc(hidden)] | |
pub(crate) mod __internal { | |
#[track_caller] | |
pub(crate) fn cfg_test(cfg: &str, query: Option<&str>) -> bool { | |
assert!( | |
validate_cfg(cfg), | |
"should have already checked {:?}?", | |
(cfg, query), | |
); | |
let var_name = format!("CARGO_CFG_{}", cfg.to_ascii_uppercase()); | |
let var_value = std::env::var(&var_name); | |
eprintln!( | |
"cfg test [from {:?}]: `{}={:?}`", | |
core::panic::Location::caller(), | |
var_name, | |
var_value, | |
); | |
match (query, var_value.ok().as_deref()) { | |
(None, Some(_)) => true, | |
// (None, Some(s)) => true, | |
(Some(""),) => false, | |
(Some(want), Some(have)) => want == have || have.split(",").any(|v| v == want), | |
} | |
} | |
pub(crate) const fn validate_cfg(s: &str) -> bool { | |
let s = s.as_bytes(); | |
match s { | |
b"" => return false, | |
b"unix" => return true, | |
b"windows" => return true, | |
[b't', b'a', b'r', b'g', b'e', b't', b'_', rest @ ..] => valid_ident_bytes(rest), | |
_ => return false, | |
} | |
} | |
// tests something like `/^[_a-zA-Z][_a-zA-Z0-9]*$/`. | |
const fn valid_ident_bytes(s: &[u8]) -> bool { | |
if s.is_empty() || s[0].is_ascii_digit() { | |
return false; | |
} | |
let mut i = 0; | |
while i != s.len() { | |
let c = s[i]; | |
let valid = c == b'_' || c.is_ascii_alphanumeric(); | |
if !valid { | |
return false; | |
} | |
i += 1; | |
} | |
true | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment