1
0
Fork 0

Merging upstream version 1.13~rc1.

Signed-off-by: Daniel Baumann <daniel@debian.org>
This commit is contained in:
Daniel Baumann 2025-02-24 06:03:46 +01:00
parent f40403d840
commit 95e3ee3bd3
Signed by: daniel
GPG key ID: FBB4F0E80A80222F
29 changed files with 472 additions and 517 deletions

53
zcmp.cc
View file

@ -58,13 +58,10 @@ void show_help()
"\nThe formats supported are bzip2, gzip, lzip, xz, and zstd.\n"
"\nUsage: zcmp [options] file1 [file2]\n"
"\nzcmp compares file1 to file2. The standard input is used only if file1 or\n"
"file2 refers to standard input. If file2 is omitted zcmp tries the\n"
"following:\n"
"\n - If file1 is compressed, compares its decompressed contents with\n"
" the corresponding uncompressed file (the name of file1 with the\n"
" extension removed).\n"
"\n - If file1 is uncompressed, compares it with the decompressed\n"
" contents of file1.[lz|bz2|gz|zst|xz] (the first one that is found).\n"
"file2 refers to standard input. If file2 is omitted zcmp tries to compare\n"
"file1 with the corresponding uncompressed file (if file1 is compressed), and\n"
"then with the corresponding compressed files of the remaining formats until\n"
"one is found.\n"
"\nExit status is 0 if inputs are identical, 1 if different, 2 if trouble.\n"
"\nOptions:\n"
" -h, --help display this help and exit\n"
@ -98,9 +95,9 @@ void show_help()
// separate numbers of 5 or more digits in groups of 3 digits using '_'
const char * format_num3( long long num )
{
const char * const si_prefix = "kMGTPEZY";
const char * const binary_prefix = "KMGTPEZY";
enum { buffers = 8, bufsize = 4 * sizeof num };
enum { buffers = 8, bufsize = 4 * sizeof num, n = 10 };
const char * const si_prefix = "kMGTPEZYRQ";
const char * const binary_prefix = "KMGTPEZYRQ";
static char buffer[buffers][bufsize]; // circle of static buffers for printf
static int current = 0;
@ -108,19 +105,22 @@ const char * format_num3( long long num )
char * p = buf + bufsize - 1; // fill the buffer backwards
*p = 0; // terminator
const bool negative = num < 0;
char prefix = 0; // try binary first, then si
for( int i = 0; i < 8 && num != 0 && ( num / 1024 ) * 1024 == num; ++i )
{ num /= 1024; prefix = binary_prefix[i]; }
if( prefix ) *(--p) = 'i';
else
for( int i = 0; i < 8 && num != 0 && ( num / 1000 ) * 1000 == num; ++i )
{ num /= 1000; prefix = si_prefix[i]; }
if( prefix ) *(--p) = prefix;
if( num > 1024 || num < -1024 )
{
char prefix = 0; // try binary first, then si
for( int i = 0; i < n && num != 0 && num % 1024 == 0; ++i )
{ num /= 1024; prefix = binary_prefix[i]; }
if( prefix ) *(--p) = 'i';
else
for( int i = 0; i < n && num != 0 && num % 1000 == 0; ++i )
{ num /= 1000; prefix = si_prefix[i]; }
if( prefix ) *(--p) = prefix;
}
const bool split = num >= 10000 || num <= -10000;
for( int i = 0; ; )
{
long long onum = num; num /= 10;
const long long onum = num; num /= 10;
*(--p) = llabs( onum - ( 10 * num ) ) + '0'; if( num == 0 ) break;
if( split && ++i >= 3 ) { i = 0; *(--p) = '_'; }
}
@ -129,6 +129,7 @@ const char * format_num3( long long num )
}
// Recognized formats: <num>k[B], <num>Ki[B], <num>[MGTPEZYRQ][i][B]
long long getnum( const char * const arg, const char * const option_name,
const char ** const tailp = 0,
const long long llimit = 0,
@ -152,6 +153,8 @@ long long getnum( const char * const arg, const char * const option_name,
int exponent = -1; // -1 = bad multiplier
switch( ch )
{
case 'Q': exponent = 10; break;
case 'R': exponent = 9; break;
case 'Y': exponent = 8; break;
case 'Z': exponent = 7; break;
case 'E': exponent = 6; break;
@ -210,7 +213,7 @@ bool skip_ignore_initial( const long long ignore_initial, const int infd )
const int size = std::min( rest, (long long)buffer_size );
const int rd = readblock( infd, buffer, size );
if( rd != size && errno ) return false;
if( rd < size ) break;
if( rd < size ) break; // EOF
rest -= rd;
}
}
@ -270,6 +273,7 @@ int cmp( const long long max_size, const int infd[2],
uint8_t * buffer[2];
buffer[0] = buffer0; buffer[1] = buffer1;
int retval = 0;
bool empty[2] = { true, true };
while( rest > 0 )
{
@ -282,6 +286,7 @@ int cmp( const long long max_size, const int infd[2],
if( rd[i] != size && errno )
{ show_file_error( filenames[i].c_str(), "Read error", errno );
retval = 2; goto done; }
if( rd[i] > 0 ) empty[i] = false;
}
for( int i = 0; i < 2; ++i )
if( rd[i] < size ) finished[i] = true;
@ -345,11 +350,13 @@ int cmp( const long long max_size, const int infd[2],
if( rd[0] != rd[1] )
{
const int i = rd[1] < rd[0];
if( verbosity >= 0 )
std::fprintf( stderr, list ?
std::fprintf( stderr, empty[i] ?
"%s: EOF on %s which is empty\n" : list ?
"%s: EOF on %s after byte %llu\n" :
"%s: EOF on %s after byte %llu, in line %llu\n",
program_name, filenames[rd[1]<rd[0]].c_str(),
program_name, filenames[i].c_str(),
byte_number - 1, line_number );
retval = 1; break;
}
@ -434,7 +441,7 @@ int main( const int argc, const char * const argv[] )
case lz_opt: parse_compressor( sarg, pn, fmt_lz ); break;
case xz_opt: parse_compressor( sarg, pn, fmt_xz ); break;
case zst_opt: parse_compressor( sarg, pn, fmt_zst ); break;
default : internal_error( "uncaught option." );
default: internal_error( "uncaught option." );
}
} // end process options