update
This commit is contained in:
parent
90e9d4cb3b
commit
4a73dc87f7
@ -1023,6 +1023,127 @@ fn resolve_text_macro_usage<T: AsRef<Path>, U: AsRef<Path>>(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn resolve_text_macro_usage_retain_error<T: AsRef<Path>, U: AsRef<Path>>(
|
||||||
|
x: &TextMacroUsage,
|
||||||
|
s: &str,
|
||||||
|
path: T,
|
||||||
|
defines: &Defines,
|
||||||
|
include_paths: &[U],
|
||||||
|
strip_comments: bool,
|
||||||
|
resolve_depth: usize,
|
||||||
|
) -> Result<Option<(String, Option<(PathBuf, Range)>, Defines)>, Error> {
|
||||||
|
let (_, ref name, ref args) = x.nodes;
|
||||||
|
let id = identifier((&name.nodes.0).into(), &s).unwrap();
|
||||||
|
|
||||||
|
if resolve_depth > RECURSIVE_LIMIT {
|
||||||
|
return Err(Error::ExceedRecursiveLimit);
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut args_str = String::from("");
|
||||||
|
let mut actual_args = Vec::new();
|
||||||
|
let no_args = args.is_none();
|
||||||
|
if let Some(args) = args {
|
||||||
|
args_str.push_str(&get_str((&args.nodes.0).into(), s));
|
||||||
|
args_str.push_str(&get_str((&args.nodes.1).into(), s));
|
||||||
|
args_str.push_str(&get_str((&args.nodes.2).into(), s));
|
||||||
|
|
||||||
|
let (_, ref args, _) = args.nodes;
|
||||||
|
let (ref args,) = args.nodes;
|
||||||
|
for arg in args.contents() {
|
||||||
|
if let Some(arg) = arg {
|
||||||
|
let (ref arg,) = arg.nodes;
|
||||||
|
let arg = arg.str(&s).trim_end();
|
||||||
|
actual_args.push(Some(arg));
|
||||||
|
} else {
|
||||||
|
actual_args.push(None);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let define = defines.get(&id);
|
||||||
|
if let Some(Some(define)) = define {
|
||||||
|
let mut arg_map = HashMap::new();
|
||||||
|
|
||||||
|
if !define.arguments.is_empty() && no_args {
|
||||||
|
return Err(Error::DefineNoArgs(define.identifier.clone()));
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i, (arg, default)) in define.arguments.iter().enumerate() {
|
||||||
|
let value = match actual_args.get(i) {
|
||||||
|
Some(Some(actual_arg)) => *actual_arg,
|
||||||
|
Some(None) => {
|
||||||
|
if let Some(default) = default {
|
||||||
|
default
|
||||||
|
} else {
|
||||||
|
""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
None => {
|
||||||
|
if let Some(default) = default {
|
||||||
|
default
|
||||||
|
} else {
|
||||||
|
return Err(Error::DefineArgNotFound(String::from(arg)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
arg_map.insert(String::from(arg), value);
|
||||||
|
}
|
||||||
|
|
||||||
|
// restore () for textmacro without arguments
|
||||||
|
let paren = if define.arguments.is_empty() {
|
||||||
|
Some(args_str)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
};
|
||||||
|
|
||||||
|
if let Some(ref text) = define.text {
|
||||||
|
let mut replaced = String::from("");
|
||||||
|
for text in split_text(&text.text) {
|
||||||
|
if let Some(value) = arg_map.get(&text) {
|
||||||
|
replaced.push_str(*value);
|
||||||
|
} else {
|
||||||
|
replaced.push_str(
|
||||||
|
&text
|
||||||
|
.replace("``", "") // Argument substitution.
|
||||||
|
.replace("`\\`\"", "\\\"") // Escaped backslash.
|
||||||
|
.replace("`\"", "\"") // Escaped quote.
|
||||||
|
.replace("\\\n", "\n") // Line continuation (Unix).
|
||||||
|
.replace("\\\r\n", "\r\n") // Line continuation (Windows).
|
||||||
|
.replace("\\\r", "\r"), // Line continuation (old Mac).
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(paren) = paren {
|
||||||
|
replaced.push_str(&paren);
|
||||||
|
}
|
||||||
|
|
||||||
|
let (replaced, new_defines) = preprocess_str(
|
||||||
|
&replaced,
|
||||||
|
path.as_ref(),
|
||||||
|
&defines,
|
||||||
|
include_paths,
|
||||||
|
false,
|
||||||
|
strip_comments,
|
||||||
|
resolve_depth,
|
||||||
|
0, // include_depth
|
||||||
|
)?;
|
||||||
|
Ok(Some((
|
||||||
|
String::from(replaced.text()),
|
||||||
|
text.origin.clone(),
|
||||||
|
new_defines,
|
||||||
|
)))
|
||||||
|
} else {
|
||||||
|
Ok(None)
|
||||||
|
}
|
||||||
|
} else if define.is_some() {
|
||||||
|
Ok(None)
|
||||||
|
} else {
|
||||||
|
Err(Error::DefineNotFound(id))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
@ -12,6 +12,7 @@ pub use sv_parser_pp::preprocess::{
|
|||||||
preprocess, preprocess_str, Define, DefineText, Defines, PreprocessedText,
|
preprocess, preprocess_str, Define, DefineText, Defines, PreprocessedText,
|
||||||
};
|
};
|
||||||
pub use sv_parser_syntaxtree::*;
|
pub use sv_parser_syntaxtree::*;
|
||||||
|
pub use sv_parser_pp::range as sv_parser_pp_range;
|
||||||
|
|
||||||
pub struct SyntaxTree {
|
pub struct SyntaxTree {
|
||||||
node: AnyNode,
|
node: AnyNode,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user