diff --git a/src/patch/mod.rs b/src/patch/mod.rs index 194f3166..cec4bea3 100644 --- a/src/patch/mod.rs +++ b/src/patch/mod.rs @@ -1,7 +1,6 @@ pub mod patch_cli; use globset::Glob; -use regex::Regex; use std::fs::File; use std::io::{Read, Write}; use std::path::{Path, PathBuf}; @@ -571,13 +570,9 @@ fn make_cpu(cmod: &Hash) -> Result { /// Find left and right indices of enumeration token in specification string /// -/// # Panics -/// -/// Panics if the expression contains no or more than one token. -/// /// # Examples /// -/// ``` +/// ```ignore /// let cases = [ /// ("RELOAD?", (6, 0)), /// ("TMR[1-57]_MUX", (3, 4)), @@ -586,20 +581,25 @@ fn make_cpu(cmod: &Hash) -> Result { /// ("CSPT[1][7-9],CSPT[2][0-5]", (4, 0)), /// ]; /// for (spec, (li, ri)) in cases { -/// assert_eq!(patch::spec_ind(spec), (li, ri)); +/// assert_eq!(spec_ind(spec), Some((li, ri))); /// } /// ``` /// -fn spec_ind(spec: &str) -> (usize, usize) { +fn spec_ind(spec: &str) -> Option<(usize, usize)> { + use once_cell::sync::Lazy; + use regex::Regex; let spec = spec.split(',').next().unwrap_or(spec); - let re = - Regex::new(r"^\w*((?:[\?*]|\[\d+(?:-\d+)?\]|\[[a-zA-Z]+(?:-[a-zA-Z]+)?\])+)\w*$").unwrap(); - let caps = re.captures(spec).unwrap(); + static RE: Lazy = Lazy::new(|| { + Regex::new(r"^\w*((?:[\?*]|\[\d+(?:-\d+)?\]|\[[a-zA-Z]+(?:-[a-zA-Z]+)?\])+)\w*$").unwrap() + }); + let Some(caps) = RE.captures(spec) else { + return None; + }; let spec = caps.get(0).unwrap(); let token = caps.get(1).unwrap(); let li = token.start(); let ri = spec.end() - token.end(); - (li, ri) + Some((li, ri)) } fn check_offsets(offsets: &[u32], dim_increment: u32) -> bool { diff --git a/src/patch/peripheral.rs b/src/patch/peripheral.rs index c4d70314..3edb9cd5 100644 --- a/src/patch/peripheral.rs +++ b/src/patch/peripheral.rs @@ -1135,7 +1135,11 @@ fn collect_in_array( return Err(anyhow!("{path}: registers {rspec} not found")); } registers.sort_by_key(|r| r.address_offset); - let (li, ri) = spec_ind(rspec); + let Some((li, ri)) = spec_ind(rspec) else { + return Err(anyhow!( + "`{rspec}` contains no tokens or contains more than one token" + )); + }; let dim = registers.len(); let dim_index = if rmod.contains_key(&"_start_from_zero".to_yaml()) { (0..dim).map(|v| v.to_string()).collect::>() @@ -1241,10 +1245,18 @@ fn collect_in_cluster( .iter() .map(|r| { let match_rspec = matchsubspec(&r.name, rspec).unwrap(); - let (li, ri) = spec_ind(match_rspec); - r.name[li..r.name.len() - ri].to_string() + let Some((li, ri)) = spec_ind(match_rspec) else { + return Err(anyhow!( + "`{match_rspec}` contains no tokens or contains more than one token" + )); + }; + Ok(r.name[li..r.name.len() - ri].to_string()) }) - .collect::>(); + .collect::, _>>(); + let new_dim_index = match new_dim_index { + Ok(v) => v, + Err(e) => return Err(e), + }; if first { dim = registers.len(); dim_index = new_dim_index; @@ -1316,7 +1328,11 @@ fn collect_in_cluster( reg.name = if let Some(name) = rmod.get_str("name")? { name.into() } else { - let (li, ri) = spec_ind(&rspec); + let Some((li, ri)) = spec_ind(&rspec) else { + return Err(anyhow!( + "`{rspec}` contains no tokens or contains more than one token" + )); + }; format!("{}{}", &rspec[..li], &rspec[rspec.len() - ri..]) }; if let Some(desc) = rmod.get_str("description")? { diff --git a/src/patch/register.rs b/src/patch/register.rs index fc40abc9..03c7fea3 100644 --- a/src/patch/register.rs +++ b/src/patch/register.rs @@ -373,7 +373,11 @@ impl RegisterExt for Register { return Err(anyhow!("{}: fields {fspec} not found", self.name)); } fields.sort_by_key(|f| f.bit_range.offset); - let (li, ri) = spec_ind(fspec); + let Some((li, ri)) = spec_ind(fspec) else { + return Err(anyhow!( + "`{fspec}` contains no tokens or contains more than one token" + )); + }; let dim = fields.len(); let dim_index = if fmod.contains_key(&"_start_from_zero".to_yaml()) { (0..dim).map(|v| v.to_string()).collect::>()