Sync with 4.4lite2
This commit is contained in:
parent
917ef72d79
commit
94f6fc8e46
|
@ -1,6 +1,7 @@
|
|||
# from: @(#)Makefile 5.3 (Berkeley) 5/11/90
|
||||
# $Id: Makefile,v 1.2 1993/07/31 15:24:56 mycroft Exp $
|
||||
# @(#)Makefile 8.1 (Berkeley) 6/6/93
|
||||
# $NetBSD: Makefile,v 1.3 1995/09/08 03:22:54 tls Exp $
|
||||
|
||||
PROG= cmp
|
||||
SRCS= cmp.c misc.c regular.c special.c
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
.\" Copyright (c) 1987, 1990 The Regents of the University of California.
|
||||
.\" All rights reserved.
|
||||
.\" $NetBSD: cmp.1,v 1.4 1995/09/08 03:22:55 tls Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 1987, 1990, 1993
|
||||
.\" The Regents of the University of California. All rights reserved.
|
||||
.\"
|
||||
.\" This code is derived from software contributed to Berkeley by
|
||||
.\" the Institute of Electrical and Electronics Engineers, Inc.
|
||||
|
@ -32,22 +34,22 @@
|
|||
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
.\" SUCH DAMAGE.
|
||||
.\"
|
||||
.\" from: @(#)cmp.1 6.7 (Berkeley) 6/27/91
|
||||
.\" $Id: cmp.1,v 1.3 1993/09/21 22:37:52 jtc Exp $
|
||||
.\" @(#)cmp.1 8.1 (Berkeley) 6/6/93
|
||||
.\"
|
||||
.Dd June 27, 1991
|
||||
.Dd June 6, 1993
|
||||
.Dt CMP 1
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm cmp
|
||||
.Nd Compare two files.
|
||||
.Nd compare two files
|
||||
.Sh SYNOPSIS
|
||||
.Nm cmp
|
||||
.Op Fl l Li \&| Fl s
|
||||
.Op Fl l | Fl s
|
||||
.Ar file1 file2
|
||||
.Op Ar skip1 Op Ar skip2
|
||||
.Sh DESCRIPTION
|
||||
The cmp utility compares two files of any type and
|
||||
writes the results to the standard output.
|
||||
The cmp utility compares two files of any type and writes the results
|
||||
to the standard output.
|
||||
By default,
|
||||
.Nm
|
||||
is silent if the files are the same; if they differ, the byte
|
||||
|
@ -56,7 +58,7 @@ and line number at which the first difference occurred is reported.
|
|||
Bytes and lines are numbered beginning with one.
|
||||
.Pp
|
||||
The following options are available:
|
||||
.Bl -tag -width Ds
|
||||
.Bl -tag -width flag
|
||||
.It Fl l
|
||||
Print the byte number (decimal) and the differing
|
||||
byte values (octal) for each difference.
|
||||
|
@ -65,11 +67,17 @@ Print nothing for differing files; return exit
|
|||
status only.
|
||||
.El
|
||||
.Pp
|
||||
If
|
||||
The optional arguments
|
||||
.Ar skip1
|
||||
and
|
||||
.Ar skip2
|
||||
are the byte offsets from the beginning of
|
||||
.Ar file1
|
||||
or
|
||||
.Ar file2
|
||||
is ``-'', the the standard input is used.
|
||||
and
|
||||
.Ar file2 ,
|
||||
respectively, where the comparison will begin.
|
||||
The offset is decimal by default, but may be expressed as an hexadecimal
|
||||
or octal value by preceding it with a leading ``0x'' or ``0''.
|
||||
.Pp
|
||||
The
|
||||
.Nm cmp
|
||||
|
@ -83,10 +91,10 @@ where one file is identical to the first part of
|
|||
the other.
|
||||
In the latter case, if the
|
||||
.Fl s
|
||||
option has
|
||||
not been specified, cmp writes to standard error
|
||||
that EOF was reached in the shorter file (before
|
||||
any differences were found).
|
||||
option has not been specified,
|
||||
.Nm cmp
|
||||
writes to standard output that EOF was reached in the shorter
|
||||
file (before any differences were found).
|
||||
.It >1
|
||||
An error occurred.
|
||||
.El
|
||||
|
@ -96,5 +104,6 @@ An error occurred.
|
|||
.Sh STANDARDS
|
||||
The
|
||||
.Nm cmp
|
||||
utility conforms to
|
||||
.St -p1003.2-92 .
|
||||
utility is expected to be
|
||||
.St -p1003.2
|
||||
compatible.
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
/* $NetBSD: cmp.c,v 1.7 1995/09/08 03:22:56 tls Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1987 Regents of the University of California.
|
||||
* All rights reserved.
|
||||
* Copyright (c) 1987, 1990, 1993, 1994
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
|
@ -32,254 +34,119 @@
|
|||
*/
|
||||
|
||||
#ifndef lint
|
||||
char copyright[] =
|
||||
"@(#) Copyright (c) 1987, 1990 Regents of the University of California.\n\
|
||||
All rights reserved.\n";
|
||||
static char copyright[] =
|
||||
"@(#) Copyright (c) 1987, 1990, 1993, 1994\n\
|
||||
The Regents of the University of California. All rights reserved.\n";
|
||||
#endif /* not lint */
|
||||
|
||||
#ifndef lint
|
||||
/*static char sccsid[] = "from: @(#)cmp.c 5.3 (Berkeley) 6/1/90";*/
|
||||
static char rcsid[] = "$Id: cmp.c,v 1.6 1994/03/25 17:07:02 mycroft Exp $";
|
||||
#if 0
|
||||
static char sccsid[] = "@(#)cmp.c 8.3 (Berkeley) 4/2/94";
|
||||
#else
|
||||
static char rcsid[] = "$NetBSD: cmp.c,v 1.7 1995/09/08 03:22:56 tls Exp $";
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/file.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include <err.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <locale.h>
|
||||
#include <unistd.h>
|
||||
#include <locale.h>
|
||||
|
||||
#define EXITNODIFF 0
|
||||
#define EXITDIFF 1
|
||||
#define EXITERR 2
|
||||
#include "extern.h"
|
||||
|
||||
void skip __P(());
|
||||
__dead void cmp __P(());
|
||||
__dead void error __P(());
|
||||
__dead void endoffile __P(());
|
||||
__dead void usage __P(());
|
||||
int lflag, sflag;
|
||||
|
||||
int all, fd1, fd2, silent;
|
||||
u_char buffer1[MAXBSIZE], buffer2[MAXBSIZE];
|
||||
char *file1, *file2;
|
||||
static void usage __P((void));
|
||||
|
||||
int
|
||||
main(argc, argv)
|
||||
int argc;
|
||||
char **argv;
|
||||
char *argv[];
|
||||
{
|
||||
int ch;
|
||||
struct stat sb1, sb2;
|
||||
off_t skip1, skip2;
|
||||
int ch, fd1, fd2, special;
|
||||
char *file1, *file2;
|
||||
|
||||
setlocale(LC_ALL, "");
|
||||
|
||||
while ((ch = getopt(argc, argv, "ls")) != -1)
|
||||
while ((ch = getopt(argc, argv, "ls")) != EOF)
|
||||
switch (ch) {
|
||||
case 'l': /* print all differences */
|
||||
all = 1;
|
||||
lflag = 1;
|
||||
break;
|
||||
case 's': /* silent run */
|
||||
silent = 1;
|
||||
sflag = 1;
|
||||
break;
|
||||
case '?':
|
||||
default:
|
||||
usage();
|
||||
}
|
||||
endargs:
|
||||
argv += optind;
|
||||
argc -= optind;
|
||||
|
||||
if (lflag && sflag)
|
||||
errx(ERR_EXIT, "only one of -l and -s may be specified");
|
||||
|
||||
if (argc < 2 || argc > 4)
|
||||
usage();
|
||||
|
||||
if (all && silent)
|
||||
usage ();
|
||||
|
||||
if (strcmp(file1 = argv[0], "-") == 0)
|
||||
/* Backward compatibility -- handle "-" meaning stdin. */
|
||||
special = 0;
|
||||
if (strcmp(file1 = argv[0], "-") == 0) {
|
||||
special = 1;
|
||||
fd1 = 0;
|
||||
file1 = "stdin";
|
||||
}
|
||||
else if ((fd1 = open(file1, O_RDONLY, 0)) < 0)
|
||||
error(file1);
|
||||
if (strcmp(file2 = argv[1], "-") == 0)
|
||||
err(ERR_EXIT, "%s", file1);
|
||||
if (strcmp(file2 = argv[1], "-") == 0) {
|
||||
if (special)
|
||||
errx(ERR_EXIT,
|
||||
"standard input may only be specified once");
|
||||
special = 1;
|
||||
fd2 = 0;
|
||||
file2 = "stdin";
|
||||
}
|
||||
else if ((fd2 = open(file2, O_RDONLY, 0)) < 0)
|
||||
error(file2);
|
||||
if (fd1 == fd2) {
|
||||
fprintf(stderr,
|
||||
"cmp: standard input may only be specified once.\n");
|
||||
exit(EXITERR);
|
||||
}
|
||||
err(ERR_EXIT, "%s", file2);
|
||||
|
||||
/* handle skip arguments */
|
||||
if (argc > 2) {
|
||||
skip(strtoul(argv[2], NULL, 0), fd1, file1);
|
||||
if (argc == 4)
|
||||
skip(strtoul(argv[3], NULL, 0), fd2, file2);
|
||||
}
|
||||
cmp();
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
skip1 = argc > 2 ? strtoq(argv[2], NULL, 10) : 0;
|
||||
skip2 = argc == 4 ? strtoq(argv[3], NULL, 10) : 0;
|
||||
|
||||
/*
|
||||
* skip --
|
||||
* skip first part of file
|
||||
*/
|
||||
void
|
||||
skip(dist, fd, fname)
|
||||
register u_long dist;
|
||||
register int fd;
|
||||
char *fname;
|
||||
{
|
||||
register int rlen, nread;
|
||||
|
||||
for (; dist; dist -= rlen) {
|
||||
rlen = MIN(dist, sizeof(buffer1));
|
||||
if ((nread = read(fd, buffer1, rlen)) != rlen) {
|
||||
if (nread < 0)
|
||||
error(fname);
|
||||
else
|
||||
endoffile(fname);
|
||||
if (!special) {
|
||||
if (fstat(fd1, &sb1))
|
||||
err(ERR_EXIT, "%s", file1);
|
||||
if (!S_ISREG(sb1.st_mode))
|
||||
special = 1;
|
||||
else {
|
||||
if (fstat(fd2, &sb2))
|
||||
err(ERR_EXIT, "%s", file2);
|
||||
if (!S_ISREG(sb2.st_mode))
|
||||
special = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (special)
|
||||
c_special(fd1, file1, skip1, fd2, file2, skip2);
|
||||
else
|
||||
c_regular(fd1, file1, skip1, sb1.st_size,
|
||||
fd2, file2, skip2, sb2.st_size);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
void
|
||||
cmp()
|
||||
{
|
||||
register u_char *p1, *p2;
|
||||
u_char *buf1, *buf2;
|
||||
register int cnt;
|
||||
int len = 0, len1 = 0, len2 = 0;
|
||||
register long byte, line;
|
||||
int dfound = 0;
|
||||
|
||||
for (byte = 0, line = 1; ; ) {
|
||||
len1 -= len;
|
||||
len2 -= len;
|
||||
if (len1)
|
||||
buf1 += len;
|
||||
else
|
||||
switch (len1 = read(fd1, buf1 = buffer1, MAXBSIZE)) {
|
||||
case -1:
|
||||
error(file1);
|
||||
case 0:
|
||||
if (len2)
|
||||
endoffile(file1);
|
||||
/*
|
||||
* read of file 1 just failed, find out
|
||||
* if there's anything left in file 2
|
||||
*/
|
||||
switch (read(fd2, buf2 = buffer2, 1)) {
|
||||
case -1:
|
||||
error(file2);
|
||||
/* NOTREACHED */
|
||||
case 0:
|
||||
exit(dfound ? EXITDIFF : EXITNODIFF);
|
||||
/* NOTREACHED */
|
||||
default:
|
||||
endoffile(file1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (len2)
|
||||
buf2 += len;
|
||||
else
|
||||
switch (len2 = read(fd2, buf2 = buffer2, MAXBSIZE)) {
|
||||
case -1:
|
||||
error(file2);
|
||||
case 0:
|
||||
/*
|
||||
* read of file 2 just failed; we know there is
|
||||
* data left in file 1 if we got this far
|
||||
*/
|
||||
endoffile(file2);
|
||||
break;
|
||||
}
|
||||
/*
|
||||
* Either file might be stdio. We compare only the minimum
|
||||
* number of bytes we know are common, then loop back to the
|
||||
* top. This avoids blocking on input if a difference is
|
||||
* found early.
|
||||
*/
|
||||
if (len1 < len2)
|
||||
len = len1;
|
||||
else
|
||||
len = len2;
|
||||
if (memcmp(buf1, buf2, len)) {
|
||||
if (silent)
|
||||
exit(EXITDIFF);
|
||||
if (all) {
|
||||
dfound = 1;
|
||||
for (p1 = buf1, p2 = buf2, cnt = len; cnt--;
|
||||
++p1, ++p2) {
|
||||
++byte;
|
||||
if (*p1 != *p2)
|
||||
printf("%6ld %3o %3o\n",
|
||||
byte, *p1, *p2);
|
||||
}
|
||||
} else for (p1 = buf1, p2 = buf2; ; ++p1, ++p2) {
|
||||
++byte;
|
||||
if (*p1 != *p2) {
|
||||
printf("%s %s differ: char %ld, line %ld\n", file1, file2, byte, line);
|
||||
exit(EXITDIFF);
|
||||
}
|
||||
if (*p1 == '\n')
|
||||
++line;
|
||||
}
|
||||
} else {
|
||||
byte += len;
|
||||
/*
|
||||
* here's the real performance problem, we've got to
|
||||
* count the stupid lines, which means that -l is a
|
||||
* *much* faster version, i.e., unless you really
|
||||
* *want* to know the line number, run -s or -l.
|
||||
*/
|
||||
if (!silent && !all)
|
||||
for (p1 = buf1, cnt = len; cnt--; )
|
||||
if (*p1++ == '\n')
|
||||
++line;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* error --
|
||||
* print I/O error message and die
|
||||
*/
|
||||
void
|
||||
error(filename)
|
||||
char *filename;
|
||||
{
|
||||
extern int errno;
|
||||
char *strerror();
|
||||
|
||||
if (!silent)
|
||||
(void) fprintf(stderr, "cmp: %s: %s\n",
|
||||
filename, strerror(errno));
|
||||
exit(EXITERR);
|
||||
}
|
||||
|
||||
/*
|
||||
* endoffile --
|
||||
* print end-of-file message and exit indicating the files were different
|
||||
*/
|
||||
void
|
||||
endoffile(filename)
|
||||
char *filename;
|
||||
{
|
||||
if (!silent)
|
||||
(void) fprintf(stderr, "cmp: EOF on %s\n", filename);
|
||||
exit(EXITDIFF);
|
||||
}
|
||||
|
||||
/*
|
||||
* usage --
|
||||
* print usage and die
|
||||
*/
|
||||
void
|
||||
static void
|
||||
usage()
|
||||
{
|
||||
fputs("usage: cmp [-l | -s] file1 file2 [skip1] [skip2]\n", stderr);
|
||||
exit(EXITERR);
|
||||
|
||||
(void)fprintf(stderr,
|
||||
"usage: cmp [-l | s] file1 file2 [skip1 [skip2]]\n");
|
||||
exit(ERR_EXIT);
|
||||
}
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
/* $NetBSD: extern.h,v 1.2 1995/09/08 03:22:57 tls Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1991, 1993, 1994
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
/* $NetBSD: misc.c,v 1.2 1995/09/08 03:22:58 tls Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1991, 1993, 1994
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
|
@ -32,7 +34,11 @@
|
|||
*/
|
||||
|
||||
#ifndef lint
|
||||
#if 0
|
||||
static char sccsid[] = "@(#)misc.c 8.3 (Berkeley) 4/2/94";
|
||||
#else
|
||||
static char rcsid[] = "$NetBSD: misc.c,v 1.2 1995/09/08 03:22:58 tls Exp $";
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
|
||||
#include <sys/types.h>
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
/* $NetBSD: regular.c,v 1.2 1995/09/08 03:22:59 tls Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1991, 1993, 1994
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
|
@ -32,7 +34,11 @@
|
|||
*/
|
||||
|
||||
#ifndef lint
|
||||
#if 0
|
||||
static char sccsid[] = "@(#)regular.c 8.3 (Berkeley) 4/2/94";
|
||||
#else
|
||||
static char rcsid[] = "$NetBSD: regular.c,v 1.2 1995/09/08 03:22:59 tls Exp $";
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
|
||||
#include <sys/param.h>
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
/* $NetBSD: special.c,v 1.2 1995/09/08 03:23:00 tls Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1991, 1993, 1994
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
|
@ -32,7 +34,11 @@
|
|||
*/
|
||||
|
||||
#ifndef lint
|
||||
#if 0
|
||||
static char sccsid[] = "@(#)special.c 8.3 (Berkeley) 4/2/94";
|
||||
#else
|
||||
static char rcsid[] = "$NetBSD: special.c,v 1.2 1995/09/08 03:23:00 tls Exp $";
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
|
||||
#include <sys/types.h>
|
||||
|
|
Loading…
Reference in New Issue