1 /*
2 	rua_set.c
3 
4 	Ruamoko set api
5 
6 	Copyright (C) 2012 Bill Currie
7 
8 	Author: Bill Currie <bill@taniwha.org>
9 	Date: 2012/12/15
10 
11 	This program is free software; you can redistribute it and/or
12 	modify it under the terms of the GNU General Public License
13 	as published by the Free Software Foundation; either version 2
14 	of the License, or (at your option) any later version.
15 
16 	This program is distributed in the hope that it will be useful,
17 	but WITHOUT ANY WARRANTY; without even the implied warranty of
18 	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
19 
20 	See the GNU General Public License for more details.
21 
22 	You should have received a copy of the GNU General Public License
23 	along with this program; if not, write to:
24 
25 		Free Software Foundation, Inc.
26 		59 Temple Place - Suite 330
27 		Boston, MA  02111-1307, USA
28 
29 */
30 #ifdef HAVE_CONFIG_H
31 # include "config.h"
32 #endif
33 
34 #ifdef HAVE_STRING_H
35 # include <string.h>
36 #endif
37 #ifdef HAVE_STRINGS_H
38 # include <strings.h>
39 #endif
40 #include <stdlib.h>
41 
42 #include "QF/progs.h"
43 #include "QF/pr_obj.h"
44 #include "QF/set.h"
45 
46 #include "rua_internal.h"
47 
48 typedef struct {
49 	pr_id_t     obj;
50 	pr_int_t    set;
51 } pr_set_t;
52 
53 typedef struct {
54 	pr_id_t     obj;
55 	pr_int_t    iter;
56 } pr_set_iter_t;
57 
58 typedef struct bi_set_s {
59 	struct bi_set_s *next;
60 	struct bi_set_s **prev;
61 	set_t      *set;
62 } bi_set_t;
63 
64 typedef struct bi_set_iter_s {
65 	struct bi_set_iter_s *next;
66 	struct bi_set_iter_s **prev;
67 	set_iter_t *iter;
68 } bi_set_iter_t;
69 
70 typedef struct {
71 	PR_RESMAP (bi_set_t) set_map;
72 	PR_RESMAP (bi_set_iter_t) set_iter_map;
73 	bi_set_t   *sets;
74 	bi_set_iter_t *set_iters;
75 } set_resources_t;
76 
77 static bi_set_t *
res_set_new(set_resources_t * res)78 res_set_new (set_resources_t *res)
79 {
80 	PR_RESNEW (bi_set_t, res->set_map);
81 }
82 
83 static void
res_set_free(set_resources_t * res,bi_set_t * set)84 res_set_free (set_resources_t *res, bi_set_t *set)
85 {
86 	PR_RESFREE (bi_set_t, res->set_map, set);
87 }
88 
89 static void
res_set_reset(set_resources_t * res)90 res_set_reset (set_resources_t *res)
91 {
92 	PR_RESRESET (bi_set_t, res->set_map);
93 }
94 
95 static inline bi_set_t *
res_set_get(set_resources_t * res,int index)96 res_set_get (set_resources_t *res, int index)
97 {
98 	PR_RESGET(res->set_map, index);
99 }
100 
101 static inline int
res_set_index(set_resources_t * res,bi_set_t * set)102 res_set_index (set_resources_t *res, bi_set_t *set)
103 {
104 	PR_RESINDEX(res->set_map, set);
105 }
106 
107 static bi_set_iter_t *
res_set_iter_new(set_resources_t * res)108 res_set_iter_new (set_resources_t *res)
109 {
110 	PR_RESNEW (bi_set_iter_t, res->set_iter_map);
111 }
112 
113 static void
res_set_iter_free(set_resources_t * res,bi_set_iter_t * set_iter)114 res_set_iter_free (set_resources_t *res, bi_set_iter_t *set_iter)
115 {
116 	PR_RESFREE (bi_set_iter_t, res->set_iter_map, set_iter);
117 }
118 
119 static void
res_set_iter_reset(set_resources_t * res)120 res_set_iter_reset (set_resources_t *res)
121 {
122 	PR_RESRESET (bi_set_iter_t, res->set_iter_map);
123 }
124 
125 static inline bi_set_iter_t *
res_set_iter_get(set_resources_t * res,int index)126 res_set_iter_get (set_resources_t *res, int index)
127 {
128 	PR_RESGET(res->set_iter_map, index);
129 }
130 
131 static inline int
res_set_iter_index(set_resources_t * res,bi_set_iter_t * set_iter)132 res_set_iter_index (set_resources_t *res, bi_set_iter_t *set_iter)
133 {
134 	PR_RESINDEX(res->set_iter_map, set_iter);
135 }
136 
137 static bi_set_t *
get_set(progs_t * pr,const char * name,int index)138 get_set (progs_t *pr, const char *name, int index)
139 {
140 	set_resources_t *res = PR_Resources_Find (pr, "Set");
141 	bi_set_t   *set = res_set_get (res, index);
142 
143 	if (!set)
144 		PR_RunError (pr, "invalid set index passed to %s", name + 3);
145 	return set;
146 }
147 
148 static bi_set_iter_t *
get_set_iter(progs_t * pr,const char * name,int index)149 get_set_iter (progs_t *pr, const char *name, int index)
150 {
151 	set_resources_t *res = PR_Resources_Find (pr, "Set");
152 	bi_set_iter_t   *set = res_set_iter_get (res, index);
153 
154 	if (!set)
155 		PR_RunError (pr, "invalid set iterator index passed to %s", name + 3);
156 	return set;
157 }
158 
159 static void
del_set_iter(progs_t * pr,bi_set_iter_t * set_iter)160 del_set_iter (progs_t *pr, bi_set_iter_t *set_iter)
161 {
162 	set_resources_t *res = PR_Resources_Find (pr, "Set");
163 
164 	*set_iter->prev = set_iter->next;
165 	if (set_iter->next)
166 		set_iter->next->prev = set_iter->prev;
167 	res_set_iter_free (res, set_iter);
168 }
169 
170 static void
bi_set_del_iter(progs_t * pr)171 bi_set_del_iter (progs_t *pr)
172 {
173 	bi_set_iter_t   *set_iter = get_set_iter (pr, __FUNCTION__, P_INT (pr, 0));
174 
175 	set_del_iter (set_iter->iter);
176 	del_set_iter (pr, set_iter);
177 }
178 
179 static void
bi_set_new(progs_t * pr)180 bi_set_new (progs_t *pr)
181 {
182 	set_resources_t *res = PR_Resources_Find (pr, "Set");
183 	bi_set_t   *set;
184 
185 	set = res_set_new (res);
186 
187 	set->next = res->sets;
188 	set->prev = &res->sets;
189 	if (res->sets)
190 		res->sets->prev = &set->next;
191 	res->sets = set;
192 
193 	set->set = set_new ();
194 
195 	R_INT (pr) = res_set_index (res, set);
196 }
197 
198 static void
bi_set_delete(progs_t * pr)199 bi_set_delete (progs_t *pr)
200 {
201 	set_resources_t *res = PR_Resources_Find (pr, "Set");
202 	bi_set_t   *set = get_set (pr, __FUNCTION__, P_INT (pr, 0));
203 
204 	set_delete (set->set);
205 	*set->prev = set->next;
206 	if (set->next)
207 		set->next->prev = set->prev;
208 	res_set_free (res, set);
209 }
210 
211 static void
bi_set_add(progs_t * pr)212 bi_set_add (progs_t *pr)
213 {
214 	bi_set_t   *set = get_set (pr, __FUNCTION__, P_INT (pr, 0));
215 
216 	set_add (set->set, P_UINT (pr, 1));
217 	R_INT (pr) = P_INT (pr, 0);
218 }
219 
220 static void
bi_set_remove(progs_t * pr)221 bi_set_remove (progs_t *pr)
222 {
223 	bi_set_t   *set = get_set (pr, __FUNCTION__, P_INT (pr, 0));
224 
225 	set_remove (set->set, P_UINT (pr, 1));
226 	R_INT (pr) = P_INT (pr, 0);
227 }
228 
229 static void
bi_set_invert(progs_t * pr)230 bi_set_invert (progs_t *pr)
231 {
232 	bi_set_t   *set = get_set (pr, __FUNCTION__, P_INT (pr, 0));
233 
234 	set_invert (set->set);
235 	R_INT (pr) = P_INT (pr, 0);
236 }
237 
238 static void
bi_set_union(progs_t * pr)239 bi_set_union (progs_t *pr)
240 {
241 	bi_set_t   *set1 = get_set (pr, __FUNCTION__, P_INT (pr, 0));
242 	bi_set_t   *set2 = get_set (pr, __FUNCTION__, P_INT (pr, 1));
243 
244 	set_union (set1->set, set2->set);
245 	R_INT (pr) = P_INT (pr, 0);
246 }
247 
248 static void
bi_set_intersection(progs_t * pr)249 bi_set_intersection (progs_t *pr)
250 {
251 	bi_set_t   *set1 = get_set (pr, __FUNCTION__, P_INT (pr, 0));
252 	bi_set_t   *set2 = get_set (pr, __FUNCTION__, P_INT (pr, 1));
253 
254 	set_intersection (set1->set, set2->set);
255 	R_INT (pr) = P_INT (pr, 0);
256 }
257 
258 static void
bi_set_difference(progs_t * pr)259 bi_set_difference (progs_t *pr)
260 {
261 	bi_set_t   *set1 = get_set (pr, __FUNCTION__, P_INT (pr, 0));
262 	bi_set_t   *set2 = get_set (pr, __FUNCTION__, P_INT (pr, 1));
263 
264 	set_difference (set1->set, set2->set);
265 	R_INT (pr) = P_INT (pr, 0);
266 }
267 
268 static void
bi_set_reverse_difference(progs_t * pr)269 bi_set_reverse_difference (progs_t *pr)
270 {
271 	bi_set_t   *set1 = get_set (pr, __FUNCTION__, P_INT (pr, 0));
272 	bi_set_t   *set2 = get_set (pr, __FUNCTION__, P_INT (pr, 1));
273 
274 	set_reverse_difference (set1->set, set2->set);
275 	R_INT (pr) = P_INT (pr, 0);
276 }
277 
278 static void
bi_set_assign(progs_t * pr)279 bi_set_assign (progs_t *pr)
280 {
281 	bi_set_t   *set1 = get_set (pr, __FUNCTION__, P_INT (pr, 0));
282 	bi_set_t   *set2 = get_set (pr, __FUNCTION__, P_INT (pr, 1));
283 
284 	set_assign (set1->set, set2->set);
285 	R_INT (pr) = P_INT (pr, 0);
286 }
287 
288 static void
bi_set_empty(progs_t * pr)289 bi_set_empty (progs_t *pr)
290 {
291 	bi_set_t   *set = get_set (pr, __FUNCTION__, P_INT (pr, 0));
292 
293 	set_empty (set->set);
294 	R_INT (pr) = P_INT (pr, 0);
295 }
296 
297 static void
bi_set_everything(progs_t * pr)298 bi_set_everything (progs_t *pr)
299 {
300 	bi_set_t   *set = get_set (pr, __FUNCTION__, P_INT (pr, 0));
301 
302 	set_everything (set->set);
303 	R_INT (pr) = P_INT (pr, 0);
304 }
305 
306 static void
bi_set_is_empty(progs_t * pr)307 bi_set_is_empty (progs_t *pr)
308 {
309 	bi_set_t   *set = get_set (pr, __FUNCTION__, P_INT (pr, 0));
310 
311 	R_INT (pr) = set_is_empty (set->set);
312 }
313 
314 static void
bi_set_is_everything(progs_t * pr)315 bi_set_is_everything (progs_t *pr)
316 {
317 	bi_set_t   *set = get_set (pr, __FUNCTION__, P_INT (pr, 0));
318 
319 	R_INT (pr) = set_is_everything (set->set);
320 }
321 
322 static void
bi_set_is_disjoint(progs_t * pr)323 bi_set_is_disjoint (progs_t *pr)
324 {
325 	bi_set_t   *set1 = get_set (pr, __FUNCTION__, P_INT (pr, 0));
326 	bi_set_t   *set2 = get_set (pr, __FUNCTION__, P_INT (pr, 1));
327 
328 	R_INT (pr) = set_is_disjoint (set1->set, set2->set);
329 }
330 
331 static void
bi_set_is_intersecting(progs_t * pr)332 bi_set_is_intersecting (progs_t *pr)
333 {
334 	bi_set_t   *set1 = get_set (pr, __FUNCTION__, P_INT (pr, 0));
335 	bi_set_t   *set2 = get_set (pr, __FUNCTION__, P_INT (pr, 1));
336 
337 	R_INT (pr) = set_is_intersecting (set1->set, set2->set);
338 }
339 
340 static void
bi_set_is_equivalent(progs_t * pr)341 bi_set_is_equivalent (progs_t *pr)
342 {
343 	bi_set_t   *set1 = get_set (pr, __FUNCTION__, P_INT (pr, 0));
344 	bi_set_t   *set2 = get_set (pr, __FUNCTION__, P_INT (pr, 1));
345 
346 	R_INT (pr) = set_is_equivalent (set1->set, set2->set);
347 }
348 
349 static void
bi_set_is_subset(progs_t * pr)350 bi_set_is_subset (progs_t *pr)
351 {
352 	bi_set_t   *set1 = get_set (pr, __FUNCTION__, P_INT (pr, 0));
353 	bi_set_t   *set2 = get_set (pr, __FUNCTION__, P_INT (pr, 1));
354 
355 	R_INT (pr) = set_is_subset (set1->set, set2->set);
356 }
357 
358 static void
bi_set_is_member(progs_t * pr)359 bi_set_is_member (progs_t *pr)
360 {
361 	bi_set_t   *set = get_set (pr, __FUNCTION__, P_INT (pr, 0));
362 
363 	R_INT (pr) = set_is_member (set->set, P_UINT (pr, 1));
364 }
365 
366 static void
bi_set_size(progs_t * pr)367 bi_set_size (progs_t *pr)
368 {
369 	bi_set_t   *set = get_set (pr, __FUNCTION__, P_INT (pr, 0));
370 
371 	R_INT (pr) = set_size (set->set);
372 }
373 
374 static void
bi_set_first(progs_t * pr)375 bi_set_first (progs_t *pr)
376 {
377 	set_resources_t *res = PR_Resources_Find (pr, "Set");
378 	bi_set_t   *set = get_set (pr, __FUNCTION__, P_INT (pr, 0));
379 	set_iter_t *iter;
380 	bi_set_iter_t *set_iter;
381 
382 	iter = set_first (set->set);
383 	if (!iter) {
384 		R_INT (pr) = 0;
385 		return;
386 	}
387 	set_iter = res_set_iter_new (res);
388 
389 	set_iter->next = res->set_iters;
390 	set_iter->prev = &res->set_iters;
391 	if (res->set_iters)
392 		res->set_iters->prev = &set_iter->next;
393 	res->set_iters = set_iter;
394 
395 	set_iter->iter = iter;;
396 
397 	R_INT (pr) = res_set_iter_index (res, set_iter);
398 }
399 
400 static void
bi_set_next(progs_t * pr)401 bi_set_next (progs_t *pr)
402 {
403 	bi_set_iter_t *set_iter = get_set_iter (pr, __FUNCTION__, P_INT (pr, 0));
404 
405 	if (!set_next (set_iter->iter)) {
406 		del_set_iter (pr, set_iter);
407 		R_INT (pr) = 0;
408 		return;
409 	}
410 	R_INT (pr) = P_INT (pr, 0);
411 }
412 
413 static void
bi_set_as_string(progs_t * pr)414 bi_set_as_string (progs_t *pr)
415 {
416 	bi_set_t   *set = get_set (pr, __FUNCTION__, P_INT (pr, 0));
417 
418 	RETURN_STRING (pr, set_as_string (set->set));
419 }
420 
421 static void
bi_i_SetIterator__element(progs_t * pr)422 bi_i_SetIterator__element (progs_t *pr)
423 {
424 	pr_set_iter_t *iter_obj = &P_STRUCT (pr, pr_set_iter_t, 0);
425 	bi_set_iter_t *set_iter = get_set_iter (pr, __FUNCTION__, iter_obj->iter);
426 
427 	R_INT (pr) = set_iter->iter->element;
428 }
429 
430 static void
bi_i_Set__add_(progs_t * pr)431 bi_i_Set__add_ (progs_t *pr)
432 {
433 	pointer_t    set_ptr = P_POINTER (pr, 0);
434 	pr_set_t    *set_obj = &G_STRUCT (pr, pr_set_t, set_ptr);
435 
436 	PR_RESET_PARAMS (pr);
437 	P_INT (pr, 0) = set_obj->set;
438 	P_INT (pr, 1) = P_INT (pr, 2);
439 	bi_set_add (pr);
440 	R_INT (pr) = set_ptr;
441 }
442 
443 static void
bi_i_Set__remove_(progs_t * pr)444 bi_i_Set__remove_ (progs_t *pr)
445 {
446 	pointer_t    set_ptr = P_POINTER (pr, 0);
447 	pr_set_t    *set_obj = &G_STRUCT (pr, pr_set_t, set_ptr);
448 
449 	PR_RESET_PARAMS (pr);
450 	P_INT (pr, 0) = set_obj->set;
451 	P_INT (pr, 1) = P_INT (pr, 2);
452 	bi_set_remove (pr);
453 	R_INT (pr) = set_ptr;
454 }
455 
456 static void
bi_i_Set__invert(progs_t * pr)457 bi_i_Set__invert (progs_t *pr)
458 {
459 	pointer_t    set_ptr = P_POINTER (pr, 0);
460 	pr_set_t    *set_obj = &G_STRUCT (pr, pr_set_t, set_ptr);
461 
462 	PR_RESET_PARAMS (pr);
463 	P_INT (pr, 0) = set_obj->set;
464 	bi_set_invert (pr);
465 	R_INT (pr) = set_ptr;
466 }
467 
468 static void
bi_i_Set__union_(progs_t * pr)469 bi_i_Set__union_ (progs_t *pr)
470 {
471 	pointer_t    dst_ptr = P_POINTER (pr, 0);
472 	pr_set_t    *dst_obj = &G_STRUCT (pr, pr_set_t, dst_ptr);
473 	pr_set_t    *src_obj = &P_STRUCT (pr, pr_set_t, 2);
474 
475 	PR_RESET_PARAMS (pr);
476 	P_INT (pr, 0) = dst_obj->set;
477 	P_INT (pr, 1) = src_obj->set;
478 	bi_set_union (pr);
479 	R_INT (pr) = dst_ptr;
480 }
481 
482 static void
bi_i_Set__intersection_(progs_t * pr)483 bi_i_Set__intersection_ (progs_t *pr)
484 {
485 	pointer_t    dst_ptr = P_POINTER (pr, 0);
486 	pr_set_t    *dst_obj = &G_STRUCT (pr, pr_set_t, dst_ptr);
487 	pr_set_t    *src_obj = &P_STRUCT (pr, pr_set_t, 2);
488 
489 	PR_RESET_PARAMS (pr);
490 	P_INT (pr, 0) = dst_obj->set;
491 	P_INT (pr, 1) = src_obj->set;
492 	bi_set_intersection (pr);
493 	R_INT (pr) = dst_ptr;
494 }
495 
496 static void
bi_i_Set__difference_(progs_t * pr)497 bi_i_Set__difference_ (progs_t *pr)
498 {
499 	pointer_t    dst_ptr = P_POINTER (pr, 0);
500 	pr_set_t    *dst_obj = &G_STRUCT (pr, pr_set_t, dst_ptr);
501 	pr_set_t    *src_obj = &P_STRUCT (pr, pr_set_t, 2);
502 
503 	PR_RESET_PARAMS (pr);
504 	P_INT (pr, 0) = dst_obj->set;
505 	P_INT (pr, 1) = src_obj->set;
506 	bi_set_difference (pr);
507 	R_INT (pr) = dst_ptr;
508 }
509 
510 static void
bi_i_Set__reverse_difference_(progs_t * pr)511 bi_i_Set__reverse_difference_ (progs_t *pr)
512 {
513 	pointer_t    dst_ptr = P_POINTER (pr, 0);
514 	pr_set_t    *dst_obj = &G_STRUCT (pr, pr_set_t, dst_ptr);
515 	pr_set_t    *src_obj = &P_STRUCT (pr, pr_set_t, 2);
516 
517 	PR_RESET_PARAMS (pr);
518 	P_INT (pr, 0) = dst_obj->set;
519 	P_INT (pr, 1) = src_obj->set;
520 	bi_set_reverse_difference (pr);
521 	R_INT (pr) = dst_ptr;
522 }
523 
524 static void
bi_i_Set__assign_(progs_t * pr)525 bi_i_Set__assign_ (progs_t *pr)
526 {
527 	pointer_t    dst_ptr = P_POINTER (pr, 0);
528 	pr_set_t    *dst_obj = &G_STRUCT (pr, pr_set_t, dst_ptr);
529 	pr_set_t    *src_obj = &P_STRUCT (pr, pr_set_t, 2);
530 
531 	PR_RESET_PARAMS (pr);
532 	P_INT (pr, 0) = dst_obj->set;
533 	P_INT (pr, 1) = src_obj->set;
534 	bi_set_assign (pr);
535 	R_INT (pr) = dst_ptr;
536 }
537 
538 static void
bi_i_Set__empty(progs_t * pr)539 bi_i_Set__empty (progs_t *pr)
540 {
541 	pointer_t    set_ptr = P_POINTER (pr, 0);
542 	pr_set_t    *set_obj = &G_STRUCT (pr, pr_set_t, set_ptr);
543 
544 	PR_RESET_PARAMS (pr);
545 	P_INT (pr, 0) = set_obj->set;
546 	bi_set_empty (pr);
547 	R_INT (pr) = set_ptr;
548 }
549 
550 static void
bi_i_Set__everything(progs_t * pr)551 bi_i_Set__everything (progs_t *pr)
552 {
553 	pointer_t    set_ptr = P_POINTER (pr, 0);
554 	pr_set_t    *set_obj = &G_STRUCT (pr, pr_set_t, set_ptr);
555 
556 	PR_RESET_PARAMS (pr);
557 	P_INT (pr, 0) = set_obj->set;
558 	bi_set_everything (pr);
559 	R_INT (pr) = set_ptr;
560 }
561 
562 static void
bi_i_Set__is_empty(progs_t * pr)563 bi_i_Set__is_empty (progs_t *pr)
564 {
565 	pr_set_t    *set_obj = &P_STRUCT (pr, pr_set_t, 0);
566 
567 	PR_RESET_PARAMS (pr);
568 	P_INT (pr, 0) = set_obj->set;
569 	bi_set_is_empty (pr);
570 }
571 
572 static void
bi_i_Set__is_everything(progs_t * pr)573 bi_i_Set__is_everything (progs_t *pr)
574 {
575 	pr_set_t    *set_obj = &P_STRUCT (pr, pr_set_t, 0);
576 
577 	PR_RESET_PARAMS (pr);
578 	P_INT (pr, 0) = set_obj->set;
579 	bi_set_is_everything (pr);
580 }
581 
582 static void
bi_i_Set__is_disjoint_(progs_t * pr)583 bi_i_Set__is_disjoint_ (progs_t *pr)
584 {
585 	pr_set_t    *s1_obj = &P_STRUCT (pr, pr_set_t, 0);
586 	pr_set_t    *s2_obj = &P_STRUCT (pr, pr_set_t, 2);
587 
588 	PR_RESET_PARAMS (pr);
589 	P_INT (pr, 0) = s1_obj->set;
590 	P_INT (pr, 1) = s2_obj->set;
591 	bi_set_is_disjoint (pr);
592 }
593 
594 static void
bi_i_Set__is_intersecting_(progs_t * pr)595 bi_i_Set__is_intersecting_ (progs_t *pr)
596 {
597 	pr_set_t    *s1_obj = &P_STRUCT (pr, pr_set_t, 0);
598 	pr_set_t    *s2_obj = &P_STRUCT (pr, pr_set_t, 2);
599 
600 	PR_RESET_PARAMS (pr);
601 	P_INT (pr, 0) = s1_obj->set;
602 	P_INT (pr, 1) = s2_obj->set;
603 	bi_set_is_intersecting (pr);
604 }
605 
606 static void
bi_i_Set__is_equivalent_(progs_t * pr)607 bi_i_Set__is_equivalent_ (progs_t *pr)
608 {
609 	pr_set_t    *s1_obj = &P_STRUCT (pr, pr_set_t, 0);
610 	pr_set_t    *s2_obj = &P_STRUCT (pr, pr_set_t, 2);
611 
612 	PR_RESET_PARAMS (pr);
613 	P_INT (pr, 0) = s1_obj->set;
614 	P_INT (pr, 1) = s2_obj->set;
615 	bi_set_is_equivalent (pr);
616 }
617 
618 static void
bi_i_Set__is_subset_(progs_t * pr)619 bi_i_Set__is_subset_ (progs_t *pr)
620 {
621 	pr_set_t    *s1_obj = &P_STRUCT (pr, pr_set_t, 0);
622 	pr_set_t    *s2_obj = &P_STRUCT (pr, pr_set_t, 2);
623 
624 	PR_RESET_PARAMS (pr);
625 	P_INT (pr, 0) = s1_obj->set;
626 	P_INT (pr, 1) = s2_obj->set;
627 	bi_set_is_subset (pr);
628 }
629 
630 static void
bi_i_Set__is_member_(progs_t * pr)631 bi_i_Set__is_member_ (progs_t *pr)
632 {
633 	pr_set_t    *set_obj = &P_STRUCT (pr, pr_set_t, 0);
634 
635 	PR_RESET_PARAMS (pr);
636 	P_INT (pr, 0) = set_obj->set;
637 	P_UINT (pr, 1) = P_UINT (pr, 2);
638 	bi_set_is_member (pr);
639 }
640 
641 static void
bi_i_Set__size(progs_t * pr)642 bi_i_Set__size (progs_t *pr)
643 {
644 	pr_set_t    *set_obj = &P_STRUCT (pr, pr_set_t, 0);
645 
646 	PR_RESET_PARAMS (pr);
647 	P_INT (pr, 0) = set_obj->set;
648 	bi_set_size (pr);
649 }
650 
651 static void
bi_i_Set__as_string(progs_t * pr)652 bi_i_Set__as_string (progs_t *pr)
653 {
654 	pr_set_t    *set_obj = &P_STRUCT (pr, pr_set_t, 0);
655 
656 	PR_RESET_PARAMS (pr);
657 	P_INT (pr, 0) = set_obj->set;
658 	bi_set_as_string (pr);
659 }
660 
661 static void
res_set_clear(progs_t * pr,void * data)662 res_set_clear (progs_t *pr, void *data)
663 {
664 	set_resources_t *res = (set_resources_t *) data;
665 	bi_set_t *set;
666 	bi_set_iter_t *set_iter;
667 
668 	for (set = res->sets; set; set = set->next)
669 		set_delete (set->set);
670 	for (set_iter = res->set_iters; set_iter; set_iter = set_iter->next)
671 		set_del_iter (set_iter->iter);
672 	res->sets = 0;
673 	res->set_iters = 0;
674 	res_set_reset (res);
675 	res_set_iter_reset (res);
676 }
677 
678 static builtin_t builtins[] = {
679 	{"set_del_iter",			bi_set_del_iter,			-1},
680 	{"set_new",					bi_set_new,					-1},
681 	{"set_delete",				bi_set_delete,				-1},
682 	{"set_add",					bi_set_add,					-1},
683 	{"set_remove",				bi_set_remove,				-1},
684 	{"set_invert",				bi_set_invert,				-1},
685 	{"set_union",				bi_set_union,				-1},
686 	{"set_intersection",		bi_set_intersection,		-1},
687 	{"set_difference",			bi_set_difference,			-1},
688 	{"set_reverse_difference",	bi_set_reverse_difference,	-1},
689 	{"set_assign",				bi_set_assign,				-1},
690 	{"set_empty",				bi_set_empty,				-1},
691 	{"set_everything",			bi_set_everything,			-1},
692 	{"set_is_empty",			bi_set_is_empty,			-1},
693 	{"set_is_everything",		bi_set_is_everything,		-1},
694 	{"set_is_disjoint",			bi_set_is_disjoint,			-1},
695 	{"set_is_intersecting",		bi_set_is_intersecting,		-1},
696 	{"set_is_equivalent",		bi_set_is_equivalent,		-1},
697 	{"set_is_subset",			bi_set_is_subset,			-1},
698 	{"set_is_member",			bi_set_is_member,			-1},
699 	{"set_size",				bi_set_size,				-1},
700 	{"set_first",				bi_set_first,				-1},
701 	{"set_next",				bi_set_next,				-1},
702 	{"set_as_string",			bi_set_as_string,			-1},
703 
704 	{"_i_SetIterator__element",	bi_i_SetIterator__element,	-1},
705 
706 	{"_i_Set__add_",				bi_i_Set__add_,					-1},
707 	{"_i_Set__remove_",				bi_i_Set__remove_,				-1},
708 	{"_i_Set__invert",				bi_i_Set__invert,				-1},
709 	{"_i_Set__union_",				bi_i_Set__union_,				-1},
710 	{"_i_Set__intersection_",		bi_i_Set__intersection_,		-1},
711 	{"_i_Set__difference_",			bi_i_Set__difference_,			-1},
712 	{"_i_Set__reverse_difference_",	bi_i_Set__reverse_difference_,	-1},
713 	{"_i_Set__assign_",				bi_i_Set__assign_,				-1},
714 	{"_i_Set__empty",				bi_i_Set__empty,				-1},
715 	{"_i_Set__everything",			bi_i_Set__everything,			-1},
716 	{"_i_Set__is_empty",			bi_i_Set__is_empty,				-1},
717 	{"_i_Set__is_everything",		bi_i_Set__is_everything,		-1},
718 	{"_i_Set__is_disjoint_",		bi_i_Set__is_disjoint_,			-1},
719 	{"_i_Set__is_intersecting_",	bi_i_Set__is_intersecting_,		-1},
720 	{"_i_Set__is_equivalent_",		bi_i_Set__is_equivalent_,		-1},
721 	{"_i_Set__is_subset_",			bi_i_Set__is_subset_,			-1},
722 	{"_i_Set__is_member_",			bi_i_Set__is_member_,			-1},
723 	{"_i_Set__size",				bi_i_Set__size,					-1},
724 	{"_i_Set__as_string",			bi_i_Set__as_string,			-1},
725 
726 	{0}
727 };
728 
729 void
RUA_Set_Init(progs_t * pr,int secure)730 RUA_Set_Init (progs_t *pr, int secure)
731 {
732 	set_resources_t *res = calloc (1, sizeof (set_resources_t));
733 	res->sets = 0;
734 
735 	PR_Resources_Register (pr, "Set", res, res_set_clear);
736 	PR_RegisterBuiltins (pr, builtins);
737 }
738