2
Numdiff - compare putatively similar files,
3
ignoring small numeric differences
4
Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010 Ivano Primi <ivprimi@libero.it>
6
This program is free software: you can redistribute it and/or modify
7
it under the terms of the GNU General Public License as published by
8
the Free Software Foundation, either version 3 of the License, or
9
(at your option) any later version.
11
This program is distributed in the hope that it will be useful,
12
but WITHOUT ANY WARRANTY; without even the implied warranty of
13
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
GNU General Public License for more details.
16
You should have received a copy of the GNU General Public License
17
along with this program. If not, see <http://www.gnu.org/licenses/>.
23
/* Constants and default values */
24
#define CHUNK_ALLOC 20480
26
static flg_array internal_table;
29
`table' must be the address of a `flg_array' structure.
31
static int init_flg_array (flg_array* table)
36
table->size = table->len = 0;
45
return init_flg_array (&internal_table);
49
`table' must be the address of a `flg_array' structure.
51
static int print_flg_array (FILE* fp, const flg_array* table)
55
unsigned char byte, elem;
57
if (!table || !table->ptr)
58
return (fputs (_("<The array is empty>\n"), fp) == EOF);
63
for (n = 0; !outerror && n < table->len; n += 4U)
65
byte = table->ptr[n/4U];
66
for (i = 0; i < 4U; i++)
68
if ( (elem = (byte & 0x03 << 2*i) >> 2 * i) )
70
if ( fprintf (fp, "%u", elem) < 0 )
81
outerror = (fputc ('\n', fp) == EOF);
86
int print_flags (FILE* fp)
88
return print_flg_array (fp, &internal_table);
92
array must be the address of a `flg_array' structure.
94
static void addnewelem (flg_array* array, unsigned char elem)
100
array->ptr = xcalloc (CHUNK_ALLOC, sizeof (unsigned char));
101
array->size = CHUNK_ALLOC;
102
array->ptr[0] = elem;
105
fprintf (stderr, "size = %6zu, len = %6zu, string:",
106
array->size, array->len);
107
print_flg_array (stderr, array);
112
if (array->len == 4 * array->size - 1)
116
array->ptr = xrealloc (array->ptr, array->size + CHUNK_ALLOC);
117
array->size += CHUNK_ALLOC;
118
array->ptr[array->len / 4U] |= elem << 2 * (array->len % 4U);
119
array->len++; /* Now array->len == 4 * array->"old"size */
120
for (p = array->ptr + array->len / 4; p < array->ptr + array->size; *p = 0, p++);
122
fprintf (stderr, "size = %6zu, len = %6zu, string:",
123
array->size, array->len);
124
print_flg_array (stderr, array);
129
array->ptr[array->len / 4U] |= elem << 2 * (array->len % 4U);
132
fprintf (stderr, "size = %6zu, len = %6zu, string:",
133
array->size, array->len);
134
print_flg_array (stderr, array);
140
flg_array copy_of_intflagtab (void)
142
return internal_table;
146
array must be the address of a `flg_array' structure.
148
static void destroy_flg_array (flg_array* array)
150
if ((array) && (array->ptr))
152
free ((void*)array->ptr);
154
array->size = array->len = 0;
158
void erase_flags (void)
160
destroy_flg_array (&internal_table);
163
static void notedown_sdiff_common_lines (lin, lin);
164
static void notedown_sdiff_hunk (struct change *);
166
/* Next line number to be printed in the two input files. */
167
static lin next0, next1;
170
* Note down the edit-script SCRIPT in the INTERNAL_TABLE.
174
notedown_sdiff_script (struct change *script)
176
next0 = next1 = - files[0].prefix_lines;
177
print_script (script, notedown_sdiff_hunk);
179
notedown_sdiff_common_lines (files[0].valid_lines, files[1].valid_lines);
182
/* Print lines common to both files in side-by-side format. */
184
notedown_sdiff_common_lines (lin limit0, lin limit1)
186
lin i0 = next0, i1 = next1;
188
if (i0 != limit0 || i1 != limit1)
190
for (; i0 != limit0 && i1 != limit1; i0++, i1++)
191
addnewelem (&internal_table, 3);
193
for (; i1 != limit1; i1++)
194
addnewelem (&internal_table, 2);
196
for (; i0 != limit0; i0++)
197
addnewelem (&internal_table, 1);
204
/* Note down a hunk of an sdiff diff.
205
This is a contiguous portion of a complete edit script,
206
describing changes in consecutive lines. */
209
notedown_sdiff_hunk (struct change *hunk)
211
lin first0, last0, first1, last1;
214
/* Determine range of line numbers involved in each file. */
215
enum changes changes =
216
analyze_hunk (hunk, &first0, &last0, &first1, &last1);
220
/* Note down lines up to this change. */
221
notedown_sdiff_common_lines (first0, first1);
223
/* Note down ``xxx | xxx '' lines */
224
if (changes == CHANGED)
226
for (i = first0, j = first1; i <= last0 && j <= last1; i++, j++)
227
addnewelem (&internal_table, 3);
228
changes = (i <= last0 ? OLD : 0) + (j <= last1 ? NEW : 0);
233
/* Note down `` > xxx '' lines */
236
for (j = first1; j <= last1; ++j)
237
addnewelem (&internal_table, 2);
241
/* Note down ``xxx < '' lines */
244
for (i = first0; i <= last0; ++i)
245
addnewelem (&internal_table, 1);