ppTests Allow define __FILE__ and define __LINE__ to parse.

- Redefinitions are silently ignored.
- ifdef/ifndef will always treat them as defined.
- Enables compatibility with code from a silicon vendor I can think of.
- NOTE: Whitespace bugs around endif/undef are observable in testcases.
This commit is contained in:
damc 2022-07-25 22:21:28 +02:00
parent f85809f55a
commit 963e17a5ea
2 changed files with 53 additions and 42 deletions

View File

@ -1446,8 +1446,6 @@ pub(crate) const KEYWORDS_1800_2017: &[&str] = &[
]; ];
pub(crate) const KEYWORDS_DIRECTIVE: &[&str] = &[ pub(crate) const KEYWORDS_DIRECTIVE: &[&str] = &[
"__FILE__",
"__LINE__",
"begin_keywords", "begin_keywords",
"celldefine", "celldefine",
"default_nettype", "default_nettype",

View File

@ -399,7 +399,7 @@ pub fn preprocess_str<T: AsRef<Path>, U: AsRef<Path>, V: BuildHasher>(
let ifid = identifier(ifid.into(), &s).unwrap(); let ifid = identifier(ifid.into(), &s).unwrap();
let mut hit = false; let mut hit = false;
if defines.contains_key(&ifid) { if defines.contains_key(&ifid) || is_predefined_text_macro(&ifid) {
hit = true; hit = true;
} else { } else {
skip_nodes.push(ifbody.into()); skip_nodes.push(ifbody.into());
@ -413,7 +413,7 @@ pub fn preprocess_str<T: AsRef<Path>, U: AsRef<Path>, V: BuildHasher>(
let elsifid = identifier(elsifid.into(), &s).unwrap(); let elsifid = identifier(elsifid.into(), &s).unwrap();
if hit { if hit {
skip_nodes.push(elsifbody.into()); skip_nodes.push(elsifbody.into());
} else if defines.contains_key(&elsifid) { } else if defines.contains_key(&elsifid) || is_predefined_text_macro(&ifid) {
hit = true; hit = true;
} else { } else {
skip_nodes.push(elsifbody.into()); skip_nodes.push(elsifbody.into());
@ -447,7 +447,7 @@ pub fn preprocess_str<T: AsRef<Path>, U: AsRef<Path>, V: BuildHasher>(
let ifid = identifier(ifid.into(), &s).unwrap(); let ifid = identifier(ifid.into(), &s).unwrap();
let mut hit = false; let mut hit = false;
if !defines.contains_key(&ifid) { if !defines.contains_key(&ifid) && !is_predefined_text_macro(&ifid) {
hit = true; hit = true;
} else { } else {
skip_nodes.push(ifbody.into()); skip_nodes.push(ifbody.into());
@ -461,7 +461,7 @@ pub fn preprocess_str<T: AsRef<Path>, U: AsRef<Path>, V: BuildHasher>(
let elsifid = identifier(elsifid.into(), &s).unwrap(); let elsifid = identifier(elsifid.into(), &s).unwrap();
if hit { if hit {
skip_nodes.push(elsifbody.into()); skip_nodes.push(elsifbody.into());
} else if defines.contains_key(&elsifid) { } else if defines.contains_key(&elsifid) || is_predefined_text_macro(&ifid) {
hit = true; hit = true;
} else { } else {
skip_nodes.push(elsifbody.into()); skip_nodes.push(elsifbody.into());
@ -484,6 +484,7 @@ pub fn preprocess_str<T: AsRef<Path>, U: AsRef<Path>, V: BuildHasher>(
let (ref name, ref args) = proto.nodes; let (ref name, ref args) = proto.nodes;
let id = identifier(name.into(), &s).unwrap(); let id = identifier(name.into(), &s).unwrap();
if !is_predefined_text_macro(id.as_str()) {
let mut define_args = Vec::new(); let mut define_args = Vec::new();
if let Some(args) = args { if let Some(args) = args {
let (_, ref args, _) = args.nodes; let (_, ref args, _) = args.nodes;
@ -524,6 +525,7 @@ pub fn preprocess_str<T: AsRef<Path>, U: AsRef<Path>, V: BuildHasher>(
}; };
defines.insert(id, Some(define)); defines.insert(id, Some(define));
}
// Keep TextMacroDefinition after preprocess // Keep TextMacroDefinition after preprocess
let locate: Locate = x.try_into().unwrap(); let locate: Locate = x.try_into().unwrap();
@ -708,6 +710,17 @@ fn get_str(node: RefNode, s: &str) -> String {
ret ret
} }
fn is_predefined_text_macro(s: &str) -> bool {
match s {
"__LINE__" | "__FILE__" => {
true
}
_ => {
false
}
}
}
fn split_text(s: &str) -> Vec<String> { fn split_text(s: &str) -> Vec<String> {
let mut is_string = false; let mut is_string = false;
let mut is_ident = false; let mut is_ident = false;