hbase

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

diffh.c (10259B)


      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 #if __GNUC__ >= 3 && __GNUC_MINOR__ >= 4 || __GNUC__ >= 4
     75 #define	USED	__attribute__ ((used))
     76 #elif defined __GNUC__
     77 #define	USED	__attribute__ ((unused))
     78 #else
     79 #define	USED
     80 #endif
     81 static const char sccsid[] USED = "@(#)diffh.sl	1.11 (gritter) 5/29/05";
     82 
     83 /*	from 4.3BSD diffh.c 4.4 11/27/85>	*/
     84 
     85 #include <stdio.h>
     86 #include <ctype.h>
     87 #include <sys/types.h>
     88 #include <sys/stat.h>
     89 #include <stdlib.h>
     90 #include <string.h>
     91 #include <limits.h>
     92 #include <unistd.h>
     93 #include <locale.h>
     94 #include <wchar.h>
     95 #include <wctype.h>
     96 
     97 #include <iblok.h>
     98 #include <mbtowi.h>
     99 
    100 #define C 3
    101 #define RANGE 30
    102 #define INF 16384
    103 
    104 #define	next(wc, s, n)	(*(s) & 0200 ? ((n) = mbtowi(&(wc), (s), mb_cur_max), \
    105 		(n) = ((n) > 0 ? (n) : (n) < 0 ? (wc=WEOF, 1) : 1)) :\
    106 		((wc) = *(s) & 0377, (n) = 1))
    107 
    108 static char *text[2][RANGE];
    109 static size_t size[2][RANGE];
    110 static long long lineno[2] = {1, 1};	/*no. of 1st stored line in each file*/
    111 static int ntext[2];		/*number of stored lines in each*/
    112 static long long n0,n1;		/*scan pointer in each*/
    113 static int bflag;
    114 static int mb_cur_max;
    115 static int debug = 0;
    116 static struct iblok *file[2];
    117 static int eof[2];
    118 
    119 static char *getl(int, long long);
    120 static void clrl(int, long long);
    121 static void movstr(int, int, int);
    122 static int easysynch(void);
    123 static int output(int, int);
    124 static void change(long long, int, long long, int, const char *);
    125 static void range(long long, int);
    126 static int cmp(const char *, const char *);
    127 static struct iblok *dopen(const char *, const char *);
    128 static void progerr(const char *);
    129 static void error(const char *, const char *);
    130 static int hardsynch(void);
    131 static void *lrealloc(void *, size_t);
    132 
    133 	/* return pointer to line n of file f*/
    134 static char *
    135 getl(int f, long long n)
    136 {
    137 	register int delta, nt;
    138 	size_t	len;
    139 
    140 	delta = n - lineno[f];
    141 	nt = ntext[f];
    142 	if(delta<0)
    143 		progerr("1");
    144 	if(delta<nt)
    145 		return(text[f][delta]);
    146 	if(delta>nt)
    147 		progerr("2");
    148 	if(nt>=RANGE)
    149 		progerr("3");
    150 	if(eof[f])
    151 		return(NULL);
    152 	len = ib_getlin(file[f], &text[f][nt], &size[f][nt], lrealloc);
    153 	if (len != 0) {
    154 		ntext[f]++;
    155 		return(text[f][nt]);
    156 	} else {
    157 		eof[f]++;
    158 		return NULL;
    159 	}
    160 }
    161 
    162 	/*remove thru line n of file f from storage*/
    163 static void
    164 clrl(int f,long long n)
    165 {
    166 	register long long i,j;
    167 	j = n-lineno[f]+1;
    168 	for(i=0;i+j<ntext[f];i++)
    169 		movstr(f, i+j, i);
    170 	lineno[f] = n+1;
    171 	ntext[f] -= j;
    172 }
    173 
    174 static void
    175 movstr(register int f, register int i, register int j)
    176 {
    177 	free(text[f][j]);
    178 	text[f][j] = text[f][i];
    179 	size[f][j] = size[f][i];
    180 	text[f][i] = 0;
    181 	size[f][i] = 0;
    182 }
    183 
    184 int
    185 main(int argc,char **argv)
    186 {
    187 	char *s0,*s1;
    188 	register int c, status = 0;
    189 
    190 	setlocale(LC_CTYPE, "");
    191 	mb_cur_max = MB_CUR_MAX;
    192 	while((c=getopt(argc,argv,":b")) != EOF) {
    193 		switch (c) {
    194 		case 'b':
    195 			bflag++;
    196 			break;
    197 		}
    198 	}
    199 	if(argc-optind!=2)
    200 		error("must have 2 file arguments","");
    201 	file[0] = dopen(argv[optind],argv[optind+1]);
    202 	file[1] = dopen(argv[optind+1],argv[optind]);
    203 	for(;;) {
    204 		s0 = getl(0,++n0);
    205 		s1 = getl(1,++n1);
    206 		if(s0==NULL||s1==NULL)
    207 			break;
    208 		if(cmp(s0,s1)!=0) {
    209 			if(!easysynch()&&!hardsynch())
    210 				progerr("5");
    211 			status = 1;
    212 		} else {
    213 			clrl(0,n0);
    214 			clrl(1,n1);
    215 		}
    216 	}
    217 	if(s0==NULL&&s1==NULL)
    218 		exit(status);
    219 	if(s0==NULL)
    220 		output(-1,INF);
    221 	if(s1==NULL)
    222 		output(INF,-1);
    223 	return (1);
    224 }
    225 
    226 	/* synch on C successive matches*/
    227 static int
    228 easysynch(void)
    229 {
    230 	int i,j;
    231 	register int k,m;
    232 	char *s0,*s1;
    233 	for(i=j=1;i<RANGE&&j<RANGE;i++,j++) {
    234 		s0 = getl(0,n0+i);
    235 		if(s0==NULL)
    236 			return(output(INF,INF));
    237 		for(k=C-1;k<j;k++) {
    238 			for(m=0;m<C;m++)
    239 				if(cmp(getl(0,n0+i-m),
    240 					getl(1,n1+k-m))!=0)
    241 					goto cont1;
    242 			return(output(i-C,k-C));
    243 cont1:			;
    244 		}
    245 		s1 = getl(1,n1+j);
    246 		if(s1==NULL)
    247 			return(output(INF,INF));
    248 		for(k=C-1;k<=i;k++) {
    249 			for(m=0;m<C;m++)
    250 				if(cmp(getl(0,n0+k-m),
    251 					getl(1,n1+j-m))!=0)
    252 					goto cont2;
    253 			return(output(k-C,j-C));
    254 cont2:			;
    255 		}
    256 	}
    257 	return(0);
    258 }
    259 
    260 static int
    261 output(int a,int b)
    262 {
    263 	register int i;
    264 	char *s;
    265 	if(a<0)
    266 		change(n0-1,0,n1,b,"a");
    267 	else if(b<0)
    268 		change(n0,a,n1-1,0,"d");
    269 	else
    270 		change(n0,a,n1,b,"c");
    271 	for(i=0;i<=a;i++) {
    272 		s = getl(0,n0+i);
    273 		if(s==NULL)
    274 			break;
    275 		printf("< %s",s);
    276 		clrl(0,n0+i);
    277 	}
    278 	n0 += i-1;
    279 	if(a>=0&&b>=0)
    280 		printf("---\n");
    281 	for(i=0;i<=b;i++) {
    282 		s = getl(1,n1+i);
    283 		if(s==NULL)
    284 			break;
    285 		printf("> %s",s);
    286 		clrl(1,n1+i);
    287 	}
    288 	n1 += i-1;
    289 	return(1);
    290 }
    291 
    292 static void
    293 change(long long a,int b,long long c,int d,const char *s)
    294 {
    295 	range(a,b);
    296 	printf("%s",s);
    297 	range(c,d);
    298 	printf("\n");
    299 }
    300 
    301 static void
    302 range(long long a,int b)
    303 {
    304 	if(b==INF)
    305 		printf("%lld,$",a);
    306 	else if(b==0)
    307 		printf("%lld",a);
    308 	else
    309 		printf("%lld,%lld",a,a+b);
    310 }
    311 
    312 static int
    313 cmp(const char *s,const char *t)
    314 {
    315 	if(debug)
    316 		printf("%s:%s\n",s,t);
    317 	for(;;){
    318 		if(bflag) {
    319 			if (mb_cur_max > 1) {
    320 				wint_t	wc, wd;
    321 				int	n, m;
    322 
    323 				if (next(wc, s, n), next(wd, t, m),
    324 						iswspace(wc) && iswspace(wd)) {
    325 					while (s += n, next(wc, s, n),
    326 							iswspace(wc));
    327 					while (t += m, next(wd, t, m),
    328 							iswspace(wd));
    329 				}
    330 			} else {
    331 				if (isspace(*s)&&isspace(*t)) {
    332 					while(isspace(*++s)) ;
    333 					while(isspace(*++t)) ;
    334 				}
    335 			}
    336 		}
    337 		if(*s!=*t||*s==0)
    338 			break;
    339 		s++;
    340 		t++;
    341 	}
    342 	return((*s&0377)-(*t&0377));
    343 }
    344 
    345 static struct iblok *
    346 dopen(const char *f1,const char *f2)
    347 {
    348 	struct iblok *ip;
    349 	char *b=0,*bptr;
    350 	const char *eptr;
    351 	struct stat statbuf;
    352 	if(cmp(f1,"-")==0)
    353 		if(cmp(f2,"-")==0)
    354 			error("can't do - -","");
    355 		else
    356 			return(ib_alloc(0, 0));
    357 	if(stat(f1,&statbuf)==-1)
    358 		error("can't access ",f1);
    359 	if((statbuf.st_mode&S_IFMT)==S_IFDIR) {
    360 		b = lrealloc(0, strlen(f1) + strlen(f2) + 2);
    361 		for(bptr=b;*bptr= *f1++;bptr++) ;
    362 		*bptr++ = '/';
    363 		for(eptr=f2;*eptr;eptr++)
    364 			if(*eptr=='/'&&eptr[1]!=0&&eptr[1]!='/')
    365 				f2 = eptr+1;
    366 		while(*bptr++= *f2++) ;
    367 		f1 = b;
    368 	}
    369 	ip = ib_open(f1,0);
    370 	if(ip==NULL)
    371 		error("can't open",f1);
    372 	if (b)
    373 		free(b);
    374 	return(ip);
    375 }
    376 
    377 static void
    378 progerr(const char *s)
    379 {
    380 	error("program error ",s);
    381 }
    382 
    383 static void
    384 error(const char *s,const char *t)
    385 {
    386 	fprintf(stderr,"diffh: %s%s\n",s,t);
    387 	exit(2);
    388 }
    389 
    390 	/*stub for resychronization beyond limits of text buf*/
    391 static int
    392 hardsynch(void)
    393 {
    394 	change(n0,INF,n1,INF,"c");
    395 	printf("---change record omitted\n");
    396 	error("can't resynchronize","");
    397 	return(0);
    398 }
    399 
    400 static void *
    401 lrealloc(void *op, size_t size)
    402 {
    403 	void	*np;
    404 
    405 	if ((np = realloc(op, size)) == NULL) {
    406 		write(2, "diffh: line too long\n", 21);
    407 		_exit(1);
    408 	}
    409 	return np;
    410 }