[hackers] [sbase] Refactor cmp(1) code and manpage || FRIGN

From: <git_AT_suckless.org>
Date: Tue, 24 Mar 2015 23:53:34 +0100 (CET)

commit 79e45395e5fc8a2933df1fd3dccb570df6890929
Author: FRIGN <dev_AT_frign.de>
Date: Sat Feb 7 21:05:33 2015 +0100

    Refactor cmp(1) code and manpage
    
    The algorithm had some areas which had potential for improvement.
    This should make cmp(1) faster.
    There have been changes to behaviour as well:
    
    1) If argv[0] and argv[1] are the same, cmp(1) returns Same.
    2) POSIX specifies the format of the difference-message to be:
          "%s %s differ: char %d, line %d\n", file1, file2,
          <byte number>, <line number>
       However, as cmp(1) operates on bytes, not characters, I changed
       it to
          "%s %s differ: byte %d, line %d\n", file1, file2,
          <byte number>, <line number>
       This is one example where the standard just keeps the old format
       for backwards-compatibility. As this is harmful, this change
       makes sense in the sense of consistentcy (and because we take
       the difference of char and byte very seriously in sbase, as
       opposed to GNU coreutils).
    
    The manpage has been annotated, reflecting the second change, and
    sections shortened where possible.
    Thus I marked cmp(1) as finished in README.

diff --git a/README b/README
index 8bb82fe..1c9adcb 100644
--- a/README
+++ b/README
_AT_@ -17,7 +17,7 @@ The following tools are implemented ('*' == finished, '#' == UTF-8 support,
 = chown no -h, -H, -L, -P
 =* chroot non-posix none
 =* cksum yes none
- cmp yes none
+=* cmp yes none
 #* cols non-posix none
 =* comm yes none
 = cp no -H, (-i), -L
diff --git a/cmp.1 b/cmp.1
index 204d65a..0a25681 100644
--- a/cmp.1
+++ b/cmp.1
_AT_@ -1,4 +1,4 @@
-.Dd November 21, 2014
+.Dd February 7, 2015
 .Dt CMP 1
 .Os sbase
 .Sh NAME
_AT_@ -10,23 +10,32 @@
 .Ar file1 file2
 .Sh DESCRIPTION
 .Nm
-compares two files byte by byte. If the files differ,
+compares
+.Ar file1
+and
+.Ar file2
+byte by byte. If they differ,
 .Nm
-prints the byte and
-line number at which the difference occurred.
+writes the first differing byte- and line-number to stdout.
 .Sh OPTIONS
 .Bl -tag -width Ds
 .It Fl l
-Print the byte number, and the differing bytes (in octal), for each difference.
+Print byte-number and bytes (in octal) for each difference.
 .It Fl s
-Print nothing, only returns status.
+Print nothing and only return status.
 .El
 .Sh EXIT STATUS
 .Bl -tag -width Ds
 .It 0
-The files are identical.
+.Ar file1
+and
+.Ar file2
+are identical.
 .It 1
-The files are different.
+.Ar file1
+and
+.Ar file2
+are different.
 .It > 1
 An error occurred.
 .El
_AT_@ -39,3 +48,5 @@ The
 utility is compliant with the
 .St -p1003.1-2008
 specification.
+.Pp
+The "char" in the default result format has been replaced with "byte".
diff --git a/cmp.c b/cmp.c
index 4e67e96..8bcef66 100644
--- a/cmp.c
+++ b/cmp.c
_AT_@ -1,6 +1,7 @@
 /* See LICENSE file for copyright and license details. */
 #include <stdio.h>
 #include <stdlib.h>
+#include <string.h>
 #include <unistd.h>
 
 #include "util.h"
_AT_@ -16,12 +17,9 @@ usage(void)
 int
 main(int argc, char *argv[])
 {
- int lflag = 0;
- int sflag = 0;
- int same = 1;
- int b[2], i;
- long line = 1, n = 1;
         FILE *fp[2];
+ size_t i, line = 1, n = 1;
+ int lflag = 0, sflag = 0, same = 1, b[2];
 
         ARGBEGIN {
         case 'l':
_AT_@ -37,45 +35,41 @@ main(int argc, char *argv[])
         if (argc != 2 || (lflag && sflag))
                 usage();
 
- if (argv[0][0] == '-' && !argv[0][1])
- argv[0] = "/dev/fd/0";
- fp[0] = fopen(argv[0], "r");
- if (!fp[0]) {
- if (!sflag)
- weprintf("fopen %s:", argv[0]);
- exit(Error);
- }
+ if (!strcmp(argv[0], argv[1]))
+ return Same;
 
- if (argv[1][0] == '-' && !argv[1][1])
- argv[1] = "/dev/fd/0";
- fp[1] = fopen(argv[1], "r");
- if (!fp[1]) {
- if (!sflag)
- weprintf("fopen %s:", argv[1]);
- exit(Error);
+ for (i = 0; i < 2; i++) {
+ if (argv[i][0] == '-' && !argv[i][1])
+ argv[i] = "/dev/fd/0";
+ fp[i] = fopen(argv[i], "r");
+ if (!fp[i]) {
+ if (!sflag)
+ weprintf("fopen %s:", argv[i]);
+ exit(Error);
+ }
         }
 
         for (n = 1; ; n++) {
                 b[0] = getc(fp[0]);
                 b[1] = getc(fp[1]);
- if (b[0] == EOF && b[1] == EOF)
- break;
- if (b[0] == '\n' && b[1] == '\n')
- line++;
- if (b[0] == b[1])
+
+ if (b[0] == b[1]) {
+ if (b[0] == EOF)
+ break;
+ else if (b[0] == '\n')
+ line++;
                         continue;
- for (i = 0; i < 2; i++) {
- if (b[i] == EOF) {
- if (!sflag)
- fprintf(stderr, "cmp: EOF on %s\n",
- !argv[i] ? "<stdin>" : argv[i]);
- exit(Diff);
- }
+ }
+ if (b[0] == EOF || b[1] == EOF) {
+ if (!sflag)
+ fprintf(stderr, "cmp: EOF on %s\n",
+ argv[(b[0] == EOF) ? 0 : 1]);
+ exit(Diff);
                 }
                 if (!lflag) {
                         if (!sflag)
- printf("%s %s differ: char %ld, line %ld\n",
- argv[0], !argv[1] ? "<stdin>" : argv[1], n, line);
+ printf("%s %s differ: byte %ld, line %ld\n",
+ argv[0], argv[1], n, line);
                         exit(Diff);
                 } else {
                         printf("%ld %o %o\n", n, b[0], b[1]);
Received on Tue Mar 24 2015 - 23:53:34 CET

This archive was generated by hypermail 2.3.0 : Wed Mar 25 2015 - 00:07:59 CET