home *** CD-ROM | disk | FTP | other *** search
- /* lists.c - list manipulation routines for geneal
- *
- * 18.Aug.87 jimmc Initial definition
- * 28.Sep.87 jimmc Add LAndNot function
- * 17.Oct.87 jimmc Convert to spin interface
- * 6.Nov.87 jimmc Name change: xalloc to xallocm, xrealloc to xreallom
- * 4.Jan.88 jimmc Add LRange
- * 8.Jan.88 jimmc Add olisttoiarr; lint cleanup
- */
-
- #include <stdio.h>
- #include "xalloc.h"
- #include "geneal.h"
- #include "spin.h"
-
- extern SPtoken *SPiarrtolist();
-
- GroupAppend(group,item)
- Group *group;
- int item;
- {
- static char *mm="GroupAppend";
-
- if (group->count >= group->alloc) {
- if (group->alloc==0) group->alloc=15;
- else group->alloc *= 2;
- if (group->n) group->n = (int *)xreallocm((char *)group->n,
- group->alloc*sizeof(group->n[0]),mm);
- else group->n = (int *)xallocm(
- group->alloc*sizeof(group->n[0]),mm);
- }
- group->n[group->count++] = item;
- }
-
- /* Assumes the list is sorted; inserts the new item in sorted order if
- * it does not already exist */
- GroupSortedAdd(group,item)
- Group *group;
- int item;
- {
- int i,j;
-
- /* The following linear search could be replaced
- * by something more intelligent, like a binary search. */
- for (i=0; i<group->count; i++) {
- if (group->n[i]==item) return; /* already there */
- if (group->n[i]>item) break;
- }
- GroupAppend(group,item); /* make space for it */
- if (i<group->count-1) {
- for (j=group->count-1; j>i; j--)
- group->n[j] = group->n[j-1];
- group->n[i] = item; /* insert in sorted order */
- }
- }
-
- static int icmp(a,b) int *a,*b; { return *a - *b; }
-
- int
- llunion(ac1,av1,ac2,av2,pav3)
- int ac1, *av1;
- int ac2, *av2;
- int **pav3; /* return value - we malloc an array and return pointer */
- {
- Group clist;
- int i1,i2;
- int n1,n2;
-
- qsort((char *)av1,ac1,sizeof(av1[0]),icmp);
- qsort((char *)av2,ac2,sizeof(av2[0]),icmp);
- clist.count = clist.alloc = 0;
- clist.n = 0;
- i1 = i2 = 0;
- while (i1<ac1 && i2<ac2) {
- n1 = av1[i1];
- n2 = av2[i2];
- if (n1<n2) {
- if (clist.count==0 || n1>clist.n[clist.count-1]) {
- GroupAppend(&clist,n1);
- }
- i1++;
- }
- else { /* n1>=n2 */
- if (clist.count==0 || n2>clist.n[clist.count-1]) {
- GroupAppend(&clist,n2);
- }
- i2++;
- if (n1==n2) i1++;
- }
- }
- while (i1<ac1) {
- n1 = av1[i1];
- if (clist.count==0 || n1>clist.n[clist.count-1]) {
- GroupAppend(&clist,n1);
- }
- i1++;
- }
- while (i2<ac2) {
- n2 = av2[i2];
- if (clist.count==0 || n2>clist.n[clist.count-1]) {
- GroupAppend(&clist,n2);
- }
- i2++;
- }
- *pav3 = clist.n;
- return clist.count;
- }
-
- static int
- llintersect(ac1,av1,ac2,av2,pav3)
- int ac1, *av1;
- int ac2, *av2;
- int **pav3; /* return value - we malloc an array and return pointer */
- {
- Group clist;
- int i1,i2;
- int n1,n2;
-
- qsort((char *)av1,ac1,sizeof(av1[0]),icmp);
- qsort((char *)av2,ac2,sizeof(av2[0]),icmp);
- clist.count = clist.alloc = 0;
- clist.n = 0;
- i1 = i2 = 0;
- while (i1<ac1 && i2<ac2) {
- n1 = av1[i1];
- n2 = av2[i2];
- if (n1<n2) i1++;
- else if (n1>n2) i2++;
- else { /* n1==n2 */
- if (clist.count==0 || n2>clist.n[clist.count-1]) {
- GroupAppend(&clist,n2);
- }
- i1++; i2++;
- }
- }
- *pav3 = clist.n;
- return clist.count;
- }
-
- static int
- llandnot(ac1,av1,ac2,av2,pav3)
- int ac1, *av1;
- int ac2, *av2;
- int **pav3; /* return value - we malloc an array and return pointer */
- {
- Group clist;
- int i1,i2;
- int n1,n2;
-
- qsort((char *)av1,ac1,sizeof(av1[0]),icmp);
- qsort((char *)av2,ac2,sizeof(av2[0]),icmp);
- clist.count = clist.alloc = 0;
- clist.n = 0;
- i2 = 0;
- for (i1=0; i1<ac1; i1++) {
- n1 = av1[i1];
- for ( ; i2<ac2; i2++) {
- n2 = av2[i2];
- if (n1==n2) goto no_insert;
- if (n2>n1) break;
- }
- if (clist.count==0 || n1>clist.n[clist.count-1]) {
- GroupAppend(&clist,n1);
- }
- no_insert: ;
- }
- *pav3 = clist.n;
- return clist.count;
- }
-
- static int
- llrange(from,to,pav3)
- int from, to; /* range, inclusive */
- int **pav3; /* return value - we malloc an array and return pointer */
- {
- int r,i;
- int *v;
-
- r = to - from + 1; /* number of items in the range */
- if (r<=0) return 0; /* no range */
- v = XALLOC(int,r);
- for (i=0; i<r; i++) {
- v[i] = from+i;
- }
- *pav3 = v;
- return r;
- }
-
- SPtoken *
- Libin2(i1,i2,opfunc)
- int i1, i2;
- int (*opfunc)();
- {
- int ac3, *av3;
- SPtoken *l;
-
- ac3 = (*opfunc)(i1,i2,&av3);
- l = SPiarrtolist(ac3,av3);
- free((char *)av3);
- return l;
- }
-
- SPtoken *
- LRange(i1,i2)
- int i1,i2;
- {
- return Libin2(i1,i2,llrange);
- }
-
- SPtoken *
- Lbinop(l1,l2,opfunc)
- SPtoken *l1, *l2;
- int (*opfunc)();
- {
- int ac1, *av1;
- int ac2, *av2;
- int ac3, *av3;
- SPtoken *l;
-
- ac1 = olisttoiarr(l1,&av1);
- ac2 = olisttoiarr(l2,&av2);
- ac3 = (*opfunc)(ac1,av1,ac2,av2,&av3);
- l = SPiarrtolist(ac3,av3);
- free((char *)av3);
- return l;
- }
-
- SPtoken *
- LIntersect(l1,l2)
- SPtoken *l1, *l2;
- {
- return Lbinop(l1,l2,llintersect);
- }
-
- SPtoken *
- LUnion(l1,l2)
- SPtoken *l1, *l2;
- {
- return Lbinop(l1,l2,llunion);
- }
-
- SPtoken *
- LAndNot(l1,l2)
- SPtoken *l1, *l2;
- {
- return Lbinop(l1,l2,llandnot);
- }
-
- int /* returns number of entries in list */
- olisttoiarr(l,pav)
- SPtoken *l; /* list of ints or single int */
- int **pav; /* where to put the return pointer to array of ints */
- {
- int ac;
- int *av;
-
- if (l->type==SPTokInt) { /* special case for single int */
- ac = 1;
- av = XALLOC(int,1);
- av[0] = l->value.n;
- *pav = av;
- }
- else {
- ac = SPlisttoiarr(l,pav);
- }
- return ac;
- }
- /* end */
-