rizin/librz/include/rz_cons.h
NOT XVilka c9a372c333
librz/cons/histogram: revamp visual horizontal histogram (#6365, #4431) (#6440)
This rewrites the look of the interactive horizontal histogram in Rizin -
the output of `p==v`, `p==ev`, `p==mv`, `p==0v`, `p==fv`, `p==pv`, `p==zv`,
`p==Sv` and the analysis-based interactive variants. It closes #6365 and
#4431 in full, and now sits on top of the recently merged static-histogram
PR (#6427) so it reuses the new RzHistogramOptions struct and its helpers.

Five sub-tasks from #6365:
  - Context-aware vertical ruler with up to 5 anchor labels (top, bottom,
    quarter, half, three-quarter) honouring opts->value_min..value_max,
    value_precision, value_scale and value_unit. Reuses the static
    helpers compute_ruler_gutter, render_ruler_gutter, label_value_at and
    select_ruler_label_rows so visual and static stay consistent.
  - X-axis byte-offset ruler at the bottom: `^` ticks every (addr_w + 3)
    cols followed by absolute byte offsets computed from opts->offpos +
    realj * blocksize.
  - Cursor offset + percentage shown right-aligned on the status line, with
    "Index N data V" on the left.
  - Top minimap: Unicode block characters (▁▂▃▄▅▆▇█) for the density of
    each slice of the whole data, plus a ┏━━━┓ window indicator showing the
    visible slice. Always rendered when the new `scr.hist.minimap` config
    is true. When the terminal is wide (hist->w > 200) the minimap shrinks
    by 43 columns to make room for a two-line `px 0x20`-style hex preview
    panel on the right showing the 32 bytes at the cursor's file offset.
    Each byte is wrapped in its px-style colour code (b0x00 / b0x7f /
    b0xff / btext / other) when opts->color is set, matching rz_print's
    rz_print_byte_color exactly. A trailing safety pad keeps the canvas
    from clipping the last byte of the first hex row.
  - Missing-half bug on `p==v` when the cursor is at offset 0 fixed by
    clamping `adder` to [0, histogramwidth - span]. The old expression
    `barnumber + 1 - histogramwidth/(zoom*2)` was always negative for the
    default barnumber=0, causing the rendering loop to read `data[-N]`
    (segfault on large files, missing left half on small ones).

Cursor visibility:
  - The cursor column is drawn as a CONTINUOUS vertical line connecting two
    plain markers at the top and bottom, ALWAYS exactly one character wide.
    The line itself uses the dedicated `wordhl` palette colour (default
    red background, configurable via `ec wordhl ...`), drawn on every
    chart row so the cursor is always a full-height vertical strip. The
    markers (`▼` at the top and `▲` at the bottom, or ASCII `v` / `^`
    when scr.utf8=false) are intentionally left un-highlighted so they
    read as a clean pair of arrows pointing at the cursor column.
  - The cursor screen column is computed up-front (j_cursor) by inverting
    the data-to-column map (rel * zoom * width / histogramwidth). Two
    distinct widening bugs are avoided this way:
      1. sizeofonebar > 1 (high zoom) - each data index spans several
         screen columns; only j == j_cursor && kbar == 0 renders as the
         cursor, the remaining kbar columns fall through to the gradient.
      2. histogramwidth < width (chart much wider than data) - several
         adjacent screen columns map to the same data index via integer
         truncation; only the j_cursor column may render as the cursor.

Interactive keybindings & live config:
  - The `:` hotkey drops into rz_core_visual_prompt_input, matching the
    rest of Rizin's visual modes. Lets the user run arbitrary rizin
    commands without leaving the histogram.
  - The `?` help text now uses the same colour-coded format as the
    visual / visual-bit-editor modes (rz_core_visual_append_help with
    pal.args for keys and pal.help for descriptions), shown via
    rz_cons_less_str.
  - The config-driven opts (scr.hist.minimap, scr.hist.block, scr.utf8,
    scr.color, hex.offset) are re-read on every redraw via
    refresh_visual_opts_from_config, so `:` `e scr.hist.minimap=true`
    <Enter> takes effect immediately without having to quit and re-enter.
    The canvas's `color` field is refreshed alongside so `scr.color`
    changes take effect on the same redraw.

Hex preview panel:
  - When the terminal is wide (hist->w > 200) and the minimap is enabled,
    the visual mode shows a two-line hex preview on the right of the
    minimap rows: 32 bytes at the cursor's file offset, formatted as 8
    pairs of 2 bytes separated by spaces (`abcd ef00 1234 5678 ...`),
    matching `px 0x20` minus the header / offsets / ASCII column. The
    bytes are fetched live via rz_io_read_at_mapped each redraw, so
    moving the cursor (`h` / `l`) updates the preview.
  - Each byte gets its px-style colour code: green for 0x00, red for
    0xff, yellow for 0x7f, btext (white) for printable ASCII, "other"
    (magenta) for non-printable. Mirrors rz_print_byte_color so the
    histogram preview reads consistently with `px`.
  - A trailing safety pad keeps the canvas from clipping the last hex
    byte of the first row (a side effect of UTF-8 minimap glyphs
    interacting with the canvas's width tracking when the row fills
    the canvas exactly).
  - Implemented via two new fields on RzHistogramInteractive
    (`cursor_bytes`, `cursor_bytes_len`) that the caller fills in just
    before the render call and clears right after. The minimap helper
    grows two extra parameters that the visual function passes through;
    when the panel is disabled (narrow terminal, no cursor_bytes, or
    shrinking the minimap would leave it < 40 cols) the helper falls
    back to the previous full-width minimap.

Closes #4431 in full:
  - The negative-offset crash above is the immediate segfault from the
    bug report.
  - `print_histogram_bytes` now samples one byte per block instead of
    reading nblocks contiguous bytes from core->offset. For an 8 GB file
    shown across 80 bars the original code rendered the first 80 bytes
    of the file; the new code samples at offsets brange->from + i *
    blocksize so the chart represents the full span.
  - The inner `int i` in the column-aggregation loop is renamed to `k`
    to drop the shadow over the outer `size_t i`.

Refactor on the cmd_print.c side:
  - New default_visual_opts(core, offset) returns an RZ_OWN
    RzHistogramOptions* pre-populated for the visual commands (ruler=true,
    minimap from scr.hist.minimap, offpos from caller, palette and
    screen-mode toggles from config via refresh_visual_opts_from_config).
    The nine print_visual_bytes call sites now build opts via this helper,
    then pass it to print_visual_bytes which takes ownership. Entropy
    sets value_max=8 / value_precision=1 / data_f=fdata so the visual
    histogram shows the Shannon range matching the static side.
  - `print_visual_bytes(core, opts, data, brange)` now propagates opts
    cleanup along every error path; rz_histogram_interactive_new no
    longer leaves a heap-allocated opts pointer dangling. The redraw loop
    fetches 32 cursor bytes via rz_io_read_at_mapped, points
    hist->cursor_bytes at a stack buffer for the call, then NULLs it
    back so the next iteration's fetch is independent.
  - RzHistogramInteractive gains `blocksize`, `cursor_bytes` and
    `cursor_bytes_len` fields.

New config option:
  - `scr.hist.minimap` (bool, default true) controls whether the top
    minimap is shown for p==v / p==ev. Surfaces as `opts->minimap` and
    is honoured by `rz_histogram_interactive_horizontal`. When true,
    the minimap is ALWAYS rendered (provided there's room) - even when
    the chart already shows the full data, in which case the window
    indicator spans the whole map. Changes via `:` `e scr.hist.minimap=...`
    <Enter> are picked up on the very next redraw.

Tests (33 total, 10 new for the visual side):
  - test_histogram_interactive_horizontal_basic - smoke test with
    barnumber=0 (pins the #4431 crash regression).
  - test_histogram_interactive_horizontal_ruler_percent - fractional
    labels with value_max=100 / value_scale=0.01 / unit="%".
  - test_histogram_interactive_horizontal_ruler_default - the legacy
    0..255 byte ruler.
  - test_histogram_interactive_horizontal_no_negative_adder - covers
    `p==v` at offset 0 on a small data set.
  - test_histogram_interactive_horizontal_percent - status-line percent
    indicator present.
  - test_histogram_interactive_horizontal_cursor_markers - the ▼/▲
    cursor markers (and ASCII v/^ fallback) appear on the cursor column,
    left un-highlighted.
  - test_histogram_interactive_horizontal_cursor_full_line - the cursor
    bar is rendered on every chart row between the markers regardless
    of the data threshold (continuous vertical line).
  - test_histogram_interactive_horizontal_cursor_width - pins single-
    char width across BOTH cursor-widening bugs: high zoom (sizeofonebar
    > 1) AND chart wider than data (histogramwidth < width).
  - test_histogram_interactive_horizontal_minimap_toggle - pins the
    scr.hist.minimap gating across {zoomed, not zoomed} when
    opts->minimap=true / =false.
  - test_histogram_interactive_horizontal_hex_preview - 4 cases: wide
    terminal + cursor_bytes shows the hex panel; narrow terminal
    suppresses it; missing cursor_bytes suppresses it; colour mode
    emits ANSI escape sequences for the bytes.
  Both p== integration tests in test/db/cmd/cmd_print pass with their
  regenerated EXPECT blocks (the per-block sampling change moves the
  visible bars for small buffers).

Co-authored-by: Anton Kochkov <anton.kochkov@gmail.com>
2026-06-07 14:00:31 +08:00

1310 lines
43 KiB
C
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#ifndef RZ_CONS_H
#define RZ_CONS_H
#ifdef __cplusplus
extern "C" {
#endif
#include <rz_types.h>
#include <rz_util/rz_graph.h>
#include <rz_util/rz_hex.h>
#include <rz_util/rz_log.h>
#include <rz_util/rz_num.h>
#include <rz_util/rz_panels.h>
#include <rz_util/rz_pj.h>
#include <rz_util/rz_signal.h>
#include <rz_util/rz_stack.h>
#include <rz_util/rz_str.h>
#include <rz_util/rz_str_constpool.h>
#include <rz_util/rz_sys.h>
#include <rz_util/rz_utf8.h>
#include <rz_util/rz_file.h>
#include <rz_vector.h>
#include <sdb.h>
#include <rz_util/ht_up.h>
#include <rz_util/ht_pp.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#if __UNIX__
#include <termios.h>
#include <sys/ioctl.h>
#include <sys/wait.h>
#include <sys/socket.h>
#endif
#if !__WINDOWS__
#include <unistd.h>
#endif
/* constants */
#define CONS_MAX_USER 102400
#define CONS_BUFSZ 0x4f00
#define STR_IS_NULL(x) (!x || !x[0])
/* palette */
#define CONS_PALETTE_SIZE 22
#define CONS_COLORS_SIZE 21
#define RZ_CONS_GREP_WORDS 10
#define RZ_CONS_GREP_WORD_SIZE 64
#define RZ_CONS_GREP_TOKENS 64
RZ_LIB_VERSION_HEADER(rz_cons);
#define RZ_CONS_CMD_DEPTH 100
typedef int (*RzConsGetSize)(int *rows);
typedef int (*RzConsGetCursor)(RZ_NONNULL int *rows);
typedef bool (*RzConsIsBreaked)(void);
typedef void (*RzConsFlush)(void);
typedef void (*RzConsGrepCallback)(const char *grep);
typedef struct rz_cons_bind_t {
RzConsGetSize get_size;
RzConsGetCursor get_cursor;
PrintfCallback cb_printf;
RzConsIsBreaked is_breaked;
RzConsFlush cb_flush;
RzConsGrepCallback cb_grep;
} RzConsBind;
typedef struct rz_cons_grep_t {
char strings[RZ_CONS_GREP_WORDS][RZ_CONS_GREP_WORD_SIZE];
int nstrings;
char *str;
int counter;
bool charCounter;
int less;
bool hud;
bool human;
int json;
char *json_path;
int range_line;
int line;
int sort;
int sort_row;
bool sort_invert;
int f_line; // first line
int l_line; // last line
int tokens[RZ_CONS_GREP_TOKENS];
int tokens_used;
int amp;
int zoom;
int zoomy; // if set then its scaled unproportionally
int neg;
int begin;
int end;
int icase;
int sorted_column;
RzList /*<char *>*/ *sorted_lines;
RzList /*<char *>*/ *unsorted_lines;
} RzConsGrep;
#if 0
// TODO Might be better than using rz_cons_pal_get_i
// And have smaller RzConsPrintablePalette and RzConsPalette
enum {
RZ_CONS_PAL_0x00 = 0,
RZ_CONS_PAL_0x7f,
RZ_CONS_PAL_0xff,
RZ_CONS_PAL_ARGS,
RZ_CONS_PAL_BIN,
RZ_CONS_PAL_BTEXT,
RZ_CONS_PAL_CALL,
RZ_CONS_PAL_CJMP,
RZ_CONS_PAL_CMP,
RZ_CONS_PAL_COMMENT,
RZ_CONS_PAL_CREG,
RZ_CONS_PAL_FLAG,
RZ_CONS_PAL_FLINE,
RZ_CONS_PAL_FLOC,
RZ_CONS_PAL_FLOW,
RZ_CONS_PAL_FLOW2,
RZ_CONS_PAL_FNAME,
RZ_CONS_PAL_HELP,
RZ_CONS_PAL_INPUT,
RZ_CONS_PAL_INVALID,
RZ_CONS_PAL_JMP,
RZ_CONS_PAL_LABEL,
RZ_CONS_PAL_MATH,
RZ_CONS_PAL_MOV,
RZ_CONS_PAL_NOP,
RZ_CONS_PAL_NUM,
RZ_CONS_PAL_OFFSET,
RZ_CONS_PAL_OTHER,
RZ_CONS_PAL_POP,
RZ_CONS_PAL_PROMPT,
RZ_CONS_PAL_PUSH,
RZ_CONS_PAL_CRYPTO,
RZ_CONS_PAL_REG,
RZ_CONS_PAL_RESET,
RZ_CONS_PAL_RET,
RZ_CONS_PAL_SWI,
RZ_CONS_PAL_TRAP,
RZ_CONS_PAL_AI_READ,
RZ_CONS_PAL_AI_WRITE,
RZ_CONS_PAL_AI_EXEC,
RZ_CONS_PAL_AI_SEQ,
RZ_CONS_PAL_AI_ASCII,
RZ_CONS_PAL_AI_UNMAP,
RZ_CONS_PAL_GUI_CFLOW,
RZ_CONS_PAL_GUI_DATAOFFSET,
RZ_CONS_PAL_GUI_BACKGROUND,
RZ_CONS_PAL_GUI_ALT_BACKGROUND,
RZ_CONS_PAL_GUI_BORDER,
RZ_CONS_PAL_LINEHL,
RZ_CONS_PAL_GRAPH_BOX,
RZ_CONS_PAL_GRAPH_BOX2,
RZ_CONS_PAL_GRAPH_BOX3,
RZ_CONS_PAL_GRAPH_BOX4,
RZ_CONS_PAL_GRAPH_TRUE,
RZ_CONS_PAL_GRAPH_FALSE,
RZ_CONS_PAL_GRAPH_TRUFAE,
RZ_CONS_PAL_GRAPH_TRACED,
RZ_CONS_PAL_GRAPH_CURRENT,
RZ_CONS_PAL_LAST
};
#endif
enum {
ALPHA_RESET = 0x00,
ALPHA_FG = 0x01,
ALPHA_BG = 0x02,
ALPHA_FGBG = 0x03
};
enum {
RZ_CONS_ATTR_BOLD = 1u << 1,
RZ_CONS_ATTR_DIM = 1u << 2,
RZ_CONS_ATTR_ITALIC = 1u << 3,
RZ_CONS_ATTR_UNDERLINE = 1u << 4,
RZ_CONS_ATTR_BLINK = 1u << 5
};
typedef struct rcolor_t {
// bold, italic, underline, ...
ut8 attr;
ut8 a;
ut8 r;
ut8 g;
ut8 b;
ut8 r2; // Background color
ut8 g2; // Only used when a &= ALPHA_FGBG
ut8 b2;
st8 id16; // Mapping to 16-color table
} RzColor;
typedef struct rz_cons_palette_t {
RzColor b0x00;
RzColor b0x7f;
RzColor b0xff;
RzColor args;
RzColor bin;
RzColor btext;
RzColor call;
RzColor cjmp;
RzColor cmp;
RzColor comment;
RzColor usercomment;
RzColor creg;
RzColor flag;
RzColor fline;
RzColor floc;
RzColor flow;
RzColor flow2;
RzColor fname;
RzColor help;
RzColor input;
RzColor invalid;
RzColor jmp;
RzColor label;
RzColor math;
RzColor mov;
RzColor nop;
RzColor num;
RzColor offset;
RzColor other;
RzColor pop;
RzColor prompt;
RzColor push;
RzColor crypto;
RzColor reg;
RzColor reset;
RzColor ret;
RzColor swi;
RzColor trap;
RzColor ucall;
RzColor ujmp;
RzColor ai_read;
RzColor ai_write;
RzColor ai_exec;
RzColor ai_seq;
RzColor ai_ascii;
RzColor gui_cflow;
RzColor gui_dataoffset;
RzColor gui_background;
RzColor gui_alt_background;
RzColor gui_border;
RzColor wordhl;
RzColor linehl;
RzColor func_var;
RzColor func_var_type;
RzColor func_var_addr;
RzColor widget_bg;
RzColor widget_sel;
RzColor meta;
/* Graph colors */
RzColor graph_box;
RzColor graph_box2;
RzColor graph_box3;
RzColor graph_box4;
RzColor graph_true;
RzColor graph_false;
RzColor graph_ujump;
RzColor graph_traced;
RzColor graph_current;
RzColor diff_match;
RzColor diff_unmatch;
RzColor diff_unknown;
RzColor diff_new;
} RzConsPalette;
typedef struct rz_cons_printable_palette_t {
char *b0x00;
char *b0x7f;
char *b0xff;
char *args;
char *bin;
char *btext;
char *call;
char *cjmp;
char *cmp;
char *comment;
char *usercomment;
char *creg;
char *flag;
char *fline;
char *floc;
char *flow;
char *flow2;
char *fname;
char *help;
char *input;
char *invalid;
char *jmp;
char *label;
char *math;
char *mov;
char *nop;
char *num;
char *offset;
char *other;
char *pop;
char *prompt;
char *push;
char *crypto;
char *reg;
char *reset;
char *ret;
char *swi;
char *trap;
char *ucall;
char *ujmp;
char *ai_read;
char *ai_write;
char *ai_exec;
char *ai_seq;
char *ai_ascii;
char *ai_unmap;
char *gui_cflow;
char *gui_dataoffset;
char *gui_background;
char *gui_alt_background;
char *gui_border;
char *wordhl;
char *linehl;
char *func_var;
char *func_var_type;
char *func_var_addr;
char *widget_bg;
char *widget_sel;
char *meta;
/* graph colors */
char *graph_box;
char *graph_box2;
char *graph_box3;
char *graph_box4;
char *diff_match;
char *diff_unmatch;
char *diff_unknown;
char *diff_new;
char *graph_true;
char *graph_false;
char *graph_ujump;
char *graph_traced;
char *graph_current;
char **rainbow; // rainbow
int rainbow_sz; // size of rainbow
} RzConsPrintablePalette;
typedef void (*RzConsEvent)(void *);
#define CONS_MAX_ATTR_SZ 16
typedef struct rz_cons_canvas_t {
int w;
int h;
int x;
int y;
char **b;
int *blen;
int *bsize;
const char *attr; // The current attr (inserted on each write)
HtUP *attrs; // all the different attributes <key: unsigned int loc, const char *attr>
RzStrConstPool constpool; // Pool for non-compile-time attrs
int sx; // scrollx
int sy; // scrolly
int color;
int linemode; // 0 = diagonal , 1 = square
} RzConsCanvas;
#define RUNECODE_MIN 0xc8 // 200
#define RUNECODE_LINE_VERT 0xc8
#define RUNECODE_LINE_CROSS 0xc9
#define RUNECODE_CORNER_BR 0xca
#define RUNECODE_CORNER_BL 0xcb
#define RUNECODE_ARROW_RIGHT 0xcc
#define RUNECODE_ARROW_LEFT 0xcd
#define RUNECODE_LINE_HORIZ 0xce
#define RUNECODE_CORNER_TL 0xcf
#define RUNECODE_CORNER_TR 0xd0
#define RUNECODE_LINE_UP 0xd1
#define RUNECODE_CURVE_CORNER_TL 0xd2
#define RUNECODE_CURVE_CORNER_TR 0xd3
#define RUNECODE_CURVE_CORNER_BR 0xd4
#define RUNECODE_CURVE_CORNER_BL 0xd5
#define RUNECODE_MAX 0xd6
#define RUNECODESTR_MIN 0xc8 // 200
#define RUNECODESTR_LINE_VERT "\xc8"
#define RUNECODESTR_LINE_CROSS "\xc9"
#define RUNECODESTR_CORNER_BR "\xca"
#define RUNECODESTR_CORNER_BL "\xcb"
#define RUNECODESTR_ARROW_RIGHT "\xcc"
#define RUNECODESTR_ARROW_LEFT "\xcd"
#define RUNECODESTR_LINE_HORIZ "\xce"
#define RUNECODESTR_CORNER_TL "\xcf"
#define RUNECODESTR_CORNER_TR "\xd0"
#define RUNECODESTR_LINE_UP "\xd1"
#define RUNECODESTR_CURVE_CORNER_TL "\xd2"
#define RUNECODESTR_CURVE_CORNER_TR "\xd3"
#define RUNECODESTR_CURVE_CORNER_BR "\xd4"
#define RUNECODESTR_CURVE_CORNER_BL "\xd5"
#define RUNECODESTR_MAX 0xd5
#define RUNE_LINE_VERT "│"
#define RUNE_LINE_CROSS "┼" /* ├ */
#define RUNE_LINE_HORIZ "─"
#define RUNE_LINE_UP "↑"
#define RUNE_CORNER_BR "┘"
#define RUNE_CORNER_BL "└"
#define RUNE_CORNER_TL "┌"
#define RUNE_CORNER_TR "┐"
#define RUNE_ARROW_RIGHT ""
#define RUNE_ARROW_LEFT ""
#define RUNE_ARROW_UP "ᐱ"
#define RUNE_ARROW_DOWN ""
#define RUNE_CURVE_CORNER_TL "╭"
#define RUNE_CURVE_CORNER_TR "╮"
#define RUNE_CURVE_CORNER_BR "╯"
#define RUNE_CURVE_CORNER_BL "╰"
#define RUNE_LONG_LINE_HORIZ "―"
#define UTF_CIRCLE "\u25EF"
#define UTF_BLOCK "\u2588"
// Lower partial block elements (ascending height) for the minimap density ramp.
#define UTF_BLOCK_LOWER_EIGHTH "\u2581" // ▁
#define UTF_BLOCK_LOWER_QUARTER "\u2582" // ▂
#define UTF_BLOCK_LOWER_THREE_EIGHTHS "\u2583" // ▃
#define UTF_BLOCK_LOWER_HALF "\u2584" // ▄
#define UTF_BLOCK_LOWER_FIVE_EIGHTHS "\u2585" // ▅
#define UTF_BLOCK_LOWER_THREE_QUARTERS "\u2586" // ▆
#define UTF_BLOCK_LOWER_SEVEN_EIGHTHS "\u2587" // ▇
// Heavy box-drawing pieces for the minimap window indicator.
#define RUNE_LINE_HORIZ_HEAVY "\u2501" // ━
#define RUNE_CORNER_TL_HEAVY "\u250F" // ┏
#define RUNE_CORNER_TR_HEAVY "\u2513" // ┓
#define UTF_TRIANGLE_DOWN "\u25BC" // ▼
#define UTF_TRIANGLE_UP "\u25B2" // ▲
// Emoji
#define UTF8_POLICE_CARS_REVOLVING_LIGHT "🚨"
#define UTF8_WHITE_HEAVY_CHECK_MARK "✅"
#define UTF8_SEE_NO_EVIL_MONKEY "🙈"
#define UTF8_SKULL_AND_CROSSBONES "☠"
#define UTF8_KEYBOARD "⌨"
#define UTF8_LEFT_POINTING_MAGNIFYING_GLASS "🔍"
#define UTF8_DOOR "🚪"
// Variation Selectors
#define UTF8_VS16 "\xef\xb8\x8f"
typedef char *(*RzConsEditorCallback)(void *core, const char *file, const char *str);
typedef int (*RzConsClickCallback)(void *core, int x, int y);
typedef void (*RzConsBreakCallback)(void *core);
typedef void *(*RzConsSleepBeginCallback)(void *core);
typedef void (*RzConsSleepEndCallback)(void *core, void *user);
typedef void (*RzConsQueueTaskOneshot)(void *core, void *task, void *user);
typedef void (*RzConsFunctionKey)(void *core, int fkey);
typedef enum {
COLOR_MODE_DISABLED = 0,
COLOR_MODE_16,
COLOR_MODE_256,
COLOR_MODE_16M
} RzConsColorMode;
typedef enum {
RZ_VIRT_TERM_MODE_DISABLE = 0, ///< Windows only: Use console c api for everything (Windows <= 8)
RZ_VIRT_TERM_MODE_OUTPUT_ONLY, ///< Windows only: Use console c api for input, but output on VT (Windows >= 10)
RZ_VIRT_TERM_MODE_COMPLETE, ///< All the sequences goes through VT (Windows Terminal, mintty, all OSs)
} RzVirtTermMode;
typedef struct rz_cons_input_context_t {
size_t readbuffer_length;
char *readbuffer;
bool bufactive;
} RzConsInputContext;
typedef enum {
RZ_CONS_PAL_SEEK_PREVIOUS,
RZ_CONS_PAL_SEEK_NEXT,
} RzConsPalSeekMode;
typedef struct rz_cons_context_t {
RzConsGrep grep;
RzStack *cons_stack;
char *buffer;
size_t buffer_len;
size_t buffer_sz;
bool breaked;
RzStack *break_stack;
RzConsEvent event_interrupt;
void *event_interrupt_data;
int cmd_depth;
// Used for per-task logging redirection
RzLogCallback log_callback; // TODO: RzList of callbacks
char *lastOutput;
int lastLength;
bool lastMode;
bool lastEnabled;
bool is_interactive;
bool last_interactive_option; ///< To be deprecated for a push/pop behavior
bool pageable;
bool noflush;
int color_mode;
RzConsPalette cpal;
RzConsPrintablePalette pal;
// Memoized last calculated row/column inside buffer
int row;
int col;
int rowcol_calc_start;
} RzConsContext;
#define HUD_BUF_SIZE 512
typedef enum {
MOUSE_NONE = 0,
MOUSE_DEFAULT, // indicate an event with no consideration of specific type
LEFT_PRESS,
LEFT_RELEASE,
WHEEL_PRESS,
WHEEL_RELEASE,
RIGHT_PRESS,
RIGHT_RELEASE,
WHEEL_UP,
WHEEL_DOWN,
} MouseEvent;
typedef struct rz_cons_t {
RzConsContext *context;
RzConsInputContext *input;
bool is_html;
bool was_html;
int lines;
int rows;
int echo; // dump to stdout in realtime
int columns;
int force_rows;
int force_columns;
int fix_rows;
int fix_columns;
bool break_lines;
bool show_autocomplete_widget;
FILE *fdin; // FILE? and then int ??
int fdout; // only used in pipe.c :?? remove?
const char *teefile;
int (*user_fgets)(char *buf, int len, void *user);
void *user_fgets_user;
RzConsEvent event_resize;
void *event_data;
MouseEvent mouse_event;
RzConsEditorCallback cb_editor;
RzConsBreakCallback cb_break;
RzConsSleepBeginCallback cb_sleep_begin;
RzConsSleepEndCallback cb_sleep_end;
RzConsClickCallback cb_click;
RzConsQueueTaskOneshot cb_task_oneshot;
RzConsFunctionKey cb_fkey;
void *user; // Used by <RzCore*>
int oldraw; ///< To be deprecated for a push/pop behavior
#if __UNIX__
struct termios term_raw, term_buf;
#elif __WINDOWS__
unsigned long term_raw, term_buf, term_pty;
void *saved_input_handle;
void *saved_output_handle;
bool saved_input_console;
bool saved_output_console;
unsigned long old_input_mode, old_output_mode;
ut32 old_cp;
ut32 old_ocp;
#endif
RzNum *num;
/* Pager (like more or less) to use if the output doesn't fit on the
* current window. If NULL or "" no pager is used. */
char *pager;
int blankline;
char *highlight;
bool enable_highlight;
int null; // if set, does not show anything
int mouse;
int is_wine;
struct rz_line_t *line;
const char **vline;
int refcnt;
RZ_DEPRECATE bool newline;
RzVirtTermMode vtmode;
bool flush;
bool use_utf8; // use utf8 features
bool use_utf8_curvy; // use utf8 curved corners
bool dotted_lines;
int linesleep;
int pagesize;
char *break_word;
int break_word_len;
ut64 timeout; // must come from rz_time_now_mono()
bool grep_color;
bool grep_highlight;
int grep_icase;
bool filter;
char *(*rgbstr)(char *str, size_t sz, ut64 addr);
bool click_set;
int click_x;
int click_y;
bool show_vals; // show which section in Vv
RzStrBuf *echobuf;
// TODO: move into instance? + avoid unnecessary copies
} RzCons;
#define RZ_CONS_SEARCH_CASE_SENSITIVE 0
#define RZ_CONS_SEARCH_CASE_INSENSITIVE 1
#define RZ_CONS_SEARCH_CASE_SMART 2
#define RZ_CONS_KEY_F1 0xf1
#define RZ_CONS_KEY_F2 0xf2
#define RZ_CONS_KEY_F3 0xf3
#define RZ_CONS_KEY_F4 0xf4
#define RZ_CONS_KEY_F5 0xf5
#define RZ_CONS_KEY_F6 0xf6
#define RZ_CONS_KEY_F7 0xf7
#define RZ_CONS_KEY_F8 0xf8
#define RZ_CONS_KEY_F9 0xf9
#define RZ_CONS_KEY_F10 0xfa
#define RZ_CONS_KEY_F11 0xfb
#define RZ_CONS_KEY_F12 0xfc
#define RZ_CONS_KEY_ESC 0x1b
#define RZ_CONS_CLEAR_LINE "\x1b[2K\r"
#define RZ_CONS_CLEAR_SCREEN "\x1b[2J\r"
#define RZ_CONS_CLEAR_FROM_CURSOR_TO_END "\x1b[0J\r"
#define RZ_CONS_CURSOR_SAVE "\x1b[s"
#define RZ_CONS_CURSOR_RESTORE "\x1b[u"
#define RZ_CONS_GET_CURSOR_POSITION "\x1b[6n"
#define RZ_CONS_CURSOR_UP "\x1b[A"
#define RZ_CONS_CURSOR_DOWN "\x1b[B"
#define RZ_CONS_CURSOR_RIGHT "\x1b[C"
#define RZ_CONS_CURSOR_LEFT "\x1b[D"
#define Color_BLINK "\x1b[5m"
#define Color_INVERT "\x1b[7m"
#define Color_INVERT_RESET "\x1b[27m"
/* See 'man 4 console_codes' for details:
* "ESC c" -- Reset
* "ESC ( K" -- Select user mapping
* "ESC [ 0 m" -- Reset all display attributes
* "ESC [ J" -- Erase to the end of screen
* "ESC [ ? 25 h" -- Make cursor visible
*/
#define Color_RESET_TERMINAL "\x1b" \
"c\x1b(K\x1b[0m\x1b[J\x1b[?25h"
#define Color_RESET "\x1b[0m" /* reset all */
#define Color_RESET_NOBG "\x1b[27;22;24;25;28;39m" /* Reset everything except background (order is important) */
#define Color_RESET_BG "\x1b[49m"
#define Color_RESET_ALL "\x1b[0m\x1b[49m"
#define Color_BLACK "\x1b[30m"
#define Color_BGBLACK "\x1b[40m"
#define Color_RED "\x1b[31m"
#define Color_BGRED "\x1b[41m"
#define Color_WHITE "\x1b[37m"
#define Color_BGWHITE "\x1b[47m"
#define Color_GREEN "\x1b[32m"
#define Color_BGGREEN "\x1b[42m"
#define Color_MAGENTA "\x1b[35m"
#define Color_BGMAGENTA "\x1b[45m"
#define Color_YELLOW "\x1b[33m"
#define Color_BGYELLOW "\x1b[43m"
#define Color_CYAN "\x1b[36m"
#define Color_BGCYAN "\x1b[46m"
#define Color_BLUE "\x1b[34m"
#define Color_BGBLUE "\x1b[44m"
#define Color_GRAY "\x1b[90m"
#define Color_BGGRAY "\x1b[100m"
/* bright colors */
#define Color_BBLACK Color_GRAY
#define Color_BBGBLACK Color_BGGRAY
#define Color_BRED "\x1b[91m"
#define Color_BBGRED "\x1b[101m"
#define Color_BWHITE "\x1b[97m"
#define Color_BBGWHITE "\x1b[107m"
#define Color_BGREEN "\x1b[92m"
#define Color_BBGGREEN "\x1b[102m"
#define Color_BMAGENTA "\x1b[95m"
#define Color_BBGMAGENTA "\x1b[105m"
#define Color_BYELLOW "\x1b[93m"
#define Color_BBGYELLOW "\x1b[103m"
#define Color_BCYAN "\x1b[96m"
#define Color_BBGCYAN "\x1b[106m"
#define Color_BBLUE "\x1b[94m"
#define Color_BBGBLUE "\x1b[104m"
#if defined(_MSC_VER) || (defined(__GNUC__) && __GNUC__ < 5)
#define RZCOLOR(a, r, g, b, bgr, bgg, bgb, id16) \
{ 0, a, r, g, b, bgr, bgg, bgb, id16 }
#else
#define RZCOLOR(a, r, g, b, bgr, bgg, bgb, id16) \
(RzColor) { \
0, a, r, g, b, bgr, bgg, bgb, id16 \
}
#endif
#define RzColor_NULL RZCOLOR(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -1)
#if __WINDOWS__
#define RzColor_BLACK RZCOLOR(ALPHA_FG, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0)
#define RzColor_BGBLACK RZCOLOR(ALPHA_BG, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0)
#define RzColor_RED RZCOLOR(ALPHA_FG, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 1)
#define RzColor_BGRED RZCOLOR(ALPHA_BG, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 1)
#define RzColor_WHITE RZCOLOR(ALPHA_FG, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 7)
#define RzColor_BGWHITE RZCOLOR(ALPHA_BG, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 7)
#define RzColor_GREEN RZCOLOR(ALPHA_FG, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 2)
#define RzColor_BGGREEN RZCOLOR(ALPHA_BG, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 2)
#define RzColor_MAGENTA RZCOLOR(ALPHA_FG, 0x80, 0x00, 0x80, 0x00, 0x00, 0x00, 5)
#define RzColor_BGMAGENTA RZCOLOR(ALPHA_BG, 0x80, 0x00, 0x80, 0x00, 0x00, 0x00, 5)
#define RzColor_YELLOW RZCOLOR(ALPHA_FG, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 3)
#define RzColor_BGYELLOW RZCOLOR(ALPHA_BG, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 3)
#define RzColor_CYAN RZCOLOR(ALPHA_FG, 0x00, 0x80, 0x80, 0x00, 0x00, 0x00, 6)
#define RzColor_BGCYAN RZCOLOR(ALPHA_BG, 0x00, 0x80, 0x80, 0x00, 0x00, 0x00, 6)
#define RzColor_BLUE RZCOLOR(ALPHA_FG, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 4)
#define RzColor_BGBLUE RZCOLOR(ALPHA_BG, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 4)
#define RzColor_BBLACK RZCOLOR(ALPHA_FG, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 8)
#define RzColor_BBGBLACK RZCOLOR(ALPHA_BG, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 8)
#define RzColor_BRED RZCOLOR(ALPHA_FG, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 9)
#define RzColor_BBGRED RZCOLOR(ALPHA_BG, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 9)
#define RzColor_BWHITE RZCOLOR(ALPHA_FG, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 15)
#define RzColor_BBGWHITE RZCOLOR(ALPHA_BG, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 15)
#define RzColor_BGREEN RZCOLOR(ALPHA_FG, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 10)
#define RzColor_BBGGREEN RZCOLOR(ALPHA_BG, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 10)
#define RzColor_BMAGENTA RZCOLOR(ALPHA_FG, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 13)
#define RzColor_BBGMAGENTA RZCOLOR(ALPHA_BG, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 13)
#define RzColor_BYELLOW RZCOLOR(ALPHA_FG, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 11)
#define RzColor_BBGYELLOW RZCOLOR(ALPHA_BG, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 11)
#define RzColor_BCYAN RZCOLOR(ALPHA_FG, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 14)
#define RzColor_BBGCYAN RZCOLOR(ALPHA_BG, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 14)
#define RzColor_BBLUE RZCOLOR(ALPHA_FG, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 12)
#define RzColor_BBGBLUE RZCOLOR(ALPHA_BG, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 12)
#else
// Campbell (https://devblogs.microsoft.com/commandline/updating-the-windows-console-colors/).
// Not used on Windows since cmd.exe doesn't support bold (needed for easier
// differentiation between normal and bright color text for some colors).
#define RzColor_BLACK RZCOLOR(ALPHA_FG, 12, 12, 12, 0x00, 0x00, 0x00, 0)
#define RzColor_BGBLACK RZCOLOR(ALPHA_BG, 12, 12, 12, 0x00, 0x00, 0x00, 0)
#define RzColor_RED RZCOLOR(ALPHA_FG, 197, 15, 31, 0x00, 0x00, 0x00, 1)
#define RzColor_BGRED RZCOLOR(ALPHA_BG, 197, 15, 31, 0x00, 0x00, 0x00, 1)
#define RzColor_WHITE RZCOLOR(ALPHA_FG, 204, 204, 204, 0x00, 0x00, 0x00, 7)
#define RzColor_BGWHITE RZCOLOR(ALPHA_BG, 204, 204, 204, 0x00, 0x00, 0x00, 7)
#define RzColor_GREEN RZCOLOR(ALPHA_FG, 19, 161, 14, 0x00, 0x00, 0x00, 2)
#define RzColor_BGGREEN RZCOLOR(ALPHA_BG, 19, 161, 14, 0x00, 0x00, 0x00, 2)
#define RzColor_MAGENTA RZCOLOR(ALPHA_FG, 136, 23, 152, 0x00, 0x00, 0x00, 5)
#define RzColor_BGMAGENTA RZCOLOR(ALPHA_BG, 136, 23, 152, 0x00, 0x00, 0x00, 5)
#define RzColor_YELLOW RZCOLOR(ALPHA_FG, 193, 156, 0, 0x00, 0x00, 0x00, 3)
#define RzColor_BGYELLOW RZCOLOR(ALPHA_BG, 193, 156, 0, 0x00, 0x00, 0x00, 3)
#define RzColor_CYAN RZCOLOR(ALPHA_FG, 58, 150, 221, 0x00, 0x00, 0x00, 6)
#define RzColor_BGCYAN RZCOLOR(ALPHA_BG, 58, 150, 221, 0x00, 0x00, 0x00, 6)
#define RzColor_BLUE RZCOLOR(ALPHA_FG, 0, 55, 218, 0x00, 0x00, 0x00, 4)
#define RzColor_BGBLUE RZCOLOR(ALPHA_BG, 0, 55, 218, 0x00, 0x00, 0x00, 4)
#define RzColor_BBLACK RZCOLOR(ALPHA_FG, 118, 118, 118, 0x00, 0x00, 0x00, 8)
#define RzColor_BBGBLACK RZCOLOR(ALPHA_BG, 118, 118, 118, 0x00, 0x00, 0x00, 8)
#define RzColor_BRED RZCOLOR(ALPHA_FG, 231, 72, 86, 0x00, 0x00, 0x00, 9)
#define RzColor_BBGRED RZCOLOR(ALPHA_BG, 231, 72, 86, 0x00, 0x00, 0x00, 9)
#define RzColor_BWHITE RZCOLOR(ALPHA_FG, 242, 242, 242, 0x00, 0x00, 0x00, 15)
#define RzColor_BBGWHITE RZCOLOR(ALPHA_BG, 242, 242, 242, 0x00, 0x00, 0x00, 15)
#define RzColor_BGREEN RZCOLOR(ALPHA_FG, 22, 198, 12, 0x00, 0x00, 0x00, 10)
#define RzColor_BBGGREEN RZCOLOR(ALPHA_BG, 22, 198, 12, 0x00, 0x00, 0x00, 10)
#define RzColor_BMAGENTA RZCOLOR(ALPHA_FG, 180, 0, 158, 0x00, 0x00, 0x00, 13)
#define RzColor_BBGMAGENTA RZCOLOR(ALPHA_BG, 180, 0, 158, 0x00, 0x00, 0x00, 13)
#define RzColor_BYELLOW RZCOLOR(ALPHA_FG, 249, 241, 165, 0x00, 0x00, 0x00, 11)
#define RzColor_BBGYELLOW RZCOLOR(ALPHA_BG, 249, 241, 165, 0x00, 0x00, 0x00, 11)
#define RzColor_BCYAN RZCOLOR(ALPHA_FG, 97, 214, 214, 0x00, 0x00, 0x00, 14)
#define RzColor_BBGCYAN RZCOLOR(ALPHA_BG, 97, 214, 214, 0x00, 0x00, 0x00, 14)
#define RzColor_BBLUE RZCOLOR(ALPHA_FG, 59, 120, 255, 0x00, 0x00, 0x00, 12)
#define RzColor_BBGBLUE RZCOLOR(ALPHA_BG, 59, 120, 255, 0x00, 0x00, 0x00, 12)
#endif
#define RzColor_GRAY RzColor_BBLACK
#define RzColor_BGGRAY RzColor_BBGBLACK
#define Colors_PLAIN \
{ \
Color_BLACK, Color_RED, Color_WHITE, \
Color_GREEN, Color_MAGENTA, Color_YELLOW, \
Color_CYAN, Color_BLUE, Color_GRAY \
}
enum {
PAL_PROMPT = 0,
PAL_ADDRESS,
PAL_DEFAULT,
PAL_CHANGED,
PAL_JUMP,
PAL_CALL,
PAL_PUSH,
PAL_TRAP,
PAL_CMP,
PAL_RET,
PAL_NOP,
PAL_METADATA,
PAL_HEADER,
PAL_PRINTABLE,
PAL_LINES0,
PAL_LINES1,
PAL_LINES2,
PAL_00,
PAL_7F,
PAL_FF
};
/* canvas line colors */
enum {
LINE_NONE = 0,
LINE_TRUE,
LINE_FALSE,
LINE_UNCJMP,
LINE_NOSYM_VERT,
LINE_NOSYM_HORIZ
};
typedef enum {
INSERT_MODE = 'i',
CONTROL_MODE = 'c'
} RViMode;
#define DOT_STYLE_NORMAL 0
#define DOT_STYLE_CONDITIONAL 1
#define DOT_STYLE_BACKEDGE 2
typedef struct rz_cons_canvas_line_style_t {
int color;
int symbol;
int dot_style;
} RzCanvasLineStyle;
// UTF-8 symbols indexes
#define LINE_VERT 0
#define LINE_CROSS 1
#define LINE_HORIZ 2
#define LINE_UP 3
#define CORNER_TL 6
#define CORNER_BR 4
#define CORNER_BL 5
#define CORNER_TR 6
#define ARROW_RIGHT 8
#define ARROW_LEFT 9
#define SELF_LOOP 10
typedef struct rz_histogram_options_t {
bool unicode; ///< Use Unicode characters instead of ASCII
bool thinline; ///< Use thin lines instead of block lines
bool ruler; ///< Show ruler
bool legend; ///< Show axes and legend
bool offset; ///< Show offsets
bool cursor; ///< Show cursor position
bool color; ///< Use colors
bool minimap; ///< Show top minimap on visual histogram (visual mode only; auto-hides when data fits)
ut32 cols; ///< Screen-column width (0 = default 78)
ut64 offpos; ///< Starting offset value
ut64 curpos; ///< Cursor position
ut64 blocksize; ///< Bytes per data point (drives the X-axis offset ruler; 0 disables it)
int value_min; ///< Minimum value for ruler labels and threshold scale (0..255 default)
int value_max; ///< Maximum value for ruler labels and threshold scale (0 = 0..255 default)
int value_precision; ///< Decimal digits on ruler labels (0 = integer)
double value_scale; ///< Multiplier on integer row values for ruler labels (0 = 1.0)
const char *value_unit; ///< Optional unit suffix after ruler values (NULL = none)
RZ_NULLABLE const double *data_f; ///< Optional fp data buffer; overrides ut8 data when set
RzConsPrintablePalette *pal; ///< Colors palette if color is enabled
} RzHistogramOptions;
typedef struct rz_bar_options_t {
bool unicode; //<< Use Unicode characters instead of ASCII
bool thinline; //<< Use thin lines instead of block lines
bool legend; //<< Show axes and legend
bool offset; //<< Show offsets
ut64 offpos; //<< Starting offset value
bool cursor; //<< Show cursor position
ut64 curpos; //<< Cursor position
bool color; //<< Use colors
} RzBarOptions;
typedef struct rz_histogram_interactive_t {
RzConsCanvas *can;
int barnumber;
int size;
ut64 blocksize; ///< Bytes per data point (drives the X-axis offset ruler in interactive horizontal mode).
int zoom;
int movspeed;
int x, y;
int w, h;
const ut8 *cursor_bytes; ///< Up to 32 raw bytes read at the cursor's file offset; shown on the right of the minimap when `hist->w > 200`. NULL = no hex preview this redraw.
ut32 cursor_bytes_len; ///< Length of cursor_bytes (typically 32, can be less near EOF). Ignored when cursor_bytes is NULL.
RzHistogramOptions *opts;
} RzHistogramInteractive;
#ifdef RZ_API
RZ_API RzConsCanvas *rz_cons_canvas_new(int w, int h);
RZ_API void rz_cons_canvas_free(RzConsCanvas *c);
RZ_API void rz_cons_canvas_clear(RzConsCanvas *c);
RZ_API void rz_cons_canvas_print(RzConsCanvas *c);
RZ_API void rz_cons_canvas_print_region(RzConsCanvas *c);
RZ_API RZ_OWN char *rz_cons_canvas_to_string(RzConsCanvas *c);
RZ_API void rz_cons_canvas_write(RzConsCanvas *c, const char *_s);
RZ_API bool rz_cons_canvas_gotoxy(RzConsCanvas *c, int x, int y);
RZ_API void rz_cons_canvas_box(RzConsCanvas *c, int x, int y, int w, int h, const char *color);
RZ_API void rz_cons_canvas_line(RzConsCanvas *c, int x, int y, int x2, int y2, RzCanvasLineStyle *style);
RZ_API void rz_cons_canvas_line_diagonal(RzConsCanvas *c, int x, int y, int x2, int y2, RzCanvasLineStyle *style);
RZ_API void rz_cons_canvas_line_square(RzConsCanvas *c, int x, int y, int x2, int y2, RzCanvasLineStyle *style);
RZ_API int rz_cons_canvas_resize(RzConsCanvas *c, int w, int h);
RZ_API void rz_cons_canvas_fill(RzConsCanvas *c, int x, int y, int w, int h, char ch);
RZ_API void rz_cons_canvas_line_square_defined(RzConsCanvas *c, int x, int y, int x2, int y2, RzCanvasLineStyle *style, int bendpoint, int isvert);
RZ_API void rz_cons_canvas_line_back_edge(RzConsCanvas *c, int x, int y, int x2, int y2, RzCanvasLineStyle *style, int ybendpoint1, int xbendpoint, int ybendpoint2, int isvert);
RZ_API RzCons *rz_cons_new(void);
RZ_API RzCons *rz_cons_singleton(void);
RZ_API RzCons *rz_cons_free(void);
RZ_API char *rz_cons_lastline(int *size);
RZ_API char *rz_cons_lastline_utf8_ansi_len(int *len);
RZ_API void rz_cons_set_click(int x, int y, MouseEvent event);
RZ_API bool rz_cons_get_click(int *x, int *y);
typedef void (*RzConsBreak)(void *);
RZ_API bool rz_cons_is_breaked(void);
RZ_API bool rz_cons_is_interactive(void);
RZ_API bool rz_cons_default_context_is_interactive(void);
RZ_API void *rz_cons_sleep_begin(void);
RZ_API void rz_cons_sleep_end(void *user);
/* ^C */
RZ_API void rz_cons_break_push(RzConsBreak cb, void *user);
RZ_API void rz_cons_break_pop(void);
RZ_API void rz_cons_break_clear(void);
RZ_API void rz_cons_breakword(RZ_NULLABLE const char *s);
RZ_API void rz_cons_break_end(void);
RZ_API void rz_cons_break_timeout(int timeout);
/* pipe */
typedef struct rz_cons_pipe_t RzConsPipe;
RZ_API RZ_OWN RzConsPipe *rz_cons_pipe_open(RZ_NONNULL const char *file, int old_fd, bool append);
RZ_API void rz_cons_pipe_close(RZ_NULLABLE RzConsPipe *cpipe);
#if __WINDOWS__
RZ_API RzVirtTermMode rz_cons_detect_vt_mode(void);
RZ_API void rz_cons_w32_clear(void);
RZ_API void rz_cons_w32_gotoxy(int fd, int x, int y);
RZ_API int rz_cons_w32_print(const char *ptr, int len, bool vmode);
RZ_API int rz_cons_win_printf(bool vmode, const char *fmt, ...) RZ_PRINTF_CHECK(2, 3);
RZ_API int rz_cons_win_eprintf(bool vmode, const char *fmt, ...) RZ_PRINTF_CHECK(2, 3);
RZ_API int rz_cons_win_vhprintf(unsigned long hdl, bool vmode, const char *fmt, va_list ap);
#endif
RZ_API void rz_cons_push(void);
RZ_API void rz_cons_pop(void);
RZ_API RzConsContext *rz_cons_context_new(RZ_NULLABLE RzConsContext *parent);
RZ_API void rz_cons_context_free(RzConsContext *context);
RZ_API void rz_cons_context_load(RzConsContext *context);
RZ_API void rz_cons_context_reset(void);
RZ_API bool rz_cons_context_is_main(void);
RZ_API void rz_cons_context_break(RzConsContext *context);
RZ_API void rz_cons_context_break_push(RzConsContext *context, RzConsBreak cb, void *user, bool sig);
RZ_API void rz_cons_context_break_pop(RzConsContext *context, bool sig);
/* control */
RZ_API void rz_cons_reset(void);
RZ_API void rz_cons_reset_colors(void);
RZ_API void rz_cons_goto_origin_reset(void);
RZ_API void rz_cons_echo(const char *msg);
RZ_API void rz_cons_zero(void);
RZ_API void rz_cons_highlight(const char *word);
RZ_API void rz_cons_clear(void);
RZ_API void rz_cons_clear_buffer(void);
RZ_API void rz_cons_clear00(void);
RZ_API void rz_cons_clear_line(FILE *stream);
RZ_API void rz_cons_fill_line(void);
RZ_API void rz_cons_gotoxy(int x, int y);
RZ_API int rz_cons_get_cur_line(void);
RZ_API void rz_cons_show_cursor(int cursor);
RZ_API char *rz_cons_swap_ground(const char *col);
RZ_API bool rz_cons_drop(int n);
RZ_API void rz_cons_chop(void);
RZ_API void rz_cons_set_raw(bool b);
RZ_API void rz_cons_set_interactive(bool b);
RZ_API void rz_cons_set_last_interactive(void);
RZ_API void rz_cons_set_utf8(bool b);
RZ_API void rz_cons_grep(const char *grep);
/* output */
RZ_API int rz_cons_printf(const char *format, ...) RZ_PRINTF_CHECK(1, 2);
RZ_API void rz_cons_printf_list(const char *format, va_list ap);
RZ_API void rz_cons_strcat(const char *str);
RZ_API void rz_cons_strcat_at(const char *str, int x, char y, int w, int h);
#define rz_cons_print(x) rz_cons_strcat(x)
RZ_API void rz_cons_println(const char *str);
RZ_API void rz_cons_strcat_justify(const char *str, int j, char c);
RZ_API int rz_cons_memcat(const char *str, int len);
RZ_API void rz_cons_newline(void);
RZ_API void rz_cons_filter(void);
RZ_API void rz_cons_flush(void);
RZ_API void rz_cons_set_flush(bool flush);
RZ_API void rz_cons_last(void);
RZ_API int rz_cons_less_str(const char *str, const char *exitkeys);
RZ_API void rz_cons_less(void);
RZ_API void rz_cons_memset(char ch, int len);
RZ_API void rz_cons_visual_flush(void);
RZ_API void rz_cons_visual_write(char *buffer);
RZ_API bool rz_cons_is_utf8(void);
RZ_API void rz_cons_cmd_help(const char *help[], bool use_color);
/* input */
RZ_API int rz_cons_controlz(int ch);
RZ_API int rz_cons_readchar(void);
RZ_API bool rz_cons_readbuffer_readchar(char *ch);
RZ_API bool rz_cons_readpush(const char *str, int len);
RZ_API void rz_cons_readflush(void);
RZ_API void rz_cons_switchbuf(bool active);
RZ_API int rz_cons_readchar_timeout(ut32 usec);
RZ_API int rz_cons_any_key(const char *msg);
RZ_API int rz_cons_eof(void);
RZ_API int rz_cons_pal_set(const char *key, const char *val);
RZ_API void rz_cons_pal_update_event(void);
RZ_API void rz_cons_pal_free(RzConsContext *ctx);
RZ_API void rz_cons_pal_init(RzConsContext *ctx);
RZ_API void rz_cons_pal_copy(RzConsContext *dst, RzConsContext *src);
RZ_API char *rz_cons_pal_parse(const char *str, RzColor *outcol);
RZ_API void rz_cons_pal_random(void);
RZ_API RzColor rz_cons_pal_get(const char *key);
RZ_API RzColor rz_cons_pal_get_i(int index);
RZ_API const char *rz_cons_pal_get_name(int index);
RZ_API int rz_cons_pal_len(void);
RZ_API int rz_cons_rgb_parse(const char *p, ut8 *r, ut8 *g, ut8 *b, ut8 *a);
RZ_API char *rz_cons_rgb_tostring(ut8 r, ut8 g, ut8 b);
RZ_API void rz_cons_pal_list_as_json(RZ_NONNULL PJ *pj);
RZ_API void rz_cons_pal_list_as_css(RZ_NULLABLE const char *name_prefix);
RZ_API void rz_cons_pal_list_visual(void);
RZ_API void rz_cons_pal_show(void);
RZ_API int rz_cons_get_size(int *rows);
RZ_API bool rz_cons_isatty(void);
RZ_API int rz_cons_get_cursor(RZ_NONNULL int *rows);
RZ_API int rz_cons_arrow_to_hjkl(int ch);
RZ_API char *rz_cons_html_filter(const char *ptr, int *newlen);
RZ_API char *rz_cons_rainbow_get(int idx, int last, bool bg);
RZ_API void rz_cons_rainbow_free(RzConsContext *ctx);
RZ_API void rz_cons_rainbow_new(RzConsContext *ctx, int sz);
RZ_API int rz_cons_fgets(char *buf, int len, int argc, const char **argv);
RZ_API char *rz_cons_hud(RzList /*<char *>*/ *list, const char *prompt);
RZ_API char *rz_cons_hud_path(const char *path, int dir);
RZ_API char *rz_cons_hud_string(const char *s);
RZ_API char *rz_cons_hud_file(const char *f);
RZ_API const char *rz_cons_get_buffer(void);
RZ_API RZ_OWN char *rz_cons_get_buffer_dup(void);
RZ_API int rz_cons_get_buffer_len(void);
RZ_API void rz_cons_grep_help(void);
RZ_API void rz_cons_grep_parsecmd(char *cmd, const char *quotestr);
RZ_API char *rz_cons_grep_strip(char *cmd, const char *quotestr);
RZ_API void rz_cons_grep_process(RZ_OWN char *grep);
RZ_API int rz_cons_grep_line(char *buf, int len); // must be static
RZ_API void rz_cons_grepbuf(void);
RZ_API void rz_cons_rgb_init(void);
RZ_API char *rz_cons_rgb_str_mode(RzConsColorMode mode, char *outstr, size_t sz, const RzColor *rcolor);
RZ_API char *rz_cons_rgb_str(char *outstr, size_t sz, const RzColor *rcolor);
RZ_API char *rz_cons_rgb_str_off(char *outstr, size_t sz, ut64 off);
RZ_API void rz_cons_color(int fg, int r, int g, int b);
RZ_API RzColor rz_cons_color_random(ut8 alpha);
RZ_API void rz_cons_invert(int set, int color);
RZ_API bool rz_cons_yesno(int def, const char *fmt, ...) RZ_PRINTF_CHECK(2, 3);
RZ_API char *rz_cons_input(const char *msg);
RZ_API bool rz_cons_set_cup(bool enable);
RZ_API void rz_cons_column(int c);
RZ_API int rz_cons_get_column(void);
RZ_API void rz_cons_message(RZ_NONNULL const char *msg);
RZ_API void rz_cons_set_title(const char *str);
RZ_API bool rz_cons_enable_mouse(const bool enable);
RZ_API void rz_cons_enable_highlight(const bool enable);
RZ_API void rz_cons_bind(RzConsBind *bind);
RZ_API const char *rz_cons_get_rune(const ut8 ch);
/* Histograms */
RZ_API RZ_OWN RzStrBuf *rz_histogram_horizontal(RZ_NONNULL RzHistogramOptions *opts, RZ_NONNULL const ut8 *data, ut32 width, ut32 height);
RZ_API RZ_OWN RzStrBuf *rz_histogram_vertical(RZ_NONNULL RzHistogramOptions *opts, RZ_NONNULL const ut8 *data, int width, int step);
RZ_API RZ_OWN RzStrBuf *rz_histogram_interactive_horizontal(RZ_NONNULL RzHistogramInteractive *hist, RZ_NONNULL const ut8 *data);
RZ_API RzHistogramOptions *rz_histogram_options_new();
RZ_API void rz_histogram_options_free(RzHistogramOptions *histops);
RZ_API RzHistogramInteractive *rz_histogram_interactive_new(RzConsCanvas *can, RzHistogramOptions *opts);
RZ_API void rz_histogram_interactive_free(RzHistogramInteractive *hist);
RZ_API void rz_histogram_interactive_zoom_in(RzHistogramInteractive *hist);
RZ_API void rz_histogram_interactive_zoom_out(RzHistogramInteractive *hist);
#endif
/* Bars */
RZ_API RZ_OWN RzStrBuf *rz_progressbar(RZ_NONNULL RzBarOptions *opts, int pc, int width);
RZ_API RZ_OWN RzStrBuf *rz_rangebar(RZ_NONNULL RzBarOptions *opts, ut64 startA, ut64 endA, ut64 min,
ut64 max, int width);
/* rz_line */
#define RZ_LINE_BUFSIZE 4096
#define RZ_LINE_HISTSIZE 256
#define RZ_LINE_UNDOSIZE 512
#define RZ_EDGES_X_INC 4
#define RZ_SELWIDGET_MAXH 15
#define RZ_SELWIDGET_MAXW 30
#define RZ_SELWIDGET_DIR_UP 0
#define RZ_SELWIDGET_DIR_DOWN 1
typedef struct rz_selection_widget_t {
const char **options;
int options_len;
int selection;
int w, h;
int scroll;
bool complete_common;
bool direction;
} RzSelWidget;
typedef struct rz_line_hist_t {
char **data;
char *match;
int size;
int index;
int top;
int autosave;
bool do_setup_match;
} RzLineHistory;
typedef struct rz_line_buffer_t {
char data[RZ_LINE_BUFSIZE];
int index;
int length;
} RzLineBuffer;
typedef struct rz_hud_t {
int current_entry_n;
int top_entry_n;
char activate;
int vi;
} RzLineHud;
typedef struct rz_line_t RzLine; // forward declaration
typedef struct rz_line_comp_t RzLineCompletion;
typedef enum { RZ_LINE_PROMPT_DEFAULT,
RZ_LINE_PROMPT_OFFSET,
RZ_LINE_PROMPT_FILE } RzLinePromptType;
typedef int (*RzLineCompletionCb)(RzLineCompletion *completion, RzLineBuffer *buf, RzLinePromptType prompt_type, void *user);
struct rz_line_comp_t {
bool opt;
size_t args_limit;
bool quit;
RzPVector /*<char *>*/ args;
RzLineCompletionCb run;
void *run_user;
};
typedef struct rz_line_ns_completion_t RzLineNSCompletion;
/**
* Result returned by a completion callback function. It includes all the
* information required to provide meaningful autocompletion suggestion to the
* user.
*/
typedef struct rz_line_ns_completion_result_t {
RzPVector /*<char *>*/ options; ///< Vector of options that can be used for autocompletion
HtPP /*<char *, char *>*/ *options_ht; ///< Hash table to keep track of duplicated autocompletion suggestions
size_t start; ///< First byte that was considered for autocompletion. Everything before this will be left intact.
size_t end; ///< Last byte that was considered for autocompletion. Everything after this will be left intact.
const char *end_string; ///< String to place after the only option available is autocompleted. By default a space is used.
} RzLineNSCompletionResult;
/**
* Callback that analyze the current user input and provides options for autocompletion.
*
* \param buf RLineBuffer pointer, containing all the info about the current user input
* \param prompt_type Type of prompt used
* \param user User data that was previously setup in \p RzLineNSCompletion
*/
typedef RzLineNSCompletionResult *(*RzLineNSCompletionCb)(RzLineBuffer *buf, RzLinePromptType prompt_type, void *user);
/**
* Autocompletion callback data.
*/
struct rz_line_ns_completion_t {
RzLineNSCompletionCb run; ///< Callback function that is called when autocompletion is required. (e.g. TAB is pressed)
void *run_user; ///< User data that can be passed to the callback
};
typedef char *(*RzLineEditorCb)(void *core, const char *str);
typedef int (*RzLineHistoryUpCb)(RzLine *line);
typedef int (*RzLineHistoryDownCb)(RzLine *line);
typedef struct rz_line_undo_entry_t RzLineUndoEntry;
struct rz_line_t {
RzLineCompletion completion;
RzLineNSCompletion ns_completion;
RzLineBuffer buffer;
RzLineHistory history;
RzVector /*<RzLineUndoEntry>*/ *undo_vec;
RzSelWidget *sel_widget;
/* callbacks */
RzLineHistoryUpCb cb_history_up;
RzLineHistoryDownCb cb_history_down;
RzLineEditorCb cb_editor;
// RzLineFunctionKeyCb cb_fkey;
RzConsFunctionKey cb_fkey;
/* state , TODO: use more bool */
int gcomp;
int gcomp_idx;
int echo;
int has_echo;
char *prompt;
RzList /*<char *>*/ *kill_ring;
int kill_ring_ptr;
bool yank_flag;
int undo_cursor;
bool undo_continue;
char *clipboard;
int disable;
void *user;
int (*hist_up)(void *user);
int (*hist_down)(void *user);
char *contents;
bool zerosep;
bool enable_vi_mode;
int vi_mode;
bool prompt_mode;
RzLinePromptType prompt_type;
int offset_hist_index;
int file_hist_index;
RzLineHud *hud;
RzList /*<char *>*/ *sdbshell_hist;
RzListIter /*<char *>*/ *sdbshell_hist_iter;
RzVirtTermMode vtmode;
}; /* RzLine */
#ifdef RZ_API
RZ_API RZ_OWN RzLine *rz_line_new(void);
RZ_API void rz_line_free(RZ_NULLABLE RzLine *line);
RZ_API RZ_OWN char *rz_line_get_prompt(RZ_NONNULL RzLine *line);
RZ_API void rz_line_set_prompt(RZ_NONNULL RzLine *line, RZ_NONNULL const char *prompt);
RZ_API bool rz_line_dietline_init(RZ_NONNULL RzLine *line);
RZ_API void rz_line_clipboard_push(RZ_NONNULL RzLine *line, RZ_NONNULL const char *str);
RZ_API void rz_line_hist_free(RZ_NULLABLE RzLine *line);
RZ_API void rz_line_autocomplete(RZ_NONNULL RzLine *line);
typedef int(RzLineReadCallback)(void *user, const char *line);
RZ_API const char *rz_line_readline(RZ_NONNULL RzLine *line);
RZ_API const char *rz_line_readline_cb(RZ_NONNULL RzLine *line, RzLineReadCallback cb, void *user);
RZ_API bool rz_line_hist_load(RZ_NONNULL RzLine *line, RZ_NONNULL const char *file);
RZ_API bool rz_line_hist_add(RZ_NONNULL RzLine *line, RZ_NONNULL const char *str);
RZ_API bool rz_line_hist_save(RZ_NONNULL RzLine *line, const char *file);
RZ_API int rz_line_hist_list(RZ_NONNULL RzLine *line);
RZ_API const char *rz_line_hist_get(RZ_NONNULL RzLine *line, int n);
RZ_API int rz_line_set_hist_callback(RZ_NONNULL RzLine *line, RzLineHistoryUpCb cb_up, RzLineHistoryDownCb cb_down);
RZ_API int rz_line_hist_cmd_up(RZ_NONNULL RzLine *line);
RZ_API int rz_line_hist_cmd_down(RZ_NONNULL RzLine *line);
RZ_API void rz_line_completion_init(RzLineCompletion *completion, size_t args_limit);
RZ_API void rz_line_completion_fini(RzLineCompletion *completion);
RZ_API void rz_line_completion_push(RzLineCompletion *completion, const char *str);
RZ_API void rz_line_completion_set(RzLineCompletion *completion, int argc, const char **argv);
RZ_API void rz_line_completion_clear(RzLineCompletion *completion);
RZ_API RzLineNSCompletionResult *rz_line_ns_completion_result_new(size_t start, size_t end, const char *end_string);
RZ_API void rz_line_ns_completion_result_free(RzLineNSCompletionResult *res);
RZ_API void rz_line_ns_completion_result_add(RzLineNSCompletionResult *res, const char *option);
RZ_API void rz_line_ns_completion_result_propose(RzLineNSCompletionResult *res, const char *option, const char *cur, size_t cur_len);
RZ_API RZ_OWN char *rz_cons_prompt(RZ_NONNULL const char *str, RZ_NULLABLE const char *txt);
#define RZ_CONS_INVERT(x, y) (y ? (x ? Color_INVERT : Color_INVERT_RESET) : (x ? "[" : "]"))
#endif
#ifdef __sun
static inline void cfmakeraw(struct termios *tm) {
tm->c_cflag &= ~(CSIZE | PARENB);
tm->c_cflag |= CS8;
tm->c_iflag &= ~(IMAXBEL | IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL | IXON);
tm->c_oflag &= ~OPOST;
tm->c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN);
}
#endif
#ifdef __cplusplus
}
#endif
#endif