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

char dolist_[] "~|^`dolist.c:	3.2";
/*
	Parses delta list as used by -i/-x args of get, for example.
	Syntax of list:

		<list>	::=  <range> | <list> , <range>
		<range>	::=  <delta> | <delta> - <delta>
		<delta>	::=  <rel> | <rel> . <lev>

	Delta numbers are checked for validity.  For each delta,
	enter() is called.  The caller of dolist() should define his
	own enter().

	Argument "ch" is converted to upper-case and passed on to enter().
	This strange arrangement is vestigial.
*/

struct Range {
	int Rr1;
	int Rl1;
	int Rr2;
	int Rl2;
};

char *extlist;		/* used by routines in this file only */

dolist(pkt,list,ch)
struct Packet *pkt;
char list[], ch;
{
	register int r, l, maxl;
	struct Range range;

	ch =+ 'A' - 'a';
	extlist = list;

	while(getrange(pkt,&range))
		for(r=range.Rr1; r<=range.Rr2; r++) {
			maxl = maxlev(pkt,r);
			for(l=(r==range.Rr1?range.Rl1:1); l<=maxl; l++)
				if(r == range.Rr2 && l > range.Rl2) continue;
				else enter(pkt,ch,r,l);
		}
}


getrange(pkt,rn)
register struct Packet *pkt;
register struct Range *rn;
{
	rn->Rr1 = rn->Rl1 = rn->Rr2 = rn->Rl2 = -1;
	if(*extlist == '\0') return(0);

	getrl(pkt,&rn->Rr1,&rn->Rl1);
	if(*extlist == '-') {
		extlist++;
		getrl(pkt,&rn->Rr2,&rn->Rl2);
		if(pkt->Pverbose&DOLIST)
		  printf("%d.%d-%d.%d\n",rn->Rr1,rn->Rl1,rn->Rr2,rn->Rl2);
		if(!gt(&rn->Rr2,&rn->Rr1))
			fatal("bad range (222)");
	}
	else {
		rn->Rr2 = rn->Rr1;
		rn->Rl2 = rn->Rl1;
		if(pkt->Pverbose&DOLIST) printf("%d.%d\n",rn->Rr1,rn->Rl1);
	}
	if(*extlist == ',') extlist++;
	else if(*extlist != '\0') fatal("delta list syntax (223)");
	return(1);
}


getrl(pkt,rp,lp)
register struct Packet *pkt;
register int *rp, *lp;
{
	*rp = getnum();
	if(*rp < 1 || *rp > maxrel(pkt) || *rp > pkt->Prel)
		fatal("invalid release (224)");

	if(*extlist == '.') {
		extlist++;
		*lp = getnum();
		if(*lp < 1 || *lp > maxlev(pkt,*rp))
			fatal("invalid level (225)");
	}
	else if((*lp=maxlev(pkt,*rp)) == 0) fatal("vacant release (226)");
}


getnum()
{
	char num[50];
	register char *n;

	for(n=num; *extlist>='0' && *extlist<='9'; extlist++)
		*n++ = *extlist;
	if(n == num) fatal("delta list syntax (223)");
	*n = '\0';
	return(patoi(num));
}
