Skip to content

Commit

Permalink
wip ellipsis tokens
Browse files Browse the repository at this point in the history
  • Loading branch information
misson20000 committed Oct 29, 2024
1 parent deed567 commit 0e72956
Show file tree
Hide file tree
Showing 10 changed files with 124 additions and 47 deletions.
2 changes: 1 addition & 1 deletion src/model/document/structure.rs
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ impl ContentDisplay {
match self {
ContentDisplay::None => None,
ContentDisplay::Hexdump { line_pitch, .. } => Some(*line_pitch),
ContentDisplay::Hexstring => None,
ContentDisplay::Hexstring => Some(32.into()),
}
}

Expand Down
48 changes: 44 additions & 4 deletions src/model/listing/line.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,10 @@ pub enum LineType {
title: Option<token::Title>,
tokens: collections::VecDeque<token::Token>
},
Ellipsis {
title: Option<token::Title>,
token: token::Ellipsis,
},
}

#[derive(Debug, PartialEq, Eq)]
Expand Down Expand Up @@ -178,6 +182,8 @@ impl Line {
token::Token::SummaryPunctuation(_) |
token::Token::SummaryLabel(_) => panic!("Got Summary-type token but wasn't told we were in a summary"),

token::Token::Ellipsis(t) => LineType::Ellipsis { title: None, token: t },

token::Token::Hexdump(token) => LineType::Hexdump {
title: None,
node: token.common.node.clone(),
Expand Down Expand Up @@ -279,6 +285,21 @@ impl Line {
token: hexstring_token,
}, LinePushResult::Accepted),

/* An ellipsis token can end a line */
(LineType::Empty, token::Token::Ellipsis(token)) => (LineType::Ellipsis {
title: None,
token
}, LinePushResult::Accepted),

/* A title token can occur on the same line as an ellipsis if the title is inline and there isn't already a title. */
(LineType::Ellipsis { title: None, token: ellipsis_token }, token::Token::Title(token))
if sync::Arc::ptr_eq(&token.common.node, &ellipsis_token.common.node)
&& token.common.node.props.title_display.is_inline()
=> (LineType::Ellipsis {
title: Some(token),
token: ellipsis_token,
}, LinePushResult::Accepted),

/* Summaries... */
(LineType::Empty, token::Token::SummaryEpilogue(token)) => (LineType::Summary {
title: None,
Expand All @@ -304,11 +325,13 @@ impl Line {
(LineType::Summary { title, tokens }, result)
},

/*
(LineType::Empty, _) => {
(LineType::Empty, LinePushResult::BadPosition)
},
},
*/

(ty, _) => (ty, LinePushResult::Rejected)
(ty, _) => (ty, LinePushResult::Rejected)
};

self.ty = new_ty;
Expand Down Expand Up @@ -394,7 +417,22 @@ impl Line {
title: Some(title_token),
token,
}, LinePushResult::Accepted),


/* An ellipsis token can begin a line */
(LineType::Empty, token::Token::Ellipsis(token)) => (LineType::Ellipsis {
title: None,
token
}, LinePushResult::Completed),

/* An ellipsis token can occur on the same line as a title if the title is inline. */
(LineType::Title(title_token), token::Token::Ellipsis(token))
if sync::Arc::ptr_eq(title_token.node(), token.node())
&& title_token.node().props.title_display.is_inline()
=> (LineType::Ellipsis {
title: Some(title_token),
token,
}, LinePushResult::Accepted),

/* Summaries... */
(LineType::Empty, token::Token::SummaryPreamble(token)) => (LineType::Summary {
title: None,
Expand Down Expand Up @@ -448,6 +486,7 @@ impl Line {
LineType::Hexdump { title, tokens, .. } => util::PhiIteratorOf5::I3(title.as_ref().map(AsTokenRef::as_token_ref).into_iter().chain(tokens.iter().map(AsTokenRef::as_token_ref))),
LineType::Hexstring { title, token, .. } => util::PhiIteratorOf5::I4(title.as_ref().map(AsTokenRef::as_token_ref).into_iter().chain(iter::once(token.as_token_ref()))),
LineType::Summary { title, tokens, .. } => util::PhiIteratorOf5::I5(title.as_ref().map(AsTokenRef::as_token_ref).into_iter().chain(tokens.iter().map(AsTokenRef::as_token_ref))),
LineType::Ellipsis { title, token } => util::PhiIteratorOf5::I4(title.as_ref().map(AsTokenRef::as_token_ref).into_iter().chain(iter::once(token.as_token_ref()))),
}
}

Expand All @@ -459,6 +498,7 @@ impl Line {
LineType::Hexdump { title, tokens, .. } => util::PhiIteratorOf5::I3(title.map(Into::into).into_iter().chain(tokens.into_iter().map(Into::into))),
LineType::Hexstring { title, token, .. } => util::PhiIteratorOf5::I4(title.map(Into::into).into_iter().chain(iter::once(token.into()))),
LineType::Summary { title, tokens, .. } => util::PhiIteratorOf5::I5(title.map(Into::into).into_iter().chain(tokens.into_iter())),
LineType::Ellipsis { title, token } => util::PhiIteratorOf5::I4(title.map(Into::into).into_iter().chain(iter::once(token.into()))),
}
}
}
Expand Down Expand Up @@ -530,6 +570,7 @@ impl fmt::Debug for Line {
LineType::Hexdump { .. } => &"hexdump",
LineType::Hexstring { .. } => &"hexstring",
LineType::Summary { .. } => &"summary",
LineType::Ellipsis { .. } => &"ellipsis",
})
.field("tokens", &self.iter_tokens().map(|tok| token::TokenTestFormat(tok)).collect::<Vec<_>>())
.finish()
Expand Down Expand Up @@ -562,7 +603,6 @@ mod tests {
depth: 0,
},
extent: addr::Extent::sized_u64(0, 8),
truncated: false,
})), LinePushResult::Accepted);

