|
@@ -1,4 +1,4 @@
|
|
|
-use crate::{AmlContext, Handler};
|
|
|
+use crate::{parser::Propagate, AmlContext, AmlValue, Handler};
|
|
|
use alloc::boxed::Box;
|
|
|
|
|
|
struct TestHandler;
|
|
@@ -71,14 +71,16 @@ impl Handler for TestHandler {
|
|
|
}
|
|
|
|
|
|
pub(crate) fn make_test_context() -> AmlContext {
|
|
|
- AmlContext::new(Box::new(TestHandler), false, crate::DebugVerbosity::None)
|
|
|
+ AmlContext::new(Box::new(TestHandler), crate::DebugVerbosity::None)
|
|
|
}
|
|
|
|
|
|
pub(crate) macro check_err($parse: expr, $error: pat, $remains: expr) {
|
|
|
match $parse {
|
|
|
Ok((remains, _, result)) => panic!("Expected Err, got {:#?}. Remaining = {:#x?}", result, remains),
|
|
|
- Err((remains, _, $error)) if *remains == *$remains => (),
|
|
|
- Err((remains, _, $error)) => panic!("Correct error, incorrect stream returned: {:#x?}", remains),
|
|
|
+ Err((remains, _, Propagate::Err($error))) if *remains == *$remains => (),
|
|
|
+ Err((remains, _, Propagate::Err($error))) => {
|
|
|
+ panic!("Correct error, incorrect stream returned: {:#x?}", remains)
|
|
|
+ }
|
|
|
Err((_, _, err)) => panic!("Got wrong error: {:?}", err),
|
|
|
}
|
|
|
}
|
|
@@ -93,3 +95,86 @@ pub(crate) macro check_ok($parse: expr, $expected: expr, $remains: expr) {
|
|
|
Err((_, _, err)) => panic!("Expected Ok, got {:#?}", err),
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+pub(crate) macro check_ok_value($parse: expr, $expected: expr, $remains: expr) {
|
|
|
+ match $parse {
|
|
|
+ Ok((remains, _, ref result)) if remains == *$remains && crudely_cmp_values(result, &$expected) => (),
|
|
|
+ Ok((remains, _, ref result)) if crudely_cmp_values(result, &$expected) => {
|
|
|
+ panic!("Correct result, incorrect slice returned: {:x?}", remains)
|
|
|
+ }
|
|
|
+ Ok((_, _, ref result)) => panic!("Successfully parsed Ok, but it was wrong: {:#?}", result),
|
|
|
+ Err((_, _, err)) => panic!("Expected Ok, got {:#?}", err),
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+/// This is a bad (but good for testing) way of comparing `AmlValue`s, which tests that they're exactly the same if
|
|
|
+/// it can, and gives up if it can't. It's useful in tests to be able to see if you're getting the `AmlValue` that
|
|
|
+/// you're expecting.
|
|
|
+///
|
|
|
+/// NOTE: almost all of the `AmlValue` variants are `Eq`, and so for a long time, `AmlValue` implemented `Eq`.
|
|
|
+/// However, this is a footgun as, in the real interpreter, you rarely want to directly compare values, as you need
|
|
|
+/// to apply the AML value conversion rules to compare them correctly. This is therefore only useful for artificial
|
|
|
+/// testing scenarios.
|
|
|
+pub(crate) fn crudely_cmp_values(a: &AmlValue, b: &AmlValue) -> bool {
|
|
|
+ match a {
|
|
|
+ AmlValue::Boolean(a) => match b {
|
|
|
+ AmlValue::Boolean(b) => a == b,
|
|
|
+ _ => false,
|
|
|
+ },
|
|
|
+ AmlValue::Integer(a) => match b {
|
|
|
+ AmlValue::Integer(b) => a == b,
|
|
|
+ _ => false,
|
|
|
+ },
|
|
|
+ AmlValue::String(ref a) => match b {
|
|
|
+ AmlValue::String(ref b) => a == b,
|
|
|
+ _ => false,
|
|
|
+ },
|
|
|
+ AmlValue::OpRegion { region, offset, length, parent_device } => match b {
|
|
|
+ AmlValue::OpRegion {
|
|
|
+ region: b_region,
|
|
|
+ offset: b_offset,
|
|
|
+ length: b_length,
|
|
|
+ parent_device: b_parent_device,
|
|
|
+ } => {
|
|
|
+ region == b_region && offset == b_offset && length == b_length && parent_device == b_parent_device
|
|
|
+ }
|
|
|
+ _ => false,
|
|
|
+ },
|
|
|
+ AmlValue::Field { region, flags, offset, length } => match b {
|
|
|
+ AmlValue::Field { region: b_region, flags: b_flags, offset: b_offset, length: b_length } => {
|
|
|
+ region == b_region && flags == b_flags && offset == b_offset && length == b_length
|
|
|
+ }
|
|
|
+ _ => false,
|
|
|
+ },
|
|
|
+ AmlValue::Method { flags, code } => match b {
|
|
|
+ AmlValue::Method { flags: b_flags, code: b_code } => flags == b_flags && code == b_code,
|
|
|
+ _ => false,
|
|
|
+ },
|
|
|
+ AmlValue::Buffer(a) => match b {
|
|
|
+ AmlValue::Buffer(b) => a == b,
|
|
|
+ _ => false,
|
|
|
+ },
|
|
|
+ AmlValue::Processor { id, pblk_address, pblk_len } => match b {
|
|
|
+ AmlValue::Processor { id: b_id, pblk_address: b_pblk_address, pblk_len: b_pblk_len } => {
|
|
|
+ id == b_id && pblk_address == b_pblk_address && pblk_len == b_pblk_len
|
|
|
+ }
|
|
|
+ _ => false,
|
|
|
+ },
|
|
|
+ AmlValue::Mutex { sync_level } => match b {
|
|
|
+ AmlValue::Mutex { sync_level: b_sync_level } => sync_level == b_sync_level,
|
|
|
+ _ => false,
|
|
|
+ },
|
|
|
+ AmlValue::Package(a) => match b {
|
|
|
+ AmlValue::Package(b) => {
|
|
|
+ for (a, b) in a.iter().zip(b) {
|
|
|
+ if crudely_cmp_values(a, b) == false {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ true
|
|
|
+ }
|
|
|
+ _ => false,
|
|
|
+ },
|
|
|
+ }
|
|
|
+}
|