1 /* 2 * Copyright (c) 1989, 1993, 1994 3 * The Regents of the University of California. All rights reserved. 4 * 5 * This code is derived from software contributed to Berkeley by 6 * Case Larsen. 7 * 8 * %sccs.include.redist.c% 9 */ 10 11 #ifndef lint 12 static char copyright[] = 13 "@(#) Copyright (c) 1989, 1993, 1994\n\ 14 The Regents of the University of California. All rights reserved.\n"; 15 #endif /* not lint */ 16 17 #ifndef lint 18 static char sccsid[] = "@(#)comm.c 8.4 (Berkeley) 05/04/95"; 19 #endif /* not lint */ 20 21 #include <fcntl.h> 22 #include <limits.h> 23 #include <errno.h> 24 #include <stdio.h> 25 #include <stdlib.h> 26 #include <string.h> 27 #include <unistd.h> 28 29 #define MAXLINELEN (LINE_MAX + 1) 30 31 char *tabs[] = { "", "\t", "\t\t" }; 32 33 FILE *file __P((char *)); 34 void show __P((FILE *, char *, char *)); 35 void usage __P((void)); 36 37 int 38 main(argc, argv) 39 int argc; 40 char *argv[]; 41 { 42 int comp, file1done, file2done, read1, read2; 43 int ch, flag1, flag2, flag3; 44 FILE *fp1, *fp2; 45 char *col1, *col2, *col3; 46 char **p, line1[MAXLINELEN], line2[MAXLINELEN]; 47 48 flag1 = flag2 = flag3 = 1; 49 while ((ch = getopt(argc, argv, "-123")) != EOF) 50 switch(ch) { 51 case '-': 52 --optind; 53 goto done; 54 case '1': 55 flag1 = 0; 56 break; 57 case '2': 58 flag2 = 0; 59 break; 60 case '3': 61 flag3 = 0; 62 break; 63 case '?': 64 default: 65 usage(); 66 } 67 done: argc -= optind; 68 argv += optind; 69 70 if (argc != 2) 71 usage(); 72 73 fp1 = file(argv[0]); 74 fp2 = file(argv[1]); 75 76 /* for each column printed, add another tab offset */ 77 p = tabs; 78 col1 = col2 = col3 = NULL; 79 if (flag1) 80 col1 = *p++; 81 if (flag2) 82 col2 = *p++; 83 if (flag3) 84 col3 = *p; 85 86 for (read1 = read2 = 1;;) { 87 /* read next line, check for EOF */ 88 if (read1) 89 file1done = !fgets(line1, MAXLINELEN, fp1); 90 if (read2) 91 file2done = !fgets(line2, MAXLINELEN, fp2); 92 93 /* if one file done, display the rest of the other file */ 94 if (file1done) { 95 if (!file2done && col2) 96 show(fp2, col2, line2); 97 break; 98 } 99 if (file2done) { 100 if (!file1done && col1) 101 show(fp1, col1, line1); 102 break; 103 } 104 105 /* lines are the same */ 106 if (!(comp = strcmp(line1, line2))) { 107 read1 = read2 = 1; 108 if (col3) 109 (void)printf("%s%s", col3, line1); 110 continue; 111 } 112 113 /* lines are different */ 114 if (comp < 0) { 115 read1 = 1; 116 read2 = 0; 117 if (col1) 118 (void)printf("%s%s", col1, line1); 119 } else { 120 read1 = 0; 121 read2 = 1; 122 if (col2) 123 (void)printf("%s%s", col2, line2); 124 } 125 } 126 exit(0); 127 } 128 129 void 130 show(fp, offset, buf) 131 FILE *fp; 132 char *offset, *buf; 133 { 134 135 do { 136 (void)printf("%s%s", offset, buf); 137 } while (fgets(buf, MAXLINELEN, fp)); 138 } 139 140 FILE * 141 file(name) 142 char *name; 143 { 144 FILE *fp; 145 146 if (!strcmp(name, "-")) 147 return (stdin); 148 if ((fp = fopen(name, "r")) == NULL) { 149 (void)fprintf(stderr, "comm: %s: %s\n", name, strerror(errno)); 150 exit(1); 151 } 152 return (fp); 153 } 154 155 void 156 usage() 157 { 158 159 (void)fprintf(stderr, "usage: comm [-123] file1 file2\n"); 160 exit(1); 161 } 162