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.3 (Berkeley) 04/02/94"; 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 28 #define MAXLINELEN (LINE_MAX + 1) 29 30 char *tabs[] = { "", "\t", "\t\t" }; 31 32 FILE *file __P((char *)); 33 void show __P((FILE *, char *, char *)); 34 void usage __P((void)); 35 36 int 37 main(argc, argv) 38 int argc; 39 char *argv[]; 40 { 41 int comp, file1done, file2done, read1, read2; 42 int ch, flag1, flag2, flag3; 43 FILE *fp1, *fp2; 44 char *col1, *col2, *col3; 45 char **p, line1[MAXLINELEN], line2[MAXLINELEN]; 46 47 flag1 = flag2 = flag3 = 1; 48 while ((ch = getopt(argc, argv, "-123")) != EOF) 49 switch(ch) { 50 case '-': 51 --optind; 52 goto done; 53 case '1': 54 flag1 = 0; 55 break; 56 case '2': 57 flag2 = 0; 58 break; 59 case '3': 60 flag3 = 0; 61 break; 62 case '?': 63 default: 64 usage(); 65 } 66 done: argc -= optind; 67 argv += optind; 68 69 if (argc != 2) 70 usage(); 71 72 fp1 = file(argv[0]); 73 fp2 = file(argv[1]); 74 75 /* for each column printed, add another tab offset */ 76 p = tabs; 77 col1 = col2 = col3 = NULL; 78 if (flag1) 79 col1 = *p++; 80 if (flag2) 81 col2 = *p++; 82 if (flag3) 83 col3 = *p; 84 85 for (read1 = read2 = 1;;) { 86 /* read next line, check for EOF */ 87 if (read1) 88 file1done = !fgets(line1, MAXLINELEN, fp1); 89 if (read2) 90 file2done = !fgets(line2, MAXLINELEN, fp2); 91 92 /* if one file done, display the rest of the other file */ 93 if (file1done) { 94 if (!file2done && col2) 95 show(fp2, col2, line2); 96 break; 97 } 98 if (file2done) { 99 if (!file1done && col1) 100 show(fp1, col1, line1); 101 break; 102 } 103 104 /* lines are the same */ 105 if (!(comp = strcmp(line1, line2))) { 106 read1 = read2 = 1; 107 if (col3) 108 (void)printf("%s%s", col3, line1); 109 continue; 110 } 111 112 /* lines are different */ 113 if (comp < 0) { 114 read1 = 1; 115 read2 = 0; 116 if (col1) 117 (void)printf("%s%s", col1, line1); 118 } else { 119 read1 = 0; 120 read2 = 1; 121 if (col2) 122 (void)printf("%s%s", col2, line2); 123 } 124 } 125 exit(0); 126 } 127 128 void 129 show(fp, offset, buf) 130 FILE *fp; 131 char *offset, *buf; 132 { 133 134 do { 135 (void)printf("%s%s", offset, buf); 136 } while (fgets(buf, MAXLINELEN, fp)); 137 } 138 139 FILE * 140 file(name) 141 char *name; 142 { 143 FILE *fp; 144 145 if (!strcmp(name, "-")) 146 return (stdin); 147 if ((fp = fopen(name, "r")) == NULL) { 148 (void)fprintf(stderr, "comm: %s: %s\n", name, strerror(errno)); 149 exit(1); 150 } 151 return (fp); 152 } 153 154 void 155 usage() 156 { 157 158 (void)fprintf(stderr, "usage: comm [-123] file1 file2\n"); 159 exit(1); 160 } 161