Current-Users archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Weirdness in comm(1)



Here's a little script that shows the issue.  The attached patch fixes
it.  Id does make it a bit busier but comm(1) would work right.  Unless
someone has a reason not to I will commit this later today.

If there are any FreeBSD developers here, the problem exists there as
well. The Mac gets it right and at least Ubuntu does.  I have reports
that other Linux versions have the same problem.

#! /bin/sh

TEST=/tmp/$$.test
trap "rm -f $TEST.*" 0

cat << MOUSE > $TEST.1a
a b
c d
e f
e f g
h i
MOUSE

cat << MOUSE > $TEST.1b
a b
e f g
MOUSE

tr ' ' '\t' < $TEST.1a > $TEST.2a
tr ' ' '\t' < $TEST.1b > $TEST.2b

echo "Test 1 (spaces) output:"
comm -12 $TEST.1a $TEST.1b

echo ""
echo "Test 2 (tabs) output:"
comm -12 $TEST.2a $TEST.2b

-- 
D'Arcy J.M. Cain <darcy%NetBSD.org@localhost>
http://www.NetBSD.org/
Index: comm.c
===================================================================
RCS file: /cvsroot/src/usr.bin/comm/comm.c,v
retrieving revision 1.17
diff -u -p -u -r1.17 comm.c
--- comm.c      11 Apr 2009 12:18:45 -0000      1.17
+++ comm.c      27 Nov 2009 07:21:52 -0000
@@ -60,6 +60,7 @@ const char *tabs[] = { "", "\t", "\t\t" 
 FILE   *file(const char *);
 void   show(FILE *, const char *, char *);
 void   usage(void);
+char   *getnextln(char *buf, FILE *);
 
 int
 main(int argc, char **argv)
@@ -116,9 +117,9 @@ main(int argc, char **argv)
        for (read1 = read2 = 1;;) {
                /* read next line, check for EOF */
                if (read1)
-                       file1done = !fgets(line1, MAXLINELEN, fp1);
+                       file1done = !getnextln(line1, fp1);
                if (read2)
-                       file2done = !fgets(line2, MAXLINELEN, fp2);
+                       file2done = !getnextln(line2, fp2);
 
                /* if one file done, display the rest of the other file */
                if (file1done) {
@@ -136,7 +137,7 @@ main(int argc, char **argv)
                if (!(comp = compare(line1, line2))) {
                        read1 = read2 = 1;
                        if (col3)
-                               if (printf("%s%s", col3, line1) < 0)
+                               if (printf("%s%s\n", col3, line1) < 0)
                                        break;
                        continue;
                }
@@ -146,13 +147,13 @@ main(int argc, char **argv)
                        read1 = 1;
                        read2 = 0;
                        if (col1)
-                               if (printf("%s%s", col1, line1) < 0)
+                               if (printf("%s%s\n", col1, line1) < 0)
                                        break;
                } else {
                        read1 = 0;
                        read2 = 1;
                        if (col2)
-                               if (printf("%s%s", col2, line2) < 0)
+                               if (printf("%s%s\n", col2, line2) < 0)
                                        break;
                }
        }
@@ -166,7 +167,7 @@ main(int argc, char **argv)
 void
 show(FILE *fp, const char *offset, char *buf)
 {
-       while (printf("%s%s", offset, buf) >= 0 && fgets(buf, MAXLINELEN, fp))
+       while (printf("%s%s\n", offset, buf) >= 0 && getnextln(buf, fp))
                ;
 }
 
@@ -189,3 +190,25 @@ usage(void)
        (void)fprintf(stderr, "usage: comm [-123f] file1 file2\n");
        exit(1);
 }
+
+char *
+getnextln(char *buf, FILE *fp)
+{
+    int i = 0;
+    int c;
+
+       while ((c = fgetc(fp)) != '\n' && c != EOF)
+       {
+               buf[i++] = c;
+
+               if (i >= MAXLINELEN)
+                       i--; /* consumes extra characters till newline */
+       }
+
+       if (c == EOF && !i)
+               return NULL;
+
+       buf[i] = 0;
+       return buf;
+}
+


Home | Main Index | Thread Index | Old Index