diff --git a/Cargo.lock b/Cargo.lock index 6abfa15..1074f82 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -97,6 +97,7 @@ dependencies = [ "getrandom", "log", "object", + "regex", "rstest", ] diff --git a/Cargo.toml b/Cargo.toml index 0b8221a..e038300 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -16,6 +16,7 @@ evalexpr = "12" getrandom = "0.2" log = "0.4" object = { version = "0.35", default-features = false, features = ["read_core", "elf", "std"] } +regex = "1.11" [dev-dependencies] assert_cmd = "2.0" diff --git a/src/main.rs b/src/main.rs index 39d3407..f19f15b 100644 --- a/src/main.rs +++ b/src/main.rs @@ -13,6 +13,8 @@ use std::{ use object::{elf, Object as _, ObjectSection, SectionFlags}; +use regex::Regex; + type Result = std::result::Result>; const EXIT_CODE_FAILURE: i32 = 1; @@ -299,6 +301,20 @@ fn get_includes_from_linker_script(linker_script: &str) -> Vec<&str> { /// Looks for "RAM : ORIGIN = $origin, LENGTH = $length" // FIXME this is a dumb line-by-line parser fn find_ram_in_linker_script(linker_script: &str) -> Option { + let linker_script = { + // Remove any multiline-style comments (/*...*/) in the linker script before processing. + // Comments within one line get replaced by an empty string. + // Comments that span multiple lines get replaced by newlines, in order to keep the final entry + // line index correct, within the original linker script. + let re = Regex::new(r"(?s)/\*.*?\*/").unwrap(); + let mut stripped_linker_script = linker_script.to_string(); + for m in re.find_iter(linker_script) { + stripped_linker_script = stripped_linker_script + .replace(m.as_str(), &"\n".repeat(m.as_str().lines().count() - 1)); + } + stripped_linker_script + }; + for (index, mut line) in linker_script.lines().enumerate() { line = line.trim(); line = eat!(line, "RAM"); @@ -416,7 +432,7 @@ mod tests { } #[test] - fn ingore_comment() { + fn ignore_comment() { _ = env_logger::try_init(); const LINKER_SCRIPT: &str = "MEMORY { @@ -441,6 +457,35 @@ mod tests { ); } + #[test] + fn ignore_multiline_comment() { + _ = env_logger::try_init(); + const LINKER_SCRIPT: &str = "MEMORY + { + /* This is a single line comment /* + FLASH : ORIGIN = 0x00000000, LENGTH = 256K + /* This is a multiline comment + RAM : ORIGIN = 0x20000000, LENGTH = 64K */ + RAM : ORIGIN = 0x20000000, /* This is a bit much... */ LENGTH = 64K + } + + INCLUDE device.x"; + + assert_eq!( + find_ram_in_linker_script(LINKER_SCRIPT), + Some(MemoryEntry { + line: 6, + origin: 0x20000000, + length: 64 * 1024, + }) + ); + + assert_eq!( + get_includes_from_linker_script(LINKER_SCRIPT), + vec!["device.x"] + ); + } + #[test] fn test_perform_addition_hex_and_number() { _ = env_logger::try_init();