hbase

heirloom base
git clone git://git.2f30.org/hbase
Log | Files | Refs | README

diff.c (10273B)


      1 /*
      2  * This code contains changes by
      3  * Gunnar Ritter, Freiburg i. Br., Germany, March 2003. All rights reserved.
      4  *
      5  * Conditions 1, 2, and 4 and the no-warranty notice below apply
      6  * to these changes.
      7  *
      8  *
      9  * Copyright (c) 1991
     10  * 	The Regents of the University of California.  All rights reserved.
     11  *
     12  * Redistribution and use in source and binary forms, with or without
     13  * modification, are permitted provided that the following conditions
     14  * are met:
     15  * 1. Redistributions of source code must retain the above copyright
     16  *    notice, this list of conditions and the following disclaimer.
     17  * 2. Redistributions in binary form must reproduce the above copyright
     18  *    notice, this list of conditions and the following disclaimer in the
     19  *    documentation and/or other materials provided with the distribution.
     20  * 3. All advertising materials mentioning features or use of this software
     21  *    must display the following acknowledgement:
     22  * 	This product includes software developed by the University of
     23  * 	California, Berkeley and its contributors.
     24  * 4. Neither the name of the University nor the names of its contributors
     25  *    may be used to endorse or promote products derived from this software
     26  *    without specific prior written permission.
     27  *
     28  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
     29  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     30  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     31  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
     32  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     33  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     34  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     35  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     36  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     37  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     38  * SUCH DAMAGE.
     39  *
     40  *
     41  * Copyright(C) Caldera International Inc. 2001-2002. All rights reserved.
     42  *
     43  * Redistribution and use in source and binary forms, with or without
     44  * modification, are permitted provided that the following conditions
     45  * are met:
     46  *   Redistributions of source code and documentation must retain the
     47  *    above copyright notice, this list of conditions and the following
     48  *    disclaimer.
     49  *   Redistributions in binary form must reproduce the above copyright
     50  *    notice, this list of conditions and the following disclaimer in the
     51  *    documentation and/or other materials provided with the distribution.
     52  *   All advertising materials mentioning features or use of this software
     53  *    must display the following acknowledgement:
     54  *      This product includes software developed or owned by Caldera
     55  *      International, Inc.
     56  *   Neither the name of Caldera International, Inc. nor the names of
     57  *    other contributors may be used to endorse or promote products
     58  *    derived from this software without specific prior written permission.
     59  *
     60  * USE OF THE SOFTWARE PROVIDED FOR UNDER THIS LICENSE BY CALDERA
     61  * INTERNATIONAL, INC. AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR
     62  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
     63  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     64  * ARE DISCLAIMED. IN NO EVENT SHALL CALDERA INTERNATIONAL, INC. BE
     65  * LIABLE FOR ANY DIRECT, INDIRECT INCIDENTAL, SPECIAL, EXEMPLARY, OR
     66  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     67  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
     68  * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
     69  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
     70  * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
     71  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     72  */
     73 
     74 /*	Sccsid @(#)diff.c	1.24 (gritter) 3/27/05>	*/
     75 /*	from 4.3BSD diff.c 4.6 4/3/86	*/
     76 
     77 #include "diff.h"
     78 #include <unistd.h>
     79 #include <locale.h>
     80 #include <iblok.h>
     81 /*
     82  * diff - driver and subroutines
     83  */
     84 
     85 const char	diff[] = "diff";
     86 const char	diffh[] = DIFFH;
     87 const char	pr[] = "pr";
     88 const char	*progname;
     89 const char	*argv0;
     90 
     91 static void	usage(void);
     92 static void	xadd(const char *);
     93 static void	Xadd(const char *);
     94 
     95 int
     96 main(int argc, char **argv)
     97 {
     98 	int	i, invalid = 0;
     99 
    100 	progname = basename(argv[0]);
    101 	setlocale(LC_CTYPE, "");
    102 	mb_cur_max = MB_CUR_MAX;
    103 	if (getenv("SYSV3") != NULL)
    104 		sysv3 = 1;
    105 	ifdef1 = "FILE1"; ifdef2 = "FILE2";
    106 	status = 2;
    107 	argv0 = argv[0];
    108 	diffargv = argv;
    109 	while ((i = getopt(argc, argv, ":D:efnbBwitcC:uU:hS:rslNx:a12pX:"))
    110 			!= EOF) {
    111 		switch (i) {
    112 #ifdef notdef
    113 		case 'I':
    114 			opt = D_IFDEF;
    115 			wantelses = 0;
    116 			break;
    117 		case 'E':
    118 			opt = D_IFDEF;
    119 			wantelses = 1;
    120 			break;
    121 		case '1':
    122 			opt = D_IFDEF;
    123 			ifdef1 = optarg;
    124 			break;
    125 #endif
    126 		case 'D':
    127 			/* -Dfoo = -E -1 -2foo */
    128 			wantelses = 1;
    129 			ifdef1 = "";
    130 			/* fall through */
    131 #ifdef notdef
    132 		case '2':
    133 #endif
    134 			opt = D_IFDEF;
    135 			ifdef2 = optarg;
    136 			break;
    137 		case 'e':
    138 			opt = D_EDIT;
    139 			break;
    140 		case 'f':
    141 			opt = D_REVERSE;
    142 			break;
    143 		case 'n':
    144 			opt = D_NREVERSE;
    145 			break;
    146 		case 'b':
    147 			bflag = 1;
    148 			break;
    149 		case 'B':
    150 			Bflag = 1;
    151 			break;
    152 		case 'w':
    153 			wflag = 1;
    154 			break;
    155 		case 'i':
    156 			iflag = 1;
    157 			break;
    158 		case 't':
    159 			tflag = 1;
    160 			break;
    161 		case 'c':
    162 			opt = D_CONTEXT;
    163 			context = 3;
    164 			break;
    165 		case 'C': {
    166 			char	*x;
    167 
    168 			opt = D_CONTEXT;
    169 			context = strtol(optarg, &x, 10);
    170 			if (*x != '\0' || *optarg == '+' || *optarg == '-') {
    171 				fprintf(stderr, "%s: use -C num\n", progname);
    172 				done();
    173 			}
    174 			break;
    175 		}
    176 		case 'u':
    177 			opt = D_UNIFIED;
    178 			context = 3;
    179 			break;
    180 		case 'U': {
    181 			char	*x;
    182 
    183 			opt = D_UNIFIED;
    184 			context = strtol(optarg, &x, 10);
    185 			if (*x != '\0' || *optarg == '+' || *optarg == '-') {
    186 				fprintf(stderr, "%s: use -U num\n", progname);
    187 				done();
    188 			}
    189 			break;
    190 		}
    191 		case 'h':
    192 			hflag++;
    193 			break;
    194 		case 'S':
    195 			start = optarg;
    196 			break;
    197 		case 'r':
    198 			rflag++;
    199 			break;
    200 		case 's':
    201 			sflag++;
    202 			break;
    203 		case 'l':
    204 			lflag++;
    205 			break;
    206 		case 'N':
    207 			Nflag |= 3;
    208 			break;
    209 		case '1':
    210 			Nflag |= 1;
    211 			break;
    212 		case '2':
    213 			Nflag |= 2;
    214 			break;
    215 		case 'x':
    216 			xadd(optarg);
    217 			break;
    218 		case 'a':
    219 			aflag++;
    220 			break;
    221 		case 'p':
    222 			pflag++;
    223 			break;
    224 		case 'X':
    225 			Xadd(optarg);
    226 			break;
    227 		default:
    228 			if (invalid == 0 && !sysv3)
    229 				invalid = optopt;
    230 		}
    231 	}
    232 	argv += optind, argc -= optind;
    233 	if (argc != 2) {
    234 		fprintf(stderr, sysv3 ? "%s: arg count\n" :
    235 				"%s: two filename arguments required\n",
    236 				progname);
    237 		done();
    238 	}
    239 	file1 = argv[0];
    240 	file2 = argv[1];
    241 	if (invalid) {
    242 		fprintf(stderr, "%s: invalid option -%c\n", progname, invalid);
    243 		usage();
    244 	}
    245 	if (pflag) {
    246 		if (opt == D_UNIFIED || opt == D_CONTEXT)
    247 			/*EMPTY*/;
    248 		else if (opt == 0) {
    249 			opt = D_CONTEXT;
    250 			context = 3;
    251 		} else {
    252 			fprintf(stderr,
    253 				"%s: -p doesn't support -e, -f, -n, or -I\n",
    254 		    		progname);
    255 			done();
    256 		}
    257 	}
    258 	if (hflag && opt) {
    259 		fprintf(stderr,
    260 		    "%s: -h doesn't support -e, -f, -n, -c, -u, or -I\n",
    261 		    	progname);
    262 		done();
    263 	}
    264 	diffany(argv);
    265 	/*NOTREACHED*/
    266 	return 0;
    267 }
    268 
    269 void
    270 diffany(char **argv)
    271 {
    272 	if (!strcmp(file1, "-"))
    273 		stb1.st_mode = S_IFREG;
    274 	else if (stat(file1, &stb1) < 0) {
    275 		if (sysv3)
    276 			stb1.st_mode = S_IFREG;
    277 		else {
    278 			fprintf(stderr, "%s: %s: %s\n", progname, file1,
    279 					strerror(errno));
    280 			done();
    281 		}
    282 	}
    283 	if (!strcmp(file2, "-"))
    284 		stb2.st_mode = S_IFREG;
    285 	else if (stat(file2, &stb2) < 0) {
    286 		if (sysv3)
    287 			stb2.st_mode = S_IFREG;
    288 		else {
    289 			fprintf(stderr, "%s: %s: %s\n", progname, file2,
    290 					strerror(errno));
    291 			done();
    292 		}
    293 	}
    294 	if ((stb1.st_mode & S_IFMT) == S_IFDIR &&
    295 	    (stb2.st_mode & S_IFMT) == S_IFDIR) {
    296 		diffdir(argv);
    297 	} else
    298 		diffreg();
    299 	done();
    300 }
    301 
    302 static void
    303 usage(void)
    304 {
    305 	fprintf(stderr, "\
    306 usage: %s [ -bcefhilnrstw -C num -D string -S name ] file1 file2\n",
    307 		progname);
    308 	done();
    309 }
    310 
    311 int
    312 min(int a,int b)
    313 {
    314 
    315 	return (a < b ? a : b);
    316 }
    317 
    318 int
    319 max(int a,int b)
    320 {
    321 
    322 	return (a > b ? a : b);
    323 }
    324 
    325 void
    326 done(void)
    327 {
    328 	if (tempfile1) {
    329 		unlink(tempfile1);
    330 		tempfile1 = NULL;
    331 	}
    332 	if (tempfile2) {
    333 		unlink(tempfile2);
    334 		tempfile2 = NULL;
    335 	}
    336 	if (recdepth == 0)
    337 		exit(status);
    338 	else
    339 		longjmp(recenv, 1);
    340 }
    341 
    342 static void	noroom(void);
    343 
    344 void *
    345 dalloc(size_t n)
    346 {
    347 	struct stackblk *sp;
    348 
    349 	if ((sp = malloc(n + sizeof *sp)) != NULL) {
    350 		sp->s_prev = NULL;
    351 		sp->s_next = curstack;
    352 		if (curstack)
    353 			curstack->s_prev = sp;
    354 		curstack = sp;
    355 		return (char *)sp + sizeof *sp;
    356 	} else
    357 		return NULL;
    358 }
    359 
    360 void *
    361 talloc(size_t n)
    362 {
    363 	register void *p;
    364 
    365 	if ((p = dalloc(n)) == NULL)
    366 		noroom();
    367 	return p;
    368 }
    369 
    370 void *
    371 ralloc(void *p,size_t n)
    372 {
    373 	struct stackblk	*sp, *sq;
    374 
    375 	if (p == NULL)
    376 		return talloc(n);
    377 	sp = (struct stackblk *)((char *)p - sizeof *sp);
    378 	if ((sq = realloc(sp, n + sizeof *sp)) == NULL)
    379 		noroom();
    380 	if (sq->s_prev)
    381 		sq->s_prev->s_next = sq;
    382 	if (sq->s_next)
    383 		sq->s_next->s_prev = sq;
    384 	if (curstack == sp)
    385 		curstack = sq;
    386 	return (char *)sq + sizeof *sq;
    387 }
    388 
    389 void
    390 tfree(void *p)
    391 {
    392 	struct stackblk	*sp;
    393 
    394 	if (p == NULL)
    395 		return;
    396 	sp = (struct stackblk *)((char *)p - sizeof *sp);
    397 	if (sp->s_prev)
    398 		sp->s_prev->s_next = sp->s_next;
    399 	if (sp->s_next)
    400 		sp->s_next->s_prev = sp->s_prev;
    401 	if (sp == curstack)
    402 		curstack = sp->s_next;
    403 	free(sp);
    404 }
    405 
    406 void
    407 purgestack(void)
    408 {
    409 	struct stackblk *sp = curstack, *sq = NULL;
    410 
    411 	do {
    412 		free(sq);
    413 		sq = sp;
    414 		if (sp)
    415 			sp = sp->s_next;
    416 	} while (sq);
    417 }
    418 
    419 static void
    420 noroom(void)
    421 {
    422 	oomsg(": files too big, try -h\n");
    423 	status = 2;
    424 	done();
    425 }
    426 
    427 static void
    428 xadd(const char *cp)
    429 {
    430 	struct xclusion	*xp;
    431 
    432 	xp = talloc(sizeof *xp);
    433 	xp->x_pat = cp;
    434 	xp->x_nxt = xflag;
    435 	xflag = xp;
    436 }
    437 
    438 static void
    439 Xadd(const char *name)
    440 {
    441 	struct iblok	*ip;
    442 	char	*line = NULL;
    443 	size_t	size = 0, len;
    444 
    445 	if (name[0] == '-' && name[1] == '\0')
    446 		ip = ib_alloc(0, 0);
    447 	else
    448 		ip = ib_open(name, 0);
    449 	if (ip == NULL) {
    450 		fprintf(stderr, "%s: -X %s: %s\n", progname, name,
    451 				strerror(errno));
    452 		done();
    453 	}
    454 	while ((len = ib_getlin(ip, &line, &size, realloc)) != 0) {
    455 		if (line[len-1] == '\n')
    456 			line[--len] = '\0';
    457 		xadd(line);
    458 		line = NULL;
    459 		size = 0;
    460 	}
    461 	free(line);
    462 	if (ip->ib_fd)
    463 		ib_close(ip);
    464 	else
    465 		ib_free(ip);
    466 }
    467 
    468 void
    469 oomsg(const char *s)
    470 {
    471 	write(2, progname, strlen(progname));
    472 	write(2, s, strlen(s));
    473 }