radare2/libr/core/cundo.c
pancake 1cd49a8d1c Add cmd.undo and handles it for w and CC commands ##core
* Improve undo command listing
* The cmd.undo variable when set some commands add entries into the `uc`
* This is wip, needs to have better facilities and support more commands
* Defer cmd.undo=true for r2-5.8.0
2022-07-31 06:34:16 -04:00

121 lines
2.6 KiB
C

/* radare2 - LGPL - Copyright 2018-2022 - pancake */
#include <r_core.h>
#if 0
TODO:
- add more methods to "undo according to some conditions"
- undo all comments in current offfset
#endif
R_API RCoreUndo *r_core_undo_new(ut64 offset, const char *action, const char *revert) {
RCoreUndo *cu = R_NEW (RCoreUndo);
if (cu) {
cu->action = strdup (action);
cu->revert = strdup (revert);
cu->tstamp = r_time_now ();
cu->offset = offset;
}
return cu;
}
R_API void r_core_undo_free(RCoreUndo *cu) {
if (cu) {
free (cu->action);
free (cu->revert);
}
free (cu);
}
R_API void r_core_undo_push(RCore *core, RCoreUndo *cu) {
r_return_if_fail (core && cu);
r_list_append (core->undos, cu);
#if R2_580
core->undoindex ++;
#endif
}
R_API void r_core_undo_pop(RCore *core) {
r_return_if_fail (core);
RCoreUndo *undo = r_list_pop (core->undos);
if (undo) {
r_core_cmd0 (core, undo->revert);
r_core_undo_free (undo);
}
}
R_API bool r_core_undo_condition(RCoreUndo *cu, RCoreUndoCondition *cond) {
if (!cond) {
return true;
}
bool mustPrint = false;
if (cond->addr != UT64_MAX) {
mustPrint = (cu->offset == cond->addr);
}
if (cond->minstamp) {
mustPrint = (cu->tstamp >= cond->minstamp);
}
if (cond->glob) {
mustPrint = r_str_glob (cu->action, cond->glob);
}
return mustPrint;
}
R_API void r_core_undo_print(RCore *core, int mode, RCoreUndoCondition *cond) {
RCoreUndo *cu;
RListIter *iter;
if (mode) {
r_list_foreach (core->undos, iter, cu) {
if (r_core_undo_condition (cu, cond)) {
r_cons_printf ("%s @ 0x%"PFMT64x"\n", cu->revert, cu->offset);
}
}
} else {
ut64 now = r_time_now ();
int i = 0;
r_list_foreach (core->undos, iter, cu) {
#if R2_580
const char * arrow = (i == core->undoindex - 1)? "*": "-";
#else
const char * arrow = "-";
#endif
r_cons_printf ("%s 0x%08"PFMT64x" old:% ds cmd: %s (revert: %s)\n",
arrow, cu->offset, (int)((now - cu->tstamp) / 1000000), cu->action, cu->revert);
i++;
}
}
}
#if R2_580
R_API void r_core_undo_down(RCore *core) {
// undo
int undos = r_list_length (core->undos);
if (core->undoindex >= undos) {
return;
}
core->undoindex++;
RCoreUndo *undo = r_list_get_n (core->undos, core->undoindex - 1);
if (undo) {
r_core_cmd0 (core, undo->action);
}
}
R_API void r_core_undo_up(RCore *core) {
// redo
const bool cmd_undo = r_config_get_b (core->config, "cmd.undo");
r_config_set_b (core->config, "cmd.undo", false);
core->undoindex--;
if (core->undoindex < 0) {
core->undoindex = 0;
return;
}
RCoreUndo *undo = r_list_get_n (core->undos, core->undoindex);
if (undo) {
r_core_cmd0 (core, undo->revert);
}
r_config_set_b (core->config, "cmd.undo", cmd_undo);
}
#endif