#include "../sccshead/sfile.h"
#include "../sccshead/sint.h"

# define ONEYEAR 31536000L

char dodelt__[] "~|^`dodelt.c:	3.14";
/*
	Routine to process the delta table and to fill in the apply array
	(set up by doreltab()).  For each delta, there is an "Apply"
	structure.  "Adt" is the pseudo date/time of the delta; that is,
	instead of actual binary date/times, monotonically descending
	integers are used.  The "Acode" is

		EMPTY	= not filled in yet
		APPLY	= delta to be applied
		NOAPPLY	= delta not to be applied

	Once "Acode" is filled in, it is not overwritten.  This makes
	include/exclude work right.

	Both include/exclude on a get and deltas which include/exclude
	are supported by this function, although only the former is
	available to users.

	This function also writes the l-file.

	The second argument is used to determine whether
	the ``Non-prop'' message should be printed.
*/

int pseudo, dlfd;
char *acklist;
int ackrel, acklev, acknowl;
long timenow;

dodeltab(pkt,prtnprp)
register struct Packet *pkt;
{
	register struct Deltab *dt;
	int wantie;
	long maxrl;
	long timediff;
	register struct Apply *ap;
	int eod;

	if (pkt->Pupd) mkdeltab(pkt);

	maxrl.hiword = 1;
	maxrl.loword = 0;
	pseudo = 32767;
	time(&timenow);
	eod = rdrec(pkt);
	dt = pkt->Pibuf.Irecptr;
	if (eod != 1) {
		timediff = timenow - dt->Ddatetime;
		if (timediff < 0)
			fatal("clock set wrong!!! (303)");
		if (timediff > ONEYEAR && pkt->Pverbose&WARNING)
			msg2("Clock may be set wrong! (306)\n");
	}
	for (; eod!=1 && (dt=pkt->Pibuf.Irecptr)->Drel; eod=rdrec(pkt)) {
		ap = &pkt->Papply[dt->Drel][dt->Dlev];
		switch(dt->Dtype) {
		case 'U':
		case 'P':
		case 'D':

			if (ap->Acode == APPLY) {
				applyd(pkt,dt,ap,'I',&maxrl);
				wantie = 1;
				continue;
			}
			if (ap->Acode == NOAPPLY) {
				skipd(pkt,dt,ap,'X');
				wantie = 0;
				continue;
			}
			if (acklist && dt->Dtype=='U') {
				ackrel = dt->Drel;
				acklev = dt->Dlev;
				acknowl = 0;
				dolist(pkt,acklist,0);
				if (acknowl) dt->Dtype = 'P';
			}
			if (dt->Drel < pkt->Prel) {
				if (dt->Dtype == 'U') {
					pkt->Punack = 1;
					if (pkt->Pverbose&UNACK)
						printf("Non-prop: %d.%d\n",
						  dt->Drel,dt->Dlev);
				}
				if (dt->Dtype=='U'||dt->Dtype=='P') {
					skipd(pkt,dt,ap,dt->Dtype);
					wantie = 0;
					continue;
				}
			}
			if (gt(&dt->Drel,&pkt->Prel)) {
				skipd(pkt,dt,ap,' ');
				wantie = 0;
				continue;
			}
/*
	WARNING!!!
	When a delta is made after the high-order bit of the time of day
	turns on (Saturday, November 27, 1999  3 AM), the following
	inequality will fail.
*/
			if (dt->Ddatetime > pkt->Pcutoff) {
				skipd(pkt,dt,ap,'C');
				wantie = 0;
				continue;
			}
			applyd(pkt,dt,ap,' ',&maxrl);
			wantie = 1;
			continue;

		case 'I':
			if (wantie && ap->Acode == EMPTY)
				ap->Acode = APPLY;
			continue;

		case 'E':
			if (wantie && ap->Acode == EMPTY)
				ap->Acode = NOAPPLY;
			continue;

		case 'R':
		case 'H':
		case 'C':
			continue;

		default:
			fmterr(pkt);
		}
	}
	if (pkt->Plfile && *pkt->Plfile != 'p') close(dlfd);
	if (pkt->Plev==0 && pkt->Prel>1 && pkt->Pverbose&RLACCESS) {
		msg2(stringf("Release %d is empty; accessing %d.%d (302)\n",
			pkt->Prel,maxrl.hiword,maxrl.loword));
		pkt->Prel = maxrl.hiword;
		pkt->Plev = maxrl.loword;
	}
}


applyd(pkt,dt,ap,reason,rlp)
register struct Packet *pkt;
register struct Deltab *dt;
register struct Apply *ap;
char reason;
int *rlp;
{
	ap->Acode = APPLY;
	ap->Adt = pseudo--;
	dlist(pkt,dt,' ',reason);
	if (!pkt->Pcdt)
		pkt->Pcdt = dt->Ddatetime;
	if (pkt->Plev==0 && gt(&dt->Drel,rlp)) {
		rlp[0] = dt->Drel;
		rlp[1] = dt->Dlev;
	}
}


skipd(pkt,dt,ap,reason)
register struct Packet *pkt;
register struct Deltab *dt;
register struct Apply *ap;
char reason;
{
	if (!ap->Acode) ap->Acode = NOAPPLY;
	ap->Adt = pseudo--;
	dlist(pkt,dt,'*',reason);
}


dlist(pkt,dt,a,reason)
struct Packet *pkt;
register struct Deltab *dt;
char a, reason;
{
	static char parsed;
	register char *p;
	register int n;

	if (!pkt->Plfile) return;
	if (!parsed) {
		if (*pkt->Plfile != 'p')
			dlfd = xcreat(auxf(pkt,'l'),0444);
		else
			dlfd = 1;
		parsed = 1;
	}
	p = deltastr(a,reason,0,dt->Drel,dt->Dlev,&dt->Ddatetime,dt->Dpgmr,
		dt->Dhist);
	p[(n=size(p))-1] = '\n';
	xwrite(dlfd,p,n);
}


fmterr(pkt)
struct Packet *pkt;
{
	fatal(stringf("format error at record %d (42)",pkt->Precno));
}
