1 /* 2 * Copyright (c) 1989 The Regents of the University of California. 3 * All rights reserved. 4 * 5 * This code is derived from software contributed to Berkeley by 6 * Case Larsen. 7 * 8 * Redistribution and use in source and binary forms are permitted 9 * provided that the above copyright notice and this paragraph are 10 * duplicated in all such forms and that any documentation, 11 * advertising materials, and other materials related to such 12 * distribution and use acknowledge that the software was developed 13 * by the University of California, Berkeley. The name of the 14 * University may not be used to endorse or promote products derived 15 * from this software without specific prior written permission. 16 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 17 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 19 */ 20 21 #ifndef lint 22 char copyright[] = 23 "@(#) Copyright (c) 1989 The Regents of the University of California.\n\ 24 All rights reserved.\n"; 25 #endif /* not lint */ 26 27 #ifndef lint 28 static char sccsid[] = "@(#)comm.c 5.3 (Berkeley) 04/25/90"; 29 #endif /* not lint */ 30 31 #include <sys/file.h> 32 #include <limits.h> 33 #include <stdio.h> 34 35 #define MAXLINELEN (LINE_MAX + 1) 36 37 char *tabs[] = { "", "\t", "\t\t" }; 38 39 main(argc,argv) 40 int argc; 41 char *argv[]; 42 { 43 register int comp, file1done, file2done, read1, read2; 44 register char *col1, *col2, *col3; 45 int ch, flag1, flag2, flag3; 46 FILE *fp1, *fp2, *file(); 47 char **p, line1[MAXLINELEN], line2[MAXLINELEN]; 48 extern int optind; 49 50 flag1 = flag2 = flag3 = 1; 51 while ((ch = getopt(argc, argv, "-123")) != EOF) 52 switch(ch) { 53 case '-': 54 --optind; 55 goto done; 56 case '1': 57 flag1 = 0; 58 break; 59 case '2': 60 flag2 = 0; 61 break; 62 case '3': 63 flag3 = 0; 64 break; 65 case '?': 66 default: 67 usage(); 68 } 69 done: argc -= optind; 70 argv += optind; 71 72 if (argc != 2) 73 usage(); 74 75 fp1 = file(argv[0]); 76 fp2 = file(argv[1]); 77 78 /* for each column printed, add another tab offset */ 79 p = tabs; 80 if (flag1) 81 col1 = *p++; 82 if (flag2) 83 col2 = *p++; 84 if (flag3) 85 col3 = *p++; 86 87 for (read1 = read2 = 1;;) { 88 /* read next line, check for EOF */ 89 if (read1) 90 file1done = !fgets(line1, MAXLINELEN, fp1); 91 if (read2) 92 file2done = !fgets(line2, MAXLINELEN, fp2); 93 94 /* if one file done, display the rest of the other file */ 95 if (file1done) { 96 if (!file2done && col2) 97 show(fp2, col2, line2); 98 break; 99 } 100 if (file2done) { 101 if (!file1done && col1) 102 show(fp1, col1, line1); 103 break; 104 } 105 106 /* lines are the same */ 107 if (!(comp = strcmp(line1, line2))) { 108 read1 = read2 = 1; 109 if (col3) 110 (void)printf("%s%s", col3, line1); 111 continue; 112 } 113 114 /* lines are different */ 115 if (comp < 0) { 116 read1 = 1; 117 read2 = 0; 118 if (col1) 119 (void)printf("%s%s", col1, line1); 120 } else { 121 read1 = 0; 122 read2 = 1; 123 if (col2) 124 (void)printf("%s%s", col2, line2); 125 } 126 } 127 exit(0); 128 } 129 130 show(fp, offset, buf) 131 FILE *fp; 132 char *offset, *buf; 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"))) { 148 (void)fprintf(stderr, "comm: can't read %s.\n", name); 149 exit(1); 150 } 151 return(fp); 152 } 153 154 usage() 155 { 156 (void)fprintf(stderr, "usage: comm [-123] [ - ] file1 file2\n"); 157 exit(1); 158 } 159