/* Copyright (C) 1993 by Thomas Glen Smith. All Rights Reserved. */
/* finda APL2 V1.0.0 ***************************************************
* Called from find to finish processing after initial checks. *
***********************************************************************/
#define INCLUDES APLCB
#include "includes.h"
void finda(left,rite,out,d)
Aplcb left,rite; /* Arguments, already matched by data type. */
Aplcb out; /* Output. */
int d; /* Difference between ranks of left and rite. */
{
Endoper; Getcb; Intcopy;
void findb(Aplcb, Aplcb, Aplcb, Aplcb, Aplcb, Aplcb, Aplcb,
int, int, int);
extern int aplerr;
Aplcb dimcb=NULL,ixcb=NULL,lccb=NULL,rccb=NULL;
int datatyp,i,j,k,*iip,*jip,*oip;
for (;;) { /* lets me use break */
datatyp = left->aplflags & (APLMASK + APLAPL);
dimcb = getcb(NULL, out->aplrank, APLTEMP + APLINT, 1, NULL);
/* Pseudo-dimensions: The first d dimensions of rite will */
/* match the first d items in dimcb. Remaining items will */
/* be the difference between right-most dimensions of rite */
/* and the dimensions of left. */
ixcb = getcb(NULL, out->aplrank, APLTEMP + APLINT, 1, NULL);
/* Indices to rite and out, bumped by calls to indices. */
/* Used for two things: */
/* 1. Select elements in out which can be 1. */
/* 2. Select the upper left corner element in rite for */
/* comparison against left. */
lccb = getcb(NULL, left->aplrank, APLTEMP + APLINT, 1, NULL);
rccb = getcb(NULL, rite->aplrank, APLTEMP + APLINT, 1, NULL);
/* Lccb and rccb will be used to make the comparison on */
/* sub-array in rite against left to determine if the */
/* current output item should be 1 or 0. */
if (aplerr) break;
i = -1; /* Set ixcb array to -1 (required by indices rtne). */
oip = intcopy(ixcb->aplptr.aplint, &i, ixcb->aplcount, 0);
/* Now compare the rightmost (Rleft) dimensions of rite to */
/* rite to dimensions of left. If a dimension of rite is less */
/* than left, all output of find must be all zeros. Also */
/* derive k = #items in out that can be 1. */
for(k = 1, i = d, oip = dimcb->aplptr.aplint,
iip = out->apldim; i; i--) k *= *oip++ = *iip++;
for( i = j = out->aplrank - d, iip = out->apldim + d,
jip = left->apldim; i && j > -1; i--)
k *= *oip++ = 1 + (j = *iip++ - *jip++);
if (j < 0) break; /* Done: Dimension of rite < left */
findb(left,rite,out,dimcb,ixcb,lccb,rccb,k,datatyp,d);
break; /* final break out of for (;;) */
}
endoper(dimcb);
endoper(ixcb);
endoper(lccb);
endoper(rccb);
}