mirror of
https://https.git.savannah.gnu.org/git/diffutils.git
synced 2026-01-26 06:57:59 +00:00
cmp: support -n N with huge N
* src/cmp.c (bytes): Use INTMAX_MAX, not -1, for “infinity”. This simplifies the code and is not a value that can be exhausted these days. (main, cmp): Treat very large -n values as “infinity”. * tests/cmp: Test this.
This commit is contained in:
parent
b7d8245828
commit
9c5fcbdc29
4
NEWS
4
NEWS
@ -4,9 +4,7 @@ GNU diffutils NEWS -*- outline -*-
|
||||
|
||||
** Bug fixes
|
||||
|
||||
cmp -i N no longer fails merely if N exceeds the maximum off_t value,
|
||||
and no longer mishandles Linux tmpfs files when N is slightly less
|
||||
than the maximum off_t value.
|
||||
cmp -i N and -n N no longer fail merely because N is enormous.
|
||||
[bug present since "the beginning"]
|
||||
|
||||
cmp -s no longer mishandles /proc files, for which the Linux kernel
|
||||
|
||||
4
TODO
4
TODO
@ -6,8 +6,10 @@ GNU patch already parses this format.
|
||||
|
||||
Add --include option (opposite of --exclude).
|
||||
|
||||
Add SEEK_DATA/SEEK_HOLE sparse file optimization to cmp, diff -q, etc.
|
||||
|
||||
Look into sdiff improvement here:
|
||||
http://www.pkix.net/~chuck/sdiff2.diff
|
||||
https://web.archive.org/web/20090106164131/http://www.pkix.net/~chuck/sdiff2.diff
|
||||
|
||||
Propagate stderr from subprocess so that diff3 does
|
||||
a better job of explaining _why_:
|
||||
|
||||
38
src/cmp.c
38
src/cmp.c
@ -81,8 +81,12 @@ static idx_t buf_size;
|
||||
requested to ignore more than TYPE_MAXIMUM (intmax_t) bytes. */
|
||||
static intmax_t ignore_initial[2];
|
||||
|
||||
/* Number of bytes to compare, or negative if there is no limit. */
|
||||
static intmax_t bytes = -1;
|
||||
/* Number of bytes to compare. INTMAX_MAX is effectively infinity,
|
||||
since there's no practical way on current computers to compare so
|
||||
many bytes. Even if cmp added SEEK_HOLE and SEEK_DATA optimization,
|
||||
regular files can't have more than TYPE_MAXIMUM (off_t) bytes
|
||||
and special files are unlikely to support this optimization. */
|
||||
static intmax_t bytes = INTMAX_MAX;
|
||||
|
||||
/* Output format. */
|
||||
static enum comparison_type
|
||||
@ -240,11 +244,10 @@ main (int argc, char **argv)
|
||||
case 'n':
|
||||
{
|
||||
intmax_t n;
|
||||
if (xstrtoimax (optarg, nullptr, 0, &n, valid_suffixes) != LONGINT_OK
|
||||
|| n < 0)
|
||||
strtol_error e = xstrtoimax (optarg, nullptr, 0, &n, valid_suffixes);
|
||||
if ((e & ~LONGINT_OVERFLOW) != LONGINT_OK || n < 0)
|
||||
try_help ("invalid --bytes value '%s'", optarg);
|
||||
if (! (0 <= bytes && bytes < n))
|
||||
bytes = n;
|
||||
bytes = MIN (bytes, n);
|
||||
}
|
||||
break;
|
||||
|
||||
@ -365,7 +368,7 @@ main (int argc, char **argv)
|
||||
s0 = 0;
|
||||
if (s1 < 0)
|
||||
s1 = 0;
|
||||
if (s0 != s1 && (bytes < 0 || MIN (s0, s1) < bytes))
|
||||
if (s0 != s1 && MIN (s0, s1) < bytes)
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
@ -412,19 +415,14 @@ cmp (void)
|
||||
|
||||
if (comparison_type == type_all_diffs)
|
||||
{
|
||||
off_t byte_number_max = (0 <= bytes && bytes <= TYPE_MAXIMUM (off_t)
|
||||
? bytes : TYPE_MAXIMUM (off_t));
|
||||
intmax_t byte_number_max = bytes;
|
||||
|
||||
for (int f = 0; f < 2; f++)
|
||||
if (0 < stat_buf[f].st_size && S_ISREG (stat_buf[f].st_mode))
|
||||
{
|
||||
off_t pos = file_position (f);
|
||||
if (0 <= pos)
|
||||
{
|
||||
off_t file_bytes = MAX (0, stat_buf[f].st_size - pos);
|
||||
if (file_bytes < byte_number_max)
|
||||
byte_number_max = file_bytes;
|
||||
}
|
||||
off_t after_pos = stat_buf[f].st_size - MAX (0, pos);
|
||||
byte_number_max = MIN (byte_number_max, after_pos);
|
||||
}
|
||||
|
||||
for (offset_width = 1; (byte_number_max /= 10) != 0; offset_width++)
|
||||
@ -484,14 +482,8 @@ cmp (void)
|
||||
|
||||
while (true)
|
||||
{
|
||||
idx_t bytes_to_read = buf_size;
|
||||
|
||||
if (0 <= remaining)
|
||||
{
|
||||
if (remaining < bytes_to_read)
|
||||
bytes_to_read = remaining;
|
||||
remaining -= bytes_to_read;
|
||||
}
|
||||
idx_t bytes_to_read = MIN (buf_size, remaining);
|
||||
remaining -= bytes_to_read;
|
||||
|
||||
ptrdiff_t read0 = (eof[0] ? 0
|
||||
: block_read (file_desc[0], buf0, bytes_to_read));
|
||||
|
||||
@ -228,6 +228,8 @@ cmp -bl j1 j2 > out2
|
||||
test $? -eq 1 || fail=1
|
||||
compare exp2 out2 || fail=1
|
||||
|
||||
cmp -i 99999999999999999999999999999999999999999999999999 j1 j2 || fail=1
|
||||
big=99999999999999999999999999999999999999999999999999999999999
|
||||
cmp -i $big j1 j2 || fail=1
|
||||
cmp -i 1000 -n $big j1 j2 || fail=1
|
||||
|
||||
Exit $fail
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user