/*Copyright (C) 1993, 1994 by Thomas Glen Smith. All Rights Reserved.*/ /* indexm APL2 V1.0.0 ************************************************** * Called by enclosf and squadix. * * Left points to an APL variable from, and perhaps to, which values * * are to be indexed. Indices identifies the index values to be used, * * and determines the shape of the output. If rite isn't NULL, it * * contains values to be stored in the indexed elements of left. * * Indexm differs from indexv in that left may be of any shape, and * * the output may have rank other than 1. Indexm is the true * * implementation of the APL indexing function. * ***********************************************************************/ #define INCLUDES APLCB+APLMEM+INDEXMI #include "includes.h" Aplcb indexm(left, indices, rite) Aplcb left, indices, rite; { Errinit; Errstop; Getcb; Indexma; Indexmb; Intcopy; Ireduce; Itimes; Matchok; Perm; Temp; extern int aplerr; extern int indxorg; int datacnt,i,*ip,itimesid,j,k,*op,rank,tempsave; struct ix p; Aplcb dimcb, x, *xcb; if (errinit()) return(errstop(0,left,indices,rite)); if ((rite != NULL ) && (!matchok(&left,&rite,APLMASK+APLAPL))) return(errstop(0,NULL,indices,NULL)); if (left->aplrank != indices->aplcount) return(errstop(53,left,indices,rite)); p.siz = left->aplsize; p.l = left; p.r = rite; p.x = indices; p.o = (void *) p.z = (void *) p.datarite = p.dataout= NULL; dimcb = indexma(&p); /* go get output dimensions */ if (dimcb != NULL) { itimesid = 1; /* identity */ datacnt = ivalue(ireduce(itimes,&itimesid,perm(dimcb),indxorg)); p.dtyp = left->aplflags & (APLMASK + APLAPL); if (0 == (rank = dimcb->aplcount) && p.dtyp == APLCHAR) rank++; /* character types can't be scalars */ if (rite != NULL) { p.datarite = rite->aplptr.aplchar; if (0 != (p.inc = (1 == rite->aplcount) ? 0 : p.siz) && rite->aplcount != datacnt) aplerr = 112; } if (aplerr == 0) p.o = getcb(NULL,datacnt,p.dtyp + APLTEMP,rank,NULL); if (aplerr == 0 && rank > 1) ip = intcopy(p.o->apldim,dimcb->aplptr.aplint,rank,1); endoper(temp(dimcb)); if (aplerr == 0) { p.dataout = p.o->aplptr.aplchar; if (p.o->aplcount) { x = *(xcb = indices->aplptr.aplapl); /* 1st index */ ip = indexmb(0,&p,xcb,0,x->aplptr.aplint, left->aplptr.aplchar); } } } if (p.z != NULL) free(p.z); endoper(indices); return(errstop(0,left,rite,p.o)); }