Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions librz/cons/d/sepia
Original file line number Diff line number Diff line change
Expand Up @@ -79,3 +79,6 @@ ec diff.unknown rgb:881798
ec diff.new rgb:c50f1f
ec diff.match rgb:767676
ec diff.unmatch rgb:c19c00

ec gui.match.perfect rgb:00ff00
ec gui.match.partial rgb:ff0000
4 changes: 4 additions & 0 deletions librz/cons/pal.c
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,8 @@ static struct {
{ "diff.new", rz_offsetof(RzConsPrintablePalette, diff_new), rz_offsetof(RzConsPalette, diff_new) },
{ "diff.match", rz_offsetof(RzConsPrintablePalette, diff_match), rz_offsetof(RzConsPalette, diff_match) },
{ "diff.unmatch", rz_offsetof(RzConsPrintablePalette, diff_unmatch), rz_offsetof(RzConsPalette, diff_unmatch) },
{ "gui.match.perfect", rz_offsetof(RzConsPrintablePalette, gui_match_perfect), rz_offsetof(RzConsPalette, gui_match_perfect) },
{ "gui.match.partial", rz_offsetof(RzConsPrintablePalette, gui_match_partial), rz_offsetof(RzConsPalette, gui_match_partial) },

{ "gui.cflow", rz_offsetof(RzConsPrintablePalette, gui_cflow), rz_offsetof(RzConsPalette, gui_cflow) },
{ "gui.dataoffset", rz_offsetof(RzConsPrintablePalette, gui_dataoffset), rz_offsetof(RzConsPalette, gui_dataoffset) },
Expand Down Expand Up @@ -242,6 +244,8 @@ RZ_API void rz_cons_pal_init(RzConsContext *ctx) {
ctx->cpal.diff_new = (RzColor)RzColor_RED;
ctx->cpal.diff_match = (RzColor)RzColor_GRAY;
ctx->cpal.diff_unmatch = (RzColor)RzColor_YELLOW;
ctx->cpal.gui_match_partial = (RzColor)RzColor_RED;
ctx->cpal.gui_match_perfect = (RzColor)RzColor_GREEN;

rz_cons_pal_free(ctx);
ctx->pal.reset = Color_RESET; // reset is not user accessible, const char* is ok
Expand Down
2 changes: 2 additions & 0 deletions librz/core/cmd_descs/cmd_descs.c
Original file line number Diff line number Diff line change
Expand Up @@ -12280,6 +12280,8 @@ static const RzCmdDescDetailEntry cmd_eval_color_list_help_Color_space_Palette_s
{ .text = "diff.new", .arg_str = NULL, .comment = "Color for new diff" },
{ .text = "diff.match", .arg_str = NULL, .comment = "Color for matched diff" },
{ .text = "diff.unmatch", .arg_str = NULL, .comment = "Color for unmatched diff" },
{ .text = "gui.match.perfect", .arg_str = NULL, .comment = "Color for perfectly matched GUI diff" },
{ .text = "gui.match.partial", .arg_str = NULL, .comment = "Color for partially matched GUI diff" },
{ .text = "gui.cflow", .arg_str = NULL, .comment = "Color for GUI control flow" },
{ .text = "gui.dataoffset", .arg_str = NULL, .comment = "Color for GUI data offset" },
{ .text = "gui.background", .arg_str = NULL, .comment = "Color for GUI background" },
Expand Down
4 changes: 4 additions & 0 deletions librz/core/cmd_descs/cmd_eval.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,10 @@ commands:
comment: "Color for matched diff"
- text: "diff.unmatch"
comment: "Color for unmatched diff"
- text: "gui.match.perfect"
comment: "Color for perfectly matched GUI diff"
- text: "gui.match.partial"
comment: "Color for partially matched GUI diff"
- text: "gui.cflow"
comment: "Color for GUI control flow"
- text: "gui.dataoffset"
Expand Down
113 changes: 101 additions & 12 deletions librz/diff/unified_diff.c
Original file line number Diff line number Diff line change
Expand Up @@ -109,19 +109,13 @@ static inline void diff_unified_append_data(RzDiff *diff, const void *array, st3
rz_strbuf_appendf(sb, "%s\n", ecol);
}

// Assumes that color is true, diffing lines, op->type is RZ_DIFF_OP_REPLACE
// and that the number of inserted lines is equal to the number of deleted
// lines.
static inline void diff_unified_lines_hl(RzDiff *diff, RzDiffOp *op, RzStrBuf *sb, char del_prefix, char ins_prefix) {
static inline void fill_char_bounds(RzDiff *diff, RzDiffOp *op, st32 *char_bounds, int num_bounds) {
RzDiffMethodElemAt elem_at = diff->methods.elem_at;
RzDiffMethodStringify stringify = diff->methods.stringify;
int len = 0;
const char *p;
const void *elem;
RzStrBuf tmp, tmp2;
const char *ecol = Color_RESET;
const char *ebgcol = Color_RESET_BG;

const void *a_array = diff->a;
st32 a_beg = op->a_beg;
if (a_beg < 0) {
Expand All @@ -135,11 +129,6 @@ static inline void diff_unified_lines_hl(RzDiff *diff, RzDiffOp *op, RzStrBuf *s
b_beg = 0;
}
st32 b_end = op->b_end;

ut32 num_nl = count_newlines(diff, a_array, a_beg, a_end);
// + 1 just in case there's no nl at end
ut32 num_bounds = num_nl + 1;
st32 *char_bounds = malloc(sizeof(st32) * 2 * num_bounds);
if (!char_bounds) {
return;
}
Expand Down Expand Up @@ -202,6 +191,46 @@ static inline void diff_unified_lines_hl(RzDiff *diff, RzDiffOp *op, RzStrBuf *s
}
rz_strbuf_fini(&tmp);
}
}

// Assumes that color is true, diffing lines, op->type is RZ_DIFF_OP_REPLACE
// and that the number of inserted lines is equal to the number of deleted
// lines.
static inline void diff_unified_lines_hl(RzDiff *diff, RzDiffOp *op, RzStrBuf *sb, char del_prefix, char ins_prefix) {
RzDiffMethodElemAt elem_at = diff->methods.elem_at;
RzDiffMethodStringify stringify = diff->methods.stringify;
int len = 0;
const char *p;
const void *elem;
RzStrBuf tmp /*, tmp2*/;
const char *ecol = Color_RESET;
const char *ebgcol = Color_RESET_BG;

const void *a_array = diff->a;
st32 a_beg = op->a_beg;
if (a_beg < 0) {
a_beg = 0;
}
st32 a_end = op->a_end;

const void *b_array = diff->b;
st32 b_beg = op->b_beg;
if (b_beg < 0) {
b_beg = 0;
}
st32 b_end = op->b_end;

ut32 num_nl = count_newlines(diff, a_array, a_beg, a_end);
// + 1 just in case there's no nl at end
ut32 num_bounds = num_nl + 1;
st32 *char_bounds = malloc(sizeof(st32) * 2 * num_bounds);
if (!char_bounds) {
return;
}
fill_char_bounds(diff, op, char_bounds, num_bounds);

ut32 bounds_idx = 0;
bool newline = false;

// Show deleted lines
char prefix = del_prefix;
Expand Down Expand Up @@ -408,6 +437,66 @@ RZ_API RZ_OWN char *rz_diff_unified_text(RZ_NONNULL RzDiff *diff, RZ_NULLABLE co
return NULL;
}

/**
* \brief stringifies the DiffOpLines
*/
RZ_API RZ_OWN char *rz_diff_op_stringify(RZ_NONNULL RzDiff *diff, RZ_NONNULL RzDiffOp *op, bool is_a) {
rz_return_val_if_fail(diff && op, rz_str_dup(""));
RzDiffMethodElemAt elem_at = diff->methods.elem_at;
RzDiffMethodStringify stringify = diff->methods.stringify;
int len = 0;
ut32 count = 0;
const char *p;
const void *elem;
RzStrBuf sb, tmp;
bool newline = false;
bool is_bytes = DIFF_IS_BYTES_METHOD(diff->methods);
const void *array = is_a ? diff->a : diff->b;
st32 beg = is_a ? op->a_beg : op->b_beg;
st32 end = is_a ? op->a_end : op->b_end;

if (beg < 0) {
beg = 0;
}

rz_strbuf_init(&sb);
for (st32 i = beg; i < end; ++i) {
if (newline || (is_bytes && count > 0 && !FAST_MOD64(count))) {
rz_strbuf_append(&sb, "\n");
newline = false;
}
rz_strbuf_init(&tmp);
elem = elem_at(array, i);
stringify(elem, &tmp);
len = rz_strbuf_length(&tmp);
p = rz_strbuf_get(&tmp);
count += len;
if (len > 0 && p[len - 1] == '\n') {
len--;
newline = true;
}
rz_strbuf_append_n(&sb, p, len);
rz_strbuf_fini(&tmp);
}
rz_strbuf_appendf(&sb, "\n");
char *res = rz_strbuf_drain_nofree(&sb);
rz_strbuf_fini(&sb);
return res;
}

/**
* \brief Produces a list of grouped RzDiffOp based on the diff->method
*/
RZ_API RZ_OWN RzList /*<RzList<RzDiffOp *> *>*/ *rz_diff_unified_text_grouped(RZ_NONNULL RzDiff *diff) {
rz_return_val_if_fail(diff && diff->methods.elem_at && diff->methods.stringify, NULL);
RzList *groups = NULL;

bool is_bytes = DIFF_IS_BYTES_METHOD(diff->methods);

groups = rz_diff_opcodes_grouped_new(diff, is_bytes ? RZ_DIFF_DEFAULT_N_GROUPS_BYTES : RZ_DIFF_DEFAULT_N_GROUPS);
return groups;
}

/**
* \brief Produces a diff output to convert A in B in a JSON format.
*
Expand Down
6 changes: 6 additions & 0 deletions librz/include/rz_cons.h
Original file line number Diff line number Diff line change
Expand Up @@ -266,10 +266,14 @@ typedef struct rz_cons_palette_t {
RzColor graph_ujump;
RzColor graph_traced;
RzColor graph_current;

/* Diff colors */
RzColor diff_match;
RzColor diff_unmatch;
RzColor diff_unknown;
RzColor diff_new;
RzColor gui_match_partial;
RzColor gui_match_perfect;
} RzConsPalette;

typedef struct rz_cons_printable_palette_t {
Expand Down Expand Up @@ -342,6 +346,8 @@ typedef struct rz_cons_printable_palette_t {
char *diff_unmatch;
char *diff_unknown;
char *diff_new;
char *gui_match_perfect;
char *gui_match_partial;
char *graph_true;
char *graph_false;
char *graph_ujump;
Expand Down
2 changes: 2 additions & 0 deletions librz/include/rz_diff.h
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,8 @@ RZ_API bool rz_diff_ratio(RZ_NONNULL RzDiff *diff, RZ_NONNULL double *result);
RZ_API bool rz_diff_sizes_ratio(RZ_NONNULL RzDiff *diff, RZ_NONNULL double *result);

RZ_API RZ_OWN char *rz_diff_unified_text(RZ_NONNULL RzDiff *diff, RZ_NULLABLE const char *from, RZ_NULLABLE const char *to, bool show_time, bool color);
RZ_API RZ_OWN RzList /*<RzList<RzDiffOp *> *>*/ *rz_diff_unified_text_grouped(RZ_NONNULL RzDiff *diff);
RZ_API RZ_OWN char *rz_diff_op_stringify(RZ_NONNULL RzDiff *diff, RZ_NONNULL RzDiffOp *op, bool is_a);
RZ_API RZ_OWN PJ *rz_diff_unified_json(RZ_NONNULL RzDiff *diff, RZ_NULLABLE const char *from, RZ_NULLABLE const char *to, bool show_time);

/* Distances algorithms */
Expand Down
6 changes: 5 additions & 1 deletion test/db/cmd/cmd_ec
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ ecc~gui_background
ecc foo_~gui_background
EOF
EXPECT=<<EOF
{"comment":{"rgb":[240,208,144]},"usrcmt":{"rgb":[240,240,240]},"args":{"rgb":[176,176,112]},"fname":{"rgb":[176,176,112]},"floc":{"rgb":[0,255,255]},"fline":{"rgb":[192,160,96]},"flag":{"rgb":[240,240,208]},"label":{"rgb":[112,128,128]},"help":{"rgb":[160,176,112]},"flow":{"rgb":[192,160,96]},"flow2":{"rgb":[240,224,192]},"prompt":{"rgb":[144,96,0]},"offset":{"rgb":[144,96,0]},"input":{"rgb":[192,160,96]},"invalid":{"rgb":[192,96,64]},"other":{"rgb":[176,160,96]},"b0x00":{"rgb":[64,48,16]},"b0x7f":{"rgb":[240,208,144]},"b0xff":{"rgb":[144,96,0]},"math":{"rgb":[208,176,112]},"bin":{"rgb":[240,224,192]},"btext":{"rgb":[240,224,192]},"push":{"rgb":[208,176,112]},"pop":{"rgb":[176,176,112]},"crypto":{"rgb":[0,0,255]},"jmp":{"rgb":[240,224,192]},"cjmp":{"rgb":[240,224,192]},"call":{"rgb":[255,255,255]},"nop":{"rgb":[112,128,128]},"ret":{"rgb":[160,176,112]},"trap":{"rgb":[64,48,16]},"ucall":{"rgb":[255,255,255]},"ujmp":{"rgb":[240,224,192]},"swi":{"rgb":[176,176,112]},"cmp":{"rgb":[192,160,96]},"reg":{"rgb":[192,160,96]},"creg":{"rgb":[144,96,0]},"num":{"rgb":[144,96,0]},"mov":{"rgb":[208,176,112]},"func_var":{"rgb":[240,208,144]},"func_var_type":{"rgb":[128,80,0]},"func_var_addr":{"rgb":[144,96,0]},"widget_bg":{"rgb":[208,176,112]},"widget_sel":{"rgb":[0,0,0]},"meta":{"rgb":[118,118,118]},"ai.read":{"rgb":[192,176,112]},"ai.write":{"rgb":[192,160,96]},"ai.exec":{"rgb":[208,176,112]},"ai.seq":{"rgb":[144,96,0]},"ai.ascii":{"rgb":[240,224,192]},"graph.box":{"rgb":[64,48,16]},"graph.box2":{"rgb":[192,160,96]},"graph.box3":{"rgb":[192,160,96]},"graph.box4":{"rgb":[192,160,96]},"graph.true":{"rgb":[240,208,144]},"graph.false":{"rgb":[64,48,16]},"graph.ujump":{"rgb":[240,208,144]},"graph.current":{"rgb":[0,0,255]},"graph.traced":{"rgb":[0,0,255]},"diff.unknown":{"rgb":[136,23,152]},"diff.new":{"rgb":[197,15,31]},"diff.match":{"rgb":[118,118,118]},"diff.unmatch":{"rgb":[193,156,0]},"gui.cflow":{"rgb":[255,255,0]},"gui.dataoffset":{"rgb":[255,255,0]},"gui.background":{"rgb":[0,0,0]},"gui.alt_background":{"rgb":[255,255,255]},"gui.border":{"rgb":[0,0,0]},"wordhl":{"rgb":[255,0,0]},"linehl":{"rgb":[32,16,0]}}
{"comment":{"rgb":[240,208,144]},"usrcmt":{"rgb":[240,240,240]},"args":{"rgb":[176,176,112]},"fname":{"rgb":[176,176,112]},"floc":{"rgb":[0,255,255]},"fline":{"rgb":[192,160,96]},"flag":{"rgb":[240,240,208]},"label":{"rgb":[112,128,128]},"help":{"rgb":[160,176,112]},"flow":{"rgb":[192,160,96]},"flow2":{"rgb":[240,224,192]},"prompt":{"rgb":[144,96,0]},"offset":{"rgb":[144,96,0]},"input":{"rgb":[192,160,96]},"invalid":{"rgb":[192,96,64]},"other":{"rgb":[176,160,96]},"b0x00":{"rgb":[64,48,16]},"b0x7f":{"rgb":[240,208,144]},"b0xff":{"rgb":[144,96,0]},"math":{"rgb":[208,176,112]},"bin":{"rgb":[240,224,192]},"btext":{"rgb":[240,224,192]},"push":{"rgb":[208,176,112]},"pop":{"rgb":[176,176,112]},"crypto":{"rgb":[0,0,255]},"jmp":{"rgb":[240,224,192]},"cjmp":{"rgb":[240,224,192]},"call":{"rgb":[255,255,255]},"nop":{"rgb":[112,128,128]},"ret":{"rgb":[160,176,112]},"trap":{"rgb":[64,48,16]},"ucall":{"rgb":[255,255,255]},"ujmp":{"rgb":[240,224,192]},"swi":{"rgb":[176,176,112]},"cmp":{"rgb":[192,160,96]},"reg":{"rgb":[192,160,96]},"creg":{"rgb":[144,96,0]},"num":{"rgb":[144,96,0]},"mov":{"rgb":[208,176,112]},"func_var":{"rgb":[240,208,144]},"func_var_type":{"rgb":[128,80,0]},"func_var_addr":{"rgb":[144,96,0]},"widget_bg":{"rgb":[208,176,112]},"widget_sel":{"rgb":[0,0,0]},"meta":{"rgb":[118,118,118]},"ai.read":{"rgb":[192,176,112]},"ai.write":{"rgb":[192,160,96]},"ai.exec":{"rgb":[208,176,112]},"ai.seq":{"rgb":[144,96,0]},"ai.ascii":{"rgb":[240,224,192]},"graph.box":{"rgb":[64,48,16]},"graph.box2":{"rgb":[192,160,96]},"graph.box3":{"rgb":[192,160,96]},"graph.box4":{"rgb":[192,160,96]},"graph.true":{"rgb":[240,208,144]},"graph.false":{"rgb":[64,48,16]},"graph.ujump":{"rgb":[240,208,144]},"graph.current":{"rgb":[0,0,255]},"graph.traced":{"rgb":[0,0,255]},"diff.unknown":{"rgb":[136,23,152]},"diff.new":{"rgb":[197,15,31]},"diff.match":{"rgb":[118,118,118]},"diff.unmatch":{"rgb":[193,156,0]},"gui.match.perfect":{"rgb":[0,255,0]},"gui.match.partial":{"rgb":[255,0,0]},"gui.cflow":{"rgb":[255,255,0]},"gui.dataoffset":{"rgb":[255,255,0]},"gui.background":{"rgb":[0,0,0]},"gui.alt_background":{"rgb":[255,255,255]},"gui.border":{"rgb":[0,0,0]},"wordhl":{"rgb":[255,0,0]},"linehl":{"rgb":[32,16,0]}}
.gui_background { color: rgb(0, 0, 0); }
.foo_gui_background { color: rgb(0, 0, 0); }
EOF
Expand Down Expand Up @@ -115,6 +115,8 @@ EXPECT=<<EOF
## diff.new Color for new diff
## diff.match Color for matched diff
## diff.unmatch Color for unmatched diff
## gui.match.perfect Color for perfectly matched GUI diff
## gui.match.partial Color for partially matched GUI diff
## gui.cflow Color for GUI control flow
## gui.dataoffset Color for GUI data offset
## gui.background Color for GUI background
Expand Down Expand Up @@ -186,6 +188,8 @@ EXPECT=<<EOF
## diff.new Color for new diff
## diff.match Color for matched diff
## diff.unmatch Color for unmatched diff
## gui.match.perfect Color for perfectly matched GUI diff
## gui.match.partial Color for partially matched GUI diff
## gui.cflow Color for GUI control flow
## gui.dataoffset Color for GUI data offset
## gui.background Color for GUI background
Expand Down
Loading
Loading