diff --git a/irp/src/build_bpf.rs b/irp/src/build_bpf.rs index 68230e3..5fb1f89 100644 --- a/irp/src/build_bpf.rs +++ b/irp/src/build_bpf.rs @@ -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), @@ -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); diff --git a/irp/src/build_dfa.rs b/irp/src/build_dfa.rs index 5dc2e10..fb65bc2 100644 --- a/irp/src/build_dfa.rs +++ b/irp/src/build_dfa.rs @@ -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) } @@ -381,7 +385,10 @@ fn replace_vars(expr: &Rc, vars: &HashMap<&str, Rc>) -> 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 } @@ -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))); } diff --git a/irp/src/build_nfa.rs b/irp/src/build_nfa.rs index 3622b85..2d3a17c 100644 --- a/irp/src/build_nfa.rs +++ b/irp/src/build_nfa.rs @@ -22,7 +22,7 @@ pub(crate) struct Edge { #[derive(PartialEq, Debug, Hash, Eq, Clone)] pub(crate) enum Length { Expression(Rc), - Range(u32, u32), + Range(u32, Option), } #[derive(PartialEq, Debug, Hash, Eq, Clone)] @@ -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}"), } } } diff --git a/irp/src/decoder.rs b/irp/src/decoder.rs index dfbcb7f..80b8ff5 100644 --- a/irp/src/decoder.rs +++ b/irp/src/decoder.rs @@ -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 @@ -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; @@ -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; diff --git a/irp/tests/bpf_decoding.rs b/irp/tests/bpf_decoding.rs index 954e4d2..502ee19 100644 --- a/irp/tests/bpf_decoding.rs +++ b/irp/tests/bpf_decoding.rs @@ -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(); @@ -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();