Skip to content

Commit

Permalink
Make max_gap work in the DFA
Browse files Browse the repository at this point in the history
Signed-off-by: Sean Young <[email protected]>
  • Loading branch information
seanyoung committed Apr 7, 2024
1 parent b051b26 commit f71140a
Show file tree
Hide file tree
Showing 5 changed files with 73 additions and 53 deletions.
72 changes: 38 additions & 34 deletions irp/src/build_bpf.rs
Original file line number Diff line number Diff line change
Expand Up @@ -312,23 +312,25 @@ impl<'a> Builder<'a> {

self.builder.position_at_end(ok);

let ok = context.append_basic_block(function, "ok");

let res = self
.builder
.build_int_compare(
IntPredicate::ULE,
length,
i32.const_int(*max as u64, false),
"max",
)
.unwrap();

self.builder
.build_conditional_branch(res, ok, next)
.unwrap();

self.builder.position_at_end(ok);
if let Some(max) = max {
let ok = context.append_basic_block(function, "ok");

let res = self
.builder
.build_int_compare(
IntPredicate::ULE,
length,
i32.const_int(*max as u64, false),
"max",
)
.unwrap();

self.builder
.build_conditional_branch(res, ok, next)
.unwrap();

self.builder.position_at_end(ok);
}
}
Action::Gap {
length: Length::Range(min, max),
Expand Down Expand Up @@ -360,23 +362,25 @@ impl<'a> Builder<'a> {

self.builder.position_at_end(ok);

let ok = context.append_basic_block(function, "ok");

let res = self
.builder
.build_int_compare(
IntPredicate::ULE,
length,
i32.const_int(*max as u64, false),
"max",
)
.unwrap();

self.builder
.build_conditional_branch(res, ok, next)
.unwrap();

self.builder.position_at_end(ok);
if let Some(max) = max {
let ok = context.append_basic_block(function, "ok");

let res = self
.builder
.build_int_compare(
IntPredicate::ULE,
length,
i32.const_int(*max as u64, false),
"max",
)
.unwrap();

self.builder
.build_conditional_branch(res, ok, next)
.unwrap();

self.builder.position_at_end(ok);
}
}
Action::Set { var, expr } => {
let value = self.emit(expr, context);
Expand Down
35 changes: 25 additions & 10 deletions irp/src/build_dfa.rs
Original file line number Diff line number Diff line change
Expand Up @@ -255,12 +255,16 @@ impl<'a> Builder<'a> {
(length * (100 - self.options.eps)) / 100,
);

let max = std::cmp::min(
let max = std::cmp::max(
length + self.options.aeps,
(length * (100 + self.options.eps)) / 100,
);

Length::Range(min, max)
if self.options.max_gap > 0 && max < self.options.max_gap {
Length::Range(min, Some(max))
} else {
Length::Range(min, None)
}
} else {
Length::Expression(length)
}
Expand Down Expand Up @@ -381,7 +385,10 @@ fn replace_vars(expr: &Rc<Expression>, vars: &HashMap<&str, Rc<Expression>>) ->
impl Length {
fn overlaps(&self, other: &Self) -> bool {
if let (Length::Range(min1, max1), Length::Range(min2, max2)) = (self, other) {
!(max1 < min2 || max2 < min1)
let max1 = max1.unwrap_or(u32::MAX);
let max2 = max2.unwrap_or(u32::MAX);

!(max1 < *min2 || max2 < *min1)
} else {
false
}
Expand All @@ -400,13 +407,21 @@ impl Length {

#[test]
fn overlaps() {
assert!(!Length::Range(1, 10).overlaps(&Length::Range(11, 20)));
assert!(!Length::Range(11, 20).overlaps(&Length::Range(1, 10)));
assert!(!Length::Range(1, Some(10)).overlaps(&Length::Range(11, Some(20))));
assert!(!Length::Range(11, Some(20)).overlaps(&Length::Range(1, Some(10))));

assert!(Length::Range(1, Some(11)).overlaps(&Length::Range(11, Some(20))));
assert!(Length::Range(11, Some(20)).overlaps(&Length::Range(1, Some(11))));

assert!(Length::Range(11, Some(20)).overlaps(&Length::Range(11, Some(20))));
assert!(Length::Range(5, Some(25)).overlaps(&Length::Range(11, Some(20))));
assert!(Length::Range(11, Some(20)).overlaps(&Length::Range(5, Some(25))));

assert!(Length::Range(5, None).overlaps(&Length::Range(11, Some(20))));
assert!(!Length::Range(21, None).overlaps(&Length::Range(11, Some(20))));

assert!(Length::Range(1, 11).overlaps(&Length::Range(11, 20)));
assert!(Length::Range(11, 20).overlaps(&Length::Range(1, 11)));
assert!(Length::Range(5, Some(25)).overlaps(&Length::Range(11, None)));
assert!(!Length::Range(11, Some(20)).overlaps(&Length::Range(21, None)));

assert!(Length::Range(11, 20).overlaps(&Length::Range(11, 20)));
assert!(Length::Range(5, 25).overlaps(&Length::Range(11, 20)));
assert!(Length::Range(11, 20).overlaps(&Length::Range(5, 25)));
assert!(Length::Range(5, None).overlaps(&Length::Range(11, None)));
}
5 changes: 3 additions & 2 deletions irp/src/build_nfa.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ pub(crate) struct Edge {
#[derive(PartialEq, Debug, Hash, Eq, Clone)]
pub(crate) enum Length {
Expression(Rc<Expression>),
Range(u32, u32),
Range(u32, Option<u32>),
}

#[derive(PartialEq, Debug, Hash, Eq, Clone)]
Expand Down Expand Up @@ -1584,7 +1584,8 @@ impl fmt::Display for Length {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
Length::Expression(e) => write!(f, "{e}"),
Length::Range(min, max) => write!(f, "{min}..{max}"),
Length::Range(min, None) => write!(f, "{min}.."),
Length::Range(min, Some(max)) => write!(f, "{min}..{max}"),
}
}
}
9 changes: 6 additions & 3 deletions irp/src/decoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,10 @@ impl<'a> Decoder<'a> {
) -> bool {
match ir {
Some(InfraredData::Gap(received)) => {
if expected > self.options.max_gap as i64 && *received >= self.options.max_gap {
if self.options.max_gap > 0
&& expected > self.options.max_gap as i64
&& *received >= self.options.max_gap
{
trace!("large gap matched gap {} (expected {})", received, expected,);
*ir = None;
true
Expand Down Expand Up @@ -376,7 +379,7 @@ impl<'a> Decoder<'a> {
} else if self.consume_flash_range(
&mut ir,
(*min).into(),
(*max).into(),
max.unwrap_or(u32::MAX).into(),
*complete,
) {
continue;
Expand Down Expand Up @@ -407,7 +410,7 @@ impl<'a> Decoder<'a> {
} else if self.consume_gap_range(
&mut ir,
(*min).into(),
(*max).into(),
max.unwrap_or(u32::MAX).into(),
*complete,
) {
continue;
Expand Down
5 changes: 1 addition & 4 deletions irp/tests/bpf_decoding.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,12 @@ fn rc5() {
source: file!(),
aeps: 100,
eps: 3,
max_gap: 20000,
..Default::default()
};

let dfa = irp.compile(&options).unwrap();

dfa.dotgraphviz("lircd.dot");

let (object, vars) = dfa.compile_bpf(&options).unwrap();

let mut obj = Object::parse(&object).unwrap();
Expand Down Expand Up @@ -58,8 +57,6 @@ fn rc5() {
rel_maps.push((name.as_str(), 7, map));
}

println!("value_size: {value_size:?}");

obj.relocate_maps(rel_maps.into_iter(), &text_sections)
.unwrap();

Expand Down

0 comments on commit f71140a

Please sign in to comment.