From 944e7ae04ff80a17d74bd01cfe1d43d7732e1379 Mon Sep 17 00:00:00 2001 From: YdrMaster Date: Thu, 14 Jul 2022 20:23:58 +0800 Subject: [PATCH 1/5] =?UTF-8?q?fix:=20=E6=97=A0=E8=BF=87=E6=BB=A4=E5=99=A8?= =?UTF-8?q?=E7=9A=84=E8=AE=BE=E5=A4=87=E6=A0=91=E6=9E=84=E9=80=A0=E5=BA=94?= =?UTF-8?q?=E8=AF=A5=E6=8B=92=E7=BB=9D=E6=89=80=E6=9C=89=E4=B8=8D=E5=90=88?= =?UTF-8?q?=E8=A7=84=E8=8C=83=E7=9A=84=E6=83=85=E5=86=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: YdrMaster --- CHANGELOG.md | 28 +++++++++++++++++++++++++--- src/lib.rs | 19 ++++++++++++++----- 2 files changed, 39 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5380621..cc7efd1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,17 +10,32 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## 未发布 +## [0.2.0-alpha.2](https://github.com/YdrMaster/dtb-walker/releases/tag/0.2.0-alpha.2) - 2022-07-14 -## Unreleased +### Fixed + +- 不带过滤器构造 `Dtb` 时应该拒绝所有不合规范的情况,而不是全部接受 + +--- + +- Build `Dtb` without filter should reject all non-conformances, instead of accepting them all + +### Added + +- 从 `&[u8]` 构造 `Dtb` 时也可以使用过滤器 + +--- + +- Provides a method to build `Dtb` from `&[u8]` with a filter ## [0.2.0-alpha.1](https://github.com/YdrMaster/dtb-walker/releases/tag/0.2.0-alpha.1) - 2022-07-12 +### Changed + - 规范化更新日志格式 - 字符串统一使用一个封装的 `Str` 类型(包括节点名、属性名、`` 类型的属性值、路径),类似于 `str` 但未检查是否符合 utf-8 编码 - 格式化 `Str` 不再自带引号 - 补全文档并禁止不写文档 -- github ci 自动运行一次示例 --- @@ -28,6 +43,13 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), - uses an encapsulated `Str` type uniformly for strings (including node name, property name, property value of ``, path), similar to `str` but not checked for utf-8 encoding - will not add quotes when formating `Str` - completes documentation and missing documentation is denied from now on + +### Added + +- github ci 会运行一次示例 + +--- + - runs example during github ci ## [0.1.3](https://github.com/YdrMaster/dtb-walker/releases/tag/v0.1.3) - 2022-06-30 diff --git a/src/lib.rs b/src/lib.rs index 482d45c..14438ae 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -50,11 +50,11 @@ impl Dtb<'static> { /// 如果指针指向一个有效的 DTB 首部,其中描述的整个二进制对象会被切片。 #[inline] pub unsafe fn from_raw_parts(ptr: *const u8) -> Result { - (*ptr.cast::()).verify(|_| true)?; + (*ptr.cast::()).verify(|_| false)?; Ok(Self::from_raw_parts_unchecked(ptr)) } - /// 构造设备树二进制对象。 + /// 构造设备树二进制对象,并可以选择接受某些不合规范的情况。 /// /// # Safety /// @@ -91,13 +91,16 @@ pub enum ConvertError { } impl<'a> Dtb<'a> { - /// 从内存切片安全地创建设备树二进制对象。 - pub fn from_slice(slice: &'a [u8]) -> Result { + /// 从内存切片安全地创建设备树二进制对象,可以选择接受某些不合规范的情况。 + pub fn from_slice_filtered( + slice: &'a [u8], + f: impl Fn(&HeaderError) -> bool, + ) -> Result { if slice.len() < mem::size_of::() { return Err(ConvertError::Truncated); } let header = unsafe { &*slice.as_ptr().cast::() }; - match header.verify(|_| true) { + match header.verify(f) { Ok(()) => { let len = header.totalsize.into_u32() as usize; if len <= slice.len() { @@ -109,6 +112,12 @@ impl<'a> Dtb<'a> { Err(e) => Err(ConvertError::Header(e)), } } + + /// 从内存切片安全地创建设备树二进制对象。 + #[inline] + pub fn from_slice(slice: &'a [u8]) -> Result { + Self::from_slice_filtered(slice, |_| false) + } } impl Dtb<'_> { From b22f82f155d4a326895c9ba1e0869b9f5f3dde9d Mon Sep 17 00:00:00 2001 From: YdrMaster Date: Fri, 15 Jul 2022 05:58:32 +0800 Subject: [PATCH 2/5] publish Signed-off-by: YdrMaster --- CHANGELOG.md | 2 +- Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index cc7efd1..f6934d6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,7 +10,7 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## [0.2.0-alpha.2](https://github.com/YdrMaster/dtb-walker/releases/tag/0.2.0-alpha.2) - 2022-07-14 +## [0.2.0-alpha.2](https://github.com/YdrMaster/dtb-walker/releases/tag/0.2.0-alpha.2) - 2022-07-15 ### Fixed diff --git a/Cargo.toml b/Cargo.toml index 0bf0aad..b2e54b1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "dtb-walker" description = "A simple package for DTB depth-first walking." -version = "0.2.0-alpha.1" +version = "0.2.0-alpha.2" edition = "2021" authors = ["YdrMaster "] repository = "https://github.com/YdrMaster/dtb-walker.git" From e694aa3b114ce9a3a9dee1b7f1ea7b83ab71f0ef Mon Sep 17 00:00:00 2001 From: YdrMaster Date: Mon, 18 Jul 2022 10:48:20 +0800 Subject: [PATCH 3/5] =?UTF-8?q?feat:=20=E5=B0=81=E8=A3=85=E6=A0=88?= =?UTF-8?q?=E4=B8=8A=E6=A0=91=E7=BB=93=E6=9E=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: YdrMaster --- src/lib.rs | 1 + src/path.rs | 55 +++++++++++++------------------ src/tree_on_stack.rs | 78 ++++++++++++++++++++++++++++++++++++++++++++ src/walker.rs | 10 +----- 4 files changed, 102 insertions(+), 42 deletions(-) create mode 100644 src/tree_on_stack.rs diff --git a/src/lib.rs b/src/lib.rs index 14438ae..0b17fff 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -21,6 +21,7 @@ mod path; mod property; mod str; mod structure_block; +mod tree_on_stack; mod walker; pub use self::str::Str; diff --git a/src/path.rs b/src/path.rs index 712760a..b196354 100644 --- a/src/path.rs +++ b/src/path.rs @@ -1,38 +1,28 @@ -use crate::Str; -use core::{fmt, str}; +use crate::{tree_on_stack::Node, Str}; +use core::fmt; /// 设备树节点路径。 -pub struct Path<'a> { - pub(crate) parent: Option<&'a Path<'a>>, - pub(crate) name: Str<'a>, -} +pub struct Path<'a>(Node<'a, Str<'a>>); impl Path<'_> { - pub(crate) const ROOT: Self = Self { - parent: None, - name: Str(&[]), - }; + pub(crate) const ROOT: Self = Self(Node::root(Str(&[]))); /// 返回路径层数。定义根节点的子节点层数为 0。 #[inline] pub fn level(&self) -> usize { - if let Some(parent) = self.parent { - parent.level() + 1 - } else { - 0 - } + self.0.level() } /// 返回路径最后一级的节点名。 #[inline] pub fn last(&self) -> Str { - self.name + *self.0.as_ref() } /// 如果这是根节点的路径则返回 `true`。 #[inline] pub fn is_root(&self) -> bool { - self.name.0.is_empty() + self.0.is_root() } /// 将路径字符串格式化到 `buf` 中。 @@ -40,35 +30,34 @@ impl Path<'_> { /// 如果返回 `Ok(n)`,表示字符串长度为 `n`(`n` 不大于 `buf.len()`)。 /// 如果返回 `Err(n)`,表示缓冲区长度无法存放整个字符串,实现保证 `n` 等于 `buf.len()`。 pub fn join(&self, buf: &mut [u8]) -> Result { - let len = match self.parent { - Some(parent) => parent.join(buf)?, - None => return Ok(0), - }; - match buf.len() - len { + self.0.fold(0, |len, name| match buf.len() - len { 0 => Err(buf.len()), mut rest => { buf[len] = b'/'; rest -= 1; - if self.name.0.len() > rest { - buf[len + 1..].copy_from_slice(&self.name.0[..rest]); + if name.0.len() > rest { + buf[len + 1..].copy_from_slice(&name.0[..rest]); Err(buf.len()) } else { - buf[len + 1..][..self.name.0.len()].copy_from_slice(self.name.0); - Ok(len + self.name.0.len() + 1) + buf[len + 1..][..name.0.len()].copy_from_slice(name.0); + Ok(len + name.0.len() + 1) } } - } + }) + } +} + +impl<'a> Path<'a> { + pub(crate) fn grow(&'a self, node: Str<'a>) -> Self { + Self(self.0.grow(node)) } } impl fmt::Display for Path<'_> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - if let Some(parent) = self.parent { - parent.fmt(f)?; + self.0.fold((), |(), name| { '/'.fmt(f)?; - unsafe { str::from_utf8_unchecked(self.name.0) }.fmt(f) - } else { - Ok(()) - } + unsafe { name.as_str_unchecked() }.fmt(f) + }) } } diff --git a/src/tree_on_stack.rs b/src/tree_on_stack.rs new file mode 100644 index 0000000..823a300 --- /dev/null +++ b/src/tree_on_stack.rs @@ -0,0 +1,78 @@ +/// 树节点 +pub struct Node<'a, T> { + pub data: T, + pub parent: Option<&'a Self>, +} + +impl Node<'_, T> { + /// 构造一个树根节点。 + #[inline] + pub const fn root(data: T) -> Self { + Node { data, parent: None } + } + + /// 判断节点是不是根节点。 + #[inline] + pub const fn is_root(&self) -> bool { + self.parent.is_none() + } + + /// 返回树层数。 + #[inline] + pub fn level(&self) -> usize { + self.parent.map_or(0, |node| node.level() + 1) + } + + /// 递归左折叠。 + #[inline] + pub fn fold(&self, init: A, mut f: impl FnMut(A, &T) -> Result) -> Result { + self.fold_inner(init, &mut f) + } + + /// 递归右折叠。 + #[allow(unused)] + #[inline] + pub fn fold_r(&self, init: A, mut f: impl FnMut(A, &T) -> Result) -> Result { + self.fold_r_inner(init, &mut f) + } + + fn fold_inner(&self, init: A, f: &mut impl FnMut(A, &T) -> Result) -> Result { + match self.parent { + Some(parent) => { + let a = parent.fold_inner(init, f)?; + (*f)(a, &self.data) + } + None => Ok(init), + } + } + + fn fold_r_inner( + &self, + init: A, + f: &mut impl FnMut(A, &T) -> Result, + ) -> Result { + let a = (*f)(init, &self.data)?; + match self.parent { + Some(parent) => parent.fold_r_inner(a, f), + None => Ok(a), + } + } +} + +impl AsRef for Node<'_, T> { + #[inline] + fn as_ref(&self) -> &T { + &self.data + } +} + +impl<'a, T> Node<'a, T> { + /// 为树增加一个子节点。 + #[inline] + pub fn grow(&'a self, data: T) -> Self { + Node { + data, + parent: Some(self), + } + } +} diff --git a/src/walker.rs b/src/walker.rs index 9f4e1b2..09fb950 100644 --- a/src/walker.rs +++ b/src/walker.rs @@ -54,15 +54,7 @@ impl Walker<'_> { } Terminate => return false, }; - if !self.walk_inner( - f, - &Path { - parent: Some(path), - name, - }, - sub_reg_cfg, - escape, - ) { + if !self.walk_inner(f, &path.grow(name), sub_reg_cfg, escape) { return false; } } From e7d3708541724d1c27aadd8ed925d1ea5d7859de Mon Sep 17 00:00:00 2001 From: YdrMaster Date: Mon, 18 Jul 2022 12:05:52 +0800 Subject: [PATCH 4/5] =?UTF-8?q?feat:=20=E6=9E=84=E9=80=A0=E9=81=8D?= =?UTF-8?q?=E5=8E=86=E4=B8=8A=E4=B8=8B=E6=96=87=E7=B1=BB=E5=9E=8B=EF=BC=8C?= =?UTF-8?q?=E9=9B=86=E6=88=90=E6=89=80=E6=9C=89=E9=81=8D=E5=8E=86=E4=B8=AD?= =?UTF-8?q?=E7=9A=84=E4=BF=A1=E6=81=AF=E4=BC=A0=E9=80=92?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: YdrMaster --- CHANGELOG.md | 10 +++++ src/context.rs | 98 +++++++++++++++++++++++++++++++++++++++++++++ src/lib.rs | 8 ++-- src/path.rs | 63 ----------------------------- src/property/reg.rs | 12 ------ src/walker.rs | 59 +++++++++++++++------------ 6 files changed, 145 insertions(+), 105 deletions(-) create mode 100644 src/context.rs delete mode 100644 src/path.rs diff --git a/CHANGELOG.md b/CHANGELOG.md index f6934d6..33b9d3b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,16 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## Unreleased + +### Change + +- 删除 `Path`,增加 `Context` 类型集中处理所有从父节点向子节点传递的信息。 + +--- + +- Removes `Path` Type, and adds `Context` to handle all information passed from parent node to child node. + ## [0.2.0-alpha.2](https://github.com/YdrMaster/dtb-walker/releases/tag/0.2.0-alpha.2) - 2022-07-15 ### Fixed diff --git a/src/context.rs b/src/context.rs new file mode 100644 index 0000000..78777f9 --- /dev/null +++ b/src/context.rs @@ -0,0 +1,98 @@ +use crate::{tree_on_stack::Node, Str}; +use core::fmt; + +/// 遍历上下文。 +pub struct Context<'a>(Node<'a, Inner<'a>>); + +struct Inner<'a> { + name: Str<'a>, + cells: Cells, +} + +impl Context<'_> { + pub(crate) const ROOT: Self = Context(Node::root(Inner { + name: Str(b""), + cells: Cells::DEFAULT, + })); + + /// 返回路径层数。定义根节点的子节点层数为 0。 + #[inline] + pub fn level(&self) -> usize { + self.0.level() + } + + /// 如果这是根节点的路径则返回 `true`。 + #[inline] + pub fn is_root(&self) -> bool { + self.0.is_root() + } + + /// 返回路径最后一级的节点名。 + #[inline] + pub fn name(&self) -> Str { + self.0.as_ref().name + } + + #[inline] + pub(crate) fn cells(&self) -> Cells { + self.0.as_ref().cells + } + + /// 将路径字符串格式化到 `buf` 中。 + /// + /// 如果返回 `Ok(n)`,表示字符串长度为 `n`(`n` 不大于 `buf.len()`)。 + /// 如果返回 `Err(n)`,表示缓冲区长度无法存放整个字符串,实现保证 `n` 等于 `buf.len()`。 + pub fn fmt_path(&self, buf: &mut [u8]) -> Result { + self.0.fold(0, |len, inner| match buf.len() - len { + 0 => Err(buf.len()), + mut rest => { + let bytes = inner.name.as_bytes(); + buf[len] = b'/'; + rest -= 1; + if bytes.len() > rest { + buf[len + 1..].copy_from_slice(&bytes[..rest]); + Err(buf.len()) + } else { + buf[len + 1..][..bytes.len()].copy_from_slice(bytes); + Ok(len + bytes.len() + 1) + } + } + }) + } +} + +impl<'a> Context<'a> { + #[inline] + pub(crate) fn grow(&'a self, name: Str<'a>, cells: Cells) -> Self { + Self(self.0.grow(Inner { name, cells })) + } +} + +impl fmt::Display for Context<'_> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + self.0.fold((), |(), inner| { + '/'.fmt(f)?; + unsafe { inner.name.as_str_unchecked() }.fmt(f) + }) + } +} + +#[derive(Clone, Copy)] +pub(crate) struct Cells { + pub address: u32, + pub size: u32, + pub interrupt: u32, +} + +impl Cells { + pub const DEFAULT: Self = Self { + address: 2, + size: 1, + interrupt: 1, + }; + + #[inline] + pub fn reg_size(&self) -> usize { + (self.address + self.size) as _ + } +} diff --git a/src/lib.rs b/src/lib.rs index 0b17fff..00fb75e 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -15,9 +15,9 @@ #![no_std] #![deny(warnings, unstable_features, missing_docs)] // cancel this line during developing +mod context; mod header; mod indent; -mod path; mod property; mod str; mod structure_block; @@ -25,13 +25,13 @@ mod tree_on_stack; mod walker; pub use self::str::Str; -pub use path::Path; pub use property::{PHandle, Property, Reg, StrList}; pub mod utils { //! 用于设备树解析、格式化的工具集。 pub use crate::indent::indent; } +pub use context::Context; pub use header::HeaderError; use core::{fmt, mem, slice}; @@ -129,7 +129,7 @@ impl Dtb<'_> { } /// 遍历。 - pub fn walk(&self, mut f: impl FnMut(&Path<'_>, DtbObj) -> WalkOperation) { + pub fn walk(&self, mut f: impl FnMut(&Context<'_>, DtbObj) -> WalkOperation) { let header = self.header(); let off_struct = header.off_dt_struct.into_u32() as usize; let len_struct = header.size_dt_struct.into_u32() as usize; @@ -147,7 +147,7 @@ impl Dtb<'_> { }, strings: &self.0[off_strings..][..len_strings], } - .walk_inner(&mut f, &Path::ROOT, RegCfg::DEFAULT, false); + .walk_inner(&mut f, Some(Context::ROOT)); } #[inline] diff --git a/src/path.rs b/src/path.rs deleted file mode 100644 index b196354..0000000 --- a/src/path.rs +++ /dev/null @@ -1,63 +0,0 @@ -use crate::{tree_on_stack::Node, Str}; -use core::fmt; - -/// 设备树节点路径。 -pub struct Path<'a>(Node<'a, Str<'a>>); - -impl Path<'_> { - pub(crate) const ROOT: Self = Self(Node::root(Str(&[]))); - - /// 返回路径层数。定义根节点的子节点层数为 0。 - #[inline] - pub fn level(&self) -> usize { - self.0.level() - } - - /// 返回路径最后一级的节点名。 - #[inline] - pub fn last(&self) -> Str { - *self.0.as_ref() - } - - /// 如果这是根节点的路径则返回 `true`。 - #[inline] - pub fn is_root(&self) -> bool { - self.0.is_root() - } - - /// 将路径字符串格式化到 `buf` 中。 - /// - /// 如果返回 `Ok(n)`,表示字符串长度为 `n`(`n` 不大于 `buf.len()`)。 - /// 如果返回 `Err(n)`,表示缓冲区长度无法存放整个字符串,实现保证 `n` 等于 `buf.len()`。 - pub fn join(&self, buf: &mut [u8]) -> Result { - self.0.fold(0, |len, name| match buf.len() - len { - 0 => Err(buf.len()), - mut rest => { - buf[len] = b'/'; - rest -= 1; - if name.0.len() > rest { - buf[len + 1..].copy_from_slice(&name.0[..rest]); - Err(buf.len()) - } else { - buf[len + 1..][..name.0.len()].copy_from_slice(name.0); - Ok(len + name.0.len() + 1) - } - } - }) - } -} - -impl<'a> Path<'a> { - pub(crate) fn grow(&'a self, node: Str<'a>) -> Self { - Self(self.0.grow(node)) - } -} - -impl fmt::Display for Path<'_> { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - self.0.fold((), |(), name| { - '/'.fmt(f)?; - unsafe { name.as_str_unchecked() }.fmt(f) - }) - } -} diff --git a/src/property/reg.rs b/src/property/reg.rs index ecc5f02..ddc8733 100644 --- a/src/property/reg.rs +++ b/src/property/reg.rs @@ -53,15 +53,3 @@ pub(crate) struct RegCfg { pub address_cells: u32, pub size_cells: u32, } - -impl RegCfg { - pub const DEFAULT: Self = Self { - address_cells: 2, - size_cells: 1, - }; - - #[inline] - pub(crate) fn item_size(&self) -> usize { - (self.address_cells + self.size_cells) as _ - } -} diff --git a/src/walker.rs b/src/walker.rs index 09fb950..0a30aae 100644 --- a/src/walker.rs +++ b/src/walker.rs @@ -1,5 +1,7 @@ -use crate::{DtbObj, Path, Property, Reg, RegCfg, Str, StructureBlock as Blk, WalkOperation}; -use core::slice; +use crate::{ + context::Cells, Context, DtbObj, Property, Reg, RegCfg, Str, StructureBlock as Blk, + WalkOperation, +}; /// 设备树递归结构。 pub(crate) struct Walker<'a> { @@ -18,14 +20,12 @@ impl Walker<'_> { /// 深度优先遍历。如果返回 `false`,取消所有后续的遍历。 pub fn walk_inner( &mut self, - f: &mut impl FnMut(&Path<'_>, DtbObj) -> WalkOperation, - path: &Path<'_>, - reg_cfg: RegCfg, - mut escape: bool, + f: &mut impl FnMut(&Context<'_>, DtbObj) -> WalkOperation, + mut ctx: Option, ) -> bool { use WalkOperation::*; - let mut sub_reg_cfg = RegCfg::DEFAULT; + let mut cells = Cells::DEFAULT; loop { match self.tail.split_first() { // 子节点 @@ -34,29 +34,29 @@ impl Walker<'_> { let name_len = tail.iter().position(Blk::is_end_of_str).unwrap() + 1; let (name, tail) = tail.split_at(name_len); self.tail = tail; - if escape { - // 如果当前子树已选跳过,不可能再选择终止 - assert!(self.walk_inner(f, path, sub_reg_cfg, true)); - } else { + if let Some(ctx_) = ctx.as_ref() { // 正确舍弃尾 '\0' let name = Str(unsafe { - slice::from_raw_parts( + core::slice::from_raw_parts( name.as_ptr().cast::(), name.len() * Blk::LEN - name.last().unwrap().str_tail_zero(), ) }); - let escape = match f(path, DtbObj::SubNode { name }) { - StepInto => false, - StepOver => true, + let ctx = match f(ctx_, DtbObj::SubNode { name }) { + StepInto => Some(ctx_.grow(name, cells)), + StepOver => None, StepOut => { - escape = true; - true + ctx = None; + None } Terminate => return false, }; - if !self.walk_inner(f, &path.grow(name), sub_reg_cfg, escape) { + if !self.walk_inner(f, ctx) { return false; } + } else { + // 如果当前子树已选跳过,不可能再选择终止 + assert!(self.walk_inner(f, None)); } } // 当前节点结束 @@ -70,28 +70,35 @@ impl Walker<'_> { let len = len.into_u32() as usize; let (value, tail) = tail.split_at((len + Blk::LEN - 1) / Blk::LEN); // 如果当前子树需要解析 - if !escape { + if let Some(ctx_) = ctx.as_ref() { let op = match self.prop_name(*nameoff) { b"#address-cells" if value.len() == 1 => { - sub_reg_cfg.address_cells = value[0].into_u32(); + cells.address = value[0].into_u32(); StepOver } b"#size-cells" if value.len() == 1 => { - sub_reg_cfg.size_cells = value[0].into_u32(); + cells.size = value[0].into_u32(); + StepOver + } + b"#interrupt-cells" if value.len() == 1 => { + cells.interrupt = value[0].into_u32(); StepOver } - b"reg" if value.len() % reg_cfg.item_size() == 0 => f( - path, + b"reg" if value.len() % (ctx_.cells().reg_size()) == 0 => f( + ctx_, DtbObj::Property(Property::Reg(Reg { buf: value, - cfg: reg_cfg, + cfg: RegCfg { + address_cells: ctx_.cells().address, + size_cells: ctx_.cells().size, + }, })), ), - name => f(path, DtbObj::Property(Property::new(name, value, len))), + name => f(ctx_, DtbObj::Property(Property::new(name, value, len))), }; match op { StepInto | StepOver => {} - StepOut => escape = true, + StepOut => ctx = None, Terminate => return false, }; } From e9e4b1fecee91c42dd17c5116acbae208333b543 Mon Sep 17 00:00:00 2001 From: YdrMaster Date: Tue, 19 Jul 2022 08:36:52 +0800 Subject: [PATCH 5/5] pump to 0.2.0-alpha.3 Signed-off-by: YdrMaster --- CHANGELOG.md | 2 +- Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 33b9d3b..6a49a40 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,7 +10,7 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## Unreleased +## [0.2.0-alpha.3](https://github.com/YdrMaster/dtb-walker/releases/tag/0.2.0-alpha.3) - 2022-07-19 ### Change diff --git a/Cargo.toml b/Cargo.toml index b2e54b1..cccfea8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "dtb-walker" description = "A simple package for DTB depth-first walking." -version = "0.2.0-alpha.2" +version = "0.2.0-alpha.3" edition = "2021" authors = ["YdrMaster "] repository = "https://github.com/YdrMaster/dtb-walker.git"