cmp.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 188 行
C
188 行
/****************************************************************************
*
* Open Watcom Project
*
* Portions Copyright (c) 1983-2002 Sybase, Inc. All Rights Reserved.
*
* ========================================================================
*
* This file contains Original Code and/or Modifications of Original
* Code as defined in and that are subject to the Sybase Open Watcom
* Public License version 1.0 (the 'License'). You may not use this file
* except in compliance with the License. BY USING THIS FILE YOU AGREE TO
* ALL TERMS AND CONDITIONS OF THE LICENSE. A copy of the License is
* provided with the Original Code and Modifications, and is also
* available at www.sybase.com/developer/opensource.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND SYBASE AND ALL CONTRIBUTORS HEREBY DISCLAIM
* ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR
* NON-INFRINGEMENT. Please see the License for the specific language
* governing rights and limitations under the License.
*
* ========================================================================
*
* Description: POSIX cmp utility
* Compares files
*
****************************************************************************/
#include <stdio.h>
#include <errno.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>
#include "getopt.h"
#include "misc.h"
#include "argvenv.h"
static const char *usageTxt[] = {
"Usage:\tcmp [-?lsx] [@env] file1 file2 [seek1 [seek2]]",
"\tenv : environment variable to expand",
"\tfile1 file2 : files to compare. One of the files may be `-' for",
"\t\t the standard input.",
"\tOptions: -? : print this list",
"\t\t -l : Keep going after finding a difference",
"\t\t -s : Say nothing, return an error status",
"\t\t -x : Display differences in hex",
NULL
};
char *OptEnvVar = "cmp";
int flagKeepGoing;
int flagSayNothing;
int flagSayItInHex;
#define BUFFER_SIZE 16384
char buffer[ 2 ][ BUFFER_SIZE ];
int cmp( int fh[2], char *names[2], long offs[2] ) {
int i;
const char *fmt;
int bytes_read[2];
size_t amt;
for(;;) {
bytes_read[0] = read( fh[0], &buffer[0][0], BUFFER_SIZE );
if( bytes_read[0] == -1 ) {
Die( "error reading %s: %s\n", names[0], strerror( errno ) );
}
bytes_read[1] = read( fh[1], &buffer[1][0], BUFFER_SIZE );
if( bytes_read[1] == -1 ) {
Die( "error reading %s: %s\n", names[1], strerror( errno ) );
}
amt = bytes_read[0] < bytes_read[1] ? bytes_read[0] : bytes_read[1];
if( memcmp( &buffer[0][0], &buffer[1][0], amt ) ) {
for( i = 0; i < amt; ++i ) {
if( buffer[0][i] != buffer[1][i] ) {
if( !flagSayNothing ) {
if( offs[0] == offs[1] ) {
if( flagSayItInHex ) {
fmt = "offset %08lx: %s=%02x, %s=%02x\n";
} else {
fmt = "offset %lu: %s=%u, %s=%u\n";
}
printf( fmt, offs[0]+i, names[0], buffer[0][i],
names[1], buffer[1][i] );
} else {
if( flagSayItInHex ) {
fmt = "offset %08lx %s=%02x, offset %08lx %s=%02x\n";
} else {
fmt = "offset %lu %s=%u, offset %lu %s=%u\n";
}
printf( fmt, offs[0]+i, names[0], buffer[0][i],
offs[1]+i, names[1], buffer[1][i] );
}
}
if( !flagKeepGoing ) return( 1 );
}
}
}
offs[0] += bytes_read[0];
offs[1] += bytes_read[1];
if( bytes_read[0] != bytes_read[1] ) {
if( !flagSayNothing ) {
if( flagSayItInHex ) {
fmt = "%s ends prematurely at offset %08lx\n";
} else {
fmt = "%s ends prematurely at offset %u\n";
}
if( bytes_read[0] < bytes_read[1] ) {
printf( fmt, names[0], offs[0] );
} else {
printf( fmt, names[1], offs[1] );
}
}
return( 1 );
}
if( bytes_read[0] == 0 ) break;
}
return( 0 );
}
void main( int argc, char **argv ) {
int ch;
long offs[2];
int i;
int fh[2];
argv = ExpandEnv( &argc, argv );
for(;;) {
ch = GetOpt( &argc, argv, "lsx", usageTxt );
if( ch == -1 ) break;
switch( ch ) {
case 'l':
flagKeepGoing = 1;
break;
case 's':
flagSayNothing = 1;
break;
case 'x':
flagSayItInHex = 1;
break;
}
}
if( argc < 3 || argc > 5 ) {
Quit( usageTxt, "invalid number of arguments\n" );
}
offs[0] = offs[1] = 0;
if( argc > 3 ) {
offs[0] = strtol( argv[3], NULL, 0 );
if( argc > 4 ) {
offs[1] = strtol( argv[4], NULL, 0 );
}
}
++argv; // don't care about argv[0]
for( i = 0; i < 2; ++i ) {
if( argv[i][0] == '-' && argv[i][1] == 0 ) {
if( i == 1 && fh[0] == STDIN_FILENO ) {
Die( "cmp: only one argument can be stdin\n" );
}
fh[i] = STDIN_FILENO;
argv[i] = "(stdin)";
} else {
fh[i] = open( argv[i], O_RDONLY | O_BINARY );
if( fh[i] == -1 ) {
Die( "unable to open %s: %s\n", argv[i], strerror( errno ) );
}
}
if( offs[i] ) {
if( lseek( fh[i], offs[i], SEEK_SET ) == -1L ) {
Die( "error seeking to %s in %s: %s\n", argv[i+2], argv[i],
strerror( errno ) );
}
}
}
exit( cmp( fh, argv, offs ) );
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?