/* 5. clare           Mon Jul 26 09:14:03 1999  now we are getting file on
cdrom with crlf at end of each record */
/* 4. clare           Fri Dec 11 09:26:41 1998 r_chrul now starts
	with 2 character prefix the part number is in the
	the remaining 10 characters */
/* 3. clare           Mon Nov 23 10:38:45 1998  filter out CCNS */
/* 2. clare           Thu Jul 09 10:19:16 1998  new chrysler format */
/* 1. clare           Mon Jan 19 15:15:52 1998  allow 3 tapes */
/*------------------------------
added DUPOUT on 03-17-97 to the calls to optech sort 
----------------------------------*/
#define xunlink(a)   /*---*/
/*=============================================
record expanded to 97 bytes to allow chbackward   
a backward pointing reference on supercession
ch3 06-13-93
===============================================*/
#define MAIN
#include <stdio.h>
#include <jcs/bfile.h>
#include <jcs/cw.h>
#if 0
#include <system.1/chtapstr.h>
#else
#include "chtapstr.h"
#endif

#define MERGEORDER 12
#define LIMIT 3500
#define KEYLEN 20
#define KEYOFF 0
#if 0
/* #5 */
#define RECLEN 245
#define CHRYSLERBLOCKSIZE 6125
#endif
#if 1
/* #5 */
#define RECLEN 247
#define CHRYSLERBLOCKSIZE 6175
#endif
#define CHOPLEN sizeof(CH200)
#define SORT "c:/bin/sort.exe"
#define INORDER "c:/bin/inorder.exe"


char	*iname;
char	*iname2;
char	*iname3;
char	*iname4;
int		tape;	

char	buffer[CHRYSLERBLOCKSIZE+2];
typedef	struct	{
	char		
	r_chrectype[1],
	r_chpartnum[10],
	r_chpartname[9],
	r_chpartdescr[30],
	r_chchngsym[1],
	r_chloccode[1],
	r_chaplcode[1],
	r_chpromo[2],
	r_chretelig[1],
	r_chrul[12],
	r_chmsq[3],
	r_chparttype[10],
	r_chdiscode[1],
	r_chtaxcode[1],
	r_chunitofmeasure[1],
	r_chmerchclass[1],
	r_chpricesym[2],
	r_chlist[7],
	r_chcost[7],
	r_chqp2[7],
	r_chqp3[7],
	r_chqp4[7],
	r_chwhlsale[7],
	r_chdson[7],
	r_chfleetallow[7],
	r_chmodyearin[4],
	r_chmodyearout[4],
	r_chcanyear[4],
	r_chrulingdate[8],
	r_chpricedate[8],
	r_chreturndescr[1],
	r_chjeepindicator[1],
	r_chdistribcode[1],
	r_chweight[9],
	r_chshelflife[4],
	r_chpdlength[7],
	r_chpdwidth[7],
	r_chpdheight[7],
	r_chprodline[1],
	r_chrepairgrp[7],
	r_chcountryoforigin[3],
	r_chmsdsindicator[1],
	r_chfiller[25];
}	RAWCH;

typedef struct {
	BFILE	*in;
	char	fname[128];
	char	record[CHOPLEN+10];
	}	MFILE;

struct	hxx	{
	BFILE		*r;
	char		unc_buffer[80];
	int			len;
	char		readitbuf[160];
	char		*nextrecord;
	int		bytesleft;
	};

void convert(BFILE *out,RAWCH *p,int len);
void dump(RAWCH *p);
void dummy(RAWCH *p);
void process(BFILE *out,RAWCH *p);
int dirty_test(int rd);
int tape_read(BFILE **inptr,char *buff,int rec_len);
void main(int argc,char **argv);
int	cmp(MFILE *a,MFILE *b);
int cread_it(struct hxx *x);
void prepare_forward_file(void);
int merge_file(char *dname, char *sname);
void merge_it(int nf);
static	exchange(register char *a,register char *b,int n);
void reheap(char *array,int n,int size,int (*cmp)());

char	*strstr(char *s1, char *s2 )
{
/* find the first occurrence of s2 in s1 */
int	len;
char	*t;

len = strlen(s2);

if ( len < 1 )
	return	s1;

t = s1;

for ( ; '\0' != *t; t++ )
	if ( 0 == strncmp(t,s2,len) )
		return	t;

return ( char *) 0;
}



