/* 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); }