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.1 (Berkeley) 05/21/89"; 29 #endif /* not lint */ 30 31 #include <sys/file.h> 32 #include <stdio.h> 33 34 #define MAXLINELEN (2048 + 1) 35 36 static char *tabs[] = { "", "\t", "\t\t" }; 37 38 main(argc,argv) 39 int argc; 40 char **argv; 41 { 42 extern int optind; 43 FILE *fp1, *fp2, *file(); 44 register int comp, file1done, file2done, read1, read2; 45 register char *col1, *col2, *col3; 46 int ch, flag1, flag2, flag3; 47 char **p, line1[MAXLINELEN], line2[MAXLINELEN]; 48 49 flag1 = flag2 = flag3 = 1; 50 while ((ch = getopt(argc, argv, "-123")) != EOF) 51 switch(ch) { 52 case '-': 53 --optind; 54 goto done; 55 case '1': 56 flag1 = 0; 57 break; 58 case '2': 59 flag2 = 0; 60 break; 61 case '3': 62 flag3 = 0; 63 break; 64 case '?': 65 default: 66 usage(); 67 } 68 done: argc -= optind; 69 argv += optind; 70 71 if (argc != 2) 72 usage(); 73 74 fp1 = file(argv[0]); 75 fp2 = file(argv[1]); 76 77 /* for each column printed, add another tab offset */ 78 p = tabs; 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(fp1, col2, line2); 97 break; 98 } 99 if (file2done) { 100 if (!file1done && col1) 101 show(fp2, 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 show(fp, offset, buf) 130 FILE *fp; 131 char *offset, *buf; 132 { 133 do { 134 (void)printf("%s%s", offset, buf); 135 } while (fgets(buf, MAXLINELEN, fp)); 136 } 137 138 FILE * 139 file(name) 140 char *name; 141 { 142 FILE *fp; 143 144 if (!strcmp(name, "-")) 145 return(stdin); 146 if (!(fp = fopen(name, "r"))) { 147 (void)fprintf(stderr, "comm: can't read %s.\n", name); 148 exit(1); 149 } 150 return(fp); 151 } 152 153 usage() 154 { 155 (void)fprintf(stderr, "usage: comm [-123] [ - ] file1 file2\n"); 156 exit(1); 157 } 158