#if 0
void convert(BFILE *out,RAWCH *p,int len)
#else
void convert(out,p,len)
BFILE *out;
RAWCH *p;
int	len;
#endif
{
char	buff1[256];
char	buff2[40];
union {
	char	buffer[256];
	CH200	c;
	}	local;
static long	xl;

if ( ' ' != p->r_chrul[2] && ('N' != p->r_chrul[2] || 'S' != p->r_chrul[3]) )
	{
	sprintf(buff1,"%8.8s.%2.2s",p->r_chrul+2,p->r_chrul+10);
	}
else
	buff1[0]='\0';

sprintf(buff2,"%8.8s.%2.2s",p->r_chpartnum,p->r_chpartnum+8);

memset(local.buffer,' ',sizeof(local.buffer));

numformat(&local.c.chpartnum,buff2);
if ( 0 == strstr(buff1,"NS"))
	numformat(&local.c.chrul,buff1);

local.c.chrectype[0]=p->r_chrectype[0];
memcpy(local.c.chpartname,p->r_chpartname,45);
memcpy(local.c.chmsq,p->r_chmsq,177);


bwrite(out,local.buffer,len);

}
void process(BFILE *out,RAWCH *p)
{
static	int	count=0;
char local[64];
char	buff1[48];

sprintf(buff1,"%8.8s.%2.2s",p->r_chrul+2,p->r_chrul+10);
if (  0 == isdigit(buff1[7]) || 0 == strpbrk(buff1,"123456789") ||
	0 != strstr(buff1,"NS") )
	return;

numformat(local,buff1);
sprintf(buff1,"%8.8s.%2.2s",p->r_chpartnum,p->r_chpartnum+8);
numformat(local+20,buff1);
bwrite(out,local,40);

}

int dirty_test(int rd)
{
static	char	buff1[10];
char	*b1,*b2;
char	*b_end = buffer +rd;
char	*b;

if ( 0 == rd )
	{
	memset(buff1,' ',sizeof(buff1));
	return	1;
	}

b1 = buff1;
b2 = buffer+KEYOFF;

for ( ; b2 < b_end ;  )
	{
	if ( strncmp(b1,b2,KEYLEN) < 0 )
		{
		b1=b2;
		b2 += RECLEN;
		continue;
		}
	break;
	}

if ( b2 < b_end  )	/* we are dirty   */
	return	1;

strncpy(buff1,b1,KEYLEN);

return	0;

}
void low_bit(char *s, int i )
{
char	*s_end;

s_end = s + i;

for ( ; s < s_end ; s++ )
	*s &= 0x7f;
}
int tape_read(BFILE  **inptr,char *buff,int rec_len)
{
char	local[80];
static	int	flag=0;
int	rd;
BFILE	*in = *inptr;

if ( rd = bread(in,buff,rec_len)) 
	{
	low_bit(buff,rd);
		return	rd;
	}


/* 07-27-99 */
return	0;

tape = ( 0 == flag && 0 == strcmp("mt0",iname) ) ||
	( 1 == flag && 0 == strcmp("mt0",iname2) ) ||
	( 2 == flag && 0 == strcmp("mt0",iname3) ) ||
	( 3 == flag && 0 == strcmp("mt0",iname4) );

if ( tape )
	tapecmd(in->fh,"TU",2);

bclose(in);

if ( 3 == flag )
	return	0;

flag++;

/* now is the new file on tape */
tape =  ( 1 == flag && 0 == strcmp("mt0",iname2) ) ||
	( 2 == flag && 0 == strcmp("mt0",iname3) ) ||
	( 3 == flag && 0 == strcmp("mt0",iname4) );

switch ( flag )
	{
	case	1:
		break;
	case	2:
		iname = iname2;
		iname2 = iname3;
		break;
	case	3:
		iname = iname3;
		iname2 = iname4;
		break;
	}

if ( tape )
	{
	putchar(7);
	putchar(7);
	putchar(7);
	putchar(7);
	putchar(7);
	putchar(7);
	putchar(7);
	putchar(7);
	fputs("Load next tape.",stdout);
	
	while ( 'Y' != ltsgt("--Ready? Yes \316o") )
		;
	}
else
	{
	putchar(7);
	putchar(7);
	putchar(7);
	putchar(7);
	sprintf(local,"--Delete\t%s Yes \316o",iname);
	if ( 'Y' == ltsgt(local) )
		unlink(iname);
	}

in = *inptr = bopen(iname2,"r",CHRYSLERBLOCKSIZE);
printf("\n\nOpening %s\n\n",iname2);

if ( 0 == in  )
	{
	printf("\n\7unable to open %s\n",iname2);
	return 0;
	}

if (  0  !=  tape )
	{
	binary(in->fh);

	tapecmd(in->fh,"EA",2);
	}

return	tape_read(inptr,buff,rec_len);
}

