Metropoli BBS
VIEWER: outrprdp.c MODE: TEXT (ASCII)
/*Copyright (C) 1992, 1994 by Thomas Glen Smith.  All Rights Reserved.*/
/* outrprdp APL2 V1.0.0 ************************************************
* Called by execjota, execjotc, and execjotd.  Differs from outrprd in *
* that it expects oper to be a procedure call rather than a function.  *
* Does outer product for all matching data types, or of mixed data     *
* types where one is convertible to the other, i.e. outrprd will never *
* be invoked with either left or rite of type APLCHAR, and the other   *
* something else.  If left is of type APLCHAR, rite will be also.      *
***********************************************************************/
#define INCLUDES APLCB
#include "includes.h"
Aplcb outrprdp(oper,left,rite)
void (*oper)();
Aplcb left,rite;
{
	Chrcopy; Dyadrup; Errstop; Getcb; Intcopy; Matchok;
	int cnt,datacnt,datatyp,iw,*ip,jw,otype,rank;
     Aplcb out=NULL;
     char *ldata,*odata,*rdata;
	double wrkd[2];

	if (!matchok(&left,&rite,APLMASK))
		return(NULL);
	datacnt=left->aplcount*rite->aplcount;
	datatyp=left->aplflags & APLMASK;
	otype = (APLCHAR == datatyp) ? APLINT : datatyp;
	rank = left->aplrank + rite->aplrank;
	out = getcb(NULL, datacnt, otype + APLTEMP, rank, NULL);
	if (rank > 1) { /* set dimensions */
		ip = intcopy(out->apldim, left->apldim, left->aplrank, 1);
		ip = intcopy(ip, rite->apldim, rite->aplrank, 1);
	}
	if (datacnt) {
		cnt = 0; /* Count of output elements finished. */
     	odata = out->aplptr.aplchar;
          ldata = left->aplptr.aplchar;
		iw = left->aplcount;
		while(0 < iw--) {
	          rdata = rite->aplptr.aplchar;
			jw = rite->aplcount;
			while(0 < jw--) {
				*(wrkd+1) = 0e0; /* Initialize. */				
               	(*oper)(ldata,rdata,(char*)wrkd);
                    rdata += rite->aplsize;
				if (*(wrkd+1) != 0e0 && otype != APLCPLX) {
					otype = APLCPLX;
					out = dyadrup(out,cnt); /* Convert to complex. */
					odata = out->aplptr.aplchar + cnt * out->aplsize;
				}
				odata = chrcopy(odata,(char*)wrkd,out->aplsize,1);
				cnt++; /* Bump count of elements finished. */
               }
			ldata += left->aplsize;
		}
     }
	return(errstop(0,left,rite,out));
}
[ RETURN TO DIRECTORY ]