summaryrefslogtreecommitdiffstats
path: root/zcmp.cc
diff options
context:
space:
mode:
Diffstat (limited to 'zcmp.cc')
-rw-r--r--zcmp.cc44
1 files changed, 27 insertions, 17 deletions
diff --git a/zcmp.cc b/zcmp.cc
index 1cbd384..78debcc 100644
--- a/zcmp.cc
+++ b/zcmp.cc
@@ -1,5 +1,5 @@
/* Zcmp - decompress and compare two files byte by byte
- Copyright (C) 2010-2016 Antonio Diaz Diaz.
+ Copyright (C) 2010-2017 Antonio Diaz Diaz.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -57,21 +57,21 @@ void show_help()
"fly; no temporary files are created.\n"
"\nThe supported formats are bzip2, gzip, lzip and xz.\n"
"\nUsage: zcmp [options] file1 [file2]\n"
- "\nCompares <file1> to <file2>. If <file2> is omitted zcmp tries the\n"
+ "\nZcmp compares file1 to file2. If file2 is omitted zcmp tries the\n"
"following:\n"
- "\n 1. If <file1> is compressed, compares its decompressed contents with\n"
- " the corresponding uncompressed file (the name of <file1> with the\n"
+ "\n 1. 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 2. If <file1> is uncompressed, compares it with the decompressed\n"
- " contents of <file1>.[lz|bz2|gz|xz] (the first one that is found).\n"
- "\n 3. If no suitable file is found, compares <file1> with data read from\n"
+ "\n 2. If file1 is uncompressed, compares it with the decompressed\n"
+ " contents of file1.[lz|bz2|gz|xz] (the first one that is found).\n"
+ "\n 3. If no suitable file is found, compares file1 with data read from\n"
" standard input.\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"
" -V, --version output version information and exit\n"
" -b, --print-bytes print differing bytes\n"
- " -i, --ignore-initial=<n>[,<n2>] ignore differences in the first <n> bytes\n"
+ " -i, --ignore-initial=<n>[:<n2>] ignore differences in the first <n> bytes\n"
" -l, --list list position, value of all differing bytes\n"
" -M, --format=<list> process only the formats in <list>\n"
" -n, --bytes=<n> compare at most <n> bytes\n"
@@ -94,8 +94,8 @@ long long getnum( const char * const ptr, const char ** const tailp = 0,
const long long llimit = 0,
const long long ulimit = LLONG_MAX )
{
- errno = 0;
char * tail;
+ errno = 0;
long long result = strtoll( ptr, &tail, 0 );
if( tail == ptr )
{
@@ -106,9 +106,13 @@ long long getnum( const char * const ptr, const char ** const tailp = 0,
if( !errno && tail[0] && std::isalpha( tail[0] ) )
{
- const int factor = ( tail[1] == 'i' ) ? 1024 : 1000;
- int exponent = 0; // 0 = bad multiplier
- switch( tail[0] )
+ const unsigned char ch = *tail++;
+ int factor;
+ bool bsuf; // 'B' suffix is present
+ if( tail[0] == 'i' ) { ++tail; factor = 1024; } else factor = 1000;
+ if( tail[0] == 'B' ) { ++tail; bsuf = true; } else bsuf = false;
+ int exponent = -1; // -1 = bad multiplier
+ switch( ch )
{
case 'Y': exponent = 8; break;
case 'Z': exponent = 7; break;
@@ -119,8 +123,9 @@ long long getnum( const char * const ptr, const char ** const tailp = 0,
case 'M': exponent = 2; break;
case 'K': if( factor == 1024 ) exponent = 1; break;
case 'k': if( factor == 1000 ) exponent = 1; break;
+ case 'B': if( factor == 1000 && !bsuf ) exponent = 0; break;
}
- if( exponent <= 0 )
+ if( exponent < 0 )
{
show_error( "Bad multiplier in numerical argument.", 0, true );
std::exit( 2 );
@@ -146,9 +151,14 @@ void parse_ignore_initial( const char * const arg, long long ignore_initial[2] )
{
const char * tail;
ignore_initial[0] = getnum( arg, &tail );
- if( *tail == ',' || *tail == ':' )
+ if( *tail == ':' || *tail == ',' )
ignore_initial[1] = getnum( ++tail );
- else ignore_initial[1] = ignore_initial[0];
+ else if( *tail == 0 ) ignore_initial[1] = ignore_initial[0];
+ else
+ {
+ show_error( "Bad separator in argument of '--ignore-initial'", 0, true );
+ std::exit( 2 );
+ }
}
@@ -418,8 +428,8 @@ int main( const int argc, const char * const argv[] )
int old_infd[2]; // copy of file descriptors of the two files
old_infd[0] = infd[0]; old_infd[1] = infd[1];
Children children[2];
- if( !set_data_feeder( &infd[0], children[0], format_types[0] ) ||
- !set_data_feeder( &infd[1], children[1], format_types[1] ) )
+ if( !set_data_feeder( filenames[0], &infd[0], children[0], format_types[0] ) ||
+ !set_data_feeder( filenames[1], &infd[1], children[1], format_types[1] ) )
return 2;
for( int i = 0; i < 2; ++i )