void convert_to_printable(char *b,char *b_end)
{
/* Wed Jul 28 08:34:24 1999 */
/* chrysler put crap in the file when publishing cd */
for ( ; b < b_end ; b++ )
	{
	if ( ' ' > *b || '~' < *b )
		*b = ' ';
	}
}
		
void main(int argc,char **argv)
{
int	rd;
int	nf=0;
int	dirty=0;
int	blocks=0;
char	fname[128];
char	oname[128];
char	*b,*b_end;
BFILE	*super;
BFILE	*in,*out,*bopen();;
void (*state)();

state = dump;

puts("use: [ file1 file2 file3]\n or\n -info\n or\n -inorder\n");

iname4 = iname3 = iname2 = iname = "mt0";
if ( argc > 1 )
	{
	if ( 0 == strcmp(argv[1],"-info"))
		{
		printf("RECLEN=%d\n",RECLEN);
		printf("CHRYSLERBLOCKSIZE=%d\n",CHRYSLERBLOCKSIZE);
		printf("CHOPLEN=%d\n",CHOPLEN);
		printf("SORT=%s\n",SORT);
		printf("INORDER=%s\n",INORDER);
		exit(0);
		}
	if ( 0 == strcmp(argv[1],"-inorder"))
		{
		printf("RECLEN=%d\n",RECLEN);
		printf("CHRYSLERBLOCKSIZE=%d\n",CHRYSLERBLOCKSIZE);
		printf("CHOPLEN=%d\n",CHOPLEN);
		printf("SORT=%s\n",SORT);
		printf("INORDER=%s\n",INORDER);
		sprintf(buffer,"-c price.ch1 %d %d %d",CHOPLEN,KEYLEN,KEYOFF);
		printf("%s %s\n",INORDER,buffer);
		spawn(INORDER,buffer);
		putchar(7);
		exit(0);
		}
	iname = argv[1];
	if ( argc > 2)
		iname2 = argv[2];

	if ( argc > 3)
		iname3 = argv[3];

	if ( argc > 4)
		iname4 = argv[4];
	}

in = bopen(iname,"r",CHRYSLERBLOCKSIZE);

if ( 0 == strcmp("mt0",iname) )
	{
	binary(in->fh);
	tapecmd(in->fh,"EA",2);
	}
sprintf(fname,"\\CHRYSraw.%03d",nf );
printf("\n\n%s\n\n",fname);
out = bopen(fname,"w",CHRYSLERBLOCKSIZE);

super = bopen("super.tmp","w",8192);

while  ( nf < MERGEORDER )
	{
	CW(24,1,5);
	if ( rd = tape_read(&in,buffer,CHRYSLERBLOCKSIZE)) 
		{
		
		b_end = b = buffer;
		b_end += rd ; 
		convert_to_printable(b,b_end);
		for ( ; b < b_end  && ' ' == b[1] ;  b += RECLEN)
			;	/* skip commnet records */
		for ( ; b  < b_end ;   )
			{
			(*state)((RAWCH *)b);
			process(super,(RAWCH *)b);
			convert(out,(RAWCH *)b,CHOPLEN);
			b += RECLEN;
			}
		if ( 0 == dirty )
			dirty = dirty_test(rd);
		blocks++;
		}
	if ( rd  && blocks < LIMIT )
		continue;
	/* now we have either hit the block limit  or end of input */
	bclose(out);
	sprintf(oname,"\\CHRYSsor.%03d",nf++);
	unlink(oname);
	if ( dirty )
		{
		/* we must sort the file */
		
		sprintf(buffer,"%s %s /S(1,20,c,a)f(fix,%d)VERBOSE DUPOUT", 
			fname,oname,CHOPLEN);
		printf("\r%s %s\n\n",SORT,buffer);
		fflush(stdout);
		spawn(SORT,buffer);
		unlink(fname);
		}
	else
		{
		/* file is already in proper order */
		printf("rename %s %s\n",fname,oname);
		rename(fname,oname);
		}
	(void) dirty_test(0);
	dirty=blocks=0;
	if ( rd < CHRYSLERBLOCKSIZE || nf == MERGEORDER )
		break;
	sprintf(fname,"\\CHRYSraw.%03d",nf );
	printf("\n\n%s\n\n",fname);
	out = bopen(fname,"w",CHRYSLERBLOCKSIZE);

	
	}

if ( argc == 1 )
	tapecmd(in->fh,"TU",2);

bclose(in);
bclose(super);

if ( argc > 2 )
	{
	putchar(7);
	putchar(7);
	putchar(7);
	putchar(7);
	sprintf(buffer,"--Delete\t%s Yes \316o",iname2);
	if ( 'Y' == ltsgt(buffer) )
		unlink(iname2);
	}


strcpy(buffer,"super.tmp super.ch1 /S(1,20,c,a)f(fix,40)VERBOSE DUPOUT"); 
printf("\r%s %s\n\n",SORT,buffer);
fflush(stdout);
spawn(SORT,buffer);

unlink("super.tmp");

merge_file("pacnchr.his","super.ch1");	/* new 9-20-95 */

spawn(INORDER,"-c pacnchr.his 40 20 0");	/* new 9-20-95 */

putchar(7);
putchar(7);
putchar(7);
putchar(7);
putchar(7);
putchar(7);
putchar(7);
putchar(7);

fputs("\n\n\nPAUSE",stdout);

gets(buffer);

prepare_forward_file();

#if 1
putchar(7);
putchar(7);
putchar(7);
putchar(7);
putchar(7);
putchar(7);
putchar(7);

fputs("merge_it()......",stdout);
while ( 13 != getks() )
	;
#endif
merge_it(nf);

sprintf(buffer,"-c price.ch1 %d 20 0",sizeof(CH200));
printf("\r%s %s\n",INORDER,buffer);
fflush(stdout);
spawn(INORDER,buffer);
putchar(7);
putchar(7);
putchar(7);
putchar(7);
putchar(7);
putchar(7);
putchar(7);
putchar(7);

exit(0);
}

