rizin/librz/include/rz_diff.h

106 lines
4.5 KiB
C

// SPDX-FileCopyrightText: 2021 RizinOrg <info@rizin.re>
// SPDX-FileCopyrightText: 2021 deroad <wargio@libero.it>
// SPDX-License-Identifier: LGPL-3.0-only
#ifndef RZ_DIFF_H
#define RZ_DIFF_H
#include <rz_types.h>
#include <rz_list.h>
#include <rz_util/rz_pj.h>
#include <rz_util/rz_strbuf.h>
#ifdef __cplusplus
extern "C" {
#endif
RZ_LIB_VERSION_HEADER(rz_diff);
typedef enum rz_diff_op_type_t {
RZ_DIFF_OP_INVALID = 0,
RZ_DIFF_OP_DELETE,
RZ_DIFF_OP_EQUAL,
RZ_DIFF_OP_INSERT,
RZ_DIFF_OP_REPLACE,
} RzDiffOpType;
/**
* This interface allows to analyze any data using the same algorithm
* elem_at(array, index) [required] must return the an element of the array at position 'index'
* elem_hash(elem) [required] must return the hash value of the element (use rz_diff_hash_data)
* compare(a_elem, b_elem) [required] must return true if the two elements are the same
* stringify(elem, sb) [required] appends into sb the stringified element of the array
* ignore(elem) [optional] must return true if the element matches the user define
* rule (if set to NULL, it will be considered as always false)
*/
typedef const void *(*RzDiffMethodElemAt)(RZ_BORROW const void *array, ut32 index);
typedef ut32 (*RzDiffMethodElemHash)(RZ_BORROW const void *elem);
typedef int (*RzDiffMethodCompare)(RZ_BORROW const void *a_elem, RZ_BORROW const void *b_elem);
typedef bool (*RzDiffMethodIgnore)(RZ_BORROW const void *elem);
typedef void (*RzDiffMethodStringify)(RZ_BORROW const void *elem, RZ_BORROW RzStrBuf *sb);
typedef struct rz_diff_methods_t {
RzDiffMethodElemAt elem_at; ///< can be either be an element of A or B
RzDiffMethodElemHash elem_hash; ///< can be either be an element of A or B
RzDiffMethodCompare compare; ///< elements from A and B
RzDiffMethodStringify stringify; ///< elements from A and B
RzDiffMethodIgnore ignore; ///< elements from A and B
} RzDiffMethods;
typedef struct rz_diff_op_t {
RzDiffOpType type;
st32 a_beg;
st32 a_end;
st32 b_beg;
st32 b_end;
} RzDiffOp;
#define RZ_DIFF_OP_SIZE_A(op) (((op)->a_end) - ((op)->a_beg))
#define RZ_DIFF_OP_SIZE_B(op) (((op)->b_end) - ((op)->b_beg))
#define RZ_DIFF_DEFAULT_N_GROUPS 3
typedef struct match_p_t {
ut32 a;
ut32 b;
ut32 size;
} RzDiffMatch;
typedef bool (*RzDiffIgnoreLine)(RZ_BORROW const char *line);
typedef struct rz_diff_t RzDiff;
#ifdef RZ_API
/* To calculate the hash of a complex structure made of
* various values, xor the results before returning the final value. */
RZ_API ut32 rz_diff_hash_data(RZ_NULLABLE const ut8 *buffer, ut32 size);
RZ_API RZ_OWN RzDiff *rz_diff_bytes_new(RZ_BORROW const ut8 *a, ut32 a_size, RZ_BORROW const ut8 *b, ut32 b_size);
RZ_API RZ_OWN RzDiff *rz_diff_lines_new(RZ_BORROW const char *a, RZ_BORROW const char *b, RZ_NULLABLE RzDiffIgnoreLine ignore);
RZ_API RZ_OWN RzDiff *rz_diff_generic_new(RZ_BORROW const void *a, ut32 a_size, RZ_BORROW const void *b, ut32 b_size, RZ_NONNULL RzDiffMethods *methods);
RZ_API void rz_diff_free(RZ_NULLABLE RzDiff *diff);
RZ_API RZ_BORROW const void *rz_diff_get_a(RZ_NONNULL RzDiff *diff);
RZ_API RZ_BORROW const void *rz_diff_get_b(RZ_NONNULL RzDiff *diff);
RZ_API RZ_OWN RzList /*<RzDiffMatch *>*/ *rz_diff_matches_new(RZ_NONNULL RzDiff *diff);
RZ_API RZ_OWN RzList /*<RzDiffOp *>*/ *rz_diff_opcodes_new(RZ_NONNULL RzDiff *diff);
RZ_API RZ_OWN RzList /*<RzList<RzDiffOp *> *>*/ *rz_diff_opcodes_grouped_new(RZ_NONNULL RzDiff *diff, ut32 n_groups);
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 PJ *rz_diff_unified_json(RZ_NONNULL RzDiff *diff, RZ_NULLABLE const char *from, RZ_NULLABLE const char *to, bool show_time);
/* Distances algorithms */
RZ_API bool rz_diff_myers_distance(RZ_NONNULL const ut8 *a, ut32 size_a, RZ_NONNULL const ut8 *b, ut32 size_b, RZ_NULLABLE ut32 *distance, RZ_NULLABLE double *similarity);
RZ_API bool rz_diff_levenshtein_distance(RZ_NONNULL const ut8 *a, ut32 size_a, RZ_NONNULL const ut8 *b, ut32 size_b, RZ_NULLABLE ut32 *distance, RZ_NULLABLE double *similarity);
#define RZ_DIFF_LCS_ROLL_DEFAULT_BLOCK_SIZE 128
RZ_API bool rz_diff_lcs_rolling_distance(RZ_NONNULL const ut8 *a, ut32 la, RZ_NONNULL const ut8 *b, ut32 lb, ut32 block_size, RZ_NULLABLE ut32 *distance, RZ_NULLABLE double *similarity);
#endif
#ifdef __cplusplus
}
#endif
#endif /* RZ_DIFF_H */