Files
seta75D d6fe8fe829 Init
2021-10-11 22:19:34 -03:00

258 lines
6.3 KiB
C

static char sccsid[] = "@(#)07 1.7 src/bldenv/cmp/cmp.c, ade_build, bos412, GOLDA411a 2/7/94 11:37:32";
/*
* COMPONENT_NAME: (CMDFILES) commands that manipulate files
*
* FUNCTIONS: cmp
*
* ORIGINS: 3, 26, 27
*
* This module contains IBM CONFIDENTIAL code. -- (IBM
* Confidential Restricted when combined with the aggregated
* modules for this product)
* SOURCE MATERIALS
* (C) COPYRIGHT International Business Machines Corp. 1985, 1989
* All Rights Reserved
*
* US Government Users Restricted Rights - Use, duplication or
* disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
*
*/
#include <stdio.h>
#include <ctype.h>
#include <filehdr.h>
#include <syms.h>
#ifdef MSG
#include "cmp_msg.h"
#define MSGSTR(Num, Str) NLgetamsg(MF_CMP,MS_CMP,Num,Str)
#else
#define NLprintf printf
#define MSGSTR(Num, Str) Str
#endif
FILE *file1,*file2; /* the files to be compared */
char *arg; /* argument holder */
int eflg = 0; /* difference flag */
int lflg = 1; /* long output flag */
int sflg = 0; /* short output flag */
long line = 1; /* line number */
long chr = 0; /* char number */
FILHDR header; /* file header */
char *hdrptr;
/*
* NAME: cmp [-l] [-s] file1 file2
*
* FUNCTION: Compares two files
*
* NOTES: Compares two files sending the differences to standard out.
* If a '-' is given for file1 then cmp reads from standard in.
* The default is that cmp displays nothing if the files are the
* same. If the files differ cmp displays the byte and line number
* at which the first difference occurs.
* -l Displays, for each difference, the byte number in
* decimal and the differing bytes in octal.
* -s Returns only an exit value.
*
* RETURN VALUE DESCRIPTION:
* 0 indicates identical files.
* 1 indicates different files.
* 2 indicates inaccessible files or a missing argument.
*/
main(argc, argv)
int argc;
char **argv;
{
int c1, c2; /* current charcters from file1 and file2 */
int sccspattern[4];
int sccsflg = 0;
char *string_table = NULL;
int reading_1st_string = 0;
int reading_2nd_string = 0;
int save1, save2;
sccspattern[0] = '@';
sccspattern[1] = '(';
sccspattern[2] = '#';
sccspattern[3] = ')';
if(argc < 3) /* not enough arguments */
narg();
arg = argv[1];
if(arg[0] == '-' && arg[1] == 's') { /* return only exit codes */
sflg++;
lflg--;
argv++;
argc--;
}
arg = argv[1];
if(arg[0] == '-' && arg[1] == 'l') { /* long output */
lflg++;
argv++;
argc--;
}
if(argc != 3) /* check the number of files */
narg();
arg = argv[1];
if( arg[0]=='-' && arg[1]==0 ) /* file1 from stdin */
file1 = stdin;
else if((file1 = fopen(arg, "r")) == NULL)
barg(); /* bad file */
arg = argv[2];
if((file2 = fopen(arg, "r")) == NULL)
barg(); /* bad file */
hdrptr = (char *)&header;
while(1) { /* compare the files */
c1 = getc(file1);
c2 = getc(file2);
if (chr < FILHSZ)
*hdrptr = c1;
else if (chr == FILHSZ && header.f_magic == U802TOCMAGIC)
string_table = header.f_symptr + header.f_nsyms*SYMESZ + 4;
else if (string_table) {
if (chr == string_table)
reading_1st_string = 1;
else if (reading_1st_string) {
if (c1 == '\0') {
reading_1st_string = 0;
if (save1 == '.' && save2 == 'c')
reading_2nd_string = 2;
}
else {
save1 = save2;
save2 = c1;
}
}
}
chr++;
hdrptr++;
if (reading_2nd_string) {
if (c1 == '\0' || c1 == EOF) reading_2nd_string--;
}
else if(c1 == c2) {
if (sccsflg == 4) {
if (endofsccs(c1))
sccsflg = 0;
}
else
sccsflg = (c1 == sccspattern[sccsflg] ?
sccsflg+1 : 0);
if (c1 == '\n')
line++;
if(c1 == EOF) {
if(eflg)
exit(1);
exit(0);
}
}
else if(sccsflg == 4) {
if (endofsccs(c1)) {
sccsflg = 0;
while ( !endofsccs(c2) &&
c1 != EOF &&
c2 != EOF) {
/* If this is an xcoff file, we want to keep the two files in sync, due to
padding. string_table will be set if this is true.
*/
if (string_table)
c1 = getc(file1);
c2 = getc(file2);
chr++;
}
}
else if (endofsccs(c2)) {
sccsflg = 0;
while ( !endofsccs(c1) &&
c1 != EOF &&
c2 != EOF) {
c1 = getc(file1);
if (string_table)
c2 = getc(file2);
chr++;
}
}
}
else if(hdrptr > (char *)&header.f_timdat &&
hdrptr <= (char *)&header.f_timdat+sizeof(header.f_timdat) &&
header.f_magic == U802TOCMAGIC) ;
else {
if(sflg > 0)
exit(1);
if(c1 == EOF) {
arg = argv[1];
earg();
}
if(c2 == EOF)
earg();
if(lflg == 1) {
NLprintf(MSGSTR(DIFF, /*MSG*/
"%s %s differ: char %d, line %d\n"),
argv[1], arg, chr, line);/*MSG*/
exit(1);
}
eflg = 1;
printf("%6ld %3o %3o\n", chr, c1, c2);
}
} /* end of while */
}
/*
* NAME: narg
*
* FUNCTION: print out usage statement and exit program.
*/
narg()
{
fprintf(stderr,MSGSTR(USG,"usage: cmp [-l] [-s] file1 file2\n"));/*MSG*/
exit(2);
}
/*
* NAME: barg
*
* FUNCTION: print out error message and exit program.
*/
barg()
{
if (sflg == 0)
fprintf(stderr, MSGSTR(NOTOPEN, /*MSG*/
"cmp: cannot open %s\n"), arg); /*MSG*/
exit(2);
}
/*
* NAME: earg
*
* FUNCTION: file arg was shorter than the other file, print message
* and exit.
*/
earg()
{
fprintf(stderr, MSGSTR(EOFMSG,"cmp: EOF on %s\n"), arg); /*MSG*/
exit(1);
}
/*
* NAME: endofsccs
*
* FUNCTION: returns true if the argument is the last character of an sccsid
*/
endofsccs(c)
int c;
{
if (c == '\0' ||
c == '\n' ||
c == '>' ||
c == '"' ||
c == '\\' )
return(1);
else
return(0);
}