"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "zdiff.cc" between
zutils-1.8.tar.lz and zutils-1.9.tar.lz

About: Zutils is a collection of utilities able to deal with any combination of compressed and non-compressed files transparently. The utilities zcat, zcmp, zdiff, zgrep and ztest supports the compressors bzip2, gzip, lzip and xz.

zdiff.cc  (zutils-1.8.tar.lz):zdiff.cc  (zutils-1.9.tar.lz)
/* Zdiff - decompress and compare two files line by line /* Zdiff - decompress and compare two files line by line
Copyright (C) 2010-2019 Antonio Diaz Diaz. Copyright (C) 2010-2020 Antonio Diaz Diaz.
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or the Free Software Foundation, either version 2 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#define _FILE_OFFSET_BITS 64 #define _FILE_OFFSET_BITS 64
#include <algorithm> #include <algorithm>
#include <cctype> #include <cctype>
#include <cerrno> #include <cerrno>
#include <climits> #include <climits>
#include <csignal> #include <csignal>
#include <cstdio> #include <cstdio>
skipping to change at line 42 skipping to change at line 42
#include <unistd.h> #include <unistd.h>
#include <sys/stat.h> #include <sys/stat.h>
#if defined(__MSVCRT__) || defined(__OS2__) #if defined(__MSVCRT__) || defined(__OS2__)
#include <io.h> #include <io.h>
#endif #endif
#include "arg_parser.h" #include "arg_parser.h"
#include "rc.h" #include "rc.h"
#include "zutils.h" #include "zutils.h"
// 'verbosity' is always 0 in zdiff; no --verbose or --quiet available.
namespace { namespace {
std::string fifonames[2]; // names of the two fifos passed to diff std::string fifonames[2]; // names of the two fifos passed to diff
#include "zcmpdiff.cc" #include "zcmpdiff.cc"
void show_help() void show_help()
{ {
std::printf( "Zdiff compares two files ('-' means standard input), and if they std::printf( "zdiff compares two files and, if they differ, writes to standard
\n" output the\n"
"differ, shows the differences line by line. If any given file is "differences line by line. A hyphen '-' used as a file argument m
\n" eans standard\n"
"compressed, its decompressed content is used. Zdiff is a front e "input. If any file given is compressed, its decompressed content
nd to\n" is used.\n"
"the diff program and has the limitation that messages from diff "zdiff is a front end to the program diff and has the limitation
refer to\n" that messages\n"
"temporary filenames instead of those specified.\n" "from diff refer to temporary file names instead of those specifi
"\nThe formats supported are bzip2, gzip, lzip and xz.\n" ed.\n"
"\nThe formats supported are bzip2, gzip, lzip, and xz.\n"
"\nUsage: zdiff [options] file1 [file2]\n" "\nUsage: zdiff [options] file1 [file2]\n"
"\nZdiff compares file1 to file2. If file2 is omitted zdiff tries "\nzdiff compares file1 to file2. The standard input is used only
the\n" if file1 or\n"
"file2 refers to standard input. If file2 is omitted zdiff tries
the\n"
"following:\n" "following:\n"
"\n 1. If file1 is compressed, compares its decompressed content s with\n" "\n - If file1 is compressed, compares its decompressed contents with\n"
" the corresponding uncompressed file (the name of file1 with th e\n" " the corresponding uncompressed file (the name of file1 with th e\n"
" extension removed).\n" " extension removed).\n"
"\n 2. If file1 is uncompressed, compares it with the decompress ed\n" "\n - If file1 is uncompressed, compares it with the decompresse d\n"
" contents of file1.[lz|bz2|gz|xz] (the first one that is found) .\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 re
ad from\n"
" standard input.\n"
"\nExit status is 0 if inputs are identical, 1 if different, 2 if trouble.\n" "\nExit status is 0 if inputs are identical, 1 if different, 2 if trouble.\n"
"Some options only work if the diff program used supports them.\n "
"\nOptions:\n" "\nOptions:\n"
" -h, --help display this help and exit\n " " -h, --help display this help and exit\n "
" -V, --version output version information a nd exit\n" " -V, --version output version information a nd exit\n"
" -a, --text treat all files as text\n" " -a, --text treat all files as text\n"
" -b, --ignore-space-change ignore changes in the amount of white space\n" " -b, --ignore-space-change ignore changes in the amount of white space\n"
" -B, --ignore-blank-lines ignore changes whose lines a re all blank\n" " -B, --ignore-blank-lines ignore changes whose lines a re all blank\n"
" -c use the context output forma t\n" " -c use the context output forma t\n"
" -C, --context=<n> same as -c but use <n> lines of context\n" " -C, --context=<n> same as -c but use <n> lines of context\n"
" -d, --minimal try hard to find a smaller s et of changes\n" " -d, --minimal try hard to find a smaller s et of changes\n"
" -E, --ignore-tab-expansion ignore changes due to tab ex pansion\n" " -E, --ignore-tab-expansion ignore changes due to tab ex pansion\n"
" -i, --ignore-case ignore case differences in f ile contents\n" " -i, --ignore-case ignore case differences in f ile contents\n"
" -M, --format=<list> process only the formats in <list>\n" " -M, --format=<list> process only the formats in <list>\n"
" -N, --no-rcfile don't read runtime configura tion file\n" " -N, --no-rcfile don't read runtime configura tion file\n"
" -O, --force-format=[<f1>][,<f2>] force given formats (bz2, gz , lz, xz)\n" " -O, --force-format=[<f1>][,<f2>] force the formats given (bz2 , gz, lz, xz)\n"
" -p, --show-c-function show which C function each c hange is in\n" " -p, --show-c-function show which C function each c hange is in\n"
" -q, --brief output only whether files di ffer\n" " -q, --brief output only whether files di ffer\n"
" -s, --report-identical-files report when two files are id entical\n" " -s, --report-identical-files report when two files are id entical\n"
" -t, --expand-tabs expand tabs to spaces in out put\n" " -t, --expand-tabs expand tabs to spaces in out put\n"
" -T, --initial-tab make tabs line up by prepend ing a tab\n" " -T, --initial-tab make tabs line up by prepend ing a tab\n"
" -u use the unified output forma t\n" " -u use the unified output forma t\n"
" -U, --unified=<n> same as -u but use <n> lines of context\n" " -U, --unified=<n> same as -u but use <n> lines of context\n"
" -w, --ignore-all-space ignore all white space\n" " -w, --ignore-all-space ignore all white space\n"
" -W, --width=<n> output at most <n> print col
umns\n"
" -y, --side-by-side output in two columns\n"
" --bz2=<command> set compressor and options f or bzip2 format\n" " --bz2=<command> set compressor and options f or bzip2 format\n"
" --gz=<command> set compressor and options f or gzip format\n" " --gz=<command> set compressor and options f or gzip format\n"
" --lz=<command> set compressor and options f or lzip format\n" " --lz=<command> set compressor and options f or lzip format\n"
" --xz=<command> set compressor and options f or xz format\n" ); " --xz=<command> set compressor and options f or xz format\n" );
show_help_addr(); show_help_addr();
} }
const char * my_basename( const char * filename ) const char * my_basename( const char * filename )
{ {
const char * c = filename; const char * c = filename;
skipping to change at line 111 skipping to change at line 115
} }
extern "C" void remove_fifos() extern "C" void remove_fifos()
{ {
if( fifonames[0].size() ) if( fifonames[0].size() )
{ std::remove( fifonames[0].c_str() ); fifonames[0].clear(); } { std::remove( fifonames[0].c_str() ); fifonames[0].clear(); }
if( fifonames[1].size() ) if( fifonames[1].size() )
{ std::remove( fifonames[1].c_str() ); fifonames[1].clear(); } { std::remove( fifonames[1].c_str() ); fifonames[1].clear(); }
} }
// Set fifonames[i] to "${TMPDIR}/<coded_pid>[_-]<basename(filenames[i])>" /* Set fifonames[i] to "${TMPDIR}/<coded_pid>[_-]<basename(filenames[i])>"
// and create FIFOs. and create FIFOs. */
bool set_fifonames( const std::string filenames[2] ) bool set_fifonames( const std::string filenames[2] )
{ {
enum { num_codes = 36 }; enum { num_codes = 36 };
const char * const codes = "0123456789abcdefghijklmnopqrstuvwxyz"; const char * const codes = "0123456789abcdefghijklmnopqrstuvwxyz";
const char * p = std::getenv( "TMPDIR" ); const char * p = std::getenv( "TMPDIR" );
if( p ) { fifonames[0] = p; fifonames[0] += '/'; } if( p ) { fifonames[0] = p; fifonames[0] += '/'; }
else fifonames[0] = "/tmp/"; else fifonames[0] = "/tmp/";
int n = getpid(); int n = getpid();
unsigned pos = fifonames[0].size(); unsigned pos = fifonames[0].size();
skipping to change at line 150 skipping to change at line 154
show_file_error( fifonames[i].c_str(), "Can't create FIFO", errno ); show_file_error( fifonames[i].c_str(), "Can't create FIFO", errno );
return false; return false;
} }
return true; return true;
} }
bool set_data_feeder( const std::string & filename, bool set_data_feeder( const std::string & filename,
const std::string & fifoname, const int infd, const std::string & fifoname, const int infd,
Children & children, int format_index ) Children & children, int format_index )
{ {
const uint8_t * magic_data = 0; uint8_t magic_data[magic_buf_size];
int magic_size = 0; int magic_size = 0;
if( format_index < 0 ) if( format_index < 0 )
format_index = test_format( infd, &magic_data, &magic_size ); format_index = test_format( infd, magic_data, &magic_size );
children.compressor_name = get_compressor_name( format_index ); children.compressor_name = get_compressor_name( format_index );
if( children.compressor_name ) // compressed if( children.compressor_name ) // compressed
{ {
int fda[2]; // pipe from feeder to compressor int fda[2]; // pipe from feeder to compressor
if( pipe( fda ) < 0 ) if( pipe( fda ) < 0 )
{ show_error( "Can't create pipe", errno ); return false; } { show_error( "Can't create pipe", errno ); return false; }
const pid_t pid = fork(); const pid_t pid = fork();
if( pid == 0 ) // child 1 (compressor feeder) if( pid == 0 ) // child 1 (compressor feeder)
{ {
skipping to change at line 259 skipping to change at line 263
std::signal( SIGTERM, signal_handler ); std::signal( SIGTERM, signal_handler );
} }
} // end namespace } // end namespace
int main( const int argc, const char * const argv[] ) int main( const int argc, const char * const argv[] )
{ {
enum { bz2_opt = 256, gz_opt, lz_opt, xz_opt }; enum { bz2_opt = 256, gz_opt, lz_opt, xz_opt };
std::vector< const char * > diff_args; // args to diff, maybe empty std::vector< const char * > diff_args; // args to diff, maybe empty
int format_types[2] = { -1, -1 }; int format_types[2] = { -1, -1 };
invocation_name = argv[0];
program_name = "zdiff"; program_name = "zdiff";
invocation_name = ( argc > 0 ) ? argv[0] : program_name;
const Arg_parser::Option options[] = const Arg_parser::Option options[] =
{ {
{ 'a', "text", Arg_parser::no }, { 'a', "text", Arg_parser::no },
{ 'b', "ignore-space-change", Arg_parser::no }, { 'b', "ignore-space-change", Arg_parser::no },
{ 'B', "ignore-blank-lines", Arg_parser::no }, { 'B', "ignore-blank-lines", Arg_parser::no },
{ 'c', 0, Arg_parser::no }, { 'c', 0, Arg_parser::no },
{ 'C', "context", Arg_parser::yes }, { 'C', "context", Arg_parser::yes },
{ 'd', "minimal", Arg_parser::no }, { 'd', "minimal", Arg_parser::no },
{ 'E', "ignore-tab-expansion", Arg_parser::no }, { 'E', "ignore-tab-expansion", Arg_parser::no },
skipping to change at line 285 skipping to change at line 289
{ 'O', "force-format", Arg_parser::yes }, { 'O', "force-format", Arg_parser::yes },
{ 'p', "show-c-function", Arg_parser::no }, { 'p', "show-c-function", Arg_parser::no },
{ 'q', "brief", Arg_parser::no }, { 'q', "brief", Arg_parser::no },
{ 's', "report-identical-files", Arg_parser::no }, { 's', "report-identical-files", Arg_parser::no },
{ 't', "expand-tabs", Arg_parser::no }, { 't', "expand-tabs", Arg_parser::no },
{ 'T', "initial-tab", Arg_parser::no }, { 'T', "initial-tab", Arg_parser::no },
{ 'u', 0, Arg_parser::no }, { 'u', 0, Arg_parser::no },
{ 'U', "unified", Arg_parser::yes }, { 'U', "unified", Arg_parser::yes },
{ 'V', "version", Arg_parser::no }, { 'V', "version", Arg_parser::no },
{ 'w', "ignore-all-space", Arg_parser::no }, { 'w', "ignore-all-space", Arg_parser::no },
{ 'W', "width", Arg_parser::yes },
{ 'y', "side-by-side", Arg_parser::no },
{ bz2_opt, "bz2", Arg_parser::yes }, { bz2_opt, "bz2", Arg_parser::yes },
{ gz_opt, "gz", Arg_parser::yes }, { gz_opt, "gz", Arg_parser::yes },
{ lz_opt, "lz", Arg_parser::yes }, { lz_opt, "lz", Arg_parser::yes },
{ xz_opt, "xz", Arg_parser::yes }, { xz_opt, "xz", Arg_parser::yes },
{ 0 , 0, Arg_parser::no } }; { 0 , 0, Arg_parser::no } };
const Arg_parser parser( argc, argv, options ); const Arg_parser parser( argc, argv, options );
if( parser.error().size() ) // bad option if( parser.error().size() ) // bad option
{ show_error( parser.error().c_str(), 0, true ); return 2; } { show_error( parser.error().c_str(), 0, true ); return 2; }
skipping to change at line 328 skipping to change at line 334
case 'p': diff_args.push_back( "-p" ); break; case 'p': diff_args.push_back( "-p" ); break;
case 'q': diff_args.push_back( "-q" ); break; case 'q': diff_args.push_back( "-q" ); break;
case 's': diff_args.push_back( "-s" ); break; case 's': diff_args.push_back( "-s" ); break;
case 't': diff_args.push_back( "-t" ); break; case 't': diff_args.push_back( "-t" ); break;
case 'T': diff_args.push_back( "-T" ); break; case 'T': diff_args.push_back( "-T" ); break;
case 'u': diff_args.push_back( "-u" ); break; case 'u': diff_args.push_back( "-u" ); break;
case 'U': diff_args.push_back( "-U" ); case 'U': diff_args.push_back( "-U" );
diff_args.push_back( arg.c_str() ); break; diff_args.push_back( arg.c_str() ); break;
case 'V': show_version(); return 0; case 'V': show_version(); return 0;
case 'w': diff_args.push_back( "-w" ); break; case 'w': diff_args.push_back( "-w" ); break;
case 'W': diff_args.push_back( "-W" );
diff_args.push_back( arg.c_str() ); break;
case 'y': diff_args.push_back( "-y" ); break;
case bz2_opt: parse_compressor( arg, fmt_bz2 ); break; case bz2_opt: parse_compressor( arg, fmt_bz2 ); break;
case gz_opt: parse_compressor( arg, fmt_gz ); break; case gz_opt: parse_compressor( arg, fmt_gz ); break;
case lz_opt: parse_compressor( arg, fmt_lz ); break; case lz_opt: parse_compressor( arg, fmt_lz ); break;
case xz_opt: parse_compressor( arg, fmt_xz ); break; case xz_opt: parse_compressor( arg, fmt_xz ); break;
default : internal_error( "uncaught option." ); default : internal_error( "uncaught option." );
} }
} // end process options } // end process options
#if defined(__MSVCRT__) || defined(__OS2__) #if defined(__MSVCRT__) || defined(__OS2__)
setmode( STDIN_FILENO, O_BINARY ); setmode( STDIN_FILENO, O_BINARY );
skipping to change at line 356 skipping to change at line 365
const int files = parser.arguments() - argind; const int files = parser.arguments() - argind;
std::string filenames[2]; // file names of the two input files std::string filenames[2]; // file names of the two input files
filenames[0] = parser.argument( argind ); filenames[0] = parser.argument( argind );
if( files == 2 ) filenames[1] = parser.argument( argind + 1 ); if( files == 2 ) filenames[1] = parser.argument( argind + 1 );
int infd[2]; // file descriptors of the two files int infd[2]; // file descriptors of the two files
infd[0] = ( filenames[0] == "-" ) ? infd[0] = ( filenames[0] == "-" ) ?
STDIN_FILENO : open_instream( filenames[0] ); STDIN_FILENO : open_instream( filenames[0] );
if( infd[0] < 0 ) return 2; if( infd[0] < 0 ) return 2;
if( ( files == 1 && filenames[0] == "-" ) ||
( files == 2 && check_identical( filenames[0].c_str(),
filenames[1].c_str() ) ) )
return 0;
if( files == 2 ) if( files == 2 )
{ {
if( check_identical( filenames[0].c_str(), filenames[1].c_str() ) )
return 0;
infd[1] = ( filenames[1] == "-" ) ? infd[1] = ( filenames[1] == "-" ) ?
STDIN_FILENO : open_instream( filenames[1] ); STDIN_FILENO : open_instream( filenames[1] );
if( infd[1] < 0 ) return 2; if( infd[1] < 0 ) return 2;
} }
else else
{ {
if( filenames[0] == "-" )
{ show_error( "Missing operand after '-'.", 0, true ); return 2; }
if( format_types[0] >= 0 || format_types[1] >= 0 ) if( format_types[0] >= 0 || format_types[1] >= 0 )
{ show_error( "Two files must be given when format is specified.", 0, true ); { show_error( "Two files must be given when format is specified.", 0, true );
return 2; } return 2; }
filenames[1] = filenames[0]; filenames[1] = filenames[0];
infd[1] = open_other_instream( filenames[1] ); infd[1] = open_other_instream( filenames[1] );
if( infd[1] < 0 ) { infd[1] = STDIN_FILENO; filenames[1] = "-"; } if( infd[1] < 0 )
{
if( verbosity >= 0 )
std::fprintf( stderr, "%s: Can't find file to compare with '%s'.\n",
program_name, filenames[0].c_str() );
show_error( 0, 0, true ); return 2;
}
} }
std::atexit( remove_fifos ); std::atexit( remove_fifos );
set_signals(); set_signals();
if( !set_fifonames( filenames ) ) return 2; if( !set_fifonames( filenames ) ) return 2;
Children children[2]; Children children[2];
if( !set_data_feeder( filenames[0], fifonames[0], infd[0], children[0], if( !set_data_feeder( filenames[0], fifonames[0], infd[0], children[0],
format_types[0] ) || format_types[0] ) ||
!set_data_feeder( filenames[1], fifonames[1], infd[1], children[1], !set_data_feeder( filenames[1], fifonames[1], infd[1], children[1],
 End of changes. 23 change blocks. 
42 lines changed or deleted 58 lines changed or added

Home  |  About  |  Features  |  All  |  Newest  |  Dox  |  Diffs  |  RSS Feeds  |  Screenshots  |  Comments  |  Imprint  |  Privacy  |  HTTP(S)