n_diff regression: line diff, hunk rendering and the edit ceiling.
n_diff regression: line diff, hunk rendering and the edit ceiling.
#include <stdio.h>
#include <string.h>
#include <unistd.h>
int opt = 0;
while ((opt = getopt(argc, argv, "hvV:")) != EOF) {
switch (opt) {
case 'V':
if (!strncmp("LOG_NULL", optarg, 8))
else if (!strncmp("LOG_NOTICE", optarg, 10))
else if (!strncmp("LOG_INFO", optarg, 8))
else if (!strncmp("LOG_ERR", optarg, 7))
else if (!strncmp("LOG_DEBUG", optarg, 9))
else {
fprintf(stderr, "Unknown log level %s\n", optarg);
exit(1);
}
break;
case 'v':
fprintf(stderr, "ex_diff\n");
exit(1);
default:
fprintf(stderr, "Usage: %s [-V LOG_LEVEL]\n", argv[0]);
exit(1);
}
}
}
if (!cond) {
}
}
static void expect_size(
const char* label,
size_t got,
size_t want) {
if (got != want) {
n_log(
LOG_ERR,
"%s: got %zu, expected %zu", label, got, want);
}
}
if (!out || !out->
data || !strstr(out->
data, needle)) {
n_log(
LOG_ERR,
"%s: output does not contain '%s' (got: %s)",
label, needle, (out && out->
data) ? out->
data :
"NULL");
}
}
if (!out || !out->
data || strstr(out->
data, needle)) {
n_log(
LOG_ERR,
"%s: output should not contain '%s' (got: %s)",
label, needle, (out && out->
data) ? out->
data :
"NULL");
}
}
static void expect_unified(
const char* label,
const char* a,
const char* b,
const char* want) {
if (!res) {
return;
}
if (!out || !out->
data || strcmp(out->
data, want) != 0) {
(out && out->
data) ? out->
data :
"NULL", want);
}
}
int main(
int argc,
char** argv) {
{
expect_true(
"identical returns a result", res != NULL);
}
{
}
{
}
expect_unified(
"inserted line rendering",
"a\nb\nc\nd",
"a\nx\nb\nc\nd",
" a\n+x\n b\n c\n d\n");
expect_unified(
"replaced line",
"a\nb\nc",
"a\nB\nc",
" a\n-b\n+B\n c\n");
{
expect_true(
"NULL inputs return a result", res != NULL);
}
{
}
{
int checked = 0;
checked++;
checked++;
}
}
expect_size(
"both changed lines inspected", (
size_t)checked, 2);
}
{
"1\n2\n3\n4\nX\n6\n7\n8\n9", 0);
}
{
int hunks = 0;
for (
const char* p = out->
data; (p = strstr(p,
"@@ -")) != NULL; p++) {
hunks++;
}
}
{
"X\n2\n3\n4\n5\n6\n7\n8\nY", 0);
int hunks = 0;
for (
const char* p = out->
data; (p = strstr(p,
"@@ -")) != NULL; p++) {
hunks++;
}
expect_size(
"distant changes split", (
size_t)hunks, 2);
}
{
for (int i = 0; i < 40; i++) {
}
expect_true(
"over ceiling returns a result", res != NULL);
}
{
for (int i = 0; i < 5000; i++) {
}
}
{
}
return 1;
}
printf("ex_diff: all tests passed\n");
return 0;
}
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.