2020-12-12 06:33:20 +00:00
|
|
|
#define _POSIX_C_SOURCE 200809L
|
|
|
|
|
2020-02-12 05:30:50 +00:00
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <string.h>
|
2020-12-13 15:37:32 +00:00
|
|
|
#include <unistd.h>
|
2020-02-12 05:30:50 +00:00
|
|
|
|
|
|
|
int main(int argc, char ** argv) {
|
|
|
|
int silent_mode = 0;
|
|
|
|
int print_all_diff = 0;
|
|
|
|
int keep_printing = 1;
|
|
|
|
int files_differ = 0;
|
|
|
|
int i, f1num = 1;
|
|
|
|
FILE *file1, *file2;
|
2020-12-13 15:37:32 +00:00
|
|
|
char c1, c2, c;
|
2020-02-12 05:30:50 +00:00
|
|
|
int line = 1, byte = 1;
|
|
|
|
|
2020-12-13 15:37:32 +00:00
|
|
|
while((c = getopt(argc, argv, "sl")) != -1) {
|
|
|
|
switch(c) {
|
|
|
|
case 's': silent_mode = 1; print_all_diff = 0; break;
|
|
|
|
case 'l': print_all_diff = 1; silent_mode = 0; break;
|
2020-02-12 05:30:50 +00:00
|
|
|
}
|
|
|
|
}
|
2020-12-13 15:37:32 +00:00
|
|
|
|
|
|
|
f1num = optind;
|
|
|
|
|
|
|
|
if(argc - f1num < 2) {
|
|
|
|
fprintf(stderr, "%s: missing file operand\n", argv[0]);
|
|
|
|
return 3;
|
2020-02-12 05:30:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if(strcmp(argv[f1num], "-") == 0 && strcmp(argv[f1num+1], "-") == 0) {
|
2020-12-13 15:37:32 +00:00
|
|
|
fprintf(stderr, "%s: cannot accept stdin for both files\n", argv[0]);
|
2020-02-12 05:30:50 +00:00
|
|
|
return 2;
|
|
|
|
}
|
|
|
|
else if(strcmp(argv[f1num], "-") == 0) {
|
|
|
|
file1 = stdin;
|
|
|
|
file2 = fopen(argv[f1num+1], "r");
|
|
|
|
}
|
|
|
|
else if(strcmp(argv[f1num+1], "-") == 0) {
|
|
|
|
file1 = fopen(argv[f1num], "r");
|
|
|
|
file2 = stdin;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
file1 = fopen(argv[f1num], "r");
|
|
|
|
file2 = fopen(argv[f1num+1], "r");
|
|
|
|
}
|
|
|
|
|
2020-12-13 15:37:32 +00:00
|
|
|
if(file1 == NULL) {
|
|
|
|
fprintf(stderr, "%s: could not open file %s\n", argv[0], argv[f1num]);
|
|
|
|
return 4;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(file2 == NULL) {
|
|
|
|
fprintf(stderr, "%s: could not open file %s\n", argv[0], argv[f1num + 1]);
|
|
|
|
return 4;
|
|
|
|
}
|
|
|
|
|
2020-02-12 05:30:50 +00:00
|
|
|
if(silent_mode) {
|
|
|
|
c1 = fgetc(file1);
|
|
|
|
c2 = fgetc(file2);
|
|
|
|
for(i = 0; !(c1 == EOF || c2 == EOF); i++) {
|
|
|
|
if(c1 != c2) {
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
c1 = fgetc(file1);
|
|
|
|
c2 = fgetc(file2);
|
|
|
|
}
|
|
|
|
if(c1 != c2) {
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if(print_all_diff) {
|
|
|
|
c1 = fgetc(file1);
|
|
|
|
c2 = fgetc(file2);
|
|
|
|
for(i = 0; !(c1 == EOF || c2 == EOF); i++) {
|
|
|
|
if(c1 != c2) {
|
|
|
|
printf("%d %o %o\n", byte, c1, c2);
|
|
|
|
files_differ = 1;
|
|
|
|
}
|
|
|
|
c1 = fgetc(file1);
|
|
|
|
c2 = fgetc(file2);
|
|
|
|
line++;
|
|
|
|
byte++;
|
|
|
|
}
|
|
|
|
if(c1 != c2) {
|
|
|
|
fprintf(stderr, "%s: EOF on %s%s\n", argv[0],
|
|
|
|
c1 == EOF ? argv[f1num] : argv[f1num+1], "");
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
else if(files_differ) {
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
c1 = fgetc(file1);
|
|
|
|
c2 = fgetc(file2);
|
|
|
|
for(i = 0; !(c1 == EOF || c2 == EOF); i++) {
|
|
|
|
if(c1 != c2 && keep_printing) {
|
|
|
|
keep_printing = 0;
|
|
|
|
printf("%s %s differ: char %d, line %d\n", argv[f1num], argv[f1num+1], byte, line);
|
|
|
|
files_differ = 1;
|
|
|
|
}
|
|
|
|
c1 = fgetc(file1);
|
|
|
|
c2 = fgetc(file2);
|
|
|
|
if(c1 == '\n') line++;
|
|
|
|
byte++;
|
|
|
|
}
|
|
|
|
if(c1 != c2) {
|
|
|
|
fprintf(stderr, "%s: EOF on %s%s\n", argv[0],
|
|
|
|
c1 == EOF ? argv[f1num] : argv[f1num+1], "");
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
else if(files_differ) {
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|