int	cmp(MFILE *a,MFILE *b)
{
return	strncmp(a->record+KEYOFF,b->record+KEYOFF,KEYLEN);
}

int cread_it(struct hxx *x)
/* Returns number of chars in x->buffer */
{
char *uncomp();
char	*save;
int bytesread;

if (x->bytesleft >= 0 && x->bytesleft < x->len)		/* Possibly need more */
	{
	if (x->bytesleft)
		memcpy(x->readitbuf,x->nextrecord,x->bytesleft);
	bytesread=bread(x->r,x->readitbuf+x->bytesleft,x->len);
	x->bytesleft+=bytesread;
	x->nextrecord=x->readitbuf;
	}

if (x->bytesleft < 1 )
	{
	bclose(x->r);
	return 0;
	}

x->nextrecord=uncomp(x->unc_buffer,save=x->nextrecord,x->len);

x->bytesleft -= ( x->nextrecord -save );
return x->len;
}
void prepare_forward_file(void)
{
struct hxx  shxx;
BFILE *out,*bopen();

memset(&shxx,'\0',sizeof(shxx));

shxx.len = 40;

shxx.r = bopen("pacnchr.his","r",8192);
if ( 0 == shxx.r )
	{
	puts("Unable to open pacnchr.his");
	exit(1);
	}

out = bopen("pacnchr.tmp","w",8192);

if ( 0 == out )
	{
	puts("Unable to create pacnchr.tmp");
	exit(1);
	}

shxx.r = ( 40 == cread_it(&shxx)) ? shxx.r : 0;

while ( 0 != shxx.r )
	{
	CW(24,1,40);
	bwrite(out,shxx.unc_buffer+20,20);
	bwrite(out,shxx.unc_buffer,20);
	shxx.r = ( 40 == cread_it(&shxx)) ? shxx.r : 0;
	}

bclose(shxx.r);
bclose(out);


strcpy(buffer,"pacnchr.tmp pacnchr.for /S(1,20,c,a)f(fix,40)VERBOSE DUPOUT"); 
printf("\r%s %s\n\n",SORT,buffer);
spawn(SORT,buffer);
unlink("pacnchr.tmp");

}
int merge_file(char *dname, char *sname)
{
char	buffer[80];
struct hxx dhxx, shxx;
BFILE *out,*bopen();
int	j, cond;

memset(&dhxx,'\0',sizeof(struct hxx));
memset(&shxx,'\0',sizeof(struct hxx));

dhxx.len = shxx.len= 40;

dhxx.r=bopen(dname,"r",8192);
shxx.r=bopen(sname,"r",8192);

if ( 0 == dhxx.r )
	{
	fprintf(stderr,"Unable to open %s\n",dname);
	return	1;
	}

if ( 0 == shxx.r )
	{
	fprintf(stderr,"Unable to open %s\n",sname);
	return	1;
	}

out = bopen("pacnchr.tmp","w",8192);


if ( 0 == out )
	{
	fputs("Unable to create pacn.tmp\n",stderr);
	return	1;
	}

dhxx.r = ( 40 == cread_it(&dhxx)) ? dhxx.r : 0;
shxx.r = ( 40 == cread_it(&shxx)) ? shxx.r : 0;

while ( 0 != shxx.r && 0 != dhxx.r )
	{
	CW(24,1,40);
	cond = strncmp(shxx.unc_buffer,dhxx.unc_buffer,40);
	if ( cond > 0 )
		{
		j = compress(buffer,dhxx.unc_buffer,40);
		bwrite(out,buffer,j);
		dhxx.r = ( 40 == cread_it(&dhxx)) ? dhxx.r : 0;
		continue;
		}
	if ( cond < 0 )
		{
		j = compress(buffer,shxx.unc_buffer,40);
		bwrite(out,buffer,j);
		shxx.r = ( 40 == cread_it(&shxx)) ? shxx.r : 0;
		continue;
		}
	j = compress(buffer,shxx.unc_buffer,40);
	bwrite(out,buffer,j);
	shxx.r = ( 40 == cread_it(&shxx)) ? shxx.r : 0;
	dhxx.r = ( 40 == cread_it(&dhxx)) ? dhxx.r : 0;
	}
while ( 0 != shxx.r )
	{
	CW(24,1,40);
	j = compress(buffer,shxx.unc_buffer,40);
	bwrite(out,buffer,j);
	shxx.r = ( 40 == cread_it(&shxx)) ? shxx.r : 0;
	}
while ( 0 != dhxx.r )
	{
	CW(24,1,40);
	j = compress(buffer,dhxx.unc_buffer,40);
	bwrite(out,buffer,j);
	dhxx.r = ( 40 == cread_it(&dhxx)) ? dhxx.r : 0;
	}

bclose(out);

unlink("pacnchr.old");
rename("pacnchr.his","pacnchr.old");
rename("pacnchr.tmp","pacnchr.his");


return	0;
}
void merge_it(int nf)
{
char	local[CHOPLEN+8];
void reheap();
int	i,j,rd40,cond,rdforw40,reheap_flag;
static MFILE	mf[MERGEORDER];
MFILE *m=mf;
BFILE	*forw,*out;
struct hxx  shxx;
char	sbuff[64];
char	forwbuff[64];
char	last_pcn[40];
union {
	CH200 c;
	char	buff101[CHOPLEN];
	} temp,t2;

last_pcn[0] = '\0';

for ( i = 0; i < nf ; i++,m++ )
	{
	sprintf(m->fname,"\\CHRYSsor.%03d",i);
	m->in = bopen(m->fname,"r",CHRYSLERBLOCKSIZE);
	if ( 0 == m->in )
		{
		puts("Unable to open merge file");
		exit(1);
		}
	if ( CHOPLEN != bread(m->in,m->record,CHOPLEN) )
		{
		puts("Unable to read merge file");
		exit(1);
		}
	}

qsort(mf,nf,sizeof(MFILE),cmp);

m = mf;

memset(&shxx,'\0',sizeof(shxx));
shxx.len = 40;
shxx.r = bopen("pacnchr.his","r",8192);	/* backward reference file */

forw = bopen("pacnchr.for","r",8192);

/* now m points to the lowest reord */

out = bopen("price.ch1","w",200*(8+CHOPLEN));
binary(out->fh);

printf("\n\n%d\n\n",nf);


if ( 40 != (rd40 = cread_it(&shxx) ))
	{
	puts("Read error pacnchr.his supercession file.");
	exit(1);
	}

if ( 40 != ( rdforw40 = bread(forw,forwbuff,40)))
	{
	puts("Read error pacnchr.for supercession file.");
	exit(1);
	}


while ( nf )
	{
	CW(24,1,10);
	memset(temp.buff101,' ',sizeof(temp.buff101));
	/* -------------------------------------
	decide whether to use the forw record or the m->record 
	----------------------------------------*/
	cond = (40 == rdforw40) ? strncmp(m->record+KEYOFF,forwbuff,KEYLEN):
		-1 ;
	if ( 0 == cond )
		{
		memcpy(temp.buff101,m->record,CHOPLEN);
		reheap_flag = 1;
		rdforw40 = bread(forw,forwbuff,40);	
		}
	else if ( cond < 0 )
		{
		memcpy(temp.buff101,m->record,CHOPLEN);
		reheap_flag = 1;
		}
	else
		{
		reheap_flag = 0;
		memcpy(&temp.c.chpartnum,forwbuff,20);
		temp.c.chpartnum.chrysler.chryslerflag='C';
		memcpy(&temp.c.chrul,forwbuff+20,20);
		temp.c.chrul.chrysler.chryslerflag='C';
		temp.c.chrectype[0]='C';
		rdforw40 = bread(forw,forwbuff,40);	
		}

	/* -------------------------------------------------

	now make sure to skip ahead in forward file

	-------------------------------------------------------*/
	for ( ;; )
		{
		cond = (40 == rdforw40) ? 
			strncmp(m->record+KEYOFF,forwbuff,KEYLEN): -1 ;
		if ( 0 > cond )
			break;
		rdforw40 = bread(forw,forwbuff,40);	
		}
			

	/*----------------------------------------------------
	now decide which record to output
	-----------------------------------------------------*/
	
	do {	/*resynchronize if necessary */
		cond = (40 == rd40 ) ?
			strncmp(shxx.unc_buffer,&temp.c.chpartnum,KEYLEN)
			:	1 ;
		if ( cond < 0 )
			{
			memset(t2.buff101,' ',sizeof(t2.buff101));
			memcpy(&t2.c.chpartnum,shxx.unc_buffer,20);
			t2.c.chpartnum.chrysler.chryslerflag='C';
			memcpy(&t2.c.chbackward,shxx.unc_buffer+20,20);
			t2.c.chbackward.chrysler.chryslerflag='C';
			t2.c.chrectype[0]='C';
			j = compress(local,t2.buff101,CHOPLEN);
			if ( 0 != strncmp(last_pcn,shxx.unc_buffer,20) )
				bwrite(out,local,j);
			memcpy(last_pcn,shxx.unc_buffer,20);
			rd40 = cread_it(&shxx);
			}
		}	while ( cond < 0 );

	
	if ( 0 == cond )
		{
		memcpy(&temp.c.chbackward,shxx.unc_buffer+20,20);
		temp.c.chbackward.chrysler.chryslerflag='C';
		memcpy(last_pcn,shxx.unc_buffer,20);
		}
	j = compress(local,temp.buff101,CHOPLEN);
	bwrite(out,local,j);

	if ( 0 != reheap_flag )
		{
		if ( CHOPLEN != bread(m->in,m->record,CHOPLEN) )
			{
			bclose(m->in);
			unlink(m->fname);
			nf--;
			memcpy(m,m+nf,sizeof(MFILE));
			printf("\n\n%d\n\n",nf);
			}
		reheap(mf,nf,sizeof(MFILE),cmp);
		}
	}

bclose(out);
bclose(forw);
bclose(shxx.r);

}


