⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sort5.c

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 C
📖 第 1 页 / 共 4 页
字号:
		do		{			i = (*tp)->rn;			if (getline(tfile[i], (*tp)->rp, maxrec, 1, tag) == 0)			{				doclose(tfile[i], setfil(i + a));				if (--nf <= 0)					break;				++tp;				bonus = cmpsave(nf);			}			else				insert(tp, nf);		} while (j && (*compare)((*tp)->rp, save) == 0);	}	for (i = a; i < b; i++)	{		if (i >= eargc)			(void) unlink(setfil(i));	}	doclose(os, catgets(_m_catd, NL_SETN, 13, "merging"));	free(fbuffer);	free(buffer);	free(save);}/*======================== comparison routines ==============================*//* * cmpa -- compare two whole lines */cmpa(pa, pb)register unsigned char *pa;register unsigned char *pb;{	while(*pa == *pb++)		if(*pa++ == '\n')			return(0);	return(		*pa == '\n' ? fields[0].rflg:		*--pb == '\n' ?-fields[0].rflg:		*pb > *pa   ? fields[0].rflg:		-fields[0].rflg	);}/* * cmp -- compare two lines using fields */intcmp(line1, line2)char *line1;	/* pointer to a line */char *line2;	/* pointer to the other line */{	int result;		/* to retain result of comparison */	int fieldno;		/* index of field under consideration */	char *sfield1;		/* start of field in line1 */	char *efield1;		/* end of field in line1 */	char *sfield2;		/* start of field in line2 */	char *efield2;		/* end of field in line2 */	for (fieldno = (nfields > 0); fieldno <= nfields; fieldno++)	{		register struct field *fp; /* pointer to field description */		fp = &fields[fieldno];		/*		 * position to start and end of fields		 */		if (fieldno != 0)		{			efield1 = skip(line1, fp, 1);			sfield1 = skip(line1, fp, 0);			efield2 = skip(line2, fp, 1);			sfield2 = skip(line2, fp, 0);		}		else		{			efield1 = eol(line1);			sfield1 = line1;			efield2 = eol(line2);			sfield2 = line2;		}		/*		 * Do the comparison for the field that starts including		 * sfield[12] and ends including efield[12] in lines[12].		 */		if (result=(*fp->fcmp)(fp, sfield1, efield1, sfield2, efield2))			return fp->rflg * result;	}	/*	 * up to now all fields have compared equal, try to compare the	 * whole line to break the tie if not discarding duplicates anyway	 */	if (uflg)		return(0);	return(cmpa(line1, line2));}/* * tagcmp -- compare two tagged records. */tagcmp(r1, r2)register char *r1, *r2;{	int result;	register struct field *fp;	int fieldno;	int offset;		/* offset of record pointer */	for (fieldno = (nfields > 0);  fieldno <= nfields; fieldno++) {		fp = &fields[fieldno];		offset = fieldno + 1 - (nfields > 0);				if (result = strcmp(r1 + ((short *)r1)[offset], r2 + ((short *)r2)[offset]))			return fp->rflg * -result;	}	return 0;}#define qsexc(p,q)	t = *p; *p = *q; *q = t#define qstexc(p,q,r)	t = *p; *p = *r; *r = *q; *q = tqksort(a, l)char **a;char **l;{	register char **i;	register char **j;	register char **lp;	register char **hp;	char **k;	int c;	int delta;	char *t;	unsigned n;start:	if ((n = l - a) <= 1)		return;	n /= 2;	if (n >= MTHRESH)	{		lp = a + n;		i = lp - 1;		j = lp + 1;		delta = 0;		c = (*compare)(*lp, *i);		if (c < 0)			--delta;		else if (c > 0)			++delta;		c = (*compare)(*lp, *j);		if (c < 0)			--delta;		else if (c > 0)			++delta;		if ((delta /= 2) && (c = (*compare)(*i, *j)))			if (c > 0)				n -= delta;			else				n += delta;	}	hp = lp = a + n;	i = a;	j = l - 1;	for (;;)	{		if (i < lp)		{			if ((c = (*compare)(*i, *lp)) == 0)			{				--lp;				qsexc(i, lp);				continue;			}			if (c < 0)			{				++i;				continue;			}		}loop:		if (j > hp)		{			if ((c = (*compare)(*hp, *j)) == 0)			{				++hp;				qsexc(hp, j);				goto loop;			}			if (c > 0)			{				if (i == lp)				{					++hp;					qstexc(i, hp, j);					i = ++lp;					goto loop;				}				qsexc(i, j);				--j;				++i;				continue;			}			--j;			goto loop;		}		if (i == lp)		{			if (uflg)				for (k = lp; k < hp;)					**k++ = '\0';			if (lp - a >= l - hp)			{				qksort(hp + 1, l);				l = lp;			}			else			{				qksort(a, lp);				a = hp + 1;			}			goto start;		}		--lp;		qstexc(j, lp, i);		j = --hp;	}}/*===================== help functions for comparisons ======================*//* * skip -- skip in a record according to field specifications */char *skip(p, fp, j)register char *p;	/* line to work on */struct field *fp;	/* field to isolate */int j;			/* 1 means get the end of the field, 0 means start */{	register i;	register char tbc;	if ((i = fp->m[j]) < 0)		/* can only happen for j = 1! */		return(eol(p));	/*	 * get to correct field, handling tabchar or spaces	 */	if ((tbc = tabchar) != 0)		while (--i >= 0)		{			while (*p != tbc)				if (*p != '\n')					p++;				else					goto ret;			if (i > 0 || j == 0)				p++;		}	else		while (--i >= 0)		{			while (blank(*p))				p++;			while (!blank(*p))				if (*p != '\n')					p++;				else					goto ret;		}	/*	 * skip blanks	 */	if (fp->bflg[j])	{		if (j == 1 && fp->m[j] > 0)			p++;		while (blank(*p))			p++;	}	/*	 * get to byte position within field	 */	i = fp->n[j];	while((i-- > 0) && (*p != '\n'))		p++;ret:	return(p);}/*  * settag -- setup the tag fields for a record */char *settag(tp, start, end, amount)short *tp;		/* pointer to tag area */char  *start;		/* pointer to record area */char  *end;		int    amount;	{	char *save = (char *)tp;	int fieldno;	char charsave;	char *ep;	struct field *fp;	int len;	for (fieldno = (nfields > 0) ; fieldno <= nfields; fieldno++) {		fp = &fields[fieldno];		/*		 * set offset to start of field in pointer area		 */		*end++ = '\0';		amount--;		*++tp  = (short)(end - save);		ep     = skip(start, fp, 1);		/*		 * nul terminate for strxfrm		 */		charsave = *ep;				*ep      = '\0';		if ((len = strxfrm(end, skip(start, fp, 0), amount)) > amount) {			*ep = charsave;			return (char *)0;		}		/*		 * restore character and bump pointers		 */		*ep     = charsave;		end    += len;		amount -= len;	}	if (amount > 0)		*end++ = '\0';	else		return (char *)0;	/*	 * first field is the length of the entire record 	 */	*(short *)save = end - save;		return end;}/* * cmpsave -- save result of comparison for later use */cmpsave(n)register int n;{	register int award;	if (n < 2)		return (0);	for (n++, award = 0; (n >>= 1) > 0; award++)	;	return (award);}/* * asciicmp -- compare ascii strings */intasciicmp(fp, s1, e1, s2, e2)struct field *fp;		/* pointer to field description */register char *s1;		/* beginning of first field */char *e1;			/* end of first field */register char *s2;		/* beginning of second field */char *e2;			/* end of second field */{	register char *ignore;	/* ptr to ignore table */	register char *code;	/* ptr to code conversion */	int a;	code = fp->code;	ignore = fp->ignore;	for (;;)	{		/*		 * skip ignore characters		 */		while (ignore[*s1])			s1++;		while (ignore[*s2])			s2++;		if (s1 >= e1 || *s1 == '\n')			if (s2 < e2 && *s2 != '\n')				return 1;			else				break;		if (s2 >= e2 || *s2 == '\n')			return -1;		if (a = ((int)code[*s2++] & 0xFF) - ((int)code[*s1++] & 0xFF))			return a;	}	/*	 * the two fields compare equal	 */	return 0;}/* * intlcmp -- international collation */intintlcmp(fp, s1, e1, s2, e2)struct field *fp;		/* pointer to field description */char *s1;			/* beginning of first field */char *e1;			/* end of first field */char *s2;			/* beginning of second field */char *e2;			/* end of second field */{	int result;		/* result of collation */	char save1, save2;	/* save characters to allow nul terminarion */	/*	 * "ignore" is specified in the collation itself	 * NOT_YET: "fold" is done by converting codes to upper case	 */	/*	 * as e1/e2 are to be compared too:	 */	save1 = *++e1;	save2 = *++e2;	*e1 = *e2 = '\0';	result = strcoll(s2, s1);	*e1 = save1;	*e2 = save2;	return result;}/* * numcmp -- numerical comparison of two fields *	bytewise comparison of two numbers of the *	form [-][0-9]*\.[0-9]* */intnumcmp(fp, s1, e1, s2, e2)struct field *fp;		/* pointer to field description */char *s1;			/* beginning of first field */char *e1;			/* end of first field */char *s2;			/* beginning of second field */char *e2;			/* end of second field */{	static char radix;	/* radix char to use, initially zero */	int sa;			/* sign of number in first line */	int sb;			/* sign of number in second line */	register char *ipa;	/* tmp ptr into first number */	register char *ipb;	/* tmp ptr into second number */	char *jpa;		/* save tmp ptr into first number */	char *jpb;		/* save tmp ptr into second number */	int result = 0;		/* result of comparison */	/*	 * set radix character	 */	if (radix == '\0')	{		if ((radix = *nl_langinfo(RADIXCHAR)) == '\0')			radix = '.';	}	/*	 * evaluate sign	 */	sa = sb = 1;	if (*s1 == '-')	{		s1++;		sa = -sa;	}	if (*s2 == '-')	{		s2++;		sb = -sb;	}	/*	 * skip to end of number before the decimal point	 */	for (ipa = s1; ipa < e1 && isdigit(*ipa); ipa++)	;	for (ipb = s2; ipb < e2 && isdigit(*ipb); ipb++)	;	/*	 * save pointers for scan after decimal point	 */	jpa = ipa;	jpb = ipb;	if (sa == sb)		while (ipa > s1 && ipb > s2)			if (*--ipb - *--ipa != 0)				result = *ipb - *ipa;	while (ipa > s1)		if (*--ipa != '0')			return(-sa);	while (ipb > s2)		if (*--ipb != '0')			return(sb);	if (result)		return (result * sa);	if (*(s1 = jpa) == radix)		s1++;	if (*(s2 = jpb) == radix)		s2++;	if (sa == sb)		while (s1 < e1 && isdigit(*s1)		   && s2 < e2 && isdigit(*s2))			if ((result = *s2++ - *s1++) != 0)				return(result*sa);	while (s1 < e1 && isdigit(*s1))		if (*s1++ != '0')			return(-sa);	while (s2 < e2 && isdigit(*s2))		if (*s2++ != '0')			return(sb);	return 0;}intmonthcmp(fp, s1, e1, s2, e2)struct field *fp;		/* pointer to field description */char *s1;			/* beginning of first field */char *e1;			/* end of first field */char *s2;			/* beginning of second field */char *e2;			/* end of second field */{	return (month(s1) - month(s2));}/* * month -- return numerical match value for a month */month(s)char *s;{	static char *months[] = { "jan", "feb", "mar", "apr", "may", "jun",				  "jul", "aug", "sep", "oct", "nov", "dec" };	register char *t;	register char *u;	register i;	register char *f = fold + 128;	for (i = 0; i < sizeof(months) / sizeof(*months); i++)	{		for (t = s, u = months[i]; f[*t++] == f[*u++]; )			if (*u == 0)				return(i);	}	return(-1);}/*====================== file handling routines =============================*/

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -