41 while ((opt = getopt(argc, argv,
"hvV:")) != EOF) {
44 if (!strncmp(
"LOG_NULL", optarg, 8))
46 else if (!strncmp(
"LOG_NOTICE", optarg, 10))
48 else if (!strncmp(
"LOG_INFO", optarg, 8))
50 else if (!strncmp(
"LOG_ERR", optarg, 7))
52 else if (!strncmp(
"LOG_DEBUG", optarg, 9))
55 fprintf(stderr,
"Unknown log level %s\n", optarg);
60 fprintf(stderr,
"ex_diff\n");
63 fprintf(stderr,
"Usage: %s [-V LOG_LEVEL]\n", argv[0]);
76static void expect_size(
const char* label,
size_t got,
size_t want) {
78 n_log(
LOG_ERR,
"%s: got %zu, expected %zu", label, got, want);
84 if (!out || !out->
data || !strstr(out->
data, needle)) {
85 n_log(
LOG_ERR,
"%s: output does not contain '%s' (got: %s)",
86 label, needle, (out && out->
data) ? out->
data :
"NULL");
92 if (!out || !out->
data || strstr(out->
data, needle)) {
93 n_log(
LOG_ERR,
"%s: output should not contain '%s' (got: %s)",
94 label, needle, (out && out->
data) ? out->
data :
"NULL");
100static void expect_unified(
const char* label,
const char* a,
const char* b,
const char* want) {
105 n_log(
LOG_ERR,
"%s: n_diff_lines returned NULL", label);
110 if (!out || !out->
data || strcmp(out->
data, want) != 0) {
112 (out && out->
data) ? out->
data :
"NULL", want);
119int main(
int argc,
char** argv) {
126 expect_true(
"identical returns a result", res != NULL);
151 expect_unified(
"inserted line rendering",
"a\nb\nc\nd",
"a\nx\nb\nc\nd",
152 " a\n+x\n b\n c\n d\n");
155 expect_unified(
"deleted line",
"a\nb\nc",
"a\nc",
" a\n-b\n c\n");
156 expect_unified(
"replaced line",
"a\nb\nc",
"a\nB\nc",
" a\n-b\n+B\n c\n");
165 expect_true(
"NULL inputs return a result", res != NULL);
197 expect_size(
"both changed lines inspected", (
size_t)checked, 2);
204 "1\n2\n3\n4\nX\n6\n7\n8\n9", 0);
229 for (
const char* p = out->
data; (p = strstr(p,
"@@ -")) != NULL; p++) {
232 expect_size(
"nearby changes merge", (
size_t)hunks, 1);
240 "X\n2\n3\n4\n5\n6\n7\n8\nY", 0);
243 for (
const char* p = out->
data; (p = strstr(p,
"@@ -")) != NULL; p++) {
246 expect_size(
"distant changes split", (
size_t)hunks, 2);
258 for (
int i = 0; i < 40; i++) {
263 expect_true(
"over ceiling returns a result", res != NULL);
286 for (
int i = 0; i < 5000; i++) {
315 printf(
"ex_diff: all tests passed\n");
void process_args(int argc, char **argv)
static void expect_true(const char *label, int cond)
static void expect_unified(const char *label, const char *a, const char *b, const char *want)
static void expect_size(const char *label, size_t got, size_t want)
static void expect_contains(const char *label, const N_STR *out, const char *needle)
static void expect_missing(const char *label, const N_STR *out, const char *needle)
void line(BITMAP *bmp, int x1, int y1, int x2, int y2, int color)
draw a line
#define _nstr(__PTR)
N_STR or "NULL" string for logging purposes.
size_t nb_items
number of item currently in the list
#define list_foreach(__ITEM_, __LIST_)
ForEach macro helper, safe for node removal during iteration.
#define n_log(__LEVEL__,...)
Logging function wrapper to get line and func.
#define LOG_DEBUG
debug-level messages
#define LOG_ERR
error conditions
void set_log_level(const int log_level)
Set the global log level value ( static int LOG_LEVEL ).
#define LOG_NOTICE
normal but significant condition
#define LOG_NULL
no log output
#define LOG_INFO
informational
int truncated
1 when the edit limit was hit and the differing region was reported as one delete run followed by one...
size_t nb_deleted
number of N_DIFF_DELETE lines
size_t nb_inserted
number of N_DIFF_INSERT lines
size_t nb_common
number of N_DIFF_COMMON lines
LIST * lines
LIST of N_DIFF_LINE*, in output order.
void n_diff_result_free(N_DIFF_RESULT **result)
Free an edit script and every line it holds.
#define N_DIFF_NO_LINE
N_DIFF_LINE line_a / line_b value when the line has no counterpart there.
#define N_DIFF_DELETE
the line is only in the first text
#define N_DIFF_INSERT
the line is only in the second text
#define N_DIFF_CONTEXT_FULL
n_diff_to_unified() context asking for every common line, without hunk headers
N_DIFF_RESULT * n_diff_lines(const char *text_a, const char *text_b, size_t max_edits)
Compare two texts line by line.
N_STR * n_diff_to_unified(const N_DIFF_RESULT *result, size_t context)
Render an edit script as unified diff text.
one line of an edit script
edit script turning one text into another
size_t written
number of meaningful bytes in data, excluding the null terminator; the size including the null termin...
#define free_nstr(__ptr)
free a N_STR structure and set the pointer to NULL
#define nstrprintf_cat(__nstr_var, __format,...)
Macro to quickly allocate and sprintf and cat to a N_STR.
N_STR * new_nstr(NSTRBYTE size)
create a new N_STR string
A box including a string and his lenght.
Common headers and low-level functions & define.
Line oriented text comparison (Myers shortest edit script).
N_STR and string function declaration.