Skip to content

Commit

Permalink
Add the option to remove items
Browse files Browse the repository at this point in the history
It deletes any CHARACTERISTIC, MEASUREMENT or INSTANCE that matches the given regex.
  • Loading branch information
DanielT committed Sep 3, 2024
1 parent 23cfd22 commit ea0fdf1
Show file tree
Hide file tree
Showing 2 changed files with 126 additions and 0 deletions.
28 changes: 28 additions & 0 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ mod datatype;
mod dwarf;
mod ifdata;
mod insert;
mod remove;
mod symbol;
mod update;
mod version;
Expand Down Expand Up @@ -260,6 +261,25 @@ fn core() -> Result<(), String> {
cond_print!(verbose, now, "Include directives have been merged\n");
}

// remove items if --remove was given
if arg_matches.contains_id("REMOVE_REGEX") {
let regexes: Vec<&str> = match arg_matches.get_many::<String>("REMOVE_REGEX") {
Some(values) => values.map(|x| &**x).collect(),
None => Vec::new(),
};

let mut log_msgs: Vec<String> = Vec::new();
let removed_count = remove::remove_items(&mut a2l_file, &regexes, &mut log_msgs);
for msg in log_msgs {
cond_print!(verbose, now, msg);
}
cond_print!(
verbose,
now,
format!("Removed {} items", removed_count)
);
}

if let Some(debugdata) = &elf_info {
// update addresses
if update || update_preserve {
Expand Down Expand Up @@ -768,6 +788,14 @@ fn get_args() -> ArgMatches {
.requires("INSERT_ARGGROUP")
.value_name("GROUP")
)
.arg(Arg::new("REMOVE_REGEX")
.help("Remove any CHARACTERISTICs, MEASUREMENTs and INSTANCEs whose name matches the given regex.")
.short('R')
.long("remove")
.number_of_values(1)
.value_name("REGEX")
.action(clap::ArgAction::Append)
)
.group(
ArgGroup::new("INPUT_ARGGROUP")
.args(["INPUT", "CREATE"])
Expand Down
98 changes: 98 additions & 0 deletions src/remove.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
use a2lfile::A2lFile;

pub(crate) fn remove_items(
a2l_file: &mut A2lFile,
regex_strings: &[&str],
log_messages: &mut Vec<String>,
) -> usize {
let mut removed_items = std::collections::HashSet::<String>::new();

let compiled_regexes = regex_strings
.iter()
.map(|re| {
// extend the regex to match only the whole string, not just a substring
let extended_regex =
if !re.starts_with('^') && !re.ends_with('$') {
format!("^{re}$")
} else {
re.to_string()
};
regex::Regex::new(&extended_regex).unwrap()
})
.collect::<Vec<_>>();

for module in &mut a2l_file.project.module {
// remove all characteristics that match any of the regexes
let mut swapped_characteristics = Vec::with_capacity(module.characteristic.len());
std::mem::swap(&mut module.characteristic, &mut swapped_characteristics);
for characteristic in swapped_characteristics {
let mut removed = false;
for regex in &compiled_regexes {
if regex.is_match(&characteristic.name) {
removed_items.insert(characteristic.name.clone());
removed = true;
log_messages.push(format!("Removed characteristic {}", characteristic.name));
}
}
if !removed {
module.characteristic.push(characteristic);
}
}

// remove all measurements that match any of the regexes
let mut swapped_measurements = Vec::with_capacity(module.measurement.len());
std::mem::swap(&mut module.measurement, &mut swapped_measurements);
for measurement in swapped_measurements {
let mut removed = false;
for regex in &compiled_regexes {
if regex.is_match(&measurement.name) {
removed_items.insert(measurement.name.clone());
removed = true;
log_messages.push(format!("Removed measurement {}", measurement.name));
}
}
if !removed {
module.measurement.push(measurement);
}
}

// remove all instances that match any of the regexes
let mut swapped_instances = Vec::with_capacity(module.instance.len());
std::mem::swap(&mut module.instance, &mut swapped_instances);
for instance in swapped_instances {
let mut removed = false;
for regex in &compiled_regexes {
if regex.is_match(&instance.name) {
removed_items.insert(instance.name.clone());
removed = true;
log_messages.push(format!("Removed instance {}", instance.name));
}
}
if !removed {
module.instance.push(instance);
}
}

// remove references to removed items from all groups
for group in &mut module.group {
if let Some(ref_measurement) = &mut group.ref_measurement {
ref_measurement
.identifier_list
.retain(|ident| !removed_items.contains(ident));
if ref_measurement.identifier_list.is_empty() {
group.ref_measurement = None;
}
}
if let Some(ref_characteristic) = &mut group.ref_characteristic {
ref_characteristic
.identifier_list
.retain(|ident| !removed_items.contains(ident));
if ref_characteristic.identifier_list.is_empty() {
group.ref_characteristic = None;
}
}
}
}

removed_items.len()
}

0 comments on commit ea0fdf1

Please sign in to comment.