1 /*-----------------------------------------------------------------
2 SDCCset.c - contains support routines for sets
4 Written By - Sandeep Dutta . sandeep.dutta@usa.net (1998)
6 This program is free software; you can redistribute it and/or modify it
7 under the terms of the GNU General Public License as published by the
8 Free Software Foundation; either version 2, or (at your option) any
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 In other words, you are welcome to use, share and improve this program.
21 You are forbidden to forbid anyone else to use, share and improve
22 what you give them. Help stamp out software-hoarding!
23 -------------------------------------------------------------------------*/
30 /*-----------------------------------------------------------------*/
31 /* newSet - will allocate & return a new set entry */
32 /*-----------------------------------------------------------------*/
38 lp = Safe_alloc (sizeof (set));
39 lp->item = lp->curr = lp->next = NULL;
44 /*-----------------------------------------------------------------*/
45 /* setFromSet - creates a list from another list; the order of */
46 /* elements in new list is reverted */
47 /*-----------------------------------------------------------------*/
55 addSetHead (&lfl, lp->item);
63 /*-----------------------------------------------------------------*/
64 /* setFromSet - creates a list from another list; the order of */
65 /* elements in retained */
66 /*-----------------------------------------------------------------*/
68 setFromSetNonRev (set * lp)
74 addSet (&lfl, lp->item);
82 /*-----------------------------------------------------------------*/
83 /* isSetsEqual - are the lists equal, they are equal if they have */
84 /* the same objects & the same number of objects */
85 /*-----------------------------------------------------------------*/
87 isSetsEqual (set * dest, set * src)
91 for (; dest && src; dest = dest->next, src = src->next)
93 if (!isinSet (src1, dest->item))
101 /*-----------------------------------------------------------------*/
102 /* isSetsEqualWith - are the lists equal, they are equal if they */
103 /* have the same objects & the same number of */
104 /* objects , compare function */
105 /*-----------------------------------------------------------------*/
107 isSetsEqualWith (set * dest, set * src, int (*cFunc) (void *, void *))
111 for (; dest && src; dest = dest->next, src = src->next)
113 if (!isinSetWith (src1, dest->item, cFunc))
121 /*-----------------------------------------------------------------*/
122 /* addSetIfnotP - adds to a linked list if not already present */
123 /*-----------------------------------------------------------------*/
125 addSetIfnotP (set ** list, void *item)
128 if (isinSet (*list, item))
131 addSetHead (list, item);
136 /*-----------------------------------------------------------------*/
137 /* addSetHead - add item to head of linked list */
138 /*-----------------------------------------------------------------*/
140 addSetHead (set ** list, void *item)
147 assert (lp != lp->item);
153 /*-----------------------------------------------------------------*/
154 /* addSet - add an item to a linear linked list */
155 /*-----------------------------------------------------------------*/
157 addSet (set ** list, void *item)
161 /* item added to the tail of the list */
163 /* if the list is empty */
166 lp = *list = newSet ();
170 /* go to the end of the list */
171 for (lp = *list; lp->next; lp = lp->next);
172 lp = lp->next = newSet ();
181 /*-----------------------------------------------------------------*/
182 /* deleteItemIf - will delete from set if cond function returns 1 */
183 /*-----------------------------------------------------------------*/
185 deleteItemIf (set ** sset, int (*cond) (void *, va_list),...)
193 * On the x86 va_list is just a pointer, so due to pass by value
194 * ap is not mofified by the called function. On the PPC va_list
195 * is a pointer to a structure, so ap is modified. Re-init each time.
199 if ((*cond) (sp->item, ap))
201 deleteSetItem (sset, sp->item);
211 /*-----------------------------------------------------------------*/
212 /* deleteSetItem - will delete a given item from the list */
213 /*-----------------------------------------------------------------*/
215 deleteSetItem (set ** list, void *item)
219 /* if list is empty */
223 /* if this item is at the head of the list */
224 if ((*list)->item == item) {
226 *list = (*list)->next;
231 /* find the item in the list */
232 for (lp = *list; lp->next; lp = lp->next) {
233 if (lp->next->item == item) { /* the next one is it */
234 lp1 = lp->next; /* this one will need to be freed */
235 lp->next = lp->next->next; /* take out of list */
241 /* could not find it */
244 /*-----------------------------------------------------------------*/
245 /* isinSet - the item is present in the linked list */
246 /*-----------------------------------------------------------------*/
248 isinSet (set * list, void *item)
252 for (lp = list; lp; lp = lp->next)
253 if (lp->item == item)
259 /*-----------------------------------------------------------------*/
260 /* isinSetWith - the item is present in the linked list */
261 /*-----------------------------------------------------------------*/
263 isinSetWith (set * list, void *item, int (*cFunc) (void *, void *))
267 for (lp = list; lp; lp = lp->next)
268 if ((*cFunc) (lp->item, item))
274 /*-----------------------------------------------------------------*/
275 /* mergeSets - append list to sset */
276 /*-----------------------------------------------------------------*/
278 mergeSets (set **sset, set *list)
286 for (lp = *sset; lp->next; lp = lp->next)
292 /*-----------------------------------------------------------------*/
293 /* unionSets - will return the union of the two lists */
294 /*-----------------------------------------------------------------*/
296 unionSets (set * list1, set * list2, int throw)
301 /* add all elements in the first list */
302 for (lp = list1; lp; lp = lp->next)
303 addSet (&un, lp->item);
305 /* now for all those in list2 which does not */
306 /* already exist in the list add */
307 for (lp = list2; lp; lp = lp->next)
308 if (!isinSet (un, lp->item))
309 addSet (&un, lp->item);
314 setToNull ((void *) &list2);
317 setToNull ((void *) &list1);
320 setToNull ((void *) &list1);
321 setToNull ((void *) &list2);
327 /*-----------------------------------------------------------------*/
328 /* unionSetsWith - will return the union of the two lists */
329 /*-----------------------------------------------------------------*/
331 unionSetsWith (set * list1, set * list2, int (*cFunc) (), int throw)
336 /* add all elements in the first list */
337 for (lp = list1; lp; lp = lp->next)
338 addSet (&un, lp->item);
340 /* now for all those in list2 which does not */
341 /* already exist in the list add */
342 for (lp = list2; lp; lp = lp->next)
343 if (!isinSetWith (un, lp->item, (int (*)(void *, void *)) cFunc))
344 addSet (&un, lp->item);
349 setToNull ((void *) &list2);
352 setToNull ((void *) &list1);
355 setToNull ((void *) &list1);
356 setToNull ((void *) &list2);
362 /*-----------------------------------------------------------------*/
363 /* intersectSets - returns list of items in common to two lists */
364 /*-----------------------------------------------------------------*/
366 intersectSets (set * list1, set * list2, int throw)
371 /* we can take any one of the lists and iterate over it */
372 for (lp = list1; lp; lp = lp->next)
373 if (isinSet (list2, lp->item))
374 addSetHead (&in, lp->item);
379 setToNull ((void *) &list2);
382 setToNull ((void *) &list1);
385 setToNull ((void *) &list1);
386 setToNull ((void *) &list2);
392 /*-----------------------------------------------------------------*/
393 /* intersectSetsWith - returns list of items in common to two */
395 /*-----------------------------------------------------------------*/
397 intersectSetsWith (set * list1, set * list2,
398 int (*cFunc) (void *, void *), int throw)
403 /* we can take any one of the lists and iterate over it */
404 for (lp = list1; lp; lp = lp->next)
405 if (isinSetWith (list2, lp->item, cFunc))
406 addSetHead (&in, lp->item);
411 setToNull ((void *) &list2);
414 setToNull ((void *) &list1);
417 setToNull ((void *) &list1);
418 setToNull ((void *) &list2);
424 /*-----------------------------------------------------------------*/
425 /* elementsInSet - elements count of a set */
426 /*-----------------------------------------------------------------*/
428 elementsInSet (set * s)
442 /*-----------------------------------------------------------------*/
443 /* indexSet - returns the i'th item in set */
444 /*-----------------------------------------------------------------*/
446 indexSet (set * s, int index)
450 while(loop && index) {
459 /*-----------------------------------------------------------------*/
460 /* reverseSet - reverse the order of the items of a set */
461 /*-----------------------------------------------------------------*/
479 /*-----------------------------------------------------------------*/
480 /* subtractFromSet - take away from set1 elements of set2 */
481 /*-----------------------------------------------------------------*/
483 subtractFromSet (set * left, set * right, int throw)
485 set *result = setFromSet (left);
490 for (loop = right; loop; loop = loop->next)
491 if (isinSet (result, loop->item))
492 deleteSetItem (&result, loop->item);
498 setToNull ((void *) &right);
501 setToNull ((void *) &left);
504 setToNull ((void *) &left);
505 setToNull ((void *) &right);
512 /*-----------------------------------------------------------------*/
513 /* applyToSet - will call the supplied function with each item */
514 /*-----------------------------------------------------------------*/
516 applyToSet (set * list, int (*somefunc) (void *, va_list),...)
522 for (lp = list; lp; lp = lp->next)
524 va_start (ap, somefunc);
525 rvalue += (*somefunc) (lp->item, ap);
531 /*-----------------------------------------------------------------*/
532 /* applyToSetFTrue - will call the supplied function with each */
533 /* item until list is exhausted or a true is */
535 /*-----------------------------------------------------------------*/
537 applyToSetFTrue (set * list, int (*somefunc) (void *, va_list),...)
543 for (lp = list; lp; lp = lp->next)
545 va_start (ap, somefunc);
546 rvalue += (*somefunc) (lp->item, ap);
554 /*-----------------------------------------------------------------*/
555 /* peekSet - will return the first element of the set */
556 /*-----------------------------------------------------------------*/
566 /*-----------------------------------------------------------------*/
567 /* setFirstItem - gets the first item in the set, begins iteration */
568 /*-----------------------------------------------------------------*/
570 setFirstItem (set * sset)
580 /*-----------------------------------------------------------------*/
581 /* setNextItem - gets the next item, changes the iteration */
582 /*-----------------------------------------------------------------*/
584 setNextItem (set * sset)
586 if (sset && sset->curr)
588 sset->curr = sset->curr->next;
590 return sset->curr->item;
595 /*-----------------------------------------------------------------*/
596 /* getSet - will delete & return the first item from the set */
597 /*-----------------------------------------------------------------*/
604 /* if list is empty then we cannot delete */
606 return (void *) NULL;
609 /* find the item in the list */
611 item = lp->item; /* save the item */
617 /*-----------------------------------------------------------------*/
618 /* setToNull - will throw away the entire list */
619 /*-----------------------------------------------------------------*/
621 setToNull (void **item)
633 /*-----------------------------------------------------------------*/
634 /* deleteSet - will throw away the entire list */
635 /* note - setToNull doesn't actually throw away the whole list. */
636 /* Instead it only throws away the first item. */
637 /*-----------------------------------------------------------------*/