1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 /* 23 * Copyright 2004 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ 28 /* All Rights Reserved */ 29 30 31 #pragma ident "%Z%%M% %I% %E% SMI" 32 33 /* 34 * process common lines of two files 35 */ 36 37 #include <locale.h> 38 #include <stdio.h> 39 #include <stdlib.h> 40 #include <string.h> 41 42 static int compare(char *, char *); 43 static int rd(FILE *, char *); 44 static FILE *openfil(char *); 45 static void copy(FILE *, char *, int); 46 static void usage(void); 47 static void wr(char *, int); 48 49 #define LB 2050 /* P1003.2 minimum (2048) + 2 */ 50 51 #define RDTWO(ib1, lb1, ib2, lb2) \ 52 { \ 53 if (rd(ib1, lb1) < 0) { \ 54 if (rd(ib2, lb2) < 0) \ 55 exit(0); \ 56 copy(ib2, lb2, 2); \ 57 } \ 58 if (rd(ib2, lb2) < 0) \ 59 copy(ib1, lb1, 1); \ 60 } 61 62 static int one; 63 static int two; 64 static int three; 65 66 static char ldr[3][3] = {"", "\t", "\t\t"}; 67 68 static FILE *ib1; 69 static FILE *ib2; 70 static int is_c_locale; 71 72 int 73 main(int argc, char **argv) 74 { 75 int l = 1; 76 int c; /* used for getopt() */ 77 char lb1[LB], lb2[LB], *collate; 78 79 (void) setlocale(LC_ALL, ""); 80 #if !defined(TEXT_DOMAIN) /* Should be defined by cc -D */ 81 #define TEXT_DOMAIN "SYS_TEST" /* Use this only if it weren't */ 82 #endif 83 (void) textdomain(TEXT_DOMAIN); 84 85 if ((collate = setlocale(LC_COLLATE, NULL)) == NULL) { 86 (void) fprintf(stderr, 87 gettext("Query of LC_COLLATE category failed\n")); 88 exit(4); 89 } 90 91 is_c_locale = (strcmp("C", collate) == 0) ? 1 : 0; 92 while ((c = getopt(argc, argv, "123")) != EOF) 93 switch (c) { 94 case '1': 95 if (!one) { 96 one = 1; 97 ldr[1][0] = ldr[2][l--] = '\0'; 98 } 99 break; 100 case '2': 101 if (!two) { 102 two = 1; 103 ldr[2][l--] = '\0'; 104 } 105 break; 106 case '3': 107 three = 1; 108 break; 109 110 default: 111 usage(); 112 } 113 114 argc -= optind; 115 argv = &argv[optind]; 116 117 if (argc != 2) 118 usage(); 119 ib1 = openfil(argv[0]); 120 ib2 = openfil(argv[1]); 121 RDTWO(ib1, lb1, ib2, lb2); 122 for (;;) { 123 switch (compare(lb1, lb2)) { 124 case 0: 125 wr(lb1, 3); 126 RDTWO(ib1, lb1, ib2, lb2); 127 continue; 128 129 case 1: 130 wr(lb1, 1); 131 if (rd(ib1, lb1) < 0) 132 copy(ib2, lb2, 2); 133 continue; 134 135 case 2: 136 wr(lb2, 2); 137 if (rd(ib2, lb2) < 0) 138 copy(ib1, lb1, 1); 139 continue; 140 /* 141 * case "3" means lines are equal in collation, 142 * but not identical (not very likely) 143 */ 144 case 3: 145 wr(lb1, 1); 146 wr(lb2, 2); 147 RDTWO(ib1, lb1, ib2, lb2); 148 continue; 149 } 150 } 151 /* NOTREACHED */ 152 return (0); 153 } 154 155 static int 156 rd(file, buf) 157 FILE *file; 158 char *buf; 159 { 160 register int i, j; 161 i = j = 0; 162 while ((j = getc(file)) != EOF) { 163 *buf = (char)j; 164 if (*buf == '\n' || i > LB-2) { 165 *buf = '\0'; 166 return (0); 167 } 168 i++; 169 buf++; 170 } 171 return (-1); 172 } 173 174 static void 175 wr(str, n) 176 char *str; 177 int n; 178 { 179 switch (n) { 180 case 1: 181 if (one) 182 return; 183 break; 184 185 case 2: 186 if (two) 187 return; 188 break; 189 190 case 3: 191 if (three) 192 return; 193 } 194 (void) printf("%s%s\n", ldr[n-1], str); 195 } 196 197 static void 198 copy(ibuf, lbuf, n) 199 FILE *ibuf; 200 char *lbuf; 201 int n; 202 { 203 do { 204 wr(lbuf, n); 205 } while (rd(ibuf, lbuf) >= 0); 206 207 exit(0); 208 } 209 210 static int 211 compare(a, b) 212 char *a, *b; 213 { 214 register char *ra, *rb; 215 int ret; 216 217 ra = a - 1; 218 rb = b - 1; 219 while (*++ra == *++rb) 220 if (*ra == '\0') 221 return (0); 222 223 /* For "C" locale, just compare bytes */ 224 if (is_c_locale) { 225 if (*ra < *rb) 226 return (1); 227 return (2); 228 } 229 /* For other locales, call locale-sensitive compare routine */ 230 else { 231 ret = strcoll(a, b); 232 return (ret == 0 ? 3 : (ret < 0 ? 1 : 2)); 233 } 234 } 235 236 static FILE * 237 openfil(s) 238 char *s; 239 { 240 FILE *b; 241 if (s[0] == '-' && s[1] == 0) 242 b = stdin; 243 else if ((b = fopen(s, "r")) == NULL) { 244 (void) fprintf(stderr, "comm: "); 245 perror(s); 246 exit(2); 247 } 248 return (b); 249 } 250 251 static void 252 usage() 253 { 254 (void) fprintf(stderr, gettext("usage: comm [-123] file1 file2\n")); 255 exit(2); 256 } 257