Metropoli BBS
VIEWER: indexv.c MODE: TEXT (ASCII)
/* Copyright (C) 1993 by Thomas Glen Smith.	All Rights Reserved. */
/* indexv APL2 V1.0.0 ***************************************************
* Called by transpot.                                                   *
* Left points to an APL variable from, and perhaps to, which values are *
* to be indexed.  Indices identifies the index values to be used.  If   *
* rite isn't NULL, it contains values to be stored in the indexed	  *
* elements of left.  The actual shape of left is ignored, and the	  *
* indices must be chosen as though left were a vector.				  *
************************************************************************/
#define INCLUDES APLCB
#include "includes.h"
Aplcb indexv(left,indices,rite)
Aplcb left, indices, rite;
{
	Dtacopy; Errinit; Errstop; Getcb; Matchok; Temp; Vectin;
	extern int aplerr, indxorg;
	Aplcb ixcb,out=NULL;
	int datatyp,i,*ix,j,riteincr=0;
	char *cp,*dp,*outdata,*ritedata;

	if (errinit())
		return(errstop(0,left,indices,rite));
	if (rite == NULL)
		ritedata = NULL;
	else {
		if (!matchok(&left,&rite,APLMASK+APLAPL))
			return(errstop(0,NULL,indices,NULL));
		if (rite->aplcount > 1) {
			if (rite->aplcount != indices->aplcount)
				return(errstop(35,left,indices,rite)); /* bad data count */
			riteincr=rite->aplsize;
		}
		ritedata = rite->aplptr.aplchar;
	}
	if (NULL == (ixcb=temp(vectin(indices)))) /* get integer vector */
		return(errstop(0,left,rite,NULL));
	datatyp = left->aplflags & (APLMASK | APLAPL);
	out=getcb(NULL,ixcb->aplcount,datatyp + APLTEMP,1,NULL);
	outdata = out->aplptr.aplchar;
	ix = ixcb->aplptr.aplint;
	for(i=0; i<ixcb->aplcount; i++) {
		j=*ix++ - indxorg; /* next index */
		if (j > left->aplcount - indxorg || j < 0)
			aplerr=34; /* index out of range */
		else {
			cp = left->aplptr.aplchar + left->aplsize * j;
				/* cp is ptr to data to update/extract */
			if (rite != NULL) { /* is there update data? */
				dp=dtacopy(cp,ritedata,1,1,datatyp); /* update */
				ritedata += riteincr; /* increment update data ptr */
			}
			outdata=dtacopy(outdata,cp,1,1,datatyp); /* extract */
		}
	}
	endoper(ixcb);
	return(errstop(0,left,rite,out));
}
[ RETURN TO DIRECTORY ]