assert_eq!(line.push_front(token::Token::Title(token::Title {
Expand Down
44 changes: 38 additions & 6 deletions src/model/listing/stream.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ enum PositionState {
index: usize
},
Hexstring(addr::Extent, usize),
Ellipsis(addr::Extent, usize),

SummaryPreamble,
SummaryOpener,
Expand Down Expand Up @@ -351,6 +352,7 @@ impl Position {
PositionState::MetaContent(offset, index) => IntermediatePortState::NormalContent(Some(destructured_childhood.offset + offset.to_size()), destructured_child_index + *index),
PositionState::Hexdump { extent, index, .. } => IntermediatePortState::NormalContent(Some(destructured_childhood.offset + extent.begin.to_size()), destructured_child_index + *index),
PositionState::Hexstring(extent, index) => IntermediatePortState::NormalContent(Some(destructured_childhood.offset + extent.begin.to_size()), destructured_child_index + *index),
PositionState::Ellipsis(extent, index) => IntermediatePortState::NormalContent(Some(destructured_childhood.offset + extent.begin.to_size()), destructured_child_index + *index),
PositionState::SummaryLeaf => IntermediatePortState::NormalContent(Some(destructured_childhood.offset), *destructured_child_index),

PositionState::SummaryLabel(i)
Expand Down Expand Up @@ -378,6 +380,7 @@ impl Position {
PositionState::MetaContent(offset, index) => IntermediatePortState::NormalContent(Some(*offset), *index),
PositionState::Hexdump { extent, index, .. } => IntermediatePortState::NormalContent(Some(extent.begin), *index),
PositionState::Hexstring(extent, index) => IntermediatePortState::NormalContent(Some(extent.begin), *index),
PositionState::Ellipsis(extent, index) => IntermediatePortState::NormalContent(Some(extent.begin), *index),

PositionState::SummaryPreamble => IntermediatePortState::Finished(PositionState::Title),
PositionState::SummaryOpener => IntermediatePortState::NormalContent(Some(addr::unit::NULL), 0),
Expand All @@ -403,6 +406,7 @@ impl Position {
PositionState::MetaContent(_, index) => IntermediatePortState::SummaryLabel(*index),
PositionState::Hexdump { index, .. } => IntermediatePortState::SummaryLabel(*index),
PositionState::Hexstring(_, index) => IntermediatePortState::SummaryLabel(*index),
PositionState::Ellipsis(_, index) => IntermediatePortState::SummaryLabel(*index),

PositionState::SummaryPreamble => IntermediatePortState::Finished(PositionState::SummaryPreamble),
PositionState::SummaryOpener => IntermediatePortState::Finished(PositionState::SummaryOpener),
Expand Down Expand Up @@ -705,7 +709,13 @@ impl Position {
extent,
line: line_extent,
}.into()),
PositionState::Hexstring(extent, _) => TokenGenerationResult::Ok(token::Hexstring::new_maybe_truncate(common.adjust_depth(1), extent).into()),
PositionState::Hexstring(extent, _) => TokenGenerationResult::Ok(token::Hexstring {
common: common.adjust_depth(1),
extent,
}.into()),
PositionState::Ellipsis(_, _) => TokenGenerationResult::Ok(token::Ellipsis {
common: common.adjust_depth(1),
}.into()),

PositionState::SummaryPreamble => TokenGenerationResult::Ok(token::SummaryPreamble {
common,
Expand Down Expand Up @@ -755,8 +765,14 @@ impl Position {
kind: token::PunctuationKind::Space,
}.into(),
// Disallow hexdumps in summaries. This is a little nasty. Review later.
structure::ContentDisplay::Hexdump { .. } => token::Hexstring::new_maybe_truncate(common, extent).into(),
structure::ContentDisplay::Hexstring => token::Hexstring::new_maybe_truncate(common, extent).into(),
structure::ContentDisplay::Hexdump { .. } => token::Hexstring {
common,
extent,
}.into(),
structure::ContentDisplay::Hexstring => token::Hexstring {
common,
extent,
}.into(),
})
},
PositionState::SummaryValueEnd => TokenGenerationResult::Skip,
Expand Down Expand Up @@ -870,7 +886,7 @@ impl Position {
let interstitial = addr::Extent::between(interstitial.0, interstitial.1);

self.state = match self.node.props.content_display {
structure::ContentDisplay::None => PositionState::MetaContent(interstitial.begin, index),
structure::ContentDisplay::None => PositionState::Ellipsis(interstitial, index),
structure::ContentDisplay::Hexdump { line_pitch, gutter_pitch: _ } => {
let line_extent = self.get_line_extent(offset - addr::unit::BIT, line_pitch);

Expand Down Expand Up @@ -898,6 +914,10 @@ impl Position {
self.state = PositionState::MetaContent(extent.begin, index);
true
},
PositionState::Ellipsis(extent, index) => {
self.state = PositionState::MetaContent(extent.begin, index);
true
},

PositionState::SummaryOpener => {
self.try_ascend(AscendDirection::Prev)
Expand Down Expand Up @@ -1020,7 +1040,7 @@ impl Position {
let interstitial = addr::Extent::between(interstitial.0, interstitial.1);

self.state = match self.node.props.content_display {
structure::ContentDisplay::None => PositionState::MetaContent(interstitial.end, index),
structure::ContentDisplay::None => PositionState::Ellipsis(interstitial, index),
structure::ContentDisplay::Hexdump { line_pitch, gutter_pitch: _ } => {
let line_extent = self.get_line_extent(offset, line_pitch);

Expand Down Expand Up @@ -1048,6 +1068,10 @@ impl Position {
self.state = PositionState::MetaContent(extent.end, index);
true
},
PositionState::Ellipsis(extent, index) => {
self.state = PositionState::MetaContent(extent.end, index);
true
},

PositionState::SummaryOpener => {
if self.node.children.is_empty() {
Expand Down Expand Up @@ -1258,6 +1282,7 @@ impl Position {
PositionState::MetaContent(offset, _) => offset,
PositionState::Hexdump { extent, .. } => extent.begin,
PositionState::Hexstring(extent, _) => extent.begin,
PositionState::Ellipsis(extent, _) => extent.begin,
PositionState::SummaryPreamble => addr::unit::NULL,
PositionState::SummaryOpener => addr::unit::NULL,
PositionState::SummaryLabel(i) => self.node.children[i].offset,
Expand All @@ -1280,6 +1305,7 @@ impl Position {
PositionState::MetaContent(_, _) => false,
PositionState::Hexdump { .. } => false,
PositionState::Hexstring(_, _) => false,
PositionState::Ellipsis(_, _) => false,

PositionState::SummaryPreamble => true,
PositionState::SummaryOpener => true,
Expand Down Expand Up @@ -1606,6 +1632,8 @@ mod cmp {
super::PositionState::Hexdump { index, .. } => index.cmp(child_index),
super::PositionState::Hexstring(_, i) if i == child_index => std::cmp::Ordering::Less,
super::PositionState::Hexstring(_, i) => i.cmp(child_index),
super::PositionState::Ellipsis(_, i) if i == child_index => std::cmp::Ordering::Less,
super::PositionState::Ellipsis(_, i) => i.cmp(child_index),
super::PositionState::SummaryPreamble => std::cmp::Ordering::Less,
super::PositionState::SummaryOpener => std::cmp::Ordering::Less,
super::PositionState::SummaryLabel(i) if i == child_index => std::cmp::Ordering::Less,
Expand Down Expand Up @@ -1712,6 +1740,7 @@ mod cmp {
super::PositionState::MetaContent(addr, index) => (StateGroup::NormalContent, 0, *index, *addr, 0),
super::PositionState::Hexdump { extent, line_extent: _, index } => (StateGroup::NormalContent, 0, *index, extent.begin, 1),
super::PositionState::Hexstring(extent, index) => (StateGroup::NormalContent, 0, *index, extent.begin, 1),
super::PositionState::Ellipsis(extent, index) => (StateGroup::NormalContent, 0, *index, extent.begin, 1),
super::PositionState::SummaryPreamble => (StateGroup::SummaryContent, 0, 0, addr::unit::NULL, 0),
super::PositionState::SummaryOpener => (StateGroup::SummaryContent, 1, 0, addr::unit::NULL, 0),
super::PositionState::SummaryLabel(x) => (StateGroup::SummaryContent, 2, 2*x+1, addr::unit::NULL, 0),
Expand Down Expand Up @@ -1935,7 +1964,10 @@ pub mod xml {
extent: inflate_extent(&self.node),
line: inflate_line_extent(&self.node)
}.into(),
"hexstring" => token::Hexstring::new_maybe_truncate(common, inflate_extent(&self.node)).into(),
"hexstring" => token::Hexstring {
common,
extent: inflate_extent(&self.node)
}.into(),
tn => panic!("invalid token def: '{}'", tn)
}
}
Expand Down
30 changes: 6 additions & 24 deletions src/model/listing/token.rs
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,11 @@ declare_tokens! {
SummaryLabel {
},

/// Indicates that data is being skipped. Probably either because of ContentDisplay::Hidden or because it's being truncated by summary mode.
#[derive(Debug)]
Ellipsis {
},

/// Formatted two-column hexdump+asciidump. What you expect to see out of a hex editor.
#[derive(Debug)]
Hexdump {
Expand All @@ -207,7 +212,6 @@ declare_tokens! {
#[derive(Debug)]
Hexstring {
pub extent: addr::Extent,
pub truncated: bool,
},
}

Expand All @@ -225,9 +229,6 @@ pub enum PunctuationKind {

/* should accept cursor */
CloseBracket,

/* should not accept cursor */
Ellipsis,
}

#[derive(Clone)]
Expand Down Expand Up @@ -325,6 +326,7 @@ impl<'a> fmt::Display for TokenTestFormat<'a> {
TokenRef::SummaryPunctuation(token) => write!(f, "(#{}) {}", i, token.kind.as_str()),
TokenRef::Title(token) => write!(f, "(#{}) {}: ", i, &token.common.node.props.name),
TokenRef::SummaryLabel(token) => write!(f, "(#{}) {}: ", i, &token.common.node.props.name),
TokenRef::Ellipsis(_) => write!(f, "(#{}) ...", i),
TokenRef::Hexdump(token) => {
write!(f, "(#{}) ", i)?;
for j in 0..token.extent.length().bytes {
Expand Down Expand Up @@ -359,7 +361,6 @@ impl PunctuationKind {
PunctuationKind::Comma => ", ",
PunctuationKind::OpenBracket => "{",
PunctuationKind::CloseBracket => "}",
PunctuationKind::Ellipsis => "...",
}
}

Expand All @@ -378,25 +379,6 @@ impl Hexdump {
}

impl Hexstring {
pub fn new_maybe_truncate(common: TokenCommon, extent: addr::Extent) -> Hexstring {
// TODO: make this configurable
const LIMIT: addr::Size = addr::Size::new(16);

if extent.length() > LIMIT {
Hexstring {
common,
extent: addr::Extent::sized(extent.begin, LIMIT),
truncated: true,
}
} else {
Hexstring {
common,
extent,
truncated: false,
}
}
}

pub fn absolute_extent(&self) -> addr::Extent {
self.extent.rebase(self.common.node_addr)
}
Expand Down
2 changes: 1 addition & 1 deletion src/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ impl<T> DoubleEndedIterator for NeverIterator<T> {

// TODO: fix me up when we get variadic generics
// TODO: remove me when we get anonymous sum types
seq!(N in 1..=6 {
seq!(N in 1..=7 {
pub enum PhiIterator<Item, #(I~N: Iterator<Item = Item> = NeverIterator<Item>,)*> {
#(I~N(I~N),)*
}
Expand Down
7 changes: 4 additions & 3 deletions src/view/gsc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ pub enum Entry {
Dot,
Colon,
Space,
Ellipsis
}

pub struct Cache {
Expand All @@ -33,7 +34,7 @@ pub struct Cache {
gs_ascii: [pango::GlyphString; 0x7f-0x20], // ' ', '!', '"', ..., 'y', 'z', '{', '|', '}', '~'
gs_dot: pango::GlyphString, // "."
gs_colon: pango::GlyphString, // ": "
gs_ellipsis: pango::GlyphString, // "..."
gs_ellipsis: pango::GlyphString, // ""

space_width: i32,
}
Expand Down Expand Up @@ -77,7 +78,7 @@ impl Cache {
gs_ascii: std::array::from_fn(|i| Self::shape(pg, std::str::from_utf8(&[0x20 + i as u8]).unwrap())),
gs_dot: Self::shape(pg, "."),
gs_colon: Self::shape(pg, ": "),
gs_ellipsis: Self::shape(pg, "..."),
gs_ellipsis: Self::shape(pg, ""),

space_width,
}
Expand Down Expand Up @@ -106,14 +107,14 @@ impl Cache {
token::PunctuationKind::Comma => Some(&self.gs_comma),
token::PunctuationKind::OpenBracket => Some(&self.gs_open),
token::PunctuationKind::CloseBracket => Some(&self.gs_close),
token::PunctuationKind::Ellipsis => Some(&self.gs_ellipsis),
},
Entry::Digit(digit) => self.gs_digit.get(digit as usize),
Entry::PrintableAscii(ord) if (0x20..0x7f).contains(&ord) => Some(&self.gs_ascii[ord as usize - 0x20]),
Entry::PrintableAscii(_) => Some(&self.gs_dot),
Entry::Dot => Some(&self.gs_dot),
Entry::Colon => Some(&self.gs_colon),
Entry::Space => Some(&self.gs_space),
Entry::Ellipsis => Some(&self.gs_ellipsis),
}
}

Expand Down
Loading

0 comments on commit 0e72956

Please sign in to comment.