Mercurial > public > mercurial-scm > hg
annotate mercurial/thirdparty/xdiff/xutils.c @ 36761:09f320067591
xdiff: remove whitespace related feature
In Mercurial, whitespace related handling are done at a higher level than
the low-level diff algorithm so "ignore spaces". So it's not used by mdiff.
Some of the upcoming optimizations would be more difficult with whitespace
related features kept. So let's remove them.
Differential Revision: https://phab.mercurial-scm.org/D2683
author | Jun Wu <quark@fb.com> |
---|---|
date | Sun, 04 Mar 2018 00:07:04 -0800 |
parents | 34e2ff1f9cd8 |
children | b5bb0f99064d |
rev | line source |
---|---|
36671 | 1 /* |
2 * LibXDiff by Davide Libenzi ( File Differential Library ) | |
3 * Copyright (C) 2003 Davide Libenzi | |
4 * | |
5 * This library is free software; you can redistribute it and/or | |
6 * modify it under the terms of the GNU Lesser General Public | |
7 * License as published by the Free Software Foundation; either | |
8 * version 2.1 of the License, or (at your option) any later version. | |
9 * | |
10 * This library is distributed in the hope that it will be useful, | |
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
13 * Lesser General Public License for more details. | |
14 * | |
15 * You should have received a copy of the GNU Lesser General Public | |
16 * License along with this library; if not, see | |
17 * <http://www.gnu.org/licenses/>. | |
18 * | |
19 * Davide Libenzi <davidel@xmailserver.org> | |
20 * | |
21 */ | |
22 | |
23 #include <limits.h> | |
24 #include <assert.h> | |
25 #include "xinclude.h" | |
26 | |
27 | |
28 | |
29 | |
30 long xdl_bogosqrt(long n) { | |
31 long i; | |
32 | |
33 /* | |
34 * Classical integer square root approximation using shifts. | |
35 */ | |
36 for (i = 1; n > 0; n >>= 2) | |
37 i <<= 1; | |
38 | |
39 return i; | |
40 } | |
41 | |
42 | |
43 int xdl_emit_diffrec(char const *rec, long size, char const *pre, long psize, | |
44 xdemitcb_t *ecb) { | |
45 int i = 2; | |
46 mmbuffer_t mb[3]; | |
47 | |
48 mb[0].ptr = (char *) pre; | |
49 mb[0].size = psize; | |
50 mb[1].ptr = (char *) rec; | |
51 mb[1].size = size; | |
52 if (size > 0 && rec[size - 1] != '\n') { | |
53 mb[2].ptr = (char *) "\n\\ No newline at end of file\n"; | |
54 mb[2].size = strlen(mb[2].ptr); | |
55 i++; | |
56 } | |
57 if (ecb->outf(ecb->priv, mb, i) < 0) { | |
58 | |
59 return -1; | |
60 } | |
61 | |
62 return 0; | |
63 } | |
64 | |
65 void *xdl_mmfile_first(mmfile_t *mmf, long *size) | |
66 { | |
67 *size = mmf->size; | |
68 return mmf->ptr; | |
69 } | |
70 | |
71 | |
72 long xdl_mmfile_size(mmfile_t *mmf) | |
73 { | |
74 return mmf->size; | |
75 } | |
76 | |
77 | |
78 int xdl_cha_init(chastore_t *cha, long isize, long icount) { | |
79 | |
80 cha->head = cha->tail = NULL; | |
81 cha->isize = isize; | |
82 cha->nsize = icount * isize; | |
83 cha->ancur = cha->sncur = NULL; | |
84 cha->scurr = 0; | |
85 | |
86 return 0; | |
87 } | |
88 | |
89 | |
90 void xdl_cha_free(chastore_t *cha) { | |
91 chanode_t *cur, *tmp; | |
92 | |
93 for (cur = cha->head; (tmp = cur) != NULL;) { | |
94 cur = cur->next; | |
95 xdl_free(tmp); | |
96 } | |
97 } | |
98 | |
99 | |
100 void *xdl_cha_alloc(chastore_t *cha) { | |
101 chanode_t *ancur; | |
102 void *data; | |
103 | |
104 if (!(ancur = cha->ancur) || ancur->icurr == cha->nsize) { | |
105 if (!(ancur = (chanode_t *) xdl_malloc(sizeof(chanode_t) + cha->nsize))) { | |
106 | |
107 return NULL; | |
108 } | |
109 ancur->icurr = 0; | |
110 ancur->next = NULL; | |
111 if (cha->tail) | |
112 cha->tail->next = ancur; | |
113 if (!cha->head) | |
114 cha->head = ancur; | |
115 cha->tail = ancur; | |
116 cha->ancur = ancur; | |
117 } | |
118 | |
119 data = (char *) ancur + sizeof(chanode_t) + ancur->icurr; | |
120 ancur->icurr += cha->isize; | |
121 | |
122 return data; | |
123 } | |
124 | |
125 long xdl_guess_lines(mmfile_t *mf, long sample) { | |
126 long nl = 0, size, tsize = 0; | |
127 char const *data, *cur, *top; | |
128 | |
129 if ((cur = data = xdl_mmfile_first(mf, &size)) != NULL) { | |
130 for (top = data + size; nl < sample && cur < top; ) { | |
131 nl++; | |
132 if (!(cur = memchr(cur, '\n', top - cur))) | |
133 cur = top; | |
134 else | |
135 cur++; | |
136 } | |
137 tsize += (long) (cur - data); | |
138 } | |
139 | |
140 if (nl && tsize) | |
141 nl = xdl_mmfile_size(mf) / (tsize / nl); | |
142 | |
143 return nl + 1; | |
144 } | |
145 | |
146 int xdl_recmatch(const char *l1, long s1, const char *l2, long s2, long flags) | |
147 { | |
148 if (s1 == s2 && !memcmp(l1, l2, s1)) | |
149 return 1; | |
36761
09f320067591
xdiff: remove whitespace related feature
Jun Wu <quark@fb.com>
parents:
36671
diff
changeset
|
150 return 0; |
36671 | 151 } |
152 | |
153 unsigned long xdl_hash_record(char const **data, char const *top, long flags) { | |
154 unsigned long ha = 5381; | |
155 char const *ptr = *data; | |
156 | |
157 for (; ptr < top && *ptr != '\n'; ptr++) { | |
158 ha += (ha << 5); | |
159 ha ^= (unsigned long) *ptr; | |
160 } | |
161 *data = ptr < top ? ptr + 1: ptr; | |
162 | |
163 return ha; | |
164 } | |
165 | |
166 unsigned int xdl_hashbits(unsigned int size) { | |
167 unsigned int val = 1, bits = 0; | |
168 | |
169 for (; val < size && bits < CHAR_BIT * sizeof(unsigned int); val <<= 1, bits++); | |
170 return bits ? bits: 1; | |
171 } | |
172 | |
173 | |
174 int xdl_num_out(char *out, long val) { | |
175 char *ptr, *str = out; | |
176 char buf[32]; | |
177 | |
178 ptr = buf + sizeof(buf) - 1; | |
179 *ptr = '\0'; | |
180 if (val < 0) { | |
181 *--ptr = '-'; | |
182 val = -val; | |
183 } | |
184 for (; val && ptr > buf; val /= 10) | |
185 *--ptr = "0123456789"[val % 10]; | |
186 if (*ptr) | |
187 for (; *ptr; ptr++, str++) | |
188 *str = *ptr; | |
189 else | |
190 *str++ = '0'; | |
191 *str = '\0'; | |
192 | |
193 return str - out; | |
194 } | |
195 | |
196 int xdl_emit_hunk_hdr(long s1, long c1, long s2, long c2, | |
197 const char *func, long funclen, xdemitcb_t *ecb) { | |
198 int nb = 0; | |
199 mmbuffer_t mb; | |
200 char buf[128]; | |
201 | |
202 memcpy(buf, "@@ -", 4); | |
203 nb += 4; | |
204 | |
205 nb += xdl_num_out(buf + nb, c1 ? s1: s1 - 1); | |
206 | |
207 if (c1 != 1) { | |
208 memcpy(buf + nb, ",", 1); | |
209 nb += 1; | |
210 | |
211 nb += xdl_num_out(buf + nb, c1); | |
212 } | |
213 | |
214 memcpy(buf + nb, " +", 2); | |
215 nb += 2; | |
216 | |
217 nb += xdl_num_out(buf + nb, c2 ? s2: s2 - 1); | |
218 | |
219 if (c2 != 1) { | |
220 memcpy(buf + nb, ",", 1); | |
221 nb += 1; | |
222 | |
223 nb += xdl_num_out(buf + nb, c2); | |
224 } | |
225 | |
226 memcpy(buf + nb, " @@", 3); | |
227 nb += 3; | |
228 if (func && funclen) { | |
229 buf[nb++] = ' '; | |
230 if (funclen > sizeof(buf) - nb - 1) | |
231 funclen = sizeof(buf) - nb - 1; | |
232 memcpy(buf + nb, func, funclen); | |
233 nb += funclen; | |
234 } | |
235 buf[nb++] = '\n'; | |
236 | |
237 mb.ptr = buf; | |
238 mb.size = nb; | |
239 if (ecb->outf(ecb->priv, &mb, 1) < 0) | |
240 return -1; | |
241 | |
242 return 0; | |
243 } | |
244 | |
245 int xdl_fall_back_diff(xdfenv_t *diff_env, xpparam_t const *xpp, | |
246 int line1, int count1, int line2, int count2) | |
247 { | |
248 /* | |
249 * This probably does not work outside Git, since | |
250 * we have a very simple mmfile structure. | |
251 * | |
252 * Note: ideally, we would reuse the prepared environment, but | |
253 * the libxdiff interface does not (yet) allow for diffing only | |
254 * ranges of lines instead of the whole files. | |
255 */ | |
256 mmfile_t subfile1, subfile2; | |
257 xdfenv_t env; | |
258 | |
259 subfile1.ptr = (char *)diff_env->xdf1.recs[line1 - 1]->ptr; | |
260 subfile1.size = diff_env->xdf1.recs[line1 + count1 - 2]->ptr + | |
261 diff_env->xdf1.recs[line1 + count1 - 2]->size - subfile1.ptr; | |
262 subfile2.ptr = (char *)diff_env->xdf2.recs[line2 - 1]->ptr; | |
263 subfile2.size = diff_env->xdf2.recs[line2 + count2 - 2]->ptr + | |
264 diff_env->xdf2.recs[line2 + count2 - 2]->size - subfile2.ptr; | |
265 if (xdl_do_diff(&subfile1, &subfile2, xpp, &env) < 0) | |
266 return -1; | |
267 | |
268 memcpy(diff_env->xdf1.rchg + line1 - 1, env.xdf1.rchg, count1); | |
269 memcpy(diff_env->xdf2.rchg + line2 - 1, env.xdf2.rchg, count2); | |
270 | |
271 xdl_free_env(&env); | |
272 | |
273 return 0; | |
274 } |