From 23b68d3a7356f9cf3182759fa559af58704497f0 Mon Sep 17 00:00:00 2001 From: Jakob Kaivo Date: Wed, 13 Mar 2019 21:10:54 -0400 Subject: migrate to gitlab --- cmp.c | 114 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 114 insertions(+) create mode 100644 cmp.c diff --git a/cmp.c b/cmp.c new file mode 100644 index 0000000..6a03002 --- /dev/null +++ b/cmp.c @@ -0,0 +1,114 @@ +/* + * UNG's Not GNU + * + * Copyright (c) 2011-2017, Jakob Kaivo + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + */ + +#define _XOPEN_SOURCE 700 +#include +#include +#include +#include +#include +#include + +FILE *fileopen(const char *path) +{ + if (!strcmp(path, "-")) { + return stdin; + } + + FILE *f = fopen(path, "rb"); + if (f == NULL) { + fprintf(stderr, "cmp: Couldn't open %s: %s\n", path, strerror(errno)); + exit(1); + } + + return f; +} + +int main(int argc, char *argv[]) +{ + int c = 0; + enum { FIRSTONLY, ALL, SILENT } output = FIRSTONLY; + + while ((c = getopt(argc, argv, "ls")) != EOF) { + switch (c) { + case 'l': + output = ALL; + break; + + case 's': + output = SILENT; + break; + + default: + return 1; + } + } + + if (optind != argc - 2) { + fprintf(stderr, "cmp: Two files are required\n"); + return 1; + } + + char *file1 = argv[optind++]; + char *file2 = argv[optind]; + FILE *f1 = fileopen(file1); + FILE *f2 = fileopen(file2); + + if (f1 == stdin && f2 == stdin) { + fprintf(stderr, "cmp: Comparing stdin to itself is undefined\n"); + return 1; + } + + struct stat st1; + fstat(fileno(f1), &st1); + if (S_ISBLK(st1.st_mode) || S_ISCHR(st1.st_mode) || S_ISFIFO(st1.st_mode)) { + struct stat st2; + fstat(fileno(f2), &st2); + if (st1.st_dev == st2.st_dev && st1.st_ino == st2.st_ino) { + fprintf(stderr, "cmp: Comparing special file to itself is undefined\n"); + return 1; + } + } + + for (int byte = 1, line = 1; !(feof(f1) || feof(f2)); byte++) { + int c1 = fgetc(f1); + int c2 = fgetc(f2); + + if (c1 == c2) { + if (c1 == '\n') { + line++; + } + continue; + } + + if (c1 == EOF && output != SILENT) { + fprintf(stderr, "cmp: EOF on %s\n", file1); + } else if (c2 == EOF && output != SILENT) { + fprintf(stderr, "cmp: EOF on %s\n", file2); + } else if (output == ALL) { + printf("%d %o %o\n", byte, c1, c2); + continue; + } else if (output != SILENT) { + printf("%s %s differ: char %d, line %d\n", file1, file2, byte, line); + } + return 1; + } + + return 0; +} -- cgit v1.2.1