static	exchange(register char *a,register char *b,int n)
{
register char	t;
char	*end = a +n;

for ( ; a < end ; a++,b++ )
	{
	t = *a;
	*a = *b;
	*b = t;
	}
}


void reheap(array,n,size,cmp)
char	*array;
int	n;	/* number of items */
int	size;	/* size in bytes of each item */
int	(*cmp)();	/* comparison function */
{
int i,j;

	
for(i=0;2*i<n;i=j)
	{
	j=2*i;
	if(j<n-1 && (*cmp)(array+(j*size),array+(j+1)*size) > 0 )
			j++;
	if ( (*cmp)(array+(i*size),array+(j*size)) <= 0 )
		break;

	exchange(array+(j*size),array+(i*size),size);
	}
}
void dummy(p)
RAWCH *p;
{
}

void dump(p)
RAWCH *p;
{
static int i;

i++;
if ( i < 1000 )
	return;

i = 0;

printf("	r_chrectype[%1.1s]\n",p->	r_chrectype);
printf("	r_chpartnum[%10.10s]\n",p->	r_chpartnum);
printf("	r_chpartname[%9.9s]\n",p->	r_chpartname);
printf("	r_chpartdescr[%30.30s]\n",p->	r_chpartdescr);
printf("	r_chchngsym[%1.1s]\n",p->	r_chchngsym);
printf("	r_chloccode[%1.1s]\n",p->	r_chloccode);
printf("	r_chaplcode[%1.1s]\n",p->	r_chaplcode);
printf("	r_chpromo[%2.2s]\n",p->	r_chpromo);
printf("	r_chretelig[%1.1s]\n",p->	r_chretelig);
printf("	r_chrul[%12.12s]\n",p->	r_chrul);
printf("	r_chmsq[%3.3s]\n",p->	r_chmsq);
printf("	r_chparttype[%10.10s]\n",p->	r_chparttype);
printf("	r_chdiscode[%1.1s]\n",p->	r_chdiscode);
printf("	r_chtaxcode[%1.1s]\n",p->	r_chtaxcode);
printf("	r_chunitofmeasure[%1.1s]\n",p->	r_chunitofmeasure);
printf("	r_chmerchclass[%1.1s]\n",p->	r_chmerchclass);
printf("	r_chpricesym[%2.2s]\n",p->	r_chpricesym);
printf("	r_chlist[%7.7s]\n",p->	r_chlist);
printf("	r_chcost[%7.7s]\n",p->	r_chcost);
printf("	r_chqp2[%7.7s]\n",p->	r_chqp2);
printf("	r_chqp3[%7.7s]\n",p->	r_chqp3);
printf("	r_chqp4[%7.7s]\n",p->	r_chqp4);
printf("	r_chwhlsale[%7.7s]\n",p->	r_chwhlsale);
printf("	r_chdson[%7.7s]\n",p->	r_chdson);
printf("	r_chfleetallow[%7.7s]\n",p->	r_chfleetallow);
printf("	r_chmodyearin[%4.4s]\n",p->	r_chmodyearin);
printf("	r_chmodyearout[%4.4s]\n",p->	r_chmodyearout);
printf("	r_chcanyear[%4.4s]\n",p->	r_chcanyear);
printf("	r_chrulingdate[%8.8s]\n",p->	r_chrulingdate);
printf("	r_chpricedate[%8.8s]\n",p->	r_chpricedate);
printf("	r_chreturndescr[%1.1s]\n",p->	r_chreturndescr);
printf("	r_chjeepindicator[%1.1s]\n",p->	r_chjeepindicator);
printf("	r_chdistribcode[%1.1s]\n",p->	r_chdistribcode);
printf("	r_chweight[%9.9s]\n",p->	r_chweight);
printf("	r_chshelflife[%4.4s]\n",p->	r_chshelflife);
printf("	r_chpdlength[%7.7s]\n",p->	r_chpdlength);
printf("	r_chpdwidth[%7.7s]\n",p->	r_chpdwidth);
printf("	r_chpdheight[%7.7s]\n",p->	r_chpdheight);
printf("	r_chprodline[%1.1s]\n",p->	r_chprodline);
printf("	r_chrepairgrp[%7.7s]\n",p->	r_chrepairgrp);
printf("	r_chcountryoforigin[%3.3s]\n",p->	r_chcountryoforigin);
printf("	r_chmsdsindicator[%1.1s]\n",p->	r_chmsdsindicator);
}
