Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/libdiff/lib/diff_debug.h
35083 views
1
/*
2
* Copyright (c) 2020 Neels Hofmeyr <[email protected]>
3
*
4
* Permission to use, copy, modify, and distribute this software for any
5
* purpose with or without fee is hereby granted, provided that the above
6
* copyright notice and this permission notice appear in all copies.
7
*
8
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15
*/
16
17
#define DEBUG 0
18
19
#if DEBUG
20
#include <stdio.h>
21
#include <unistd.h>
22
#define print(args...) fprintf(stderr, ##args)
23
#define debug print
24
#define debug_dump dump
25
#define debug_dump_atom dump_atom
26
#define debug_dump_atoms dump_atoms
27
28
static inline void
29
print_atom_byte(unsigned char c) {
30
if (c == '\r')
31
print("\\r");
32
else if (c == '\n')
33
print("\\n");
34
else if ((c < 32 || c >= 127) && (c != '\t'))
35
print("\\x%02x", c);
36
else
37
print("%c", c);
38
}
39
40
static inline void
41
dump_atom(const struct diff_data *left, const struct diff_data *right,
42
const struct diff_atom *atom)
43
{
44
if (!atom) {
45
print("NULL atom\n");
46
return;
47
}
48
if (left)
49
print(" %3u '", diff_atom_root_idx(left, atom));
50
51
if (atom->at == NULL) {
52
off_t remain = atom->len;
53
if (fseek(atom->root->f, atom->pos, SEEK_SET) == -1)
54
abort(); /* cannot return error */
55
while (remain > 0) {
56
char buf[16];
57
size_t r;
58
int i;
59
r = fread(buf, 1, MIN(remain, sizeof(buf)),
60
atom->root->f);
61
if (r == 0)
62
break;
63
remain -= r;
64
for (i = 0; i < r; i++)
65
print_atom_byte(buf[i]);
66
}
67
} else {
68
const char *s;
69
for (s = atom->at; s < (const char*)(atom->at + atom->len); s++)
70
print_atom_byte(*s);
71
}
72
print("'\n");
73
}
74
75
static inline void
76
dump_atoms(const struct diff_data *d, struct diff_atom *atom,
77
unsigned int count)
78
{
79
if (count > 42) {
80
dump_atoms(d, atom, 20);
81
print("[%u lines skipped]\n", count - 20 - 20);
82
dump_atoms(d, atom + count - 20, 20);
83
return;
84
} else {
85
struct diff_atom *i;
86
foreach_diff_atom(i, atom, count) {
87
dump_atom(d, NULL, i);
88
}
89
}
90
}
91
92
static inline void
93
dump(struct diff_data *d)
94
{
95
dump_atoms(d, d->atoms.head, d->atoms.len);
96
}
97
98
/* kd is a quadratic space myers matrix from the original Myers algorithm.
99
* kd_forward and kd_backward are linear slices of a myers matrix from the Myers
100
* Divide algorithm.
101
*/
102
static inline void
103
dump_myers_graph(const struct diff_data *l, const struct diff_data *r,
104
int *kd, int *kd_forward, int kd_forward_d,
105
int *kd_backward, int kd_backward_d)
106
{
107
#define COLOR_YELLOW "\033[1;33m"
108
#define COLOR_GREEN "\033[1;32m"
109
#define COLOR_BLUE "\033[1;34m"
110
#define COLOR_RED "\033[1;31m"
111
#define COLOR_END "\033[0;m"
112
int x;
113
int y;
114
print(" ");
115
for (x = 0; x <= l->atoms.len; x++)
116
print("%2d", x % 100);
117
print("\n");
118
119
for (y = 0; y <= r->atoms.len; y++) {
120
print("%3d ", y);
121
for (x = 0; x <= l->atoms.len; x++) {
122
123
/* print d advancements from kd, if any. */
124
char label = 'o';
125
char *color = NULL;
126
if (kd) {
127
int max = l->atoms.len + r->atoms.len;
128
size_t kd_len = max + 1 + max;
129
int *kd_pos = kd;
130
int di;
131
#define xk_to_y(X, K) ((X) - (K))
132
for (di = 0; di < max; di++) {
133
int ki;
134
for (ki = di; ki >= -di; ki -= 2) {
135
if (x != kd_pos[ki]
136
|| y != xk_to_y(x, ki))
137
continue;
138
label = '0' + (di % 10);
139
color = COLOR_YELLOW;
140
break;
141
}
142
if (label != 'o')
143
break;
144
kd_pos += kd_len;
145
}
146
}
147
if (kd_forward && kd_forward_d >= 0) {
148
#define xc_to_y(X, C, DELTA) ((X) - (C) + (DELTA))
149
int ki;
150
for (ki = kd_forward_d;
151
ki >= -kd_forward_d;
152
ki -= 2) {
153
if (x != kd_forward[ki])
154
continue;
155
if (y != xk_to_y(x, ki))
156
continue;
157
label = 'F';
158
color = COLOR_GREEN;
159
break;
160
}
161
}
162
if (kd_backward && kd_backward_d >= 0) {
163
int delta = (int)r->atoms.len
164
- (int)l->atoms.len;
165
int ki;
166
for (ki = kd_backward_d;
167
ki >= -kd_backward_d;
168
ki -= 2) {
169
if (x != kd_backward[ki])
170
continue;
171
if (y != xc_to_y(x, ki, delta))
172
continue;
173
if (label == 'o') {
174
label = 'B';
175
color = COLOR_BLUE;
176
} else {
177
label = 'X';
178
color = COLOR_RED;
179
}
180
break;
181
}
182
}
183
if (color)
184
print("%s", color);
185
print("%c", label);
186
if (color)
187
print("%s", COLOR_END);
188
if (x < l->atoms.len)
189
print("-");
190
}
191
print("\n");
192
if (y == r->atoms.len)
193
break;
194
195
print(" ");
196
for (x = 0; x < l->atoms.len; x++) {
197
bool same;
198
diff_atom_same(&same, &l->atoms.head[x],
199
&r->atoms.head[y]);
200
if (same)
201
print("|\\");
202
else
203
print("| ");
204
}
205
print("|\n");
206
}
207
}
208
209
static inline void
210
debug_dump_myers_graph(const struct diff_data *l, const struct diff_data *r,
211
int *kd, int *kd_forward, int kd_forward_d,
212
int *kd_backward, int kd_backward_d)
213
{
214
if (l->atoms.len > 99 || r->atoms.len > 99)
215
return;
216
dump_myers_graph(l, r, kd, kd_forward, kd_forward_d,
217
kd_backward, kd_backward_d);
218
}
219
220
#else
221
#define debug(args...)
222
#define debug_dump(args...)
223
#define debug_dump_atom(args...)
224
#define debug_dump_atoms(args...)
225
#define debug_dump_myers_graph(args...)
226
#endif
227
228