diff options
author | Thomas Bertschinger <tahbertschinger@gmail.com> | 2024-04-23 21:43:25 -0600 |
---|---|---|
committer | Thomas Bertschinger <tahbertschinger@gmail.com> | 2024-05-07 21:29:32 -0400 |
commit | 16f2849433aafd33eae8539536169f86df124dfd (patch) | |
tree | 6431313e883f0bf3bc9eca36106c23bd48f3fb98 /src/commands/debug/parser.rs | |
parent | fbb223308961067a44d343cbca515aa12a745bde (diff) |
WIP: bcachefs: new debug command
Signed-off-by: Thomas Bertschinger <tahbertschinger@gmail.com>
Diffstat (limited to 'src/commands/debug/parser.rs')
-rw-r--r-- | src/commands/debug/parser.rs | 89 |
1 files changed, 89 insertions, 0 deletions
diff --git a/src/commands/debug/parser.rs b/src/commands/debug/parser.rs new file mode 100644 index 00000000..550860c9 --- /dev/null +++ b/src/commands/debug/parser.rs @@ -0,0 +1,89 @@ +use nom::branch::alt; +use nom::bytes::complete::{tag, take_while}; +use nom::character::complete::{alpha1, char, space1, u32, u64}; +use nom::combinator::{all_consuming, value}; +use nom::sequence::tuple; +use nom::IResult; + +use bch_bindgen::c::bpos; + +use crate::commands::debug::{DebugCommand, DumpCommand, UpdateCommand}; + +fn parse_bpos(input: &str) -> IResult<&str, bpos> { + let (input, (inode, _, offset, _, snapshot)) = tuple(( + u64, + char(':'), + u64, + char(':'), + alt((u32, value(u32::MAX, tag("U32_MAX")))), + ))(input)?; + + Ok(( + input, + bpos { + inode, + offset, + snapshot, + }, + )) +} + +fn parse_dump_cmd(input: &str) -> IResult<&str, DebugCommand> { + let (input, (_, btree, _, bpos)) = + all_consuming(tuple((space1, alpha1, space1, parse_bpos)))(input)?; + + Ok(( + input, + DebugCommand::Dump(DumpCommand { + btree: btree.to_string(), + bpos, + }), + )) +} + +fn symbol_name(input: &str) -> IResult<&str, &str> { + take_while(|c: char| c.is_alphabetic() || c == '_')(input) +} + +fn parse_update_cmd(input: &str) -> IResult<&str, DebugCommand> { + let (input, (_, btree, _, bpos, _, bkey, _, field, _, value)) = all_consuming(tuple(( + space1, + alpha1, + space1, + parse_bpos, + space1, + symbol_name, + char('.'), + symbol_name, + char('='), + u64, + )))(input)?; + + Ok(( + input, + DebugCommand::Update(UpdateCommand { + btree: btree.to_string(), + bpos, + bkey: bkey.to_string(), + field: field.to_string(), + value, + }), + )) +} + +fn parse_command_inner(input: &str) -> IResult<&str, DebugCommand> { + let (input, cmd) = alt((tag("dump"), tag("update")))(input)?; + + match cmd { + "dump" => parse_dump_cmd(input), + "update" => parse_update_cmd(input), + _ => unreachable!(), + } +} + +pub fn parse_command(input: &str) -> Option<DebugCommand> { + match parse_command_inner(input) { + Ok((_, c)) => Some(c), + Err(_) => None, + } +} |