mirror of
https://github.com/encounter/objdiff.git
synced 2025-12-16 16:37:06 +00:00
Restructure diffing code & initial 3-way diffing (WIP)
This commit is contained in:
@@ -5,7 +5,10 @@ use egui::{
|
||||
SelectableLabel, TextEdit, Ui, Vec2, Widget,
|
||||
};
|
||||
use egui_extras::{Size, StripBuilder};
|
||||
use objdiff_core::obj::{ObjInfo, ObjSection, ObjSectionKind, ObjSymbol, ObjSymbolFlags};
|
||||
use objdiff_core::{
|
||||
diff::{ObjDiff, ObjSymbolDiff},
|
||||
obj::{ObjInfo, ObjSection, ObjSectionKind, ObjSymbol, ObjSymbolFlags},
|
||||
};
|
||||
|
||||
use crate::{
|
||||
app::AppConfigRef,
|
||||
@@ -17,7 +20,7 @@ use crate::{
|
||||
views::{appearance::Appearance, function_diff::FunctionViewState, write_text},
|
||||
};
|
||||
|
||||
pub struct SymbolReference {
|
||||
pub struct SymbolRefByName {
|
||||
pub symbol_name: String,
|
||||
pub demangled_symbol_name: Option<String>,
|
||||
pub section_name: String,
|
||||
@@ -50,7 +53,7 @@ pub struct DiffViewState {
|
||||
#[derive(Default)]
|
||||
pub struct SymbolViewState {
|
||||
pub highlighted_symbol: Option<String>,
|
||||
pub selected_symbol: Option<SymbolReference>,
|
||||
pub selected_symbol: Option<SymbolRefByName>,
|
||||
pub reverse_fn_order: bool,
|
||||
pub disable_reverse_fn_order: bool,
|
||||
pub show_hidden_symbols: bool,
|
||||
@@ -180,6 +183,7 @@ fn symbol_hover_ui(ui: &mut Ui, symbol: &ObjSymbol, appearance: &Appearance) {
|
||||
fn symbol_ui(
|
||||
ui: &mut Ui,
|
||||
symbol: &ObjSymbol,
|
||||
symbol_diff: &ObjSymbolDiff,
|
||||
section: Option<&ObjSection>,
|
||||
state: &mut SymbolViewState,
|
||||
appearance: &Appearance,
|
||||
@@ -210,7 +214,7 @@ fn symbol_ui(
|
||||
write_text("h", appearance.deemphasized_text_color, &mut job, appearance.code_font.clone());
|
||||
}
|
||||
write_text("] ", appearance.text_color, &mut job, appearance.code_font.clone());
|
||||
if let Some(match_percent) = symbol.match_percent {
|
||||
if let Some(match_percent) = symbol_diff.match_percent {
|
||||
write_text("(", appearance.text_color, &mut job, appearance.code_font.clone());
|
||||
write_text(
|
||||
&format!("{match_percent:.0}%"),
|
||||
@@ -228,14 +232,14 @@ fn symbol_ui(
|
||||
if response.clicked() {
|
||||
if let Some(section) = section {
|
||||
if section.kind == ObjSectionKind::Code {
|
||||
state.selected_symbol = Some(SymbolReference {
|
||||
state.selected_symbol = Some(SymbolRefByName {
|
||||
symbol_name: symbol.name.clone(),
|
||||
demangled_symbol_name: symbol.demangled_name.clone(),
|
||||
section_name: section.name.clone(),
|
||||
});
|
||||
ret = Some(View::FunctionDiff);
|
||||
} else if section.kind == ObjSectionKind::Data {
|
||||
state.selected_symbol = Some(SymbolReference {
|
||||
state.selected_symbol = Some(SymbolRefByName {
|
||||
symbol_name: section.name.clone(),
|
||||
demangled_symbol_name: None,
|
||||
section_name: section.name.clone(),
|
||||
@@ -262,7 +266,7 @@ fn symbol_matches_search(symbol: &ObjSymbol, search_str: &str) -> bool {
|
||||
#[must_use]
|
||||
fn symbol_list_ui(
|
||||
ui: &mut Ui,
|
||||
obj: &ObjInfo,
|
||||
obj: &(ObjInfo, ObjDiff),
|
||||
state: &mut SymbolViewState,
|
||||
lower_search: &str,
|
||||
appearance: &Appearance,
|
||||
@@ -273,34 +277,50 @@ fn symbol_list_ui(
|
||||
ui.style_mut().override_text_style = Some(egui::TextStyle::Monospace);
|
||||
ui.style_mut().wrap = Some(false);
|
||||
|
||||
if !obj.common.is_empty() {
|
||||
if !obj.0.common.is_empty() {
|
||||
CollapsingHeader::new(".comm").default_open(true).show(ui, |ui| {
|
||||
for symbol in &obj.common {
|
||||
ret = ret.or(symbol_ui(ui, symbol, None, state, appearance));
|
||||
for (symbol, symbol_diff) in obj.0.common.iter().zip(&obj.1.common) {
|
||||
ret = ret.or(symbol_ui(ui, symbol, symbol_diff, None, state, appearance));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
for section in &obj.sections {
|
||||
for (section, section_diff) in obj.0.sections.iter().zip(&obj.1.sections) {
|
||||
CollapsingHeader::new(format!("{} ({:x})", section.name, section.size))
|
||||
.id_source(Id::new(section.name.clone()).with(section.index))
|
||||
.default_open(true)
|
||||
.show(ui, |ui| {
|
||||
if section.kind == ObjSectionKind::Code && state.reverse_fn_order {
|
||||
for symbol in section.symbols.iter().rev() {
|
||||
for (symbol, symbol_diff) in
|
||||
section.symbols.iter().zip(§ion_diff.symbols).rev()
|
||||
{
|
||||
if !symbol_matches_search(symbol, lower_search) {
|
||||
continue;
|
||||
}
|
||||
ret =
|
||||
ret.or(symbol_ui(ui, symbol, Some(section), state, appearance));
|
||||
ret = ret.or(symbol_ui(
|
||||
ui,
|
||||
symbol,
|
||||
symbol_diff,
|
||||
Some(section),
|
||||
state,
|
||||
appearance,
|
||||
));
|
||||
}
|
||||
} else {
|
||||
for symbol in §ion.symbols {
|
||||
for (symbol, symbol_diff) in
|
||||
section.symbols.iter().zip(§ion_diff.symbols)
|
||||
{
|
||||
if !symbol_matches_search(symbol, lower_search) {
|
||||
continue;
|
||||
}
|
||||
ret =
|
||||
ret.or(symbol_ui(ui, symbol, Some(section), state, appearance));
|
||||
ret = ret.or(symbol_ui(
|
||||
ui,
|
||||
symbol,
|
||||
symbol_diff,
|
||||
Some(section),
|
||||
state,
|
||||
appearance,
|
||||
));
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user