Skip to content

Commit 4e12ba7

Browse files
authored
Merge pull request #166 from kossnikita/spec-ind-regex
Replace spec indices search with regex
2 parents 9ab01ef + 307c246 commit 4e12ba7

File tree

3 files changed

+56
-21
lines changed

3 files changed

+56
-21
lines changed

src/patch/mod.rs

Lines changed: 30 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -569,22 +569,37 @@ fn make_cpu(cmod: &Hash) -> Result<CpuBuilder> {
569569
}
570570

571571
/// Find left and right indices of enumeration token in specification string
572-
fn spec_ind(spec: &str) -> (usize, usize) {
572+
///
573+
/// # Examples
574+
///
575+
/// ```ignore
576+
/// let cases = [
577+
/// ("RELOAD?", (6, 0)),
578+
/// ("TMR[1-57]_MUX", (3, 4)),
579+
/// ("DT[1-3]?", (2, 0)),
580+
/// ("GPIO[ABCDE]", (4, 0)),
581+
/// ("CSPT[1][7-9],CSPT[2][0-5]", (4, 0)),
582+
/// ];
583+
/// for (spec, (li, ri)) in cases {
584+
/// assert_eq!(spec_ind(spec), Some((li, ri)));
585+
/// }
586+
/// ```
587+
///
588+
fn spec_ind(spec: &str) -> Option<(usize, usize)> {
589+
use once_cell::sync::Lazy;
590+
use regex::Regex;
573591
let spec = spec.split(',').next().unwrap_or(spec);
574-
let li = spec
575-
.bytes()
576-
.position(|b| b == b'*')
577-
.or_else(|| spec.bytes().position(|b| b == b'?'))
578-
.or_else(|| spec.bytes().position(|b| b == b'['))
579-
.unwrap();
580-
let ri = spec
581-
.bytes()
582-
.rev()
583-
.position(|b| b == b'*')
584-
.or_else(|| spec.bytes().rev().position(|b| b == b'?'))
585-
.or_else(|| spec.bytes().rev().position(|b| b == b']'))
586-
.unwrap();
587-
(li, ri)
592+
static RE: Lazy<Regex> = Lazy::new(|| {
593+
Regex::new(r"^\w*((?:[\?*]|\[\d+(?:-\d+)?\]|\[[a-zA-Z]+(?:-[a-zA-Z]+)?\])+)\w*$").unwrap()
594+
});
595+
let Some(caps) = RE.captures(spec) else {
596+
return None;
597+
};
598+
let spec = caps.get(0).unwrap();
599+
let token = caps.get(1).unwrap();
600+
let li = token.start();
601+
let ri = spec.end() - token.end();
602+
Some((li, ri))
588603
}
589604

590605
fn check_offsets(offsets: &[u32], dim_increment: u32) -> bool {

src/patch/peripheral.rs

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1135,7 +1135,11 @@ fn collect_in_array(
11351135
return Err(anyhow!("{path}: registers {rspec} not found"));
11361136
}
11371137
registers.sort_by_key(|r| r.address_offset);
1138-
let (li, ri) = spec_ind(rspec);
1138+
let Some((li, ri)) = spec_ind(rspec) else {
1139+
return Err(anyhow!(
1140+
"`{rspec}` contains no tokens or contains more than one token"
1141+
));
1142+
};
11391143
let dim = registers.len();
11401144
let dim_index = if rmod.contains_key(&"_start_from_zero".to_yaml()) {
11411145
(0..dim).map(|v| v.to_string()).collect::<Vec<_>>()
@@ -1241,10 +1245,18 @@ fn collect_in_cluster(
12411245
.iter()
12421246
.map(|r| {
12431247
let match_rspec = matchsubspec(&r.name, rspec).unwrap();
1244-
let (li, ri) = spec_ind(match_rspec);
1245-
r.name[li..r.name.len() - ri].to_string()
1248+
let Some((li, ri)) = spec_ind(match_rspec) else {
1249+
return Err(anyhow!(
1250+
"`{match_rspec}` contains no tokens or contains more than one token"
1251+
));
1252+
};
1253+
Ok(r.name[li..r.name.len() - ri].to_string())
12461254
})
1247-
.collect::<Vec<_>>();
1255+
.collect::<Result<Vec<_>, _>>();
1256+
let new_dim_index = match new_dim_index {
1257+
Ok(v) => v,
1258+
Err(e) => return Err(e),
1259+
};
12481260
if first {
12491261
dim = registers.len();
12501262
dim_index = new_dim_index;
@@ -1316,7 +1328,11 @@ fn collect_in_cluster(
13161328
reg.name = if let Some(name) = rmod.get_str("name")? {
13171329
name.into()
13181330
} else {
1319-
let (li, ri) = spec_ind(&rspec);
1331+
let Some((li, ri)) = spec_ind(&rspec) else {
1332+
return Err(anyhow!(
1333+
"`{rspec}` contains no tokens or contains more than one token"
1334+
));
1335+
};
13201336
format!("{}{}", &rspec[..li], &rspec[rspec.len() - ri..])
13211337
};
13221338
if let Some(desc) = rmod.get_str("description")? {

src/patch/register.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -373,7 +373,11 @@ impl RegisterExt for Register {
373373
return Err(anyhow!("{}: fields {fspec} not found", self.name));
374374
}
375375
fields.sort_by_key(|f| f.bit_range.offset);
376-
let (li, ri) = spec_ind(fspec);
376+
let Some((li, ri)) = spec_ind(fspec) else {
377+
return Err(anyhow!(
378+
"`{fspec}` contains no tokens or contains more than one token"
379+
));
380+
};
377381
let dim = fields.len();
378382
let dim_index = if fmod.contains_key(&"_start_from_zero".to_yaml()) {
379383
(0..dim).map(|v| v.to_string()).collect::<Vec<_>>()

0 commit comments

Comments
 (0)