/* Copyright (C) 1993 by Thomas Glen Smith. All Rights Reserved. */
/* without APL2 V1.0.0 *************************************************
* Yields a vector of the items in left not occurring in rite. *
***********************************************************************/
#define INCLUDES APLCB
#include "includes.h"
Aplcb without(Aplcb left, Aplcb rite)
{
extern int aplerr;
Aplcopy; Aplfree; Aplmall; Aplmatci; Dtacopy; Errinit; Errstop;
Fifo; Getcb; Pop; Temp;
struct qlist { struct qlist *qnext; Apluptr qel; }
*qhdr,*qcur,*qnxt;
int datacnt,i,j,lefttype,ritetype;
Apluptr ld,rd;
Aplcb out;
if (errinit())
return(errstop(0,left,rite,NULL));
lefttype = left->aplflags & (APLMASK + APLAPL);
ritetype = rite->aplflags & (APLMASK + APLAPL);
if (left->aplcount == 0 || rite->aplcount == 0 ||
(lefttype != ritetype &&
!((lefttype | ritetype & APLAPL) ||
((lefttype | ritetype) == (APLINT | APLNUMB)))))
return(errstop(0,left,rite,temp(aplcopy(left))));
datacnt = 0;
qcur = qhdr = NULL; /* start of chain */
for (i = left->aplcount, ld = left->aplptr; i; i--) {
for (j = rite->aplcount, rd = rite->aplptr; j; j--) {
if (aplmatci(ld, rd, lefttype, ritetype)) break;
rd.aplchar += rite->aplsize;
}
if (j == 0) { /* no match */
datacnt++; /* count of non matches */
qcur = fifo(&qhdr,qcur,aplmall(sizeof(struct qlist)));
if (aplerr) break;
qcur->qel = ld; /* save non match pointer */
}
ld.aplchar += left->aplsize;
}
if (aplerr)
out = NULL;
else out=getcb(NULL,datacnt,lefttype+APLTEMP,1,NULL);
if (!aplerr) ld = out->aplptr;
while (NULL != (qcur = pop(&qhdr))) {
if (!aplerr) ld.aplchar = dtacopy((void *)(ld.aplchar),
(void *)(qcur->qel.aplchar),1,1,lefttype);
aplfree(qcur);
}
return(errstop(0,left,rite